OpenBSD PF’deki en buyuk eksikliklerden biri filtreleme islemlerinde IP aralıgı kullanılamaması idi. Bu ozelligi farklı yollardan (cidr) az da olsa yapabiliyorduk fakat tam bir esneklik saglamiyordu. Nihayet PF ana gelistiricisi Daniel Hartmeier gelen isteklere daha fazla dayanamayarak @tech listesine bu destegi bir sonraki surumde eklediklerini aciklayan bir yama gonderdi.
Bundan sonra PF kullanarak
pass from 10.1.1.128 – 10.2.255.255 to any keep state
gibi kurallar yazabilecegiz.
Bir sonraki surumu beklemeden bu destegi isteyenler asagidaki yamayi sistemlerine uygulayarak kullanabilirler.
Index: sys/net/pfvar.h
===================================================================
RCS file: /cvs/src/sys/net/pfvar.h,v
retrieving revision 1.254
diff -u -r1.254 pfvar.h
--- sys/net/pfvar.h 13 Jul 2007 09:17:48 -0000 1.254
+++ sys/net/pfvar.h 24 Aug 2007 14:35:35 -0000
@@ -112,7 +112,8 @@
enum { PF_POOL_NONE, PF_POOL_BITMASK, PF_POOL_RANDOM,
PF_POOL_SRCHASH, PF_POOL_ROUNDROBIN };
enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
- PF_ADDR_TABLE, PF_ADDR_RTLABEL, PF_ADDR_URPFFAILED };
+ PF_ADDR_TABLE, PF_ADDR_RTLABEL, PF_ADDR_URPFFAILED,
+ PF_ADDR_RANGE };
#define PF_POOL_TYPEMASK 0x0f
#define PF_POOL_STICKYADDR 0x20
#define PF_WSCALE_FLAG 0x80
@@ -329,6 +330,9 @@
!pfr_match_addr((aw)->p.tbl, (x), (af))) || \
((aw)->type == PF_ADDR_DYNIFTL && \
!pfi_match_addr((aw)->p.dyn, (x), (af))) || \
+ ((aw)->type == PF_ADDR_RANGE && \
+ !pf_match_addr_range(&(aw)->v.a.addr, \
+ &(aw)->v.a.mask, (x), (af))) || \
((aw)->type == PF_ADDR_ADDRMASK && \
!PF_AZERO(&(aw)->v.a.mask, (af)) && \
!PF_MATCHA(0, &(aw)->v.a.addr, \
@@ -1611,6 +1615,8 @@
u_int8_t, struct pf_rule *, struct pf_rule *, struct pf_ruleset *,
struct pf_pdesc *);
int pf_match_addr(u_int8_t, struct pf_addr *, struct pf_addr *,
+ struct pf_addr *, sa_family_t);
+int pf_match_addr_range(struct pf_addr *, struct pf_addr *,
struct pf_addr *, sa_family_t);
int pf_match(u_int8_t, u_int32_t, u_int32_t, u_int32_t);
int pf_match_port(u_int8_t, u_int16_t, u_int16_t, u_int16_t);
Index: sys/net/pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.553
diff -u -r1.553 pf.c
--- sys/net/pf.c 23 Aug 2007 11:15:49 -0000 1.553
+++ sys/net/pf.c 24 Aug 2007 14:35:37 -0000
@@ -1790,6 +1790,44 @@
}
}
+/*
+ * Return 1 if b <= a <= e, otherwise return 0.
+ */
+int
+pf_match_addr_range(struct pf_addr *b, struct pf_addr *e,
+ struct pf_addr *a, sa_family_t af)
+{
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ if ((a->addr32[0] < b->addr32[0]) ||
+ (a->addr32[0] > e->addr32[0]))
+ return (0);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6: {
+ int i;
+
+ /* check a >= b */
+ for (i = 0; i < 4; ++i)
+ if (a->addr32[i] > b->addr32[i])
+ break;
+ else if (a->addr32[i] < b->addr32[i])
+ return (0);
+ /* check a <= e */
+ for (i = 0; i < 4; ++i)
+ if (a->addr32[i] < e->addr32[i])
+ break;
+ else if (a->addr32[i] > e->addr32[i])
+ return (0);
+ break;
+ }
+#endif /* INET6 */
+ }
+ return (1);
+}
+
int
pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p)
{
Index: sbin/pfctl/parse.y
===================================================================
RCS file: /cvs/src/sbin/pfctl/parse.y,v
retrieving revision 1.519
diff -u -r1.519 parse.y
--- sbin/pfctl/parse.y 21 Jun 2007 19:30:03 -0000 1.519
+++ sbin/pfctl/parse.y 24 Aug 2007 14:35:40 -0000
@@ -1244,6 +1244,10 @@
switch (n->addr.type) {
case PF_ADDR_ADDRMASK:
continue; /* ok */
+ case PF_ADDR_RANGE:
+ yyerror("address ranges are not "
+ "permitted inside tables");
+ break;
case PF_ADDR_DYNIFTL:
yyerror("dynamic addresses are not "
"permitted inside tables");
@@ -2494,6 +2498,36 @@
}
free($1);
+ }
+ | STRING '-' STRING {
+ struct node_host *b, *e;
+
+ if ((b = host($1)) == NULL || (e = host($3)) == NULL) {
+ free($1);
+ free($3);
+ yyerror("could not parse host specification");
+ YYERROR;
+ }
+ if (b->af != e->af ||
+ b->addr.type != PF_ADDR_ADDRMASK ||
+ e->addr.type != PF_ADDR_ADDRMASK ||
+ unmask(&b->addr.v.a.mask, b->af) != (b->af == AF_INET ? 32 : 128) ||
+ unmask(&e->addr.v.a.mask, e->af) != (e->af == AF_INET ? 32 : 128) ||
+ b->next != NULL || b->not ||
+ e->next != NULL || e->not) {
+ free(b);
+ free(e);
+ free($1);
+ free($3);
+ yyerror("invalid address range");
+ YYERROR;
+ }
+ memcpy(&b->addr.v.a.mask, &e->addr.v.a.addr, sizeof(b->addr.v.a.mask));
+ b->addr.type = PF_ADDR_RANGE;
+ $$ = b;
+ free(e);
+ free($1);
+ free($3);
}
| STRING '/' number {
char *buf;
Index: sbin/pfctl/pf_print_state.c
===================================================================
RCS file: /cvs/src/sbin/pfctl/pf_print_state.c,v
retrieving revision 1.45
diff -u -r1.45 pf_print_state.c
--- sbin/pfctl/pf_print_state.c 31 May 2007 04:13:37 -0000 1.45
+++ sbin/pfctl/pf_print_state.c 24 Aug 2007 14:35:40 -0000
@@ -79,6 +79,19 @@
else
printf("<%s>", addr->v.tblname);
return;
+ case PF_ADDR_RANGE: {
+ char buf[48];
+
+ if (inet_ntop(af, &addr->v.a.addr, buf, sizeof(buf)) == NULL)
+ printf("?");
+ else
+ printf("%s", buf);
+ if (inet_ntop(af, &addr->v.a.mask, buf, sizeof(buf)) == NULL)
+ printf(" - ?");
+ else
+ printf(" - %s", buf);
+ break;
+ }
case PF_ADDR_ADDRMASK:
if (PF_AZERO(&addr->v.a.addr, AF_INET6) &&
PF_AZERO(&addr->v.a.mask, AF_INET6))
@@ -108,7 +121,8 @@
}
/* mask if not _both_ address and mask are zero */
- if (!(PF_AZERO(&addr->v.a.addr, AF_INET6) &&
+ if (addr->type != PF_ADDR_RANGE &&
+ !(PF_AZERO(&addr->v.a.addr, AF_INET6) &&
PF_AZERO(&addr->v.a.mask, AF_INET6))) {
int bits = unmask(&addr->v.a.mask, af);
huzeyfe bey,
bu ozellik freebsd icin gecerli mi?ayrica bu yamayi nasil uyguluyacagiz
tsk ederim..
FreeBSD icin calisir mi bilmiyorum. FreeBSD’de PF’i ciddi ortamlarda kullanmadim, farklari nelerdir, nasil port edilmis hic bilgim ve ilgim yok.
Yamayi uygulamak icin once sistemdeki kaynak kodlarina bu yamayi gecip cekirdegi tekrar derlemelisiniz.
test makina da bir deneyim bakalim cevabini yazarim…
ilgilenenler icin….
cevabı bekliyoruz hala?
Ben cevabi beklemiyorum ama, 1 yila yakin olcak nerdeyse, bi deneme bukadar uzun surermi 🙂
:)calisiyor calisiyor. Denemeye gerek yok.
Tamam ozaman, yoksa icim rahat etmicekti 🙂