« Firewall/Router’dan Ip-MAC degisimini kontrol etmek | Home | BSDConTR Sunumları Açıklanmaya Başladı »

OpenBSD PF adres araligi destegi

By Huzeyfe ONAL | August 27, 2007

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);

Topics: OpenBSD |

6 Responses to “OpenBSD PF adres araligi destegi”

  1. abdullah Says:
    August 29th, 2007 at 8:51 am

    huzeyfe bey,

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

    tsk ederim..

  2. Huzeyfe ONAL Says:
    August 29th, 2007 at 10:40 am

    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:
    August 30th, 2007 at 4:30 pm

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

  4. ressam Says:
    September 30th, 2007 at 3:40 am

    cevabı bekliyoruz hala?

  5. Ali KORKMAZ Says:
    April 4th, 2008 at 2:08 am

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

  6. Huzeyfe ONAL Says:
    April 4th, 2008 at 8:58 am

    :)calisiyor calisiyor. Denemeye gerek yok.

Comments

Anket Köşesi


Teknik bloglarda icerik nasil olmali?
View Results

Archives

Friends

Life(over)IP Network



View my profile on Turk Blog Yazarlari