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>