OpenBSD PF adres araligi destegi

pf.png

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);
This entry was posted in OpenBSD. Bookmark the permalink.

7 Responses to OpenBSD PF adres araligi destegi

  1. abdullah says:

    huzeyfe bey,

    bu ozellik freebsd icin gecerli mi?ayrica bu yamayi nasil uyguluyacagiz

    tsk ederim..

  2. Huzeyfe ONAL says:

    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.

  3. abdullah says:

    test makina da bir deneyim bakalim cevabini yazarim…
    ilgilenenler icin….

  4. ressam says:

    cevabı bekliyoruz hala?

  5. Ali KORKMAZ says:

    Ben cevabi beklemiyorum ama, 1 yila yakin olcak nerdeyse, bi deneme bukadar uzun surermi 🙂

  6. Huzeyfe ONAL says:

    :)calisiyor calisiyor. Denemeye gerek yok.

  7. Ali Korkmaz says:

    Tamam ozaman, yoksa icim rahat etmicekti 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

two × five =