Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Mar 2004 11:53:53 +0100
From:      "Mariano" <tortomari@email.it>
To:        "freebsd-ipfw" <freebsd-ipfw@freebsd.org>
Cc:        freebsd-net <freebsd-net@freebsd.org>
Subject:   Request for testing ipfw2/dummynet under ipv6
Message-ID:  <HV2U9T$474E23C8CE7B556828F1BE7687979F9C@email.it>

next in thread | raw e-mail | index | archive | help
--_=__=_XaM3_.1080125633.2A.383416.42.18170.52.42.007.27129
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

Hi, 
I've develped with my friend Raffaele De Lorenzo a working version =
of ipfw2/dummynet with the support of IPv6 protocol, this is an upgrade =0D
=
of the previous version posted on 
http://docs.freebsd.org/cgi/getmsg.cg=
i?fetch=3D44395+0+archive/2004/freebsd-ipfw/20040118.freebsd-ipfw by my s=
upervisor Luigi Rizzo in 
14 Jan. 
 
THIS IS STILL AN EVALUATION CODE,=
 DO NOT USE AS REGULAR 
 
We have solved the bugs of the previous code =
and this seems to work, the semantic of the userland interface is still u=
nder development. The 
"-h" opt will explain the actual status. 
 
Cou=
ld someone help us in the testing fase? We wait any suggestion and help. =

 
Thanks, 
Mariano e Raffaele 


--
Email.it, the professional e-mail, gratis per te: http://www.email.it/f

Sponsor:
Una torcia . Niente batterie. Per caricarla basta AGITARE!!!

Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid=3D2411&d=3D24-3
--_=__=_XaM3_.1080125633.2A.383416.42.18170.52.42.007.27129
Content-Type: text/x-diff;
	name="=?iso-8859-1?Q?20040323.diff?="
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="=?iso-8859-1?Q?20040323.diff?="

--- ./originali/ip6_forward.c	Wed Jan 14 10:43:54 2004=0A+++ ./sys/netine=
t6/ip6_forward.c	Tue Mar 23 15:15:52 2004=0A@@ -30,7 +30,7 @@=0A  * SUCH =
DAMAGE.=0A  */=0A =0A-#include "opt_ip6fw.h"=0A+#include "opt_ipfw.h"=0A =
#include "opt_inet.h"=0A #include "opt_inet6.h"=0A #include "opt_ipsec.h"=
=0A@@ -454,6 +454,8 @@=0A 		type =3D ND_REDIRECT;=0A 	}=0A =0A+#ifdef IPF=
W2	/* XXX this needs to be filled up */=0A+#else /* !IPFW2 */=0A 	/*=0A 	=
 * Check with the firewall...=0A 	 */=0A@@ -467,7 +469,7 @@=0A 		if (!m)=0A=
 			goto freecopy;=0A 	}=0A-=0A+#endif=0A 	/*=0A 	 * Fake scoped addresse=
s. Note that even link-local source or=0A 	 * destinaion can appear, if t=
he originating node just sends the=0A--- ./originali/ip6_input.c	Wed Jan =
14 10:35:41 2004=0A+++ ./sys/netinet6/ip6_input.c	Tue Mar 23 15:15:53 200=
4=0A@@ -65,7 +65,7 @@=0A  *	@(#)ip_input.c	8.2 (Berkeley) 1/4/94=0A  */=0A=
 =0A-#include "opt_ip6fw.h"=0A+#include "opt_ipfw.h"=0A #include "opt_ine=
t.h"=0A #include "opt_inet6.h"=0A #include "opt_ipsec.h"=0A@@ -119,7 +119=
,12 @@=0A #define	IPSEC=0A #endif /* FAST_IPSEC */=0A =0A+#ifdef IPFW2=0A=
+#include <netinet/ip_fw.h>=0A+#include <netinet/ip_dummynet.h>=0A+#else=0A=
 #include <netinet6/ip6_fw.h>=0A+#endif=0A =0A #include <netinet6/ip6prot=
osw.h>=0A =0A@@ -148,9 +153,11 @@=0A =0A =0A /* firewall hooks */=0A+#ifn=
def IPFW2=0A ip6_fw_chk_t *ip6_fw_chk_ptr;=0A ip6_fw_ctl_t *ip6_fw_ctl_pt=
r;=0A int ip6_fw_enable =3D 1;=0A+#endif	/* !IPFW2 */=0A =0A struct ip6st=
at ip6stat;=0A =0A@@ -263,6 +270,53 @@=0A 	int nxt, ours =3D 0;=0A 	struc=
t ifnet *deliverifp =3D NULL;=0A =0A+#ifdef IPFW2=0A+	int    i, hlen;=0A+=
#ifdef	IPDIVERT=0A+	u_int32_t divert_info =3D 0;              /* packet d=
ivert/tee info */=0A+#endif=0A+	struct ip_fw_args args;=0A+	args.eh =3D N=
ULL;=0A+	args.oif =3D NULL;=0A+	args.rule =3D NULL;=0A+	args.divert_rule =
=3D 0;                   /* divert cookie */=0A+	args.next_hop =3D NULL;=0A=
+=0A+	/* Grab info from MT_TAG mbufs prepended to the chain.  */=0A+	for =
(; m && m->m_type =3D=3D MT_TAG; m =3D m->m_next) {=0A+		switch(m->_m_tag=
_id) {=0A+		default:=0A+			printf("ip6_input: unrecognised MT_TAG tag %d\=
n",=0A+				m->_m_tag_id);=0A+			break;=0A+=0A+		case PACKET_TAG_DUMMYNET:=
=0A+			args.rule =3D ((struct dn_pkt *)m)->rule;=0A+			break;=0A+=0A+		ca=
se PACKET_TAG_DIVERT:=0A+			args.divert_rule =3D (int)m->m_hdr.mh_data & =
0xffff;=0A+			break;=0A+=0A+#if 0=0A+		/* The ipfw2 forwarding is not yet=
 implemented in ipv6  */=0A+		case PACKET_TAG_IPFORWARD:=0A+			args.next_=
hop =3D (struct sockaddr_in *)m->m_hdr.mh_data;=0A+			break;=0A+#endif=0A=
+		}=0A+	}=0A+=0A+	KASSERT(m !=3D NULL && (m->m_flags & M_PKTHDR) !=3D 0,=
=0A+			("ip6_input: no HDR"));=0A+=0A+	if (args.rule) {        /* dummyne=
t already filtered us */=0A+		ip6 =3D mtod(m, struct ip6_hdr *);=0A+		hle=
n =3D sizeof (struct ip6_hdr);=0A+		goto iphack;=0A+	}=0A+#endif /* IPFW2=
 */=0A+=0A #ifdef IPSEC=0A 	/*=0A 	 * should the inner packet be consider=
ed authentic?=0A@@ -354,6 +408,7 @@=0A 		goto bad;=0A 	}=0A =0A+iphack:=0A=
 	/*=0A 	 * Check if we want to allow this packet to be processed.=0A 	 *=
 Consider it to be bad if not.=0A@@ -375,6 +430,50 @@=0A 	/*=0A 	 * Check=
 with the firewall...=0A 	 */=0A+#ifdef IPFW2=0A+	if (fw_enable && IPFW_L=
OADED) {=0A+		/*=0A+		 * If we've been forwarded from the output side, th=
en=0A+		 * skip the firewall a second time=0A+		 */=0A+=0A+		if (args.nex=
t_hop)=0A+			ours=3D1; /* XXX check if this is correct */=0A+=0A+		args.m=
 =3D m;=0A+		i =3D ip_fw_chk_ptr(&args);=0A+		m =3D args.m;=0A+=0A+		if (=
 (i & IP_FW_PORT_DENY_FLAG) || m =3D=3D NULL) { /* drop */=0A+			if (m)=0A=
+				m_freem(m);=0A+			return;=0A+		}=0A+		ip6 =3D mtod(m, struct ip6_hdr=
 *); /* just in case m changed */=0A+		if (i =3D=3D 0 && args.next_hop =3D=
=3D NULL)    /* common case */=0A+			goto pass;=0A+		if (DUMMYNET_LOADED =
&& (i & IP_FW_PORT_DYNT_FLAG) !=3D 0) {=0A+			/* Send packet to the appro=
priate pipe */=0A+			ip_dn_io_ptr(m, i & 0xffff, DN_TO_IP6_IN, &args);=0A=
+			return;=0A+		}=0A+#ifdef IPDIVERT=0A+		if (i !=3D 0 && (i & IP_FW_POR=
T_DYNT_FLAG) =3D=3D 0) {=0A+			/* Divert or tee packet */=0A+			divert_in=
fo =3D i;=0A+			ours=3D1;=0A+		}=0A+#endif=0A+		if (i =3D=3D 0 && args.ne=
xt_hop !=3D NULL)=0A+			goto pass;=0A+		/*=0A+		 * if we get here, the pa=
cket must be dropped=0A+		 */=0A+		m_freem(m);=0A+		return;=0A+	}=0A+pass=
:=0A+#else	/* !IPFW2, use the old firewall */=0A 	if (ip6_fw_enable && ip=
6_fw_chk_ptr) {=0A 		u_short port =3D 0;=0A 		/* If ipfw says divert, we =
have to just drop packet */=0A@@ -386,6 +485,7 @@=0A 		if (!m)=0A 			retu=
rn;=0A 	}=0A+#endif	/* !IPFW2 */=0A =0A 	/*=0A 	 * Check against address =
spoofing/corruption.=0A--- ./originali/ip6_output.c	Wed Jan 14 10:35:41 2=
004=0A+++ ./sys/netinet6/ip6_output.c	Tue Mar 23 15:15:52 2004=0A@@ -65,7=
 +65,7 @@=0A  *	@(#)ip_output.c	8.3 (Berkeley) 1/21/94=0A  */=0A =0A-#inc=
lude "opt_ip6fw.h"=0A+#include "opt_ipfw.h"=0A #include "opt_inet.h"=0A #=
include "opt_inet6.h"=0A #include "opt_ipsec.h"=0A@@ -107,7 +107,13 @@=0A=
 #include <netipsec/key.h>=0A #endif /* FAST_IPSEC */=0A =0A+#ifdef IPFW2=
=0A+#include <netinet/ip_var.h>=0A+#include <netinet/ip_fw.h>=0A+#include=
 <netinet/ip_dummynet.h>=0A+#else  /* use old ip6fw */=0A #include <netin=
et6/ip6_fw.h>=0A+#endif=0A =0A #include <net/net_osdep.h>=0A =0A@@ -169,6=
 +175,9 @@=0A 	struct route_in6 *ro_pmtu =3D NULL;=0A 	int hdrsplit =3D 0=
;=0A 	int needipsec =3D 0;=0A+#ifdef	IPFW2=0A+	struct ip_fw_args args;=0A=
+#endif=0A #ifdef IPSEC=0A 	int needipsectun =3D 0;=0A 	struct secpolicy =
*sp =3D NULL;=0A@@ -183,6 +192,66 @@=0A 	ip6 =3D mtod(m, struct ip6_hdr *=
);=0A #endif /* FAST_IPSEC */=0A =0A+#ifdef IPFW2=0A+	args.eh =3D NULL;=0A=
+	args.rule =3D NULL;=0A+	args.next_hop =3D NULL;=0A+	args.divert_rule =3D=
 0;                   /* divert cookie */=0A+=0A+	/* Grab info from MT_TA=
G mbufs prepended to the chain. */=0A+	for (; m0 && m0->m_type =3D=3D MT_=
TAG; m0 =3D m0->m_next) {=0A+		switch(m0->_m_tag_id) {=0A+		default:=0A+	=
		printf("ip6_output: unrecognised MT_TAG tag %d\n",=0A+				m0->_m_tag_id=
);=0A+			break;=0A+=0A+		case PACKET_TAG_DUMMYNET:=0A+			/*=0A+			 * the =
packet was already tagged, so part of the=0A+			 * processing was already=
 done, and we need to go down.=0A+			 * Get parameters from the header.=0A=
+			 */=0A+			opt =3D NULL;=0A+			ro =3D &((struct dn_pkt *)m0)->ip6opt.r=
o_or;=0A+			flags =3D ((struct dn_pkt *)m0)->ip6opt.flags_or;=0A+        =
                im6o =3D NULL;=0A+			origifp =3D ((struct dn_pkt *)m0)->i=
p6opt.origifp_or;=0A+			ifp =3D ((struct dn_pkt *)m0)->ip6opt.ifp_or; =0A=
+			dst =3D  &((struct dn_pkt *)m0)->ip6opt.dst_or;=0A+			args.rule=3D((s=
truct dn_pkt *)m0)->rule;=0A+			break;=0A+=0A+		case PACKET_TAG_DIVERT:=0A=
+			args.divert_rule =3D (int)m0->m_data & 0xffff;=0A+			break;=0A+=0A+#i=
f 0=0A+		/* ipfw2 Forwarding is not yet supported in ipv6 */=0A+		case PA=
CKET_TAG_IPFORWARD:=0A+			args.next_hop =3D (struct sockaddr_in *)m0->m_d=
ata;=0A+			break;=0A+#endif=0A+		}=0A+	}=0A+	m =3D m0; =0A+=0A+	KASSERT(!=
m || (m->m_flags & M_PKTHDR) !=3D 0, ("ip6_output: no HDR"));=0A+#ifndef =
FAST_IPSEC=0A+	KASSERT(ro !=3D NULL, ("ip6_output: no route\n"));=0A+#end=
if=0A+=0A+	if (args.rule ) {        /* dummynet already saw us */=0A+		ip=
6 =3D mtod(m, struct ip6_hdr *);=0A+		hlen =3D sizeof (struct ip6_hdr) ;=0A=
+		if (ro->ro_rt)=0A+			ia =3D ifatoia6(ro->ro_rt->rt_ifa);=0A+	        b=
zero(&exthdrs, sizeof(exthdrs));=0A+		ro_pmtu =3D ro;=0A+		goto send_afte=
r_dummynet;=0A+	}=0A+#endif	/* IPFW2 */=0A+=0A #define MAKE_EXTHDR(hp, mp=
)						\=0A     do {								\=0A 	if (hp) {							\=0A@@ -455,7 +524,6 @@=
=0A skip_ipsec2:;=0A #endif=0A 	}=0A-=0A 	/*=0A 	 * If there is a routing=
 header, replace destination address field=0A 	 * with the first hop of t=
he routing header.=0A@@ -581,7 +649,6 @@=0A 		exthdrs.ip6e_ip6 =3D m;=0A =
	}=0A #endif /* IPSEC */=0A-=0A 	if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst=
)) {=0A 		/* Unicast */=0A =0A@@ -760,7 +827,6 @@=0A 			goto done;=0A 		}=
=0A 	}=0A-=0A 	/*=0A 	 * Fill the outgoing inteface to tell the upper lay=
er=0A 	 * to increment per-interface statistics.=0A@@ -768,6 +834,7 @@=0A=
 	if (ifpp)=0A 		*ifpp =3D ifp;=0A =0A+send_after_dummynet:=0A 	/*=0A 	 *=
 Determine path MTU.=0A 	 */=0A@@ -866,10 +933,71 @@=0A 	in6_clearscope(&=
ip6->ip6_src);=0A 	in6_clearscope(&ip6->ip6_dst);=0A #endif=0A-=0A 	/*=0A=
 	 * Check with the firewall...=0A 	 */=0A+#ifdef IPFW2=0A+	if (fw_enable=
 && IPFW_LOADED && !args.next_hop) {=0A+		/* =0A+		 * Check with the fire=
wall IPFW2...=0A+		 * but not if we are already being fwd'd from a firewa=
ll.=0A+		 */=0A+=0A+		struct sockaddr_in6 *old =3D dst;=0A+		args.m =3D m=
;=0A+		args.next_hop =3D (struct sockaddr_in *) dst;=0A+		args.oif =3D if=
p;=0A+		off =3D ip_fw_chk_ptr(&args);=0A+		m =3D args.m;=0A+		dst =3D (st=
ruct sockaddr_in6 *) args.next_hop;=0A+=0A+		/*=0A+		 * On return we must=
 do the following:=0A+		 * m =3D=3D NULL    -> drop the pkt (old interfac=
e, deprecated)=0A+		 * (off & IP_FW_PORT_DENY_FLAG) -> drop the pkt (new =
interface)=0A+		 * 1<=3Doff<=3D 0xffff              -> DIVERT=0A+		 * (of=
f & IP_FW_PORT_DYNT_FLAG) -> send to a DUMMYNET pipe=0A+		 * (off & IP_FW=
_PORT_TEE_FLAG)  -> TEE the packet=0A+		 * dst !=3D old                  =
 -> IPFIREWALL_FORWARD=0A+		 * off=3D=3D0, dst=3D=3Dold             -> ac=
cept=0A+		 * If some of the above modules are not compiled in, then=0A+		=
 * we should't have to check the corresponding condition=0A+		 * (because=
 the ipfw control socket should not accept=0A+		 * unsupported rules), bu=
t better play safe and drop=0A+		 * packets in case of doubt.=0A+		 */=0A=
+		if ( (off & IP_FW_PORT_DENY_FLAG) || m =3D=3D NULL) {=0A+			if (m)=0A+=
				m_freem(m);=0A+			error =3D EACCES;=0A+			goto done;=0A+		}=0A+		ip6 =
=3D mtod(m, struct ip6_hdr *);   /* XXX check if necessary */=0A+		if (of=
f =3D=3D 0 && dst =3D=3D old)             /* common case */=0A+			goto pa=
ss6;=0A+		if (DUMMYNET_LOADED && (off & IP_FW_PORT_DYNT_FLAG) !=3D 0) {=0A=
+			/*=0A+			 * pass the pkt to dummynet. Need to include=0A+			 * pipe n=
umber, m, ifp, ro, dst because these are=0A+			 * not recomputed in the n=
ext pass.=0A+			 * All other parameters have been already used and=0A+			=
 * so they are not needed anymore. =0A+			 * XXX note: if the ifp or ro e=
ntry are deleted=0A+			 * while a pkt is in dummynet, we are in trouble!=0A=
+			 */ =0A+			args.dummypar.ro_or =3D *ro;=0A+			args.dummypar.flags_or =
=3D flags;=0A+			args.dummypar.ifp_or =3D ifp;=0A+			args.dummypar.origif=
p_or =3D origifp;=0A+			args.dummypar.dst_or =3D *dst;=0A+			args.flags =3D=
 flags;=0A+			error =3D ip_dn_io_ptr(m, off & 0xffff, DN_TO_IP6_OUT,=0A+	=
			&args);=0A+			goto done;=0A+		}=0A+	}=0A+pass6:=0A+#else	/* !IPFW2 */=0A=
 	if (ip6_fw_enable && ip6_fw_chk_ptr) {=0A 		u_short port =3D 0;=0A 		m-=
>m_pkthdr.rcvif =3D NULL;	/* XXX */=0A@@ -883,7 +1011,7 @@=0A 			goto don=
e;=0A 		}=0A 	}=0A-=0A+#endif	/* !IPFW2 */=0A 	/*=0A 	 * If the outgoing =
packet contains a hop-by-hop options header,=0A 	 * it must be examined a=
nd processed even by the source node.=0A@@ -1115,7 +1243,6 @@=0A 	if (sp =
!=3D NULL)=0A 		KEY_FREESP(&sp);=0A #endif /* FAST_IPSEC */=0A-=0A 	retur=
n(error);=0A =0A freehdrs:=0A@@ -1548,6 +1675,7 @@=0A 				break;=0A #endi=
f /* KAME IPSEC */=0A =0A+#ifndef IPFW2=0A 			case IPV6_FW_ADD:=0A 			cas=
e IPV6_FW_DEL:=0A 			case IPV6_FW_FLUSH:=0A@@ -1568,7 +1696,7 @@=0A 				m=
 =3D *mp;=0A 			    }=0A 				break;=0A-=0A+#endif /* !IPFW2 */=0A 			defa=
ult:=0A 				error =3D ENOPROTOOPT;=0A 				break;=0A@@ -1708,6 +1836,7 @@=0A=
 			  }=0A #endif /* KAME IPSEC */=0A =0A+#ifndef IPFW2=0A 			case IPV6_F=
W_GET:=0A 			  {=0A 				struct mbuf *m;=0A@@ -1724,6 +1853,7 @@=0A 					m=
_freem(m);=0A 			  }=0A 				break;=0A+#endif /* !IPFW2 */=0A =0A 			defau=
lt:=0A 				error =3D ENOPROTOOPT;=0A@@ -2046,8 +2176,8 @@=0A 		/*=0A 		 *=
 If the interface is specified, validate it.=0A 		 */=0A-		if (mreq->ipv6=
mr_interface < 0=0A-		 || if_index < mreq->ipv6mr_interface) {=0A+		if (m=
req->ipv6mr_interface < 0 ||=0A+		    if_index < mreq->ipv6mr_interface) =
{=0A 			error =3D ENXIO;	/* XXX EINVAL? */=0A 			break;=0A 		}=0A@@ -2097=
,7 +2227,7 @@=0A 		 */=0A 		if (IN6_IS_ADDR_MC_LINKLOCAL(&mreq->ipv6mr_mu=
ltiaddr)) {=0A 			mreq->ipv6mr_multiaddr.s6_addr16[1]=0A-				=3D htons(mr=
eq->ipv6mr_interface);=0A+				=3D htons(ifp->if_index);=0A 		}=0A 		/*=0A=
 		 * See if the membership already exists.=0A--- ./originali/ip_dummynet=
.c	Wed Jan 14 10:35:41 2004=0A+++ ./sys/netinet/ip_dummynet.c	Tue Mar 23 =
15:15:53 2004=0A@@ -85,6 +85,9 @@=0A #include <netinet/if_ether.h> /* for=
 struct arpcom */=0A #include <net/bridge.h>=0A =0A+#include <netinet/ip6=
.h>	/* for ip6_input, ip6_output prototypes */=0A+#include <netinet6/ip6_=
var.h>=0A+=0A /*=0A  * We keep a private variable for the simulation time=
, but we could=0A  * probably use an existing one ("softticks" in sys/ker=
n/kern_timer.c)=0A@@ -435,6 +438,16 @@=0A 	    ip_input((struct mbuf *)pk=
t) ;=0A 	    break ;=0A =0A+	case DN_TO_IP6_IN:=0A+	    ip6_input((struct=
 mbuf *)pkt) ; =0A+	    break ;=0A+=0A+	case DN_TO_IP6_OUT:=0A+	    (void=
)ip6_output((struct mbuf *)pkt, NULL, NULL, 0,=0A+			NULL, NULL, NULL); =0A=
+	    rt_unref (pkt->ip6opt.ro_or.ro_rt) ;=0A+	    break ;=0A+=0A 	case D=
N_TO_BDG_FWD :=0A 	    if (!BDG_LOADED) {=0A 		/* somebody unloaded the b=
ridge module. Drop pkt */=0A@@ -863,37 +876,80 @@=0A {=0A     int i =3D 0=
 ; /* we need i and q for new allocations */=0A     struct dn_flow_queue =
*q, *prev;=0A+    int is_v6 =3D IS_IP6_FLOW_ID(id);=0A =0A     if ( !(fs-=
>flags_fs & DN_HAVE_FLOW_MASK) )=0A 	q =3D fs->rq[0] ;=0A     else {=0A-	=
/* first, do the masking */=0A-	id->dst_ip &=3D fs->flow_mask.dst_ip ;=0A=
-	id->src_ip &=3D fs->flow_mask.src_ip ;=0A+	/* first, do the masking, th=
en hash */=0A 	id->dst_port &=3D fs->flow_mask.dst_port ;=0A 	id->src_por=
t &=3D fs->flow_mask.src_port ;=0A 	id->proto &=3D fs->flow_mask.proto ;=0A=
 	id->flags =3D 0 ; /* we don't care about this one */=0A-	/* then, hash =
function */=0A-	i =3D ( (id->dst_ip) & 0xffff ) ^=0A-	    ( (id->dst_ip >=
> 15) & 0xffff ) ^=0A-	    ( (id->src_ip << 1) & 0xffff ) ^=0A-	    ( (id=
->src_ip >> 16 ) & 0xffff ) ^=0A-	    (id->dst_port << 1) ^ (id->src_port=
) ^=0A-	    (id->proto );=0A+	if (is_v6) {=0A+	    APPLY_MASK(&id->dst_ip=
6, &fs->flow_mask.dst_ip6);=0A+	    APPLY_MASK(&id->src_ip6, &fs->flow_ma=
sk.src_ip6);=0A+	    id->flow_id6 &=3D fs->flow_mask.flow_id6;=0A+=0A+	  =
  i =3D ((id->dst_ip6.__u6_addr.__u6_addr32[0]) & 0xffff)^=0A+		((id->dst=
_ip6.__u6_addr.__u6_addr32[1]) & 0xffff)^ =0A+		((id->dst_ip6.__u6_addr._=
_u6_addr32[2]) & 0xffff)^=0A+		((id->dst_ip6.__u6_addr.__u6_addr32[3]) & =
0xffff)^=0A+=0A+		((id->dst_ip6.__u6_addr.__u6_addr32[0] >> 15) & 0xffff)=
^=0A+		((id->dst_ip6.__u6_addr.__u6_addr32[1] >> 15) & 0xffff)^ =0A+		((i=
d->dst_ip6.__u6_addr.__u6_addr32[2] >> 15) & 0xffff)^=0A+		((id->dst_ip6.=
__u6_addr.__u6_addr32[3] >> 15) & 0xffff)^=0A+=0A+		((id->src_ip6.__u6_ad=
dr.__u6_addr32[0] << 1) & 0xfffff)^=0A+		((id->src_ip6.__u6_addr.__u6_add=
r32[1] << 1) & 0xfffff)^ =0A+		((id->src_ip6.__u6_addr.__u6_addr32[2] << =
1) & 0xfffff)^=0A+		((id->src_ip6.__u6_addr.__u6_addr32[3] << 1) & 0xffff=
f)^=0A+=0A+		((id->src_ip6.__u6_addr.__u6_addr32[0] << 16) & 0xffff)^=0A+=
		((id->src_ip6.__u6_addr.__u6_addr32[1] << 16) & 0xffff)^ =0A+		((id->sr=
c_ip6.__u6_addr.__u6_addr32[2] << 16) & 0xffff)^=0A+		((id->src_ip6.__u6_=
addr.__u6_addr32[3] << 16) & 0xffff)^=0A+=0A+		(id->dst_port << 1) ^ (id-=
>src_port) ^=0A+		(id->proto ) ^=0A+		(id->flow_id6);=0A+	} else {=0A+	  =
  id->dst_ip &=3D fs->flow_mask.dst_ip ;=0A+	    id->src_ip &=3D fs->flow=
_mask.src_ip ;=0A+=0A+	    i =3D ( (id->dst_ip) & 0xffff ) ^=0A+		( (id->=
dst_ip >> 15) & 0xffff ) ^=0A+		( (id->src_ip << 1) & 0xffff ) ^=0A+		( (=
id->src_ip >> 16 ) & 0xffff ) ^=0A+		(id->dst_port << 1) ^ (id->src_port)=
 ^=0A+		(id->proto );=0A+	}=0A 	i =3D i % fs->rq_size ;=0A 	/* finally, s=
can the current list for a match */=0A 	searches++ ;=0A 	for (prev=3DNULL=
, q =3D fs->rq[i] ; q ; ) {=0A 	    search_steps++;=0A-	    if (id->dst_i=
p =3D=3D q->id.dst_ip &&=0A+	    if (is_v6 &&=0A+		    IN6_ARE_ADDR_EQUAL=
(&id->dst_ip6,&q->id.dst_ip6) &&=0A+		    IN6_ARE_ADDR_EQUAL(&id->src_ip6=
,&q->id.src_ip6) &&=0A+		    id->dst_port =3D=3D q->id.dst_port &&=0A+		 =
   id->src_port =3D=3D q->id.src_port &&=0A+		    id->proto =3D=3D q->id.=
proto &&=0A+		    id->flags =3D=3D q->id.flags &&=0A+		    id->flow_id6 =3D=
=3D q->id.flow_id6)=0A+		break ; /* found */=0A+=0A+	    if (!is_v6 && id=
->dst_ip =3D=3D q->id.dst_ip &&=0A 		    id->src_ip =3D=3D q->id.src_ip &=
&=0A 		    id->dst_port =3D=3D q->id.dst_port &&=0A 		    id->src_port =3D=
=3D q->id.src_port &&=0A 		    id->proto =3D=3D q->id.proto &&=0A 		    i=
d->flags =3D=3D q->id.flags)=0A 		break ; /* found */=0A-	    else if (pi=
pe_expire && q->head =3D=3D NULL && q->S =3D=3D q->F+1 ) {=0A+=0A+	    /*=
 No match. Check if we can expire the entry */=0A+	    if (pipe_expire &&=
 q->head =3D=3D NULL && q->S =3D=3D q->F+1 ) {=0A 		/* entry is idle and =
not in any heap, expire it */=0A 		struct dn_flow_queue *old_q =3D q ;=0A=
 =0A@@ -917,7 +973,7 @@=0A     if (q =3D=3D NULL) { /* no match, need to =
allocate a new entry */=0A 	q =3D create_queue(fs, i);=0A 	if (q !=3D NUL=
L)=0A-	q->id =3D *id ;=0A+	    q->id =3D *id ;=0A     }=0A     return q ;=
=0A }=0A@@ -1030,7 +1086,7 @@=0A {=0A #if IPFW2=0A     struct dn_flow_set=
 *fs;=0A-    ipfw_insn *cmd =3D rule->cmd + rule->act_ofs;=0A+    ipfw_in=
sn *cmd =3D ACTION_PTR(rule);=0A =0A     if (cmd->opcode =3D=3D O_LOG)=0A=
 	cmd +=3D F_LEN(cmd);=0A@@ -1099,7 +1155,7 @@=0A     int s =3D splimp();=
=0A     int is_pipe;=0A #if IPFW2=0A-    ipfw_insn *cmd =3D fwa->rule->cm=
d + fwa->rule->act_ofs;=0A+    ipfw_insn *cmd =3D ACTION_PTR(fwa->rule);=0A=
 =0A     if (cmd->opcode =3D=3D O_LOG)=0A 	cmd +=3D F_LEN(cmd);=0A@@ -117=
7,6 +1233,15 @@=0A =0A 	pkt->dn_dst =3D fwa->dst;=0A 	pkt->flags =3D fwa-=
>flags;=0A+    } else if (dir =3D=3D DN_TO_IP6_OUT) {=0A+	pkt->ip6opt.ro_=
or =3D fwa->dummypar.ro_or;=0A+	pkt->ip6opt.flags_or =3D fwa->dummypar.fl=
ags_or;=0A+	pkt->ip6opt.origifp_or =3D fwa->dummypar.origifp_or;=0A+	pkt-=
>ip6opt.ifp_or =3D fwa->dummypar.ifp_or;=0A+	pkt->ip6opt.dst_or =3D fwa->=
dummypar.dst_or;=0A+	if (fwa->dummypar.ro_or.ro_rt)=0A+	    fwa->dummypar=
.ro_or.ro_rt->rt_refcnt++;=0A+	pkt->flags =3D fwa->flags;=0A     }=0A    =
 if (q->head =3D=3D NULL)=0A 	q->head =3D pkt;=0A@@ -1275,6 +1340,7 @@=0A=
  */=0A #define DN_FREE_PKT(pkt)	{		\=0A 	struct dn_pkt *n =3D pkt ;		\=0A=
+	rt_unref ( n->ip6opt.ro_or.ro_rt ); /* XXX */	\=0A 	rt_unref ( n->ro.ro=
_rt ) ;		\=0A 	m_freem(n->dn_m);			\=0A 	pkt =3D DN_NEXT(n) ;			\=0A@@ -1=
937,7 +2003,7 @@=0A static void=0A ip_dn_init(void)=0A {=0A-    printf("D=
UMMYNET initialized (011031)\n");=0A+    printf("DUMMYNET with IPv6 initi=
alized (040114)\n");=0A     all_pipes =3D NULL ;=0A     all_flow_sets =3D=
 NULL ;=0A     ready_heap.size =3D ready_heap.elements =3D 0 ;=0A--- ./or=
iginali/ip_dummynet.h	Wed Jan 14 10:35:41 2004=0A+++ ./sys/netinet/ip_dum=
mynet.h	Tue Mar 23 15:15:53 2004=0A@@ -109,6 +109,7 @@=0A     struct dn_h=
eap_entry *p ;	/* really an array of "size" entries */=0A } ;=0A =0A+#ifd=
ef _KERNEL=0A /*=0A  * struct dn_pkt identifies a packet in the dummynet =
queue, but=0A  * is also used to tag packets passed back to the various d=
estinations=0A@@ -135,13 +136,17 @@=0A #define DN_TO_BDG_FWD	3=0A #define=
 DN_TO_ETH_DEMUX	4=0A #define DN_TO_ETH_OUT	5=0A+#define DN_TO_IP6_IN	6=0A=
+#define DN_TO_IP6_OUT	7=0A =0A     dn_key output_time;		/* when the pkt =
is due for delivery	*/=0A     struct ifnet *ifp;		/* interface, for ip_ou=
tput		*/=0A     struct sockaddr_in *dn_dst ;=0A     struct route ro;		/* =
route, for ip_output. MUST COPY	*/=0A     int flags ;			/* flags, for ip_=
output (IPv6 ?)	*/=0A+    struct _ip6dn_args ip6opt;	/* XXX ipv6 options	=
		*/=0A };=0A+#endif /* _KERNEL */=0A =0A /*=0A  * Overall structure of d=
ummynet (with WF2Q+):=0A--- ./originali/ip_fw2.c	Wed Jan 14 10:35:41 2004=
=0A+++ ./sys/netinet/ip_fw2.c	Tue Mar 23 15:15:53 2004=0A@@ -37,6 +37,7 @=
@=0A #include "opt_ipdn.h"=0A #include "opt_ipdivert.h"=0A #include "opt_=
inet.h"=0A+#include "opt_ipsec.h"=0A #ifndef INET=0A #error IPFIREWALL re=
quires INET.=0A #endif /* INET */=0A@@ -76,6 +77,9 @@=0A #include <netine=
t6/ipsec.h>=0A #endif=0A =0A+#include <netinet/ip6.h>=0A+#include <netine=
t/icmp6.h>=0A+=0A #include <netinet/if_ether.h> /* XXX for ETHERTYPE_IP *=
/=0A =0A #include <machine/in_cksum.h>	/* XXX for in_cksum */=0A@@ -234,1=
4 +238,19 @@=0A ip_dn_ruledel_t *ip_dn_ruledel_ptr =3D NULL;	/* hook into=
 dummynet */=0A =0A /*=0A- * This macro maps an ip pointer into a layer3 =
header pointer of type T=0A+ * L3HDR maps an ipv4 pointer into a layer3 h=
eader pointer of type T=0A+ * Other macros just cast void * into the appr=
opriate type=0A  */=0A #define	L3HDR(T, ip) ((T *)((u_int32_t *)(ip) + (i=
p)->ip_hl))=0A+#define	TCP(p) ((struct tcphdr *)(p))=0A+#define	UDP(p) ((=
struct udphdr *)(p))=0A+#define	ICMP(p) ((struct icmp *)(p))=0A+#define I=
CMP6(p) ((struct icmp6_hdr *)(p))=0A =0A static __inline int=0A-icmptype_=
match(struct ip *ip, ipfw_insn_u32 *cmd)=0A+icmptype_match(struct icmp *i=
cmp, ipfw_insn_u32 *cmd)=0A {=0A-	int type =3D L3HDR(struct icmp,ip)->icm=
p_type;=0A+	int type =3D icmp->icmp_type;=0A =0A 	return (type <=3D ICMP_=
MAXTYPE && (cmd->d[0] & (1<<type)) );=0A }=0A@@ -250,9 +259,10 @@=0A     =
(1 << ICMP_TSTAMP) | (1 << ICMP_IREQ) | (1 << ICMP_MASKREQ) )=0A =0A stat=
ic int=0A-is_icmp_query(struct ip *ip)=0A+is_icmp_query(struct icmp *icmp=
)=0A {=0A-	int type =3D L3HDR(struct icmp, ip)->icmp_type;=0A+	int type =3D=
 icmp->icmp_type;=0A+=0A 	return (type <=3D ICMP_MAXTYPE && (TT & (1<<typ=
e)) );=0A }=0A #undef TT=0A@@ -328,10 +338,9 @@=0A }=0A =0A static int=0A=
-tcpopts_match(struct ip *ip, ipfw_insn *cmd)=0A+tcpopts_match(struct tcp=
hdr *tcp, ipfw_insn *cmd)=0A {=0A 	int optlen, bits =3D 0;=0A-	struct tcp=
hdr *tcp =3D L3HDR(struct tcphdr,ip);=0A 	u_char *cp =3D (u_char *)(tcp +=
 1);=0A 	int x =3D (tcp->th_off << 2) - sizeof(struct tcphdr);=0A =0A@@ -=
449,6 +458,83 @@=0A 	return 1;=0A }=0A =0A+/*=0A+ * ipv6 specific rules h=
ere...=0A+ */=0A+static __inline int=0A+icmp6type_match (int type, ipfw_i=
nsn_u32 *cmd)=0A+{=0A+	return (type <=3D ICMP6_MAXTYPE && (cmd->d[type/32=
] & (1<<(type%32)) ) );=0A+}=0A+=0A+static int=0A+flow6id_match( int curr=
_flow, ipfw_insn_u32 *cmd )=0A+{=0A+	int i;=0A+	for (i=3D0; i <=3D cmd->o=
.arg1; ++i )=0A+		if (curr_flow =3D=3D cmd->d[i] )=0A+			return 1;=0A+	re=
turn 0;=0A+}=0A+=0A+/* support for IP6_*_ME opcodes */=0A+static int=0A+s=
earch_ip6_addr_net (struct in6_addr * ip6_addr)=0A+{=0A+	struct ifnet *md=
c;=0A+	struct ifaddr *mdc2;=0A+	struct in6_ifaddr *fdm;=0A+	struct in6_ad=
dr copia;=0A+=0A+	TAILQ_FOREACH(mdc, &ifnet, if_link)=0A+		for (mdc2 =3D =
mdc->if_addrlist.tqh_first; mdc2;=0A+		    mdc2 =3D mdc2->ifa_list.tqe_ne=
xt) {=0A+			if (!mdc2->ifa_addr)=0A+				continue;=0A+			if (mdc2->ifa_add=
r->sa_family =3D=3D AF_INET6) {=0A+				fdm =3D (struct in6_ifaddr *)mdc2;=
=0A+				copia =3D fdm->ia_addr.sin6_addr;=0A+				/* need for leaving scop=
e_id in the sock_addr */=0A+				in6_clearscope(&copia);=0A+				if (IN6_AR=
E_ADDR_EQUAL(ip6_addr, &copia))=0A+					return 1;=0A+			}=0A+		}=0A+	retu=
rn 0;=0A+}=0A+=0A+static int=0A+verify_rev_path6(struct in6_addr *src, st=
ruct ifnet *ifp)=0A+{=0A+	static struct route_in6 ro;=0A+	struct sockaddr=
_in6 *dst;=0A+=0A+	dst =3D (struct sockaddr_in6 * )&(ro.ro_dst);=0A+=0A+	=
if ( !(IN6_ARE_ADDR_EQUAL (src, &dst->sin6_addr) )) {=0A+		bzero(dst, siz=
eof(*dst));=0A+		dst->sin6_family =3D AF_INET6;=0A+		dst->sin6_len =3D si=
zeof(*dst);=0A+		dst->sin6_addr =3D *src;=0A+		rtalloc_ign((struct route =
*)&ro, RTF_CLONING | RTF_PRCLONING);=0A+	}=0A+	if ((ro.ro_rt =3D=3D NULL)=
 || (ifp =3D=3D NULL) ||=0A+	    (ro.ro_rt->rt_ifp->if_index !=3D ifp->if=
_index))=0A+		return 0;=0A+	return 1;=0A+}=0A+static __inline int=0A+hash=
_packet6(struct ipfw_flow_id *id)=0A+{=0A+	u_int32_t i;=0A+	i=3D (id->dst=
_ip6.__u6_addr.__u6_addr32[0]) ^=0A+	(id->dst_ip6.__u6_addr.__u6_addr32[1=
]) ^=0A+	(id->dst_ip6.__u6_addr.__u6_addr32[2]) ^=0A+	(id->dst_ip6.__u6_a=
ddr.__u6_addr32[3]) ^=0A+	(id->dst_port) ^ (id->src_port) ^ (id->flow_id6=
);=0A+	return i;=0A+}=0A+/* end of ipv6 opcodes */=0A =0A static u_int64_=
t norule_counter;	/* counter for ipfw_log(NULL...) */=0A =0A@@ -653,7 +73=
9,9 @@=0A {=0A 	u_int32_t i;=0A =0A-	i =3D (id->dst_ip) ^ (id->src_ip) ^ =
(id->dst_port) ^ (id->src_port);=0A+	i =3D IS_IP6_FLOW_ID(id) ? hash_pack=
et6(id):=0A+		(id->dst_ip) ^ (id->src_ip) ^ (id->dst_port) ^ (id->src_por=
t);=0A+=0A 	i &=3D (curr_dyn_buckets - 1);=0A 	return i;=0A }=0A@@ -778,7=
 +866,7 @@=0A =0A 	if (ipfw_dyn_v =3D=3D NULL)=0A 		goto done;	/* not fou=
nd */=0A-	i =3D hash_packet( pkt );=0A+	i =3D hash_packet(pkt);=0A 	for (=
prev=3DNULL, q =3D ipfw_dyn_v[i] ; q !=3D NULL ; ) {=0A 		if (q->dyn_type=
 =3D=3D O_LIMIT_PARENT && q->count)=0A 			goto next;=0A@@ -788,6 +876,27 =
@@=0A 		}=0A 		if (pkt->proto =3D=3D q->id.proto &&=0A 		    q->dyn_type =
!=3D O_LIMIT_PARENT) {=0A+		      if (IS_IP6_FLOW_ID(pkt)) {=0A+			if (IN=
6_ARE_ADDR_EQUAL(&(pkt->src_ip6),=0A+				&(q->id.src_ip6)) &&=0A+			    I=
N6_ARE_ADDR_EQUAL(&(pkt->dst_ip6),=0A+				&(q->id.dst_ip6)) &&=0A+			    =
pkt->src_port =3D=3D q->id.src_port &&=0A+			    pkt->dst_port =3D=3D q->=
id.dst_port ) {=0A+				dir =3D MATCH_FORWARD;=0A+				break;=0A+			}=0A+		=
	if (IN6_ARE_ADDR_EQUAL(&(pkt->src_ip6),=0A+				&(q->id.dst_ip6)) &&=0A+	=
		    IN6_ARE_ADDR_EQUAL(&(pkt->dst_ip6),=0A+				&(q->id.src_ip6)) &&=0A+=
			    pkt->src_port =3D=3D q->id.dst_port &&=0A+			    pkt->dst_port =3D=
=3D q->id.src_port ) {=0A+				dir =3D MATCH_REVERSE;=0A+				break;=0A+			=
}=0A+=0A+		      } else {=0A 			if (pkt->src_ip =3D=3D q->id.src_ip &&=0A=
 			    pkt->dst_ip =3D=3D q->id.dst_ip &&=0A 			    pkt->src_port =3D=3D=
 q->id.src_port &&=0A@@ -802,6 +911,7 @@=0A 				dir =3D MATCH_REVERSE;=0A=
 				break;=0A 			}=0A+		      }=0A 		}=0A next:=0A 		prev =3D q;=0A@@ -9=
78,15 +1088,25 @@=0A 	int i;=0A =0A 	if (ipfw_dyn_v) {=0A-		i =3D hash_pa=
cket( pkt );=0A+		int is_v6 =3D IS_IP6_FLOW_ID(pkt);=0A+		i =3D hash_pack=
et(pkt);=0A 		for (q =3D ipfw_dyn_v[i] ; q !=3D NULL ; q=3Dq->next)=0A 		=
	if (q->dyn_type =3D=3D O_LIMIT_PARENT &&=0A 			    rule=3D=3D q->rule &&=
=0A 			    pkt->proto =3D=3D q->id.proto &&=0A-			    pkt->src_ip =3D=3D =
q->id.src_ip &&=0A-			    pkt->dst_ip =3D=3D q->id.dst_ip &&=0A 			    pk=
t->src_port =3D=3D q->id.src_port &&=0A-			    pkt->dst_port =3D=3D q->id=
.dst_port) {=0A+			    pkt->dst_port =3D=3D q->id.dst_port &&=0A+			    (=
=0A+				(is_v6 &&=0A+				 IN6_ARE_ADDR_EQUAL(&(pkt->src_ip6),=0A+					&(q=
->id.src_ip6)) &&=0A+				 IN6_ARE_ADDR_EQUAL(&(pkt->dst_ip6),=0A+					&(q=
->id.dst_ip6))) ||=0A+				(!is_v6 &&=0A+				 pkt->src_ip =3D=3D q->id.src=
_ip &&=0A+				 pkt->dst_ip =3D=3D q->id.dst_ip)=0A+			    )=0A+			) {=0A =
				q->expire =3D time_second + dyn_short_lifetime;=0A 				DEB(printf("ip=
fw: lookup_dyn_parent found 0x%p\n",q);)=0A 				return q;=0A@@ -1052,14 +=
1172,21 @@=0A 		DEB(printf("ipfw: installing dyn-limit rule %d\n",=0A 		 =
   cmd->conn_limit);)=0A =0A-		id.dst_ip =3D id.src_ip =3D 0;=0A-		id.dst=
_port =3D id.src_port =3D 0;=0A+		bzero (&id, sizeof(id));=0A+=0A 		id.pr=
oto =3D args->f_id.proto;=0A =0A-		if (limit_mask & DYN_SRC_ADDR)=0A-			i=
d.src_ip =3D args->f_id.src_ip;=0A-		if (limit_mask & DYN_DST_ADDR)=0A-		=
	id.dst_ip =3D args->f_id.dst_ip;=0A+		if (IS_IP6_FLOW_ID (&(args->f_id))=
) {=0A+			if (limit_mask & DYN_SRC_ADDR)=0A+				id.src_ip6 =3D args->f_id=
.src_ip6;=0A+			if (limit_mask & DYN_DST_ADDR)=0A+				id.dst_ip6 =3D args=
->f_id.dst_ip6;=0A+		} else {=0A+			if (limit_mask & DYN_SRC_ADDR)=0A+			=
	id.src_ip =3D args->f_id.src_ip;=0A+			if (limit_mask & DYN_DST_ADDR)=0A=
+				id.dst_ip =3D args->f_id.dst_ip;=0A+		}=0A 		if (limit_mask & DYN_SR=
C_PORT)=0A 			id.src_port =3D args->f_id.src_port;=0A 		if (limit_mask & =
DYN_DST_PORT)=0A@@ -1299,12 +1426,8 @@=0A 	 *	consumes the packet because=
 it calls send_reject().=0A 	 *	XXX This has to change, so that ipfw_chk(=
) never modifies=0A 	 *	or consumes the buffer.=0A-	 * ip	is simply an al=
ias of the value of m, and it is kept=0A-	 *	in sync with it (the packet =
is	supposed to start with=0A-	 *	the ip header).=0A 	 */=0A 	struct mbuf =
*m =3D args->m;=0A-	struct ip *ip =3D mtod(m, struct ip *);=0A =0A 	/*=0A=
 	 * oif | args->oif	If NULL, ipfw_chk has been called on the=0A@@ -1321,=
12 +1444,12 @@=0A 	 * hlen	The length of the IPv4 header.=0A 	 *	hlen >0 =
means we have an IPv4 packet.=0A 	 */=0A-	u_int hlen =3D 0;		/* hlen >0 m=
eans we have an IP pkt */=0A+	u_int hlen =3D 0;=0A =0A 	/*=0A 	 * offset	=
The offset of a fragment. offset !=3D 0 means that=0A-	 *	we have a fragm=
ent at this offset of an IPv4 packet.=0A-	 *	offset =3D=3D 0 means that (=
if this is an IPv4 packet)=0A+	 *	we have a fragmented ip packet.=0A+	 *	=
offset =3D=3D 0 means that (if this is an IP packet)=0A 	 *	this is the f=
irst or only fragment.=0A 	 */=0A 	u_short offset =3D 0;=0A@@ -1350,95 +1=
473,197 @@=0A 	struct in_addr src_ip, dst_ip;		/* NOTE: network format	*/=
=0A 	u_int16_t ip_len=3D0;=0A 	int pktlen;=0A-	int dyn_dir =3D MATCH_UNKN=
OWN;=0A-	ipfw_dyn_rule *q =3D NULL;=0A =0A-	if (m->m_flags & M_SKIP_FIREW=
ALL)=0A-		return 0;	/* accept */=0A 	/*=0A 	 * dyn_dir =3D MATCH_UNKNOWN =
when rules unchecked,=0A 	 * 	MATCH_NONE when checked and not matched (q =
=3D NULL),=0A 	 *	MATCH_FORWARD or MATCH_REVERSE otherwise (q !=3D NULL)=0A=
 	 */=0A-=0A-	pktlen =3D m->m_pkthdr.len;=0A-	if (args->eh =3D=3D NULL ||=
		/* layer 3 packet */=0A-		( m->m_pkthdr.len >=3D sizeof(struct ip) &&=0A=
-		    ntohs(args->eh->ether_type) =3D=3D ETHERTYPE_IP))=0A-			hlen =3D i=
p->ip_hl << 2;=0A+	int dyn_dir =3D MATCH_UNKNOWN;=0A+	ipfw_dyn_rule *q =3D=
 NULL;=0A =0A 	/*=0A-	 * Collect parameters into local variables for fast=
er matching.=0A+	 * We store in ulp a pointer to the upper layer protocol=
 header.=0A+	 * In the ipv4 case this is easy to determine from the heade=
r,=0A+	 * but for ipv6 we might have some additional headers in the middl=
e.=0A+	 * ulp is NULL if not found.=0A 	 */=0A-	if (hlen =3D=3D 0) {	/* d=
o not grab addresses for non-ip pkts */=0A-		proto =3D args->f_id.proto =3D=
 0;	/* mark f_id invalid */=0A-		goto after_ip_checks;=0A-	}=0A+	void *ul=
p =3D NULL;		/* upper layer protocol pointer. */=0A+=0A+	/* XXX ipv6 vari=
ables */=0A+	int is_ipv6 =3D 0;=0A+	u_int16_t ext_hd =3D 0;   /* bits vec=
tor for extension header filtering */=0A+	/* end of ipv6 variables */=0A+=
=0A+	if (m->m_flags & M_SKIP_FIREWALL)=0A+		return 0;	/* accept */=0A+	pk=
tlen =3D m->m_pkthdr.len;=0A+	proto =3D args->f_id.proto =3D 0;	/* mark f=
_id invalid */=0A+=0A+	/* Identify ipv6 packets and fill up variables. */=
=0A+	if (pktlen >=3D sizeof(struct ip6_hdr) &&=0A+		(!args->eh || ntohs(a=
rgs->eh->ether_type)=3D=3DETHERTYPE_IPV6) &&=0A+		mtod(m, struct ip *)->i=
p_v =3D=3D 6) {=0A+=0A+	    is_ipv6 =3D 1;=0A+	    args->f_id.addr_type =3D=
 6;=0A+	    hlen =3D sizeof(struct ip6_hdr);=0A+	    proto =3D mtod(m, st=
ruct ip6_hdr *)->ip6_nxt;=0A+	    args->f_id.src_ip6 =3D (mtod(m, struct =
ip6_hdr *))->ip6_src;=0A+	    args->f_id.dst_ip6 =3D (mtod(m, struct ip6_=
hdr *))->ip6_dst;=0A+	    args->f_id.src_ip =3D 0;=0A+	    args->f_id.dst=
_ip =3D 0;=0A+	    args->f_id.flow_id6 =3D ntohs(mtod(m, struct ip6_hdr *=
)->ip6_flow);=0A+=0A+	    /* XXX where do we find ip_len ??? how do we se=
t pktlen ? */=0A+=0A+	    /*=0A+	     * PULLUP6(len, p, T) makes sure tha=
t len + sizeof(T) is=0A+	     * contiguous, then it sets p to point at th=
e offset "len" in=0A+	     * the mbuf. WARNING: the pointer might become =
stale after=0A+	     * other pullups (but we never use it this way).=0A+	=
     */=0A+#define PULLUP6(len, p, T)						\=0A+		do {							\=0A+		    i=
nt x =3D (len) + sizeof(T);				\=0A+		    if ((m)->m_len < x) {				\=0A+	=
		args->m =3D m =3D m_pullup(m, x);			\=0A+			if (m =3D=3D 0)					\=0A+		=
	    goto pullup_failed;				\=0A+		    }							\=0A+		    p =3D (mtod(m, =
char *) + (len));			\=0A+		} while (0)=0A+=0A+	    /* Search extension he=
aders to find upper layer protocols */=0A+	    while (ulp =3D=3D NULL) {=0A=
+		switch (proto) {=0A+		case IPPROTO_ICMPV6:=0A+		    PULLUP6(hlen, ulp,=
 struct icmp6_hdr);=0A+		    args->f_id.flags =3D ICMP6(ulp)->icmp6_type;=
=0A+		    break;=0A+=0A+		case IPPROTO_TCP:=0A+		    PULLUP6(hlen, ulp, s=
truct tcphdr);=0A+		    dst_port =3D TCP(ulp)->th_dport;=0A+		    src_por=
t =3D TCP(ulp)->th_sport;=0A+		    args->f_id.flags =3D TCP(ulp)->th_flag=
s;=0A+		    break;=0A =0A-	proto =3D args->f_id.proto =3D ip->ip_p;=0A-	s=
rc_ip =3D ip->ip_src;=0A-	dst_ip =3D ip->ip_dst;=0A-	if (args->eh !=3D NU=
LL) { /* layer 2 packets are as on the wire */=0A+		case IPPROTO_UDP:=0A+=
		    PULLUP6(hlen, ulp, struct udphdr);=0A+		    dst_port =3D UDP(ulp)->=
uh_dport;=0A+		    src_port =3D UDP(ulp)->uh_sport;=0A+		    break;=0A+=0A=
+		case IPPROTO_HOPOPTS:=0A+		    PULLUP6(hlen, ulp, struct ip6_hbh);=0A+=
		    ext_hd |=3D EXT_HOPOPTS;=0A+		    hlen +=3D sizeof(struct ip6_hbh);=
=0A+		    proto =3D ((struct ip6_hbh *)ulp)->ip6h_nxt;=0A+		    ulp =3D N=
ULL;=0A+		    break;=0A+=0A+		case IPPROTO_ROUTING:=0A+		    PULLUP6(hlen=
, ulp, struct ip6_rthdr);=0A+		    ext_hd |=3D EXT_ROUTING;=0A+		    hlen=
 +=3D sizeof(struct ip6_rthdr);=0A+		    proto =3D ((struct ip6_rthdr *)u=
lp)->ip6r_nxt;=0A+		    ulp =3D NULL;=0A+		    break;=0A+=0A+		case IPPRO=
TO_FRAGMENT:=0A+		    PULLUP6(hlen, ulp, struct ip6_frag);=0A+		    ext_h=
d |=3D EXT_FRAGMENT;=0A+		    hlen +=3D sizeof (struct ip6_frag);=0A+		  =
  proto =3D ((struct ip6_frag *)ulp)->ip6f_nxt;=0A+		    offset =3D 1;=0A=
+		    ulp =3D NULL; /* XXX is it correct ? */=0A+		    break;=0A+=0A+		c=
ase IPPROTO_AH:=0A+		case IPPROTO_NONE:=0A+		case IPPROTO_ESP:=0A+		    P=
ULLUP6(hlen, ulp, struct ip6_ext);=0A+		    if (proto =3D=3D IPPROTO_AH)=0A=
+			ext_hd |=3D EXT_AH;=0A+		    else if (proto =3D=3D IPPROTO_ESP)=0A+		=
	ext_hd |=3D EXT_ESP;=0A+		    hlen +=3D ((struct ip6_ext *)ulp)->ip6e_le=
n +=0A+				    sizeof (struct ip6_ext);=0A+		    proto =3D ((struct ip6_e=
xt *)ulp)->ip6e_nxt;=0A+		    ulp =3D NULL;=0A+		    break;=0A+=0A+		defa=
ult:=0A+		    printf("IPFW2: IPV6 - Unknown Extension Header (%d)\n",=0A+=
			 proto);=0A+		    return 0; /* deny */=0A+		    break;=0A+		} /*switch=
 */=0A+	    }=0A+=0A+	    /* hlen !=3D 0 is used to detect ipv4 packets, =
so clear it now */=0A+	    hlen =3D 0; /* XXX why? we have args->f_id.add=
r_type ... */=0A+=0A+	} else if (pktlen >=3D sizeof(struct ip) &&=0A+		(!=
args->eh || ntohs(args->eh->ether_type) =3D=3D ETHERTYPE_IP) &&=0A+		mtod=
(m, struct ip *)->ip_v =3D=3D 4) {=0A+	    struct ip *ip =3D mtod(m, stru=
ct ip *);=0A+=0A+	    hlen =3D ip->ip_hl << 2;=0A+	    args->f_id.addr_ty=
pe =3D 4;=0A+=0A+	    /*=0A+	     * Collect parameters into local variabl=
es for faster matching.=0A+	     */=0A+=0A+	    proto =3D ip->ip_p;=0A+	 =
   src_ip =3D ip->ip_src;=0A+	    dst_ip =3D ip->ip_dst;=0A+	    if (args=
->eh !=3D NULL) { /* layer 2 packets are as on the wire */=0A 		offset =3D=
 ntohs(ip->ip_off) & IP_OFFMASK;=0A 		ip_len =3D ntohs(ip->ip_len);=0A-	}=
 else {=0A+	    } else {=0A 		offset =3D ip->ip_off & IP_OFFMASK;=0A 		ip=
_len =3D ip->ip_len;=0A-	}=0A-	pktlen =3D ip_len < pktlen ? ip_len : pktl=
en;=0A-=0A-#define PULLUP_TO(len)						\=0A-		do {						\=0A-			if ((m)->=
m_len < (len)) {		\=0A-			    args->m =3D m =3D m_pullup(m, (len));	\=0A-=
			    if (m =3D=3D 0)				\=0A-				goto pullup_failed;		\=0A-			    ip =3D=
 mtod(m, struct ip *);		\=0A-			}					\=0A-		} while (0)=0A+	    }=0A+	  =
  pktlen =3D ip_len < pktlen ? ip_len : pktlen;=0A =0A-	if (offset =3D=3D=
 0) {=0A+	    if (offset =3D=3D 0) {=0A 		switch (proto) {=0A 		case IPPR=
OTO_TCP:=0A-		    {=0A-			struct tcphdr *tcp;=0A-=0A-			PULLUP_TO(hlen + =
sizeof(struct tcphdr));=0A-			tcp =3D L3HDR(struct tcphdr, ip);=0A-			dst=
_port =3D tcp->th_dport;=0A-			src_port =3D tcp->th_sport;=0A-			args->f_=
id.flags =3D tcp->th_flags;=0A-			}=0A+			PULLUP6(hlen, ulp, struct tcphd=
r);=0A+			dst_port =3D TCP(ulp)->th_dport;=0A+			src_port =3D TCP(ulp)->t=
h_sport;=0A+			args->f_id.flags =3D TCP(ulp)->th_flags;=0A 			break;=0A =0A=
 		case IPPROTO_UDP:=0A-		    {=0A-			struct udphdr *udp;=0A-=0A-			PULLU=
P_TO(hlen + sizeof(struct udphdr));=0A-			udp =3D L3HDR(struct udphdr, ip=
);=0A-			dst_port =3D udp->uh_dport;=0A-			src_port =3D udp->uh_sport;=0A=
-			}=0A+			PULLUP6(hlen, ulp, struct udphdr);=0A+			dst_port =3D UDP(ulp=
)->uh_dport;=0A+			src_port =3D UDP(ulp)->uh_sport;=0A 			break;=0A =0A 	=
	case IPPROTO_ICMP:=0A-			PULLUP_TO(hlen + 4);	/* type, code and checksum=
. */=0A-			args->f_id.flags =3D L3HDR(struct icmp, ip)->icmp_type;=0A+			=
/* we only care for 4 bytes: type, code, checksum */=0A+			PULLUP6(hlen, =
ulp, struct icmp);=0A+			args->f_id.flags =3D ICMP(ulp)->icmp_type;=0A 		=
	break;=0A =0A 		default:=0A 			break;=0A 		}=0A-#undef PULLUP_TO=0A-	}=0A=
+	    }=0A =0A-	args->f_id.src_ip =3D ntohl(src_ip.s_addr);=0A-	args->f_i=
d.dst_ip =3D ntohl(dst_ip.s_addr);=0A-	args->f_id.src_port =3D src_port =3D=
 ntohs(src_port);=0A-	args->f_id.dst_port =3D dst_port =3D ntohs(dst_port=
);=0A+	    args->f_id.src_ip =3D ntohl(src_ip.s_addr);=0A+	    args->f_id=
.dst_ip =3D ntohl(dst_ip.s_addr);=0A+	}=0A+	if (proto) { /* we may have p=
ort numbers, store them */=0A+	    args->f_id.proto =3D proto;=0A+	    ar=
gs->f_id.src_port =3D src_port =3D ntohs(src_port);=0A+	    args->f_id.ds=
t_port =3D dst_port =3D ntohs(dst_port);=0A+	}=0A =0A-after_ip_checks:=0A=
 	if (args->rule) {=0A 		/*=0A 		 * Packet has already been tagged. Look =
for the next rule=0A@@ -1531,13 +1756,11 @@=0A =0A 			case O_GID:=0A 			c=
ase O_UID:=0A-				/*=0A-				 * We only check offset =3D=3D 0 && proto !=3D=
 0,=0A-				 * as this ensures that we have an IPv4=0A-				 * packet with =
the ports info.=0A-				 */=0A-				if (offset!=3D0)=0A+				if (offset !=3D=
 0) /* no port info available */=0A+					break;=0A+				if (is_ipv6) /* XX=
X to be fixed later */=0A 					break;=0A+				/* the check for proto is be=
low */=0A 			    {=0A 				struct inpcbinfo *pi;=0A 				int wildcard;=0A@@=
 -1623,7 +1846,7 @@=0A 				break;=0A =0A 			case O_FRAG:=0A-				match =3D=
 (hlen > 0 && offset !=3D 0);=0A+				match =3D offset !=3D 0;=0A 				brea=
k;=0A =0A 			case O_IN:	/* "out" is "not in" */=0A@@ -1708,7 +1931,7 @@=0A=
 			case O_IP_DSTPORT:=0A 				/*=0A 				 * offset =3D=3D 0 && proto !=3D =
0 is enough=0A-				 * to guarantee that we have an IPv4=0A+				 * to guar=
antee that we have a=0A 				 * packet with port info.=0A 				 */=0A 				i=
f ((proto=3D=3DIPPROTO_UDP || proto=3D=3DIPPROTO_TCP)=0A@@ -1728,15 +1951=
,25 @@=0A =0A 			case O_ICMPTYPE:=0A 				match =3D (offset =3D=3D 0 && pr=
oto=3D=3DIPPROTO_ICMP &&=0A-				    icmptype_match(ip, (ipfw_insn_u32 *)c=
md) );=0A+				    icmptype_match(ICMP(ulp), (ipfw_insn_u32 *)cmd) );=0A+	=
			break;=0A+=0A+			case O_ICMP6TYPE:=0A+				match =3D is_ipv6 && offset =
=3D=3D 0 &&=0A+				    proto=3D=3DIPPROTO_ICMPV6 &&=0A+				    icmp6type_=
match(=0A+					((struct icmp6_hdr *)ulp)->icmp6_type,=0A+					(ipfw_insn_=
u32 *)cmd);=0A 				break;=0A =0A 			case O_IPOPT:=0A-				match =3D (hlen =
> 0 && ipopts_match(ip, cmd) );=0A+				match =3D (hlen > 0 &&=0A+				    =
ipopts_match(mtod(m, struct ip *), cmd) );=0A 				break;=0A =0A 			case O=
_IPVER:=0A-				match =3D (hlen > 0 && cmd->arg1 =3D=3D ip->ip_v);=0A+				=
match =3D (hlen > 0 &&=0A+					cmd->arg1 =3D=3D mtod(m, struct ip *)->ip_=
v);=0A 				break;=0A =0A 			case O_IPID:=0A@@ -1750,9 +1983,9 @@=0A 				 =
   if (cmd->opcode =3D=3D O_IPLEN)=0A 					x =3D ip_len;=0A 				    else =
if (cmd->opcode =3D=3D O_IPTTL)=0A-					x =3D ip->ip_ttl;=0A+					x =3D m=
tod(m, struct ip *)->ip_ttl;=0A 				    else /* must be IPID */=0A-					x=
 =3D ntohs(ip->ip_id);=0A+					x =3D ntohs(mtod(m, struct ip *)->ip_id);=0A=
 				    if (cmdlen =3D=3D 1) {=0A 					match =3D (cmd->arg1 =3D=3D x);=0A=
 					break;=0A@@ -1767,49 +2000,47 @@=0A =0A 			case O_IPPRECEDENCE:=0A =
				match =3D (hlen > 0 &&=0A-				    (cmd->arg1 =3D=3D (ip->ip_tos & 0xe=
0)) );=0A+				    (cmd->arg1 =3D=3D (mtod(m, struct ip *)->ip_tos & 0xe0)=
) );=0A 				break;=0A =0A 			case O_IPTOS:=0A 				match =3D (hlen > 0 &&=0A=
-				    flags_match(cmd, ip->ip_tos));=0A+				    flags_match(cmd, mtod(=
m, struct ip *)->ip_tos));=0A 				break;=0A =0A 			case O_TCPFLAGS:=0A-		=
		match =3D (proto =3D=3D IPPROTO_TCP && offset =3D=3D 0 &&=0A-				    fl=
ags_match(cmd,=0A-					L3HDR(struct tcphdr,ip)->th_flags));=0A+				match =
=3D proto =3D=3D IPPROTO_TCP && offset =3D=3D 0 &&=0A+				    flags_match=
(cmd, TCP(ulp)->th_flags);=0A 				break;=0A =0A 			case O_TCPOPTS:=0A-			=
	match =3D (proto =3D=3D IPPROTO_TCP && offset =3D=3D 0 &&=0A-				    tcp=
opts_match(ip, cmd));=0A+				match =3D proto =3D=3D IPPROTO_TCP && offset=
 =3D=3D 0 &&=0A+				    tcpopts_match(TCP(ulp), cmd);=0A 				break;=0A =0A=
 			case O_TCPSEQ:=0A-				match =3D (proto =3D=3D IPPROTO_TCP && offset =3D=
=3D 0 &&=0A+				match =3D proto =3D=3D IPPROTO_TCP && offset =3D=3D 0 &&=0A=
 				    ((ipfw_insn_u32 *)cmd)->d[0] =3D=3D=0A-					L3HDR(struct tcphdr,=
ip)->th_seq);=0A+					TCP(ulp)->th_seq;=0A 				break;=0A =0A 			case O_TC=
PACK:=0A-				match =3D (proto =3D=3D IPPROTO_TCP && offset =3D=3D 0 &&=0A=
+				match =3D proto =3D=3D IPPROTO_TCP && offset =3D=3D 0 &&=0A 				    =
((ipfw_insn_u32 *)cmd)->d[0] =3D=3D=0A-					L3HDR(struct tcphdr,ip)->th_a=
ck);=0A+					TCP(ulp)->th_ack;=0A 				break;=0A =0A 			case O_TCPWIN:=0A-=
				match =3D (proto =3D=3D IPPROTO_TCP && offset =3D=3D 0 &&=0A-				    =
cmd->arg1 =3D=3D=0A-					L3HDR(struct tcphdr,ip)->th_win);=0A+				match =3D=
 proto =3D=3D IPPROTO_TCP && offset =3D=3D 0 &&=0A+				    cmd->arg1 =3D=3D=
 TCP(ulp)->th_win;=0A 				break;=0A =0A 			case O_ESTAB:=0A 				/* reject=
 packets which have SYN only */=0A 				/* XXX should i also check for TH_=
ACK ? */=0A-				match =3D (proto =3D=3D IPPROTO_TCP && offset =3D=3D 0 &&=
=0A-				    (L3HDR(struct tcphdr,ip)->th_flags &=0A-				     (TH_RST | TH=
_ACK | TH_SYN)) !=3D TH_SYN);=0A+				match =3D proto =3D=3D IPPROTO_TCP &=
& offset =3D=3D 0 &&=0A+				    ( TCP(ulp)->th_flags &=0A+				     (TH_RS=
T | TH_ACK | TH_SYN)) !=3D TH_SYN;=0A 				break;=0A =0A 			case O_LOG:=0A=
@@ -1824,8 +2055,11 @@=0A =0A 			case O_VERREVPATH:=0A 				/* Outgoing pa=
ckets automatically pass/match */=0A-				match =3D ((oif !=3D NULL) ||=0A=
+				match =3D (oif !=3D NULL) ||=0A 				    (m->m_pkthdr.rcvif =3D=3D NU=
LL) ||=0A+				    (is_ipv6 ?=0A+					verify_rev_path6(&(args->f_id.src_ip=
6),=0A+						m->m_pkthdr.rcvif) :=0A 				    verify_rev_path(src_ip, m->m=
_pkthdr.rcvif));=0A 				break;=0A =0A@@ -1840,6 +2074,63 @@=0A 				/* oth=
erwise no match */=0A 				break;=0A =0A+			case O_IP6_SRC:=0A+			=0A+				=
match =3D is_ipv6 &&=0A+					IN6_ARE_ADDR_EQUAL(&args->f_id.src_ip6,=0A+	=
				    &((ipfw_insn_ip6 *)cmd)->addr6);=0A+/*					    printf("Match =3D =
%d - isip6 =3D %d - srcAddr =3D %d,%d,%d,%d - cmdAddr =3D %d,%d,%d,%d\n",=
 match, is_ipv6, args->f_id.src_ip6.s6_addr32[0], args->f_id.src_ip6.s6_a=
ddr32[1], args->f_id.src_ip6.s6_addr32[2], args->f_id.src_ip6.s6_addr32[3=
], ((ipfw_insn_ip6 *)cmd->addr6).s6_addr32[0], ((ipfw_insn_ip6 *)cmd->add=
r6).s6_addr32[1],((ipfw_insn_ip6 *)cmd->addr6).s6_addr32[2], ((ipfw_insn_=
ip6 *)cmd->addr6).s6_addr32[3]); */=0A+				break;=0A+=0A+			case O_IP6_DS=
T:=0A+				match =3D is_ipv6 &&=0A+					IN6_ARE_ADDR_EQUAL(&args->f_id.dst=
_ip6,=0A+					    &((ipfw_insn_ip6 *)cmd)->addr6);=0A+			        break;=0A=
+=0A+			case O_IP6_SRC_MASK:=0A+				if (is_ipv6) {=0A+				    ipfw_insn_i=
p6 *te =3D (ipfw_insn_ip6 *)cmd;=0A+				    struct in6_addr p =3D args->f=
_id.src_ip6;=0A+=0A+				    APPLY_MASK(&p, &te->mask6);=0A+				    match =
=3D IN6_ARE_ADDR_EQUAL(&te->addr6, &p);=0A+				}=0A+				break;=0A+=0A+			=
case O_IP6_DST_MASK:=0A+				if (is_ipv6) {=0A+				    ipfw_insn_ip6 *te =3D=
 (ipfw_insn_ip6 *)cmd;=0A+				    struct in6_addr p =3D args->f_id.dst_ip=
6;=0A+=0A+				    APPLY_MASK(&p, &te->mask6);=0A+				    match =3D IN6_AR=
E_ADDR_EQUAL(&te->addr6, &p);=0A+				}=0A+				break;=0A+=0A+			case O_IP6=
_SRC_ME:=0A+				match=3D is_ipv6 && search_ip6_addr_net(&args->f_id.src_i=
p6);=0A+				break;=0A+=0A+			case O_IP6_DST_ME:=0A+				match=3D is_ipv6 &=
& search_ip6_addr_net(&args->f_id.dst_ip6);=0A+				break;=0A+=0A+			case =
O_FLOW6ID:=0A+				match =3D is_ipv6 &&=0A+					flow6id_match(args->f_id.f=
low_id6,=0A+						(ipfw_insn_u32 *) cmd);=0A+				break;=0A+=0A+			case O_=
EXT_HDR:=0A+				match =3D is_ipv6 &&=0A+				    (ext_hd & ((ipfw_insn *) =
cmd)->arg1);=0A+				break;=0A+=0A+			case O_IP6:=0A+				match =3D is_ipv6=
;=0A+				break;=0A+=0A 			/*=0A 			 * The second set of opcodes represent=
s 'actions',=0A 			 * i.e. the terminal part of a rule once the packet=0A=
@@ -1902,7 +2193,7 @@=0A 				if (dyn_dir =3D=3D MATCH_UNKNOWN &&=0A 				 =
   (q =3D lookup_dyn_rule(&args->f_id,=0A 				     &dyn_dir, proto =3D=3D=
 IPPROTO_TCP ?=0A-					L3HDR(struct tcphdr, ip) : NULL))=0A+						TCP(ulp=
) : NULL))=0A 					!=3D NULL) {=0A 					/*=0A 					 * Found dynamic entry=
, update stats=0A@@ -1967,9 +2258,9 @@=0A 				 */=0A 				if (hlen > 0 &&=0A=
 				    (proto !=3D IPPROTO_ICMP ||=0A-				     is_icmp_query(ip)) &&=0A=
+				     is_icmp_query(ICMP(ulp))) &&=0A 				    !(m->m_flags & (M_BCAST=
|M_MCAST)) &&=0A-				    !IN_MULTICAST(dst_ip.s_addr)) {=0A+				    !IN_M=
ULTICAST(ntohl(dst_ip.s_addr))) {=0A 					send_reject(args, cmd->arg1,=0A=
 					    offset,ip_len);=0A 					m =3D args->m;=0A@@ -2414,6 +2705,10 @@=
=0A 		case O_ESTAB:=0A 		case O_VERREVPATH:=0A 		case O_IPSEC:=0A+		case =
O_IP6_SRC_ME:=0A+		case O_IP6_DST_ME:=0A+		case O_EXT_HDR:=0A+		case O_IP=
6:=0A 			if (cmdlen !=3D F_INSN_SIZE(ipfw_insn))=0A 				goto bad_size;=0A=
 			break;=0A@@ -2527,6 +2822,29 @@=0A 				return EINVAL;=0A 			}=0A 			b=
reak;=0A+=0A+		case O_IP6_SRC:=0A+		case O_IP6_DST:=0A+			if (cmdlen !=3D=
 F_INSN_SIZE(struct in6_addr) + F_INSN_SIZE(ipfw_insn))=0A+				goto bad_s=
ize;=0A+			break;=0A+=0A+		case O_FLOW6ID:=0A+			if (cmdlen !=3D F_INSN_S=
IZE(ipfw_insn_u32) +=0A+					((ipfw_insn_u32 *)cmd)->o.arg1)=0A+				goto =
bad_size;=0A+			break;=0A+=0A+		case O_IP6_SRC_MASK:=0A+		case O_IP6_DST_=
MASK:=0A+			if ( !(cmdlen & 1) || cmdlen > 127)=0A+				goto bad_size;=0A+=
			break;=0A+		case O_ICMP6TYPE:=0A+			if( cmdlen !=3D F_INSN_SIZE( ipfw_=
insn_icmp6 ) )=0A+				goto bad_size;=0A+			break;=0A+=0A 		default:=0A 		=
	printf("ipfw: opcode %d, unknown opcode\n",=0A 				cmd->opcode);=0A@@ -2=
796,7 +3114,7 @@=0A 	add_rule(&layer3_chain, &default_rule);=0A =0A 	ip_f=
w_default_rule =3D layer3_chain;=0A-	printf("ipfw2 initialized, divert %s=
, "=0A+	printf("ipfw2 (+ipv6) initialized, divert %s, "=0A 		"rule-based =
forwarding enabled, default to %s, logging ",=0A #ifdef IPDIVERT=0A 		"en=
abled",=0A--- ./originali/ip_fw2.h	Wed Jan 14 10:35:41 2004=0A+++ ./sys/n=
etinet/ip_fw2.h	Tue Mar 23 15:15:53 2004=0A@@ -126,10 +126,32 @@=0A 	 */=0A=
 	O_IPSEC,		/* has ipsec history		*/=0A =0A+	O_IP6_SRC,              /* a=
ddress without mask */=0A+	O_IP6_SRC_ME,           /* my addresses */=0A+=
	O_IP6_SRC_MASK,         /* address with the mask        */=0A+	O_IP6_DST=
,=0A+	O_IP6_DST_ME,=0A+	O_IP6_DST_MASK,=0A+	O_FLOW6ID,              /* fo=
r flow id tag in the ipv6 pkt */=0A+	O_ICMP6TYPE,            /* icmp6 pac=
ket type filtering */=0A+	O_EXT_HDR,              /* filtering for ipv6 e=
xtension header */=0A+	O_IP6,=0A+=0A 	O_LAST_OPCODE		/* not an opcode!		*=
/=0A };=0A =0A /*=0A+ * The extension header are filtered only for presen=
ce using a bit vector=0A+ * with a flag for each header.=0A+ */=0A+=0A+#d=
efine	EXT_FRAGMENT	0x1=0A+#define	EXT_HOPOPTS	0x2=0A+#define	EXT_ROUTING	=
0x4=0A+#define	EXT_AH		0x8=0A+#define	EXT_ESP		0x10=0A+=0A+/*=0A  * Templ=
ate for instructions.=0A  *=0A  * ipfw_insn is used for all instructions =
which require no operands,=0A@@ -265,6 +287,30 @@=0A 	u_int32_t log_left;=
	/* how many left to log 	*/=0A } ipfw_insn_log;=0A =0A+/* Apply ipv6 mas=
k on ipv6 addr */=0A+#define APPLY_MASK(addr,mask)				\=0A+    (addr)->__=
u6_addr.__u6_addr32[0] &=3D (mask)->__u6_addr.__u6_addr32[0]; \=0A+    (a=
ddr)->__u6_addr.__u6_addr32[1] &=3D (mask)->__u6_addr.__u6_addr32[1]; \=0A=
+    (addr)->__u6_addr.__u6_addr32[2] &=3D (mask)->__u6_addr.__u6_addr32[=
2]; \=0A+    (addr)->__u6_addr.__u6_addr32[3] &=3D (mask)->__u6_addr.__u6=
_addr32[3];=0A+=0A+/* Structure for ipv6 */=0A+typedef struct _ipfw_insn_=
ip6 {=0A+	ipfw_insn o;=0A+	struct in6_addr addr6;=0A+	struct in6_addr mas=
k6;=0A+} ipfw_insn_ip6;=0A+=0A+/* Used to support icmp6 types */=0A+typed=
ef struct _ipfw_insn_icmp6 {=0A+	ipfw_insn o;=0A+	uint32_t d[7]; /* XXX T=
his number si related to the netinet/icmp6.h=0A+	                *     de=
fine ICMP6_MAXTYPE=0A+	                *     as follows: n =3D ICMP6_MAXT=
YPE/32 + 1=0A+                        *     Actually is 203 =0A+			*/=0A+=
} ipfw_insn_icmp6;=0A+=0A /*=0A  * Here we have the structure representin=
g an ipfw rule.=0A  *=0A@@ -327,8 +373,15 @@=0A 	u_int16_t	src_port;=0A 	=
u_int8_t	proto;=0A 	u_int8_t	flags;	/* protocol-specific flags */=0A+	uin=
t8_t		addr_type; /* 4 =3D ipv4, 6 =3D ipv6, 1=3Dether ? */=0A+	uint8_t		_=
pad;=0A+	struct in6_addr dst_ip6;	/* could also store MAC addr! */=0A+	st=
ruct in6_addr src_ip6;=0A+	u_int32_t       flow_id6;=0A };=0A =0A+#define=
	IS_IP6_FLOW_ID(id)	((id)->addr_type =3D=3D 6)=0A+=0A /*=0A  * Dynamic ip=
fw rule.=0A  */=0A@@ -383,6 +436,17 @@=0A #define	IP_FW_PORT_TEE_FLAG	0x2=
0000=0A #define	IP_FW_PORT_DENY_FLAG	0x40000=0A =0A+/* =0A+ * Structure f=
or collecting parameters to dummynet for ip6_output forwarding=0A+ */=0A+=
struct	_ip6dn_args {=0A+	struct route_in6 ro_or;=0A+	int flags_or;=0A+	st=
ruct ifnet *origifp_or;=0A+	struct ifnet *ifp_or;=0A+	struct sockaddr_in6=
 dst_or;=0A+};=0A+=0A /*=0A  * Arguments for calling ipfw_chk() and dummy=
net_io(). We put them=0A  * all into a structure because this way it is e=
asier and more=0A@@ -402,6 +466,8 @@=0A 	struct ipfw_flow_id f_id;	/* gra=
bbed from IP header	*/=0A 	u_int16_t	divert_rule;	/* divert cookie		*/=0A=
 	u_int32_t	retval;=0A+=0A+	struct _ip6dn_args	dummypar; /* dummynet->ip6=
_output */=0A };=0A =0A /*=0A--- ./originali/ip_output.c	Wed Jan 14 10:38=
:41 2004=0A+++ ./sys/netinet/ip_output.c	Tue Mar 23 15:15:53 2004=0A@@ -9=
96,6 +996,32 @@=0A 				ip->ip_sum =3D in_cksum(m, hlen);=0A 			}=0A 		}=0A=
+#if 1		/* SRCSINK=0A+		 * Bits 30..16 of flags are a count used to send =
up to count-1=0A+		 * additional copies of the packet, and then continue =
inline.=0A+		 */=0A+		off =3D (flags >> 16) & 0xffff; /* replica count */=
=0A+		if (off > 1) {=0A+		    int s, sent =3D 0;=0A+		    struct mbuf *mi=
ne;=0A+=0A+		    for (;off > 1; off--) {=0A+			s =3D splimp();=0A+			mine=
 =3D m_copypacket(m, M_DONTWAIT);=0A+			splx(s);=0A+			error =3D (mine =3D=
=3D NULL) ? ENOBUFS :=0A+				    (*ifp->if_output)(ifp, mine,=0A+					(st=
ruct sockaddr *)dst, ro->ro_rt);=0A+			if (error !=3D 0)=0A+			    break;=
=0A+			sent++;=0A+		    }=0A+		    if (!(flags & IP_FORWARDING) && ia) {=0A=
+			    ia->ia_ifa.if_opackets +=3D sent;=0A+			    ia->ia_ifa.if_obytes =
+=3D sent*m->m_pkthdr.len;=0A+		    }=0A+		}=0A+#endif		/* SRCSINK */=0A =
=0A 		/* Record statistics for this interface address. */=0A 		if (!(flag=
s & IP_FORWARDING) && ia) {=0A@@ -1568,6 +1594,24 @@=0A 			switch (sopt->=
sopt_name) {=0A =0A 			case IP_TOS:=0A+#if 1	/* SRCSINK=0A+	 * getsockopt=
(IP_TOS) with a value above 0xff is used as follows:=0A+	 * + bit 23 sets=
/clear behaviour as a sink (goes into bit 15=0A+	 *   of inp_inc.inc_pad;=
=0A+	 * + bits 22..8 are the replica count (bit 14-0 of inp_inc.inc_pad)=0A=
+	 * copy back the number complemented so the caller knows this=0A+	 * is=
 handled specially.=0A+	 */=0A+				error =3D sooptcopyin(sopt, &optval,=0A=
+					    sizeof optval, sizeof optval);=0A+				if (error)=0A+					break;=
=0A+				if (optval > 0xff) {=0A+					inp->inp_inc.inc_pad =3D=0A+					   =
 (optval >> 8) & 0xffff;=0A+					optval =3D ~optval;=0A+				} else=0A+#en=
dif	/* SRCSINK */=0A 				optval =3D inp->inp_ip_tos;=0A 				break;=0A =0A=
--- ./originali/ipfw2.c	Wed Jan 14 10:48:23 2004=0A+++ ./sbin/ipfw/ipfw2.=
c	Tue Mar 23 15:15:54 2004=0A@@ -53,6 +53,7 @@=0A #include <netinet/ip_du=
mmynet.h>=0A #include <netinet/tcp.h>=0A #include <arpa/inet.h>=0A+#inclu=
de <netinet/icmp6.h>=0A =0A int=0A 		do_resolv,		/* Would try to resolve =
all */=0A@@ -243,6 +244,13 @@=0A 	TOK_DROPTAIL,=0A 	TOK_PROTO,=0A 	TOK_WE=
IGHT,=0A+=0A+	TOK_IPV6,=0A+	TOK_FLOWID,=0A+	TOK_ICMP6TYPES,=0A+	TOK_EXT6H=
DR,=0A+	TOK_DSTIP6,=0A+	TOK_SRCIP6,=0A };=0A =0A struct _s_x dummynet_par=
ams[] =3D {=0A@@ -265,6 +273,13 @@=0A 	{ "delay",		TOK_DELAY },=0A 	{ "pi=
pe",		TOK_PIPE },=0A 	{ "queue",		TOK_QUEUE },=0A+=0A+	{ "flow-id",		TOK_=
FLOWID},=0A+	{ "dst-ipv6",		TOK_DSTIP6},=0A+	{ "dst-ip6",		TOK_DSTIP6},=0A=
+	{ "src-ipv6",		TOK_SRCIP6},=0A+	{ "src-ip6",		TOK_SRCIP6},=0A+=0A 	{ "d=
ummynet-params",	TOK_NULL },=0A 	{ NULL, 0 }	/* terminator */=0A };=0A@@ =
-339,6 +354,16 @@=0A 	{ "ipsec",		TOK_IPSEC },=0A 	{ "//",			TOK_COMMENT =
},=0A =0A+	{ "icmp6type",		TOK_ICMP6TYPES },=0A+	{ "icmp6types",		TOK_ICM=
P6TYPES },=0A+	{ "ext6hdr",		TOK_EXT6HDR},=0A+	{ "flow-id",		TOK_FLOWID},=
=0A+	{ "ipv6",		TOK_IPV6},=0A+	{ "dst-ipv6",		TOK_DSTIP6},=0A+	{ "dst-ip6=
",		TOK_DSTIP6},=0A+	{ "src-ipv6",		TOK_SRCIP6},=0A+	{ "src-ip6",		TOK_SR=
CIP6},=0A+=0A 	{ "not",		TOK_NOT },		/* pseudo option */=0A 	{ "!", /* es=
cape ? */	TOK_NOT },		/* pseudo option */=0A 	{ "or",			TOK_OR },		/* pse=
udo option */=0A@@ -826,6 +851,197 @@=0A 	}=0A }=0A =0A+/* XXX ipv6 stuff=
 */=0A+/* =0A+ * Print the ip address contained in a command.=0A+ */=0A+s=
tatic void=0A+print_ip6(ipfw_insn_ip6 *cmd, char const *s)=0A+{=0A+	struc=
t hostent *he =3D NULL;=0A+	int len =3D F_LEN((ipfw_insn *) cmd) - 1;=0A+=
	struct in6_addr *a =3D &(cmd->addr6);=0A+	char trad[255];=0A+=0A+	printf=
("%s%s ", cmd->o.len & F_NOT ? " not": "", s);=0A+=0A+	if (cmd->o.opcode =
=3D=3D O_IP6_SRC_ME || cmd->o.opcode =3D=3D O_IP6_DST_ME) {=0A+		printf("=
me6");=0A+		return;=0A+	}=0A+	if (cmd->o.opcode =3D=3D O_IP6) {=0A+		prin=
tf(" ipv6");=0A+		return;=0A+	}=0A+=0A+	/*=0A+	 * len =3D=3D 4 indicates =
a single IP, whereas lists of 1 or more=0A+	 * addr/mask pairs have len =3D=
 (2n+1). We convert len to n so we=0A+	 * use that to count the number of=
 entries.=0A+	 */=0A+=0A+	for (len =3D len / 4; len > 0; len -=3D 2, a +=3D=
 2) {=0A+	    int mb =3D        /* mask length */=0A+		(cmd->o.opcode =3D=
=3D O_IP6_SRC || cmd->o.opcode =3D=3D O_IP6_DST) ?=0A+		128 : contigmask(=
(uint8_t *)&(a[1]), 128);=0A+=0A+	    if (mb =3D=3D 128 && do_resolv)=0A+=
		he =3D gethostbyaddr((char *)a, sizeof(*a), AF_INET6);=0A+	    if (he !=
=3D NULL)		/* resolved to name */=0A+		printf("%s", he->h_name);=0A+	    =
else if (mb =3D=3D 0)		/* any */=0A+		printf("any");=0A+	    else {      =
    /* numeric IP followed by some kind of mask */=0A+		if (inet_ntop(AF_=
INET6,  a, trad, sizeof( trad ) ) =3D=3D NULL)=0A+		    printf("Error nto=
p in print_ip6\n");=0A+		printf("%s",  trad );=0A+		if (mb < 0)	/* XXX no=
t really legal... */=0A+		    printf(":%s",=0A+			inet_ntop(AF_INET6, &a[=
1], trad, sizeof(trad)));=0A+		else if (mb < 128)=0A+		    printf("/%d", =
mb);=0A+	    }=0A+	    if (len > 2)=0A+		printf(",");=0A+	}=0A+}=0A+=0A+s=
tatic void=0A+fill_icmp6types(ipfw_insn_icmp6 *cmd, char *av)=0A+{=0A+	ui=
nt8_t type;=0A+=0A+	cmd->d[0] =3D 0;=0A+	while (*av) {=0A+	    if (*av =3D=
=3D ',')=0A+		av++;=0A+	    type =3D strtoul(av, &av, 0);=0A+	    if (*av=
 !=3D ',' && *av !=3D '\0')=0A+		errx(EX_DATAERR, "invalid ICMP6 type");=0A=
+	    if (type > ICMP6_MAXTYPE)=0A+		errx(EX_DATAERR, "ICMP6 type out of =
range");=0A+	    cmd->d[type / 32] |=3D ( 1 << (type % 32));=0A+	}=0A+	cm=
d->o.opcode =3D O_ICMP6TYPE;=0A+	cmd->o.len |=3D F_INSN_SIZE(ipfw_insn_ic=
mp6);=0A+}=0A+=0A+=0A+static void=0A+print_icmp6types(ipfw_insn_u32 *cmd)=
=0A+{=0A+	int i, j;=0A+	char sep=3D ' ';=0A+=0A+	printf(" ipv6 icmp6types=
");=0A+	for (i =3D 0; i < 7; i++)=0A+		for (j=3D0; j < 32; ++j) {=0A+			i=
f ( (cmd->d[i] & (1 << (j))) =3D=3D 0)=0A+				continue;=0A+			printf("%c%=
d", sep, (i*32 + j));=0A+			sep =3D ',';=0A+		}=0A+}=0A+=0A+static void=0A=
+print_flow6id( ipfw_insn_u32 *cmd)=0A+{=0A+	uint16_t i, limit =3D cmd->o=
.arg1;=0A+	char sep =3D ',';=0A+=0A+	printf(" flow-id ");=0A+	for( i=3D0;=
 i < limit; ++i) {=0A+		if (i =3D=3D limit - 1)=0A+			sep =3D ' ';=0A+		p=
rintf("%d%c", cmd->d[i], sep);=0A+	}=0A+}=0A+=0A+/* structure and define =
for the extension header in ipv6 */=0A+static struct _s_x ext6hdrcodes[] =
=3D {=0A+	{ "frag",	EXT_FRAGMENT },=0A+	{ "hopopt",	EXT_HOPOPTS },=0A+	{ =
"route",	EXT_ROUTING },=0A+	{ "ah",		EXT_AH },=0A+	{ "esp",	EXT_ESP },=0A=
+	{ NULL,		0 }=0A+};=0A+=0A+/* fills command for the extension header fil=
tering */=0A+int=0A+fill_ext6hdr( ipfw_insn *cmd, char *av)=0A+{=0A+	int =
tok;=0A+	char *s =3D av;=0A+=0A+	cmd->arg1 =3D 0;=0A+=0A+	while(s) {=0A+	=
    av =3D strsep( &s, ",") ;=0A+	    tok =3D match_token(ext6hdrcodes, a=
v);=0A+	    switch (tok) {=0A+	    case EXT_FRAGMENT:=0A+		cmd->arg1 |=3D=
 EXT_FRAGMENT;=0A+		break;=0A+=0A+	    case EXT_HOPOPTS:=0A+		cmd->arg1 |=
=3D EXT_HOPOPTS;=0A+		break;=0A+=0A+	    case EXT_ROUTING:=0A+		cmd->arg1=
 |=3D EXT_ROUTING;=0A+		break;=0A+=0A+	    case EXT_AH:=0A+		cmd->arg1 |=3D=
 EXT_AH;=0A+		break;=0A+=0A+	    case EXT_ESP:=0A+		cmd->arg1 |=3D EXT_ES=
P;=0A+		break;=0A+=0A+	    default:=0A+		errx( EX_DATAERR, "invalid optio=
n for ipv6 exten=0A+		headear" );=0A+		break;=0A+	    }=0A+	}=0A+	if (cmd=
->arg1 =3D=3D 0 )=0A+	    return 0;=0A+	cmd->opcode =3D O_EXT_HDR;=0A+	cm=
d->len |=3D F_INSN_SIZE( ipfw_insn );=0A+	return 1;=0A+}=0A+=0A+void=0A+p=
rint_ext6hdr( ipfw_insn *cmd )=0A+{=0A+	char sep =3D ' ';=0A+=0A+	printf(=
" extension header:");=0A+	if (cmd->arg1 & EXT_FRAGMENT ) {=0A+	    print=
f("%cfragmentation", sep);=0A+	    sep =3D ',';=0A+	}=0A+	if (cmd->arg1 &=
 EXT_HOPOPTS ) {=0A+	    printf("%chop options", sep);=0A+	    sep =3D ',=
';=0A+	}=0A+	if (cmd->arg1 & EXT_ROUTING ) {=0A+	    printf("%crouting op=
tions", sep);=0A+	    sep =3D ',';=0A+	}=0A+	if (cmd->arg1 & EXT_AH ) {=0A=
+	    printf("%cauthentication header", sep);=0A+	    sep =3D ',';=0A+	}=0A=
+	if (cmd->arg1 & EXT_ESP ) {=0A+	    printf("%cencapsulated security pay=
load", sep);=0A+	}=0A+}=0A+=0A+/* XXX end of ipv6 stuff */=0A+=0A /*=0A  =
* show_ipfw() prints the body of an ipfw rule.=0A  * Because the standard=
 rule has at least proto src_ip dst_ip, we use=0A@@ -844,6 +1060,7 @@=0A =
#define	HAVE_DSTIP	0x0004=0A #define	HAVE_MAC	0x0008=0A #define	HAVE_MACT=
YPE	0x0010=0A+#define	HAVE_PROTO6	0x0080=0A #define	HAVE_OPTIONS	0x8000=0A=
 =0A #define	HAVE_IP		(HAVE_PROTO | HAVE_SRCIP | HAVE_DSTIP)=0A@@ -864,6 =
+1081,8 @@=0A 		return;=0A 	}=0A 	if ( !(*flags & HAVE_OPTIONS)) {=0A+		i=
f ( !(*flags & HAVE_PROTO) && (want & HAVE_PROTO6))=0A+			printf(" ipv6")=
;=0A 		if ( !(*flags & HAVE_PROTO) && (want & HAVE_PROTO))=0A 			printf("=
 ip");=0A 		if ( !(*flags & HAVE_SRCIP) && (want & HAVE_SRCIP))=0A@@ -109=
4,6 +1313,37 @@=0A 			flags |=3D HAVE_DSTIP;=0A 			break;=0A =0A+		case O=
_IP6_SRC:=0A+		case O_IP6_SRC_MASK:=0A+		case O_IP6_SRC_ME:=0A+			show_pr=
erequisites(&flags, HAVE_PROTO6, 0);=0A+			if (!(flags & HAVE_SRCIP))=0A+=
				printf(" from");=0A+			if ((cmd->len & F_OR) && !or_block)=0A+				pri=
ntf(" {");=0A+			print_ip6((ipfw_insn_ip6 *)cmd,=0A+				(flags & HAVE_OPT=
IONS) ? " src-ip6" : "");=0A+			flags |=3D HAVE_SRCIP | HAVE_PROTO;=0A+		=
	break;=0A+=0A+		case O_IP6_DST:=0A+		case O_IP6_DST_MASK:=0A+		case O_IP=
6_DST_ME:=0A+			show_prerequisites(&flags, HAVE_PROTO|HAVE_SRCIP, 0);=0A+=
			if (!(flags & HAVE_DSTIP))=0A+				printf(" to");=0A+			if ((cmd->len &=
 F_OR) && !or_block)=0A+				printf(" {");=0A+			print_ip6((ipfw_insn_ip6 =
*)cmd,=0A+				(flags & HAVE_OPTIONS) ? " dst-ip6" : "");=0A+			flags |=3D=
 HAVE_DSTIP;=0A+			break;=0A+=0A+		case O_FLOW6ID:=0A+			print_flow6id( (=
ipfw_insn_u32 *) cmd );=0A+			flags |=3D HAVE_OPTIONS;=0A+			break;=0A+=0A=
 		case O_IP_DSTPORT:=0A 			show_prerequisites(&flags, HAVE_IP, 0);=0A 		=
case O_IP_SRCPORT:=0A@@ -1105,14 +1355,15 @@=0A 			break;=0A =0A 		case O=
_PROTO: {=0A-			struct protoent *pe;=0A+			struct protoent *pe =3D NULL;=0A=
 =0A 			if ((cmd->len & F_OR) && !or_block)=0A 				printf(" {");=0A 			if=
 (cmd->len & F_NOT)=0A 				printf(" not");=0A 			proto =3D cmd->arg1;=0A-=
			pe =3D getprotobynumber(cmd->arg1);=0A+			if (proto !=3D 41)	/* XXX ip=
v6 is special */ =0A+				pe =3D getprotobynumber(cmd->arg1);=0A 			if (fl=
ags & HAVE_OPTIONS)=0A 				printf(" proto");=0A 			if (pe)=0A@@ -1288,6 +=
1539,18 @@=0A 			    }=0A 				break;=0A =0A+			case O_IP6:=0A+				printf(=
" ipv6");=0A+				break;=0A+=0A+			case O_ICMP6TYPE:=0A+				print_icmp6typ=
es((ipfw_insn_u32 *)cmd);=0A+				break;=0A+=0A+			case O_EXT_HDR:=0A+				=
print_ext6hdr( (ipfw_insn *) cmd );=0A+				break;=0A+=0A 			default:=0A 	=
			printf(" [opcode %d len %d]",=0A 				    cmd->opcode, cmd->len);=0A@@ =
-1384,42 +1647,101 @@=0A static void=0A list_queues(struct dn_flow_set *f=
s, struct dn_flow_queue *q)=0A {=0A-	int l;=0A+	int l, index_print =3D 0;=
=0A+	char buff[255];=0A =0A-	printf("    mask: 0x%02x 0x%08x/0x%04x -> 0x=
%08x/0x%04x\n",=0A-	    fs->flow_mask.proto,=0A-	    fs->flow_mask.src_ip=
, fs->flow_mask.src_port,=0A-	    fs->flow_mask.dst_ip, fs->flow_mask.dst=
_port);=0A 	if (fs->rq_elements =3D=3D 0)=0A 		return;=0A =0A-	printf("BK=
T Prot ___Source IP/port____ "=0A-	    "____Dest. IP/port____ Tot_pkt/byt=
es Pkt/Byte Drp\n");=0A 	if (do_sort !=3D 0)=0A 		heapsort(q, fs->rq_elem=
ents, sizeof *q, sort_q);=0A-	for (l =3D 0; l < fs->rq_elements; l++) {=0A=
-		struct in_addr ina;=0A-		struct protoent *pe;=0A-=0A-		ina.s_addr =3D =
htonl(q[l].id.src_ip);=0A-		printf("%3d ", q[l].hash_slot);=0A-		pe =3D g=
etprotobynumber(q[l].id.proto);=0A-		if (pe)=0A-			printf("%-4s ", pe->p_=
name);=0A-		else=0A-			printf("%4u ", q[l].id.proto);=0A-		printf("%15s/%=
-5d ",=0A-		    inet_ntoa(ina), q[l].id.src_port);=0A-		ina.s_addr =3D ht=
onl(q[l].id.dst_ip);=0A-		printf("%15s/%-5d ",=0A-		    inet_ntoa(ina), q=
[l].id.dst_port);=0A-		printf("%4qu %8qu %2u %4u %3u\n",=0A-		    q[l].to=
t_pkts, q[l].tot_bytes,=0A-		    q[l].len, q[l].len_bytes, q[l].drops);=0A=
-		if (verbose)=0A-			printf("   S %20qd  F %20qd\n",=0A-			    q[l].S, q=
[l].F);=0A-	}=0A+=0A+	/*=0A+	 * Do IPv4 stuff=0A+	 */=0A+=0A+	for (l =3D =
0; l < fs->rq_elements; l++) =0A+		if (!IS_IP6_FLOW_ID(&(q[l].id))) {=0A+=
			struct in_addr ina;=0A+			struct protoent *pe;=0A+=0A+			if (!index_pr=
int) {=0A+				index_print =3D 1;=0A+				printf("\n        mask: 0x%02x 0x=
%08x/0x%04x -> 0x%08x/0x%04x\n",=0A+				    fs->flow_mask.proto,=0A+				 =
   fs->flow_mask.src_ip, fs->flow_mask.src_port,=0A+				    fs->flow_mask=
.dst_ip, fs->flow_mask.dst_port);=0A+=0A+				printf("    BKT Prot ___Sour=
ce IP/port____ "=0A+					"____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Dr=
p\n");=0A+			}=0A+			printf("    %3d ", q[l].hash_slot);=0A+			pe =3D get=
protobynumber(q[l].id.proto);=0A+			if (pe)=0A+				printf("%-4s ", pe->p_=
name);=0A+			else=0A+				printf("%4u ", q[l].id.proto);=0A+			ina.s_addr =
=3D htonl(q[l].id.src_ip);=0A+			printf("%15s/%-5d ",=0A+			    inet_ntoa=
(ina), q[l].id.src_port);=0A+			ina.s_addr =3D htonl(q[l].id.dst_ip);=0A+=
			printf("%15s/%-5d ",=0A+			    inet_ntoa(ina), q[l].id.dst_port);=0A+	=
		printf("%4qu %8qu %2u %4u %3u\n",=0A+		    		q[l].tot_pkts, q[l].tot_by=
tes,=0A+		    		q[l].len, q[l].len_bytes, q[l].drops);=0A+			if (verbose)=
=0A+				printf("   S %20qd  F %20qd\n",=0A+			    		q[l].S, q[l].F);=0A+	=
	}=0A+=0A+	/*=0A+	 * Do IPv6 stuff=0A+	 */=0A+=0A+	index_print =3D 0;=0A+=
	for (l =3D 0; l < fs->rq_elements; l++) =0A+		if (IS_IP6_FLOW_ID(&(q[l].=
id))) {=0A+			struct protoent *pe;=0A+=0A+			if (!index_print) {=0A+				i=
ndex_print =3D 1;=0A+				printf("\n        mask: proto: 0x%02x, flow_id: =
0x%08x,  ",=0A+		  			fs->flow_mask.proto, fs->flow_mask.flow_id6 );=0A+	=
			inet_ntop(AF_INET6, &(fs->flow_mask.src_ip6),=0A+					buff, sizeof(buf=
f) );=0A+				printf("%s/0x%04x -> ", buff, fs->flow_mask.src_port);=0A+		=
		inet_ntop( AF_INET6, &(fs->flow_mask.dst_ip6),=0A+					buff, sizeof(buf=
f) );=0A+				printf("%s/0x%04x\n", buff, fs->flow_mask.dst_port);=0A+=0A+=
				printf("    BKT ___Prot___ _flow-id_ "=0A+					"______________Source =
IPv6/port_______________ "=0A+					"_______________Dest. IPv6/port_______=
________ "=0A+					"Tot_pkt/bytes Pkt/Byte Drp\n");=0A+			}=0A+			printf(=
"    %3d ", q[l].hash_slot);=0A+			pe =3D getprotobynumber(q[l].id.proto)=
;=0A+			if (pe)=0A+				printf("%9s ", pe->p_name);=0A+			else=0A+				prin=
tf("%9u ", q[l].id.proto);=0A+			printf("%7d  %39s/%-5d ", q[l].id.flow_i=
d6,=0A+				inet_ntop(AF_INET6, &(q[l].id.src_ip6),=0A+					buff, sizeof(b=
uff)),=0A+				q[l].id.src_port);=0A+			printf(" %39s/%-5d ",=0A+				inet_=
ntop(AF_INET6, &(q[l].id.dst_ip6),=0A+					buff, sizeof(buff)),=0A+				q[=
l].id.dst_port);=0A+			printf(" %4qu %8qu %2u %4u %3u\n",=0A+		    		q[l]=
.tot_pkts, q[l].tot_bytes,=0A+				q[l].len, q[l].len_bytes, q[l].drops);=0A=
+			if (verbose)=0A+				printf("   S %20qd  F %20qd\n",=0A+				q[l].S, q[=
l].F);=0A+		}=0A+	printf("\n");=0A }=0A =0A static void=0A@@ -1802,7 +212=
4,7 @@=0A 	if (do_dynamic && ndyn) {=0A 		printf("## Dynamic rules:\n");=0A=
 		for (lac =3D ac, lav =3D av; lac !=3D 0; lac--) {=0A-			rnum =3D strto=
ul(*lav++, &endptr, 10);=0A+			last =3D rnum =3D strtoul(*lav++, &endptr,=
 10);=0A 			if (*endptr =3D=3D '-')=0A 				last =3D strtoul(endptr+1, &en=
dptr, 10);=0A 			if (*endptr)=0A@@ -1854,17 +2176,22 @@=0A "ACTION:	check=
-state | allow | count | deny | reject | skipto N |\n"=0A "		{divert|tee}=
 PORT | forward ADDR | pipe N | queue N\n"=0A "ADDR:		[ MAC dst src ether=
_type ] \n"=0A-"		[ from IPADDR [ PORT ] to IPADDR [ PORTLIST ] ]\n"=0A+"=
		[ ip from IPADDR [ PORT ] to IPADDR [ PORTLIST ] ]\n"=0A+"		[ ipv6 from=
 IP6ADDR [ PORT ] to IP6ADDR [ PORTLIST ] ]\n"=0A "IPADDR:	[not] { any | =
me | ip/bits{x,y,z} | IPLIST }\n"=0A "IPLIST:	{ ip | ip/bits | ip:mask }[=
,IPLIST]\n"=0A+"IP6ADDR:	[not] { any | me | me6 | ip6/bits | IP6LIST }\n"=
=0A+"IP6LIST:	{ ip6 | ip6/bits }[,IP6LIST]\n"=0A "OPTION_LIST:	OPTION [OP=
TION_LIST]\n"=0A-"OPTION:	bridged | {dst-ip|src-ip} ADDR | {dst-port|src-=
port} LIST |\n"=0A+"OPTION:	bridged | {dst-ip|src-ip} IPADDR | {dst-port|=
src-port} LIST |\n"=0A "	estab | frag | {gid|uid} N | icmptypes LIST | in=
 | out | ipid LIST |\n"=0A "	iplen LIST | ipoptions SPEC | ipprecedence |=
 ipsec | iptos SPEC |\n"=0A "	ipttl LIST | ipversion VER | keep-state | l=
ayer2 | limit ... |\n"=0A "	mac ... | mac-type LIST | proto LIST | {recv|=
xmit|via} {IF|IPADDR} |\n"=0A "	setup | {tcpack|tcpseq|tcpwin} NN | tcpfl=
ags SPEC | tcpoptions SPEC |\n"=0A-"	verrevpath\n"=0A+"	verrevpath | icmp=
6types LIST | ext6hdr LIST |\n"=0A+"        {dst-ip6|src-ip6|dst-ipv6|src=
-ipv6} IP6ADDR |\n"=0A+"        flow-id N[,N]\n"=0A );=0A exit(0);=0A }=0A=
@@ -2058,6 +2385,227 @@=0A     cmd->o.len |=3D len+1;=0A }=0A =0A+/* XXX =
more ipv6 stuff */=0A+/* Try to find ipv6 address by hostname */=0A+stati=
c int=0A+lookup_host6 (char *host, struct in6_addr *ip6addr)=0A+{=0A+	str=
uct hostent *he;=0A+=0A+	if (!inet_pton(AF_INET6, host, ip6addr)) {=0A+		=
if ((he =3D gethostbyname2(host, AF_INET6)) =3D=3D NULL)=0A+			return(-1)=
;=0A+		memcpy( ip6addr, he->h_addr_list[0], sizeof( struct in6_addr));=0A=
+	}=0A+	return(0);=0A+}=0A+=0A+/* n2mask sets n bits of the mask */=0A+=0A=
+static void=0A+n2mask(struct in6_addr *mask, int n)=0A+{=0A+	static int =
minimask[9] =3D {=0A+	    0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe,=
 0xff=0A+	};=0A+	u_char  *p;=0A+	int     i;=0A+=0A+	memset(mask, 0, sizeo=
f(struct in6_addr));=0A+	p =3D (u_char *) mask;=0A+	for (i =3D 0; i < 16;=
 i++, p++, n -=3D 8) {=0A+		if (n >=3D 8) {=0A+			*p =3D 0xff;=0A+			cont=
inue;=0A+		}=0A+		*p =3D minimask[n];=0A+		break;=0A+	}=0A+	return;=0A+}=0A=
+    =0A+/*=0A+ * fills the addr and mask fields in the instruction as ap=
propriate from av.=0A+ * Update length as appropriate.=0A+ * The followin=
g formats are allowed:=0A+ *     any     matches any IP6. Actually return=
s an empty instruction.=0A+ *     me      returns O_IP6_*_ME=0A+ *=0A+ * =
    03f1::234:123:0342                single IP6 addres=0A+ *     03f1::2=
34:123:0342/24            address/mask=0A+ *     03f1::234:123:0342/24,03=
f1::234:123:0343/               List of address=0A+ *=0A+ * Set of addres=
s (as in ipv6) not supported because ipv6 address=0A+ * are typically ran=
dom past the initial prefix.=0A+ * Return 1 on success, 0 on failure.=0A+=
 */=0A+=0A+static int=0A+fill_ip6(ipfw_insn_ip6 *cmd, char *av)=0A+{=0A+	=
int len =3D 0;=0A+	struct in6_addr *d =3D &(cmd->addr6);=0A+	/* Needed fo=
r multiple address.=0A+	 * Note d[1] points to struct in6_add r mask6 of =
cmd=0A+	 */=0A+=0A+	cmd->o.len &=3D ~F_LEN_MASK;      /* zero len */=0A+=0A=
+	if (!strncmp(av, "any", strlen(av)))=0A+		return 1;=0A+=0A+=0A+	if (!st=
rncmp(av, "me", strlen(av))) {	/* Set the data for "me" opt*/=0A+		cmd->o=
.len |=3D F_INSN_SIZE(ipfw_insn);=0A+		return 1;=0A+	}=0A+	if (!strncmp(a=
v, "me6", strlen(av))) {	/* Set the data for "me" opt*/=0A+		cmd->o.len |=
=3D F_INSN_SIZE(ipfw_insn);=0A+		return 1;=0A+	}=0A+=0A+	av =3D strdup(av=
);=0A+	while (av) {=0A+		/*=0A+		 * After the address we can have '/' ind=
icating a mask,=0A+		 * or ',' indicating another address follows.=0A+		 =
*/=0A+=0A+		char *p;=0A+		int masklen;=0A+		char md =3D '\0';=0A+=0A+		if=
 ((p =3D strpbrk( av, "/,")) ) {=0A+			md =3D *p;	/* save the separator *=
/=0A+			*p =3D '\0';	/* terminate address string */=0A+			p++;		/* and sk=
ip past it */=0A+		}=0A+		/* now p points to NULL, mask or next entry */=0A=
+=0A+		/* lookup stores address in *d as a side effect */=0A+		if (lookup=
_host6(av, d) !=3D 0) {=0A+			/* failed. Free memory and go */=0A+			errx=
(EX_DATAERR, "bad address \"%s\"", av);=0A+		}=0A+		/* next, look at the =
mask, if any */=0A+		masklen =3D (md =3D=3D '/') ? atoi(p) : 128;=0A+		if=
 (masklen > 128 || masklen < 0)=0A+			errx(EX_DATAERR, "bad width \"%s\''=
", p);=0A+		else=0A+			n2mask( &d[1], masklen);=0A+=0A+		APPLY_MASK( d, &=
d[1])	/* mask base address with mask */=0A+=0A+		/* find next separator *=
/=0A+=0A+		if (md =3D=3D '/') {	/* find separator past the mask */=0A+			=
p =3D strpbrk(p, ",");=0A+			if (p)=0A+				p++;=0A+		}=0A+		av =3D p;=0A+=
=0A+		/* Check this entry */=0A+		if (masklen =3D=3D 0) {=0A+		    /*=0A+=
		     * 'any' turns the entire list into a NOP.=0A+		     * 'not any' ne=
ver matches, so it is removed from the=0A+		     * list unless it is the =
only item, in which case we=0A+		     * report an error.=0A+		     */=0A+=
		    if (cmd->o.len & F_NOT) { /* "not any" never matches */=0A+			if (a=
v =3D=3D NULL && len =3D=3D 0) /* only this entry */=0A+				errx(EX_DATAE=
RR, "not any never matches");=0A+		    }=0A+		    /* else do nothing and =
skip this entry */=0A+		    continue;=0A+		}=0A+=0A+		/*=0A+		 * A single=
 IP can be stored alone=0A+		 */=0A+		if (masklen =3D=3D 128 && av =3D=3D=
 NULL && len =3D=3D 0) {=0A+		    len =3D F_INSN_SIZE(struct in6_addr);=0A=
+		    break;=0A+		}=0A+=0A+		/* Update length and pointer to arguments *=
/=0A+		len +=3D F_INSN_SIZE(struct in6_addr)*2;=0A+		d +=3D 2;=0A+	} /* e=
nd while */=0A+=0A+	/* Total lenght of the command, remember that 1 is th=
e size of the base command */=0A+	cmd->o.len |=3D len+1;=0A+	free(av);=0A=
+	return 1;=0A+}=0A+=0A+/*=0A+ * fills command for ipv6 flow-id filtering=
=0A+ * note that the 20 bit flow number is stored in a array of u_int32_t=
=0A+ * it's supported lists of flow-id, so in the o.arg1 we store how man=
y=0A+ * additional flow-id we want to filter, the basic is 1=0A+ */=0A+vo=
id=0A+fill_flow6( ipfw_insn_u32 *cmd, char *av )=0A+{=0A+	u_int32_t type;=
         /* Current flow number */=0A+	u_int16_t nflow =3D 0;    /* Curre=
nt flow index */=0A+	char *s =3D av;=0A+	cmd->d[0] =3D 0;          /* Ini=
tializing the base number*/=0A+=0A+	while (s) {=0A+	    	av =3D strsep( &=
s, ",") ;=0A+		type =3D strtoul(av, &av, 0);=0A+		if (*av !=3D ',' && *av=
 !=3D '\0')=0A+			errx(EX_DATAERR, "invalid ipv6 flow number %s", av);=0A=
+		if (type > 0xfffff)=0A+			errx(EX_DATAERR, "flow number out of range %=
s", av);=0A+		cmd->d[nflow] |=3D type;=0A+		nflow++;=0A+	}=0A+	if( nflow =
> 0 ) {=0A+		cmd->o.opcode =3D O_FLOW6ID;=0A+		cmd->o.len |=3D F_INSN_SIZ=
E(ipfw_insn_u32) + nflow;=0A+		cmd->o.arg1 =3D nflow;=0A+	}=0A+	else {=0A=
+		errx(EX_DATAERR, "invalid ipv6 flow number %s", av);=0A+	}=0A+}=0A+=0A=
+static ipfw_insn *=0A+add_srcip6(ipfw_insn *cmd, char *av)=0A+{=0A+	fill=
_ip6( (ipfw_insn_ip6 *) cmd, av);=0A+	if (F_LEN(cmd) =3D=3D 0)	/* any */=0A=
+		;=0A+	if (F_LEN(cmd) =3D=3D F_INSN_SIZE(ipfw_insn))	/* "me" */=0A+		cm=
d->opcode =3D O_IP6_SRC_ME;=0A+	else if (F_LEN(cmd) =3D=3D (F_INSN_SIZE(s=
truct in6_addr) + F_INSN_SIZE(ipfw_insn)))=0A+		/* single IP, no mask*/=0A=
+		cmd->opcode =3D O_IP6_SRC;=0A+	else						/* addr/mask opt */=0A+		cmd-=
>opcode =3D O_IP6_SRC_MASK;=0A+	return cmd;=0A+}=0A+=0A+static ipfw_insn =
*=0A+add_dstip6(ipfw_insn *cmd, char *av)=0A+{=0A+	fill_ip6((ipfw_insn_ip=
6 *)cmd, av);=0A+	if (F_LEN(cmd) =3D=3D 0)	/* any */=0A+		;=0A+	if (F_LEN=
(cmd) =3D=3D F_INSN_SIZE(ipfw_insn))	/* "me" */=0A+		cmd->opcode =3D O_IP=
6_DST_ME;=0A+	else if (F_LEN(cmd) =3D=3D (F_INSN_SIZE(struct in6_addr) + =
F_INSN_SIZE(ipfw_insn)))=0A+		/* single IP, no mask*/=0A+		cmd->opcode =3D=
 O_IP6_DST;=0A+	else						/* addr/mask opt */=0A+		cmd->opcode =3D O_IP6_=
DST_MASK;=0A+	return cmd;=0A+}=0A+/* end ipv6 stuff */=0A =0A /*=0A  * he=
lper function to process a set of flags and set bits in the=0A@@ -2181,7 =
+2729,6 @@=0A 	struct dn_pipe p;=0A 	int i;=0A 	char *end;=0A-	uint32_t a=
;=0A 	void *par =3D NULL;=0A =0A 	memset(&p, 0, sizeof p);=0A@@ -2243,16 =
+2790,15 @@=0A 			 */=0A 			par =3D NULL;=0A =0A-			p.fs.flow_mask.dst_ip=
 =3D 0;=0A-			p.fs.flow_mask.src_ip =3D 0;=0A-			p.fs.flow_mask.dst_port =
=3D 0;=0A-			p.fs.flow_mask.src_port =3D 0;=0A-			p.fs.flow_mask.proto =3D=
 0;=0A+			bzero(&p.fs.flow_mask, sizeof(p.fs.flow_mask));=0A 			end =3D N=
ULL;=0A =0A 			while (ac >=3D 1) {=0A 			    uint32_t *p32 =3D NULL;=0A 	=
		    uint16_t *p16 =3D NULL;=0A+			    uint32_t *p20 =3D NULL;=0A+			   =
 struct in6_addr *pa6 =3D NULL;=0A+			    uint32_t a;		/* the mask */=0A =
=0A 			    tok =3D match_token(dummynet_params, *av);=0A 			    ac--; av+=
+;=0A@@ -2266,6 +2812,9 @@=0A 				    p.fs.flow_mask.dst_port =3D ~0;=0A =
				    p.fs.flow_mask.src_port =3D ~0;=0A 				    p.fs.flow_mask.proto =3D=
 ~0;=0A+				    n2mask( &(p.fs.flow_mask.dst_ip6), 128);=0A+				    n2mas=
k( &(p.fs.flow_mask.src_ip6), 128);=0A+				    p.fs.flow_mask.flow_id6 =3D=
 ~0;=0A 				    p.fs.flags_fs |=3D DN_HAVE_FLOW_MASK;=0A 				    goto end=
_mask;=0A =0A@@ -2277,6 +2826,18 @@=0A 				    p32 =3D &p.fs.flow_mask.sr=
c_ip;=0A 				    break;=0A =0A+			    case TOK_DSTIP6:=0A+				    pa6 =3D=
  &(p.fs.flow_mask.dst_ip6);=0A+				    break;=0A+=0A+			    case TOK_SRC=
IP6:=0A+				    pa6 =3D &(p.fs.flow_mask.src_ip6);=0A+				    break;=0A+=0A=
+			    case TOK_FLOWID:=0A+				    p20 =3D &p.fs.flow_mask.flow_id6;=0A+=
				    break;=0A+=0A 			    case TOK_DSTPORT:=0A 				    p16 =3D &p.fs.f=
low_mask.dst_port;=0A 				    break;=0A@@ -2294,22 +2855,35 @@=0A 			    =
}=0A 			    if (ac < 1)=0A 				    errx(EX_USAGE, "mask: value missing");=
=0A-			    if (*av[0] =3D=3D '/') {=0A+			    if (*av[0] =3D=3D '/') { /*=
 mask len */=0A 				    a =3D strtoul(av[0]+1, &end, 0);=0A-				    a =3D=
 (a =3D=3D 32) ? ~0 : (1 << a) - 1;=0A-			    } else=0A+				    /* conver=
t to a mask for non IPv6 */=0A+				    if (pa6 =3D=3D NULL)=0A+					    a=
 =3D (a =3D=3D 32) ? ~0 : (1 << a) - 1;=0A+			    } else	/* explicit mask=
 (non IPv6) */=0A 				    a =3D strtoul(av[0], &end, 0);=0A 			    if (p3=
2 !=3D NULL)=0A 				    *p32 =3D a;=0A 			    else if (p16 !=3D NULL) {=0A=
-				    if (a > 65535)=0A+				    if (a > 0xffff)=0A 					    errx(EX_DA=
TAERR,=0A-						"mask: must be 16 bit");=0A+						"port mask must be 16 b=
it");=0A 				    *p16 =3D (uint16_t)a;=0A+			    } else if (p20 !=3D NULL=
) {=0A+				    if (a > 0xfffff)=0A+					errx(EX_DATAERR,=0A+					    "flo=
w_id mask must be 20 bit");=0A+				    *p20 =3D (uint32_t)a;=0A+			    } =
else if (pa6 !=3D NULL) {=0A+				    if (a < 0 || a > 128)=0A+					errx(E=
X_DATAERR,=0A+					    "in6addr invalid mask len" );=0A+				    else=0A+	=
				n2mask(pa6, a);=0A 			    } else {=0A-				    if (a > 255)=0A+				   =
 if (a > 0xff)=0A 					    errx(EX_DATAERR,=0A-						"mask: must be 8 bit=
");=0A+						"proto mask must be 8 bit");=0A 				    p.fs.flow_mask.proto=
 =3D (uint8_t)a;=0A 			    }=0A 			    if (a !=3D 0)=0A@@ -2629,21 +3203,=
27 @@=0A }=0A =0A static ipfw_insn *=0A-add_proto(ipfw_insn *cmd, char *a=
v)=0A+add_proto(ipfw_insn *cmd, char *av, u_char *proto)=0A {=0A 	struct =
protoent *pe;=0A-	u_char proto =3D 0;=0A+        *proto =3D IPPROTO_IP;=0A=
 =0A 	if (!strncmp(av, "all", strlen(av)))=0A 		; /* same as "ip" */=0A-	=
else if ((proto =3D atoi(av)) > 0)=0A+	else if ((*proto =3D atoi(av)) > 0=
)=0A 		; /* all done! */=0A 	else if ((pe =3D getprotobyname(av)) !=3D NU=
LL)=0A-		proto =3D pe->p_proto;=0A+		*proto =3D pe->p_proto;=0A+	else if(=
!strncmp(av, "ipv6", strlen(av)) ||=0A+	        !strncmp(av, "ip6", strle=
n(av)) )=0A+		{=0A+		  *proto =3D IPPROTO_IPV6;=0A+		  return cmd;	/* spe=
cial case for ipv6 */=0A+		}=0A 	else=0A 		return NULL;=0A-	if (proto !=3D=
 IPPROTO_IP)=0A-		fill_cmd(cmd, O_PROTO, 0, proto);=0A+	if (*proto !=3D I=
PPROTO_IP && *proto !=3D IPPROTO_IPV6)=0A+		fill_cmd(cmd, O_PROTO, 0, *pr=
oto);=0A 	return cmd;=0A }=0A =0A@@ -2690,6 +3270,38 @@=0A 	return NULL;=0A=
 }=0A =0A+static ipfw_insn *=0A+add_src(ipfw_insn *cmd, char *av, u_char =
proto)=0A+{=0A+	struct in6_addr a;=0A+        if( proto =3D=3D IPPROTO_IP=
V6  || strcmp( av, "me6") =3D=3D 0 || inet_pton(AF_INET6, av, &a ))=0A+	 =
 return add_srcip6(cmd, av);=0A+=0A+	if (proto =3D=3D IPPROTO_IP || strcm=
p( av, "me") =3D=3D 0 || !inet_pton(AF_INET6, av, &a ) ) =0A+	  return ad=
d_srcip(cmd, av);=0A+=0A+	if( !strcmp( av, "any") )=0A+	  return cmd; =0A=
+=0A+	return NULL;  /* bad address */=0A+}=0A+=0A+static ipfw_insn *=0A+a=
dd_dst(ipfw_insn *cmd, char *av, u_char proto)=0A+{=0A+	struct in6_addr a=
;=0A+        if( proto =3D=3D IPPROTO_IPV6  || strcmp( av, "me6") =3D=3D =
0 || inet_pton(AF_INET6, av, &a ))=0A+	  return add_dstip6(cmd, av);=0A+=0A=
+	if (proto =3D=3D IPPROTO_IP || strcmp( av, "me") =3D=3D 0 || !inet_pton=
(AF_INET6, av, &a ) ) =0A+	  return add_dstip(cmd, av);=0A+=0A+	if( !strc=
mp( av, "any") )=0A+	  return cmd; =0A+=0A+	return NULL;  /* bad address =
*/=0A+}=0A+=0A /*=0A  * Parse arguments and assemble the microinstruction=
s which make up a rule.=0A  * Rules are added into the 'rulebuf' and then=
 copied in the correct order=0A@@ -2713,7 +3325,7 @@=0A 	 */=0A 	static u=
int32_t rulebuf[255], actbuf[255], cmdbuf[255];=0A =0A-	ipfw_insn *src, *=
dst, *cmd, *action, *prev=3DNULL;=0A+	ipfw_insn *src, *dst, *cmd, *action=
, *prev=3DNULL, *retval=3DNULL;=0A 	ipfw_insn *first_cmd;	/* first match =
pattern */=0A =0A 	struct ip_fw *rule;=0A@@ -2985,11 +3597,10 @@=0A     O=
R_START(get_proto);=0A 	NOT_BLOCK;=0A 	NEED1("missing protocol");=0A-	if =
(add_proto(cmd, *av)) {=0A+	if ( add_proto(cmd, *av, &proto) ) {=0A 		av+=
+; ac--;=0A-		if (F_LEN(cmd) =3D=3D 0)	/* plain IP */=0A-			proto =3D 0;=0A=
-		else {=0A+		if (F_LEN(cmd) !=3D 0)	/* plain IP */=0A+		{=0A 			proto =3D=
 cmd->arg1;=0A 			prev =3D cmd;=0A 			cmd =3D next_cmd(cmd);=0A@@ -3000,7=
 +3611,7 @@=0A 		goto read_options;=0A     OR_BLOCK(get_proto);=0A =0A-	/=
*=0A+        /*=0A 	 * "from", mandatory=0A 	 */=0A 	if (!ac || strncmp(*=
av, "from", strlen(*av)))=0A@@ -3013,13 +3624,17 @@=0A     OR_START(sourc=
e_ip);=0A 	NOT_BLOCK;	/* optional "not" */=0A 	NEED1("missing source addr=
ess");=0A-	if (add_srcip(cmd, *av)) {=0A+	retval =3D add_src( cmd, *av, p=
roto );=0A+		=0A+	if( retval ){=0A 		ac--; av++;=0A 		if (F_LEN(cmd) !=3D=
 0) {	/* ! any */=0A 			prev =3D cmd;=0A 			cmd =3D next_cmd(cmd);=0A 		}=
=0A-	}=0A+	} else =0A+		errx(EX_USAGE, "bad source address %s", *av);=0A+=
	        =0A     OR_BLOCK(source_ip);=0A =0A 	/*=0A@@ -3048,13 +3663,17 @=
@=0A     OR_START(dest_ip);=0A 	NOT_BLOCK;	/* optional "not" */=0A 	NEED1=
("missing dst address");=0A-	if (add_dstip(cmd, *av)) {=0A+	retval =3D NU=
LL;=0A+	retval =3D add_dst(cmd, *av, proto);=0A+=0A+	if( retval ){=0A 		a=
c--; av++;=0A 		if (F_LEN(cmd) !=3D 0) {	/* ! any */=0A 			prev =3D cmd;=0A=
 			cmd =3D next_cmd(cmd);=0A 		}=0A-	}=0A+	} else=0A+		errx( EX_USAGE, "=
bad destination address %s", *av);=0A     OR_BLOCK(dest_ip);=0A =0A 	/*=0A=
@@ -3160,6 +3779,12 @@=0A 			av++; ac--;=0A 			break;=0A =0A+		case TOK_I=
CMP6TYPES:=0A+			NEED1("icmptypes requires list of types");=0A+			fill_ic=
mp6types((ipfw_insn_icmp6 *)cmd, *av);=0A+			av++; ac--;=0A+			break;=0A+=
=0A 		case TOK_IPTTL:=0A 			NEED1("ipttl requires TTL");=0A 			if (strpbr=
k(*av, "-,")) {=0A@@ -3336,8 +3961,9 @@=0A =0A 		case TOK_PROTO:=0A 			NE=
ED1("missing protocol");=0A-			if (add_proto(cmd, *av)) {=0A-				proto =3D=
 cmd->arg1;=0A+			if ( add_proto(cmd, *av, &proto)) {=0A+				if ( proto =3D=
=3D IPPROTO_IPV6 )=0A+			    	    fill_cmd(cmd, O_IP6, 0, 0);    =0A 				=
ac--; av++;=0A 			} else=0A 				errx(EX_DATAERR, "invalid protocol ``%s''=
",=0A@@ -3358,6 +3984,20 @@=0A 			}=0A 			break;=0A =0A+		case TOK_SRCIP6=
:=0A+			NEED1("missing source IP6");=0A+			if (add_srcip6(cmd, *av)) {=0A=
+				ac--; av++;=0A+			}=0A+			break;=0A+=0A+		case TOK_DSTIP6:=0A+			NEE=
D1("missing destination IP6");=0A+			if (add_dstip6(cmd, *av)) {=0A+				a=
c--; av++;=0A+			}=0A+			break;=0A+=0A 		case TOK_SRCPORT:=0A 			NEED1("m=
issing source port");=0A 			if (!strncmp(*av, "any", strlen(*av)) ||=0A@@=
 -3404,6 +4044,23 @@=0A 			fill_comment(cmd, ac, av);=0A 			av +=3D ac;=0A=
 			ac =3D 0;=0A+			break;=0A+=0A+		case TOK_IPV6:=0A+			fill_cmd(cmd, O_=
IP6, 0, 0);=0A+			ac--; av++;=0A+			break;=0A+			=0A+		case TOK_EXT6HDR:=0A=
+			fill_ext6hdr( cmd, *av );=0A+			ac--; av++;=0A+			break;=0A+=0A+		cas=
e TOK_FLOWID:=0A+			if (proto !=3D IPPROTO_IPV6 ) =0A+				errx( EX_USAGE,=
 "flow-id filter is active only for ipv6 protocol\n");=0A+			fill_flow6( =
(ipfw_insn_u32 *) cmd, *av );=0A+	     		ac--;av++;=0A 			break;=0A =0A 	=
	default:=0A--- ./originali/raw_ip.c	Wed Jan 14 10:41:40 2004=0A+++ ./sys=
/netinet/raw_ip.c	Tue Mar 23 15:15:54 2004=0A@@ -35,6 +35,7 @@=0A  */=0A =
=0A #include "opt_inet6.h"=0A+#include "opt_ipfw.h"=0A #include "opt_ipse=
c.h"=0A #include "opt_random_ip_id.h"=0A =0A--- ./originali/udp_usrreq.c	=
Wed Jan 14 10:42:52 2004=0A+++ ./sys/netinet/udp_usrreq.c	Tue Mar 23 15:1=
5:54 2004=0A@@ -393,6 +393,13 @@=0A 		goto bad;=0A #endif /*FAST_IPSEC*/=0A=
 =0A+#if 1	/* SRCSINK=0A+	 * If bit 15 if inp_inc.inc_pad is set, behave =
as a sink=0A+	 * and discard packet.=0A+	 */=0A+	if (inp->inp_inc.inc_pad=
 & 0x8000)=0A+		goto bad; /* not really bad, just discard it */=0A+#endif=
	/* SRCSINK */=0A 	/*=0A 	 * Construct sockaddr format source address.=0A=
 	 * Stuff source address and datagram in user buffer.=0A@@ -765,6 +772,1=
3 @@=0A 	((struct ip *)ui)->ip_tos =3D inp->inp_ip_tos;	/* XXX */=0A 	udp=
stat.udps_opackets++;=0A =0A+#if 1	/* SRCSINK=0A+	 * If bits 0-14 of inp_=
inc.inc_pad are set, use that as=0A+	 * a replica count and pass them in =
the upper 16 bits of ipflags.=0A+	 */=0A+	if (inp->inp_inc.inc_pad & 0x7f=
ff)=0A+		ipflags |=3D (inp->inp_inc.inc_pad & 0x7fff) << 16;=0A+#endif	/*=
 SRCSINK */=0A 	error =3D ip_output(m, inp->inp_options, &inp->inp_route,=
 ipflags,=0A 	    inp->inp_moptions, inp);=0A =0A
--_=__=_XaM3_.1080125633.2A.383416.42.18170.52.42.007.27129--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?HV2U9T$474E23C8CE7B556828F1BE7687979F9C>