socsvn commit: r269305 - soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw

dpl at FreeBSD.org dpl at FreeBSD.org
Mon Jun 9 15:09:20 UTC 2014


Author: dpl
Date: Mon Jun  9 15:09:18 2014
New Revision: 269305
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=269305

Log:
  Continue the isolating work.
  

Modified:
  soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_fw2.c
  soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.c
  soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.h

Modified: soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_fw2.c
==============================================================================
--- soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_fw2.c	Mon Jun  9 14:46:32 2014	(r269304)
+++ soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_fw2.c	Mon Jun  9 15:09:18 2014	(r269305)
@@ -1343,89 +1343,51 @@
 				break;
 
 			case O_RECV:
-				match = iface_match(m->m_pkthdr.rcvif,
-				    (ipfw_insn_if *)cmd, chain, &tablearg);
+				rule_recv(&match, m, cmd, chain, &tablearg);
 				break;
 
 			case O_XMIT:
-				match = iface_match(oif, (ipfw_insn_if *)cmd,
-				    chain, &tablearg);
+				rule_xmit(&match, oif, cmd, chain, &tableargs);
 				break;
 
 			case O_VIA:
-				match = iface_match(oif ? oif :
-				    m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd,
-				    chain, &tablearg);
+				rule_via(&match, oif, m, cmd, chain, &tablearg);
 				break;
 
 			case O_MACADDR2:
-				if (args->eh != NULL) {	/* have MAC header */
-					u_int32_t *want = (u_int32_t *)
-						((ipfw_insn_mac *)cmd)->addr;
-					u_int32_t *mask = (u_int32_t *)
-						((ipfw_insn_mac *)cmd)->mask;
-					u_int32_t *hdr = (u_int32_t *)args->eh;
-
-					match =
-					    ( want[0] == (hdr[0] & mask[0]) &&
-					      want[1] == (hdr[1] & mask[1]) &&
-					      want[2] == (hdr[2] & mask[2]) );
-				}
+				rule_macaddr(&match, args, cmd);
 				break;
 
 			case O_MAC_TYPE:
-				if (args->eh != NULL) {
-					u_int16_t *p =
-					    ((ipfw_insn_u16 *)cmd)->ports;
-					int i;
-
-					for (i = cmdlen - 1; !match && i>0;
-					    i--, p += 2)
-						match = (etype >= p[0] &&
-						    etype <= p[1]);
-				}
+				rule_mac_type(&match, args, cmd, cmdlen, etype);
 				break;
 
 			case O_FRAG:
-				match = (offset != 0);
+				rule_frag(&match, offset);
 				break;
 
-			case O_IN:	/* "out" is "not in" */
-				match = (oif == NULL);
+			case O_IN:
+				rule_in(&match, oif);
 				break;
 
 			case O_LAYER2:
-				match = (args->eh != NULL);
+				rule_layer2(&match, args);
 				break;
 
 			case O_DIVERTED:
-			    {
-				/* For diverted packets, args->rule.info
-				 * contains the divert port (in host format)
-				 * reason and direction.
-				 */
-				uint32_t i = args->rule.info;
-				match = (i&IPFW_IS_MASK) == IPFW_IS_DIVERT &&
-				    cmd->arg1 & ((i & IPFW_INFO_IN) ? 1 : 2);
-			    }
+				rule_diverted(&match, args);
 				break;
 
 			case O_PROTO:
-				/*
-				 * We do not allow an arg of 0 so the
-				 * check of "proto" only suffices.
-				 */
-				match = (proto == cmd->arg1);
+				rule_proto(&match, proto, cmd);
 				break;
 
 			case O_IP_SRC:
-				match = is_ipv4 &&
-				    (((ipfw_insn_ip *)cmd)->addr.s_addr ==
-				    src_ip.s_addr);
+				rule_src(&match, is_ipv4, cmd, src_ip);
 				break;
 
 			case O_IP_SRC_LOOKUP:
-			case O_IP_DST_LOOKUP:
+			case O_2_LOOKUP:
 				if (is_ipv4) {
 				    uint32_t key =
 					(cmd->opcode == O_IP_DST_LOOKUP) ?
@@ -1500,16 +1462,7 @@
 
 			case O_IP_SRC_MASK:
 			case O_IP_DST_MASK:
-				if (is_ipv4) {
-				    uint32_t a =
-					(cmd->opcode == O_IP_DST_MASK) ?
-					    dst_ip.s_addr : src_ip.s_addr;
-				    uint32_t *p = ((ipfw_insn_u32 *)cmd)->d;
-				    int i = cmdlen-1;
-
-				    for (; !match && i>0; i-= 2, p+= 2)
-					match = (p[0] == (a & p[1]));
-				}
+				rule_ip_dst_mask(&match, is_ipv4, cmd, cmdlen, dst_ip, src_ip);
 				break;
 
 			case O_IP_SRC_ME:
@@ -1523,229 +1476,98 @@
 #ifdef INET6
 				/* FALLTHROUGH */
 			case O_IP6_SRC_ME:
+				rule_ip6_src_me(&match, is_ipv6, args)
 				match= is_ipv6 && search_ip6_addr_net(&args->f_id.src_ip6);
 #endif
 				break;
 
 			case O_IP_DST_SET:
 			case O_IP_SRC_SET:
-				if (is_ipv4) {
-					u_int32_t *d = (u_int32_t *)(cmd+1);
-					u_int32_t addr =
-					    cmd->opcode == O_IP_DST_SET ?
-						args->f_id.dst_ip :
-						args->f_id.src_ip;
-
-					    if (addr < d[0])
-						    break;
-					    addr -= d[0]; /* subtract base */
-					    match = (addr < cmd->arg1) &&
-						( d[ 1 + (addr>>5)] &
-						  (1<<(addr & 0x1f)) );
-				}
+				rule_ip_src_set(&match, is_ipv4, cmd, args);
 				break;
 
 			case O_IP_DST:
-				match = is_ipv4 &&
-				    (((ipfw_insn_ip *)cmd)->addr.s_addr ==
-				    dst_ip.s_addr);
+				rule_ip_dst(&match, cmd, &dst_ip);
 				break;
 
 			case O_IP_DST_ME:
-				if (is_ipv4) {
-					struct ifnet *tif;
-
-					INADDR_TO_IFP(dst_ip, tif);
-					match = (tif != NULL);
-					break;
-				}
+				rule_ip_dst_me(&match, is_ipv4, is_ipv6, dst_ip, dst_ip6);
+				
 #ifdef INET6
 				/* FALLTHROUGH */
 			case O_IP6_DST_ME:
-				match= is_ipv6 && search_ip6_addr_net(&args->f_id.dst_ip6);
+				rule_ip6_dst_me(&match, args);
 #endif
 				break;
 
 
 			case O_IP_SRCPORT:
 			case O_IP_DSTPORT:
-				/*
-				 * offset == 0 && proto != 0 is enough
-				 * to guarantee that we have a
-				 * packet with port info.
-				 */
-				if ((proto==IPPROTO_UDP || proto==IPPROTO_TCP)
-				    && offset == 0) {
-					u_int16_t x =
-					    (cmd->opcode == O_IP_SRCPORT) ?
-						src_port : dst_port ;
-					u_int16_t *p =
-					    ((ipfw_insn_u16 *)cmd)->ports;
-					int i;
-
-					for (i = cmdlen - 1; !match && i>0;
-					    i--, p += 2)
-						match = (x>=p[0] && x<=p[1]);
-				}
+				rule_ip_dstport(&match, proto, offset, cmd, cmdlen);
 				break;
 
 			case O_ICMPTYPE:
-				match = (offset == 0 && proto==IPPROTO_ICMP &&
-				    icmptype_match(ICMP(ulp), (ipfw_insn_u32 *)cmd) );
+				rule_icmptype(&match, offset, proto, ulp, cmd);
 				break;
 
 #ifdef INET6
 			case O_ICMP6TYPE:
-				match = is_ipv6 && offset == 0 &&
-				    proto==IPPROTO_ICMPV6 &&
-				    icmp6type_match(
-					ICMP6(ulp)->icmp6_type,
-					(ipfw_insn_u32 *)cmd);
+				rule_icmp6type(&match, offset, proto, ulp, cmd);
 				break;
 #endif /* INET6 */
 
 			case O_IPOPT:
-				match = (is_ipv4 &&
-				    ipopts_match(ip, cmd) );
+				rule_ipopt(&match, is_ipv4, ip, cmd);
 				break;
 
 			case O_IPVER:
-				match = (is_ipv4 &&
-				    cmd->arg1 == ip->ip_v);
+				rule_ipver(&match, is_ipv4, cmd, ip);
 				break;
 
 			case O_IPID:
 			case O_IPLEN:
 			case O_IPTTL:
-				if (is_ipv4) {	/* only for IP packets */
-				    uint16_t x;
-				    uint16_t *p;
-				    int i;
-
-				    if (cmd->opcode == O_IPLEN)
-					x = iplen;
-				    else if (cmd->opcode == O_IPTTL)
-					x = ip->ip_ttl;
-				    else /* must be IPID */
-					x = ntohs(ip->ip_id);
-				    if (cmdlen == 1) {
-					match = (cmd->arg1 == x);
-					break;
-				    }
-				    /* otherwise we have ranges */
-				    p = ((ipfw_insn_u16 *)cmd)->ports;
-				    i = cmdlen - 1;
-				    for (; !match && i>0; i--, p += 2)
-					match = (x >= p[0] && x <= p[1]);
-				}
+				rule_ipttl(&match, is_ipv4, cmd, cmdlen, ip, iplen);
 				break;
 
 			case O_IPPRECEDENCE:
-				match = (is_ipv4 &&
-				    (cmd->arg1 == (ip->ip_tos & 0xe0)) );
+				rule_ipprecedence(&match, is_ipv4, cmd, ip);
 				break;
 
 			case O_IPTOS:
-				match = (is_ipv4 &&
-				    flags_match(cmd, ip->ip_tos));
+				rule_iptos(&match, is_ipv4, cmd, ip);
 				break;
 
 			case O_DSCP:
-			    {
-				uint32_t *p;
-				uint16_t x;
-
-				p = ((ipfw_insn_u32 *)cmd)->d;
-
-				if (is_ipv4)
-					x = ip->ip_tos >> 2;
-				else if (is_ipv6) {
-					uint8_t *v;
-					v = &((struct ip6_hdr *)ip)->ip6_vfc;
-					x = (*v & 0x0F) << 2;
-					v++;
-					x |= *v >> 6;
-				} else
-					break;
-
-				/* DSCP bitmask is stored as low_u32 high_u32 */
-				if (x > 32)
-					match = *(p + 1) & (1 << (x - 32));
-				else
-					match = *p & (1 << x);
-			    }
+				rule_dscp(&match, is_ipv4, is_ipv6, cmd, ip)
 				break;
 
 			case O_TCPDATALEN:
-				if (proto == IPPROTO_TCP && offset == 0) {
-				    struct tcphdr *tcp;
-				    uint16_t x;
-				    uint16_t *p;
-				    int i;
-
-				    tcp = TCP(ulp);
-				    x = iplen -
-					((ip->ip_hl + tcp->th_off) << 2);
-				    if (cmdlen == 1) {
-					match = (cmd->arg1 == x);
-					break;
-				    }
-				    /* otherwise we have ranges */
-				    p = ((ipfw_insn_u16 *)cmd)->ports;
-				    i = cmdlen - 1;
-				    for (; !match && i>0; i--, p += 2)
-					match = (x >= p[0] && x <= p[1]);
-				}
+				rule_tcpdatalen(&match, proto, offset, ulp, iplen, cmdlen, cmd);
 				break;
 
 			case O_TCPFLAGS:
-				match = (proto == IPPROTO_TCP && offset == 0 &&
-				    flags_match(cmd, TCP(ulp)->th_flags));
+				rule_tcpflags(&match, proto, offset, cmd, ulp);
 				break;
 
 			case O_TCPOPTS:
-				PULLUP_LEN(hlen, ulp, (TCP(ulp)->th_off << 2));
-				match = (proto == IPPROTO_TCP && offset == 0 &&
-				    tcpopts_match(TCP(ulp), cmd));
+				rule_tcpopts(&match, hlen, ulp, proto, offset, cmd);
 				break;
 
 			case O_TCPSEQ:
-				match = (proto == IPPROTO_TCP && offset == 0 &&
-				    ((ipfw_insn_u32 *)cmd)->d[0] ==
-					TCP(ulp)->th_seq);
+				rule_tcpseq(&match, proto, offset, cmd, ulp);
 				break;
 
 			case O_TCPACK:
-				match = (proto == IPPROTO_TCP && offset == 0 &&
-				    ((ipfw_insn_u32 *)cmd)->d[0] ==
-					TCP(ulp)->th_ack);
+				rule_tcpack(&match, proto, offset, cmd, ulp);
 				break;
 
 			case O_TCPWIN:
-				if (proto == IPPROTO_TCP && offset == 0) {
-				    uint16_t x;
-				    uint16_t *p;
-				    int i;
-
-				    x = ntohs(TCP(ulp)->th_win);
-				    if (cmdlen == 1) {
-					match = (cmd->arg1 == x);
-					break;
-				    }
-				    /* Otherwise we have ranges. */
-				    p = ((ipfw_insn_u16 *)cmd)->ports;
-				    i = cmdlen - 1;
-				    for (; !match && i > 0; i--, p += 2)
-					match = (x >= p[0] && x <= p[1]);
-				}
+				rule_tcpwin(&match, proto, offset, cmd, ulp);
 				break;
 
 			case O_ESTAB:
-				/* reject packets which have SYN only */
-				/* XXX should i also check for TH_ACK ? */
-				match = (proto == IPPROTO_TCP && offset == 0 &&
-				    (TCP(ulp)->th_flags &
-				     (TH_RST | TH_ACK | TH_SYN)) != TH_SYN);
+				rule_estab(&match, proto, offset, ulp);
 				break;
 
 			case O_ALTQ: {

Modified: soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.c
==============================================================================
--- soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.c	Mon Jun  9 14:46:32 2014	(r269304)
+++ soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw/ip_rules.c	Mon Jun  9 15:09:18 2014	(r269305)
@@ -17,7 +17,7 @@
 }
 
 inline void
-rule_jail(u_short offset, uint8_t proto, ipfw_insn cmd, struct ip_fw_args *args, int ucred_lookup, void *ucred_cache)
+rule_jail(u_short offset, uint8_t proto, ipfw_insn ipfw_insn_u32 *cmd, struct ip_fw_args *args, int ucred_lookup, void *ucred_cache)
 {
 	/*
 	 * We only check offset == 0 && proto != 0,
@@ -28,7 +28,7 @@
 		break;
 	if (proto == IPPROTO_TCP ||
 		proto == IPPROTO_UDP)
-		match = check_uidgid(
+		*match = check_uidgid(
 				(ipfw_insn_u32 *)cmd,
 				args, &ucred_lookup,
 #ifdef __FreeBSD__
@@ -38,89 +38,666 @@
 #endif
 }
 
-inline void rule_recv(int *int *int *int *match, m, cmd, chain, tablearg);
-inline void rule_xmit(int *match, oif, cmd, chain, tablearg);
-inline void rule_via(int *match, oif, rcvif, cmd, chain, tablearg);
-inline void rule_macaddr(int *match, eh, adr, mask, eh);
-inline void rule_mac_type(int *match, eh, ports, cmdlen, etype));
-inline void rule_frag(int *match, offset);
-inline void rule_in(int *match, oif);
-inline void rule_layertwo(int *match, eh);
-inline void rule_diverted(int *match, info);
-inline void rule_proto(int *match, proto, arg1);
-inline void rule_ip_src(int *match, is_ipv4, addr1, addr2);
-inline void rule_ip_2_lookup(int *match, cmd, cmdlen, is_ipv4, is_ipv6, ip, dst_ip,
-	src_ip, dst_port, src_port, offset, proto, ucred_lookup, ucred_cache, key, chain);
-inline void rule_ip_dst_mask(int *match, is_ipv4, cmd, dst_ip);
-inline void rule_ip_src_me(int *match, src_ip, args);
-inline void rule_ip_src_set(int *match, is_ipv4, cmd, args)
-inline void rule_ip_dst(int *match, is_ipv4, cmd, addr1, addr2);
-inline void rule_ip_dst_me(int *match, is_ipv4, is_ipv6, dst_ip, dst_ip6);
-inline void rule_ip_dstport(int *match, proto, opcode, ports, cmdlen);
-inline void rule_icmptype(int *match, offset, proto,ulp, cmd );
-inline void rule_ipopt(int *match, is_ipv4, ip, cmd);
-inline void rule_ipver(int *match, is_ipv4, arg1, ip_v);
-inline void rule_ipttl(int *match, is_ipv4, opcode, iplen, ip_ttl, ip_id, cmdlen, ports);
-inline void rule_ipprecedence(int *match, is_ipv4, arg1, ip_tos);
-inline void rule_iptos(int *match, is_ipv4, cmd, ip_tos)
-inline void rule_dscp(d, is_ipv4, ip_tos, is_ipv6, ip6_vfc);
-inline void rule_tcpdatalen(int *match, proto, offset, ulp, iplen, cmdlen, arg1, ports);
-inline void rule_tcpflags(int *match, proto, offset, cmd, th_flags);
-inline void rule_tcpopts(int *match, hlen, ulp, th_off, proto, offset, cmd);
-inline void rule_tcpseq(int *match, proto, offset, cmd, ulp);
-inline void rule_tcpack(int *match, proto, offset, cmd, ulp);
-inline void rule_tcpwin(int *match, proto, offset, cmd, ulp);
-inline void rule_estab(int *match, proto, offset, ulp);
-inline void rule_altq(int *match, cmd, m, tag /*PACKET_TAG_PF*/, size_t size, num);
-inline void rule_log(int *match, f, hlen, args, m, oif, offset, ip6f_mf, tablearg, ip);
-inline void rule_prob(int *match, cmd);
-inline void rule_verrevpath(int *match, oif, m, is_ipv6, args, src_ip);
-inline void rule_versrcreach(int *match, is_ipv6, args, src_ip);
-inline void rule_antispoof(int *match, oif, hlen, is_ipv4, src_ip, is_ipv6, args, m);
-inline void rule_ip4(int *match, is_ipv4);
-inline void rule_tag(int *match, cmd, m, tag, );
-inline void rule_fib(int *match, args, cmd);
-inline void rule_tagged(int *match, cmd, cmdlen, m, ipfw, tag);
+inline void
+rule_recv(int *match, ipfw_insn *cmd, struct mbuf *m, struct ip_fw_chain *chain, uint32_t *tablearg)
+{
+	//XXX What about embedding this function into code?
+	*match = iface_match(m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd, chain, tablearg);
+}
+
+inline void
+rule_xmit(int *match, struct ifnet *oif, ipfw_insn *cmd, struct ip_fw_chain *chain, uint32_t *tablearg)
+{
+	*match = iface_match(oif, (ipfw_insn_if *)cmd, chain, tablearg);
+}
+
+inline void
+rule_via(int *match, struct ifnet *oif, struct mbuf *m, ipfw_insn *cmd, struct ip_fw_chain *chain, uint32_t *tablearg)
+{
+	*match = iface_match(oif ? oif : m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd, chain, &tablearg);
+}
+
+inline void
+rule_macaddr(int *match, struct ip_fw_args *args, ipfw_insn *cmd)
+{
+	if (args->eh != NULL) {	/* have MAC header */
+		u_int32_t *want = (u_int32_t *)
+			((ipfw_insn_mac *)cmd)->addr;
+		u_int32_t *mask = (u_int32_t *)
+			((ipfw_insn_mac *)cmd)->mask;
+		u_int32_t *hdr = (u_int32_t *)args->eh;
+
+		*match =
+		    ( want[0] == (hdr[0] & mask[0]) &&
+		      want[1] == (hdr[1] & mask[1]) &&
+		      want[2] == (hdr[2] & mask[2]) );
+	}
+
+}
+
+inline void
+rule_mac_type(int *match, struct ip_fw_args *args, ipfw_insn *cmd, int cmdlen, uint16_t etype);
+{
+	if (args->eh != NULL) {
+		u_int16_t *p =
+		    ((ipfw_insn_u16 *)cmd)->ports;
+		int i;
+
+		for (i = cmdlen - 1; !match && i>0;
+		    i--, p += 2)
+			*match = (etype >= p[0] &&
+			    etype <= p[1]);
+	}
+
+}
+
+inline void
+rule_frag(int *match, u_short offset)
+{
+	*match = (offset != 0);
+}
+
+inline void
+rule_in(int *match, struct ifnet *oif)
+{
+	/* "out" is "not in" */
+	*match = (oif == NULL);
+}
+
+inline void
+rule_layertwo(int *match, struct ip_fw_args * args)
+{
+	*match = (args->eh != NULL);
+}
+
+inline void
+rule_diverted(int *match, struct ip_fw_args * args)
+{
+	/* For diverted packets, args->rule.info
+	 * contains the divert port (in host format)
+	 * reason and direction.
+	 */
+	uint32_t i = args->rule.info;
+	*match = (i&IPFW_IS_MASK) == IPFW_IS_DIVERT &&
+	    cmd->arg1 & ((i & IPFW_INFO_IN) ? 1 : 2);
+}
+
+inline void
+rule_proto(int *match, uint8_t proto, ipfs_insn *cmd)
+{
+	/*
+	 * We do not allow an arg of 0 so the
+	 * check of "proto" only suffices.
+	 */
+	*match = (proto == cmd->arg1);
+}
+
+inline void
+rule_ip_src(int *match, int is_ipv4, ipfs_insn *cmd, struct in_addr *src_ip)
+{
+	*match = is_ipv4 &&
+	    (((ipfw_insn_ip *)cmd)->addr.s_addr ==
+	    src_ip->s_addr);
+}
+
+
+//XXX Talk with mentor about ucred_cache. Only after that finish this function.
+inline void
+rule_ip_2_lookup(int *match, ipfw_insn *cmd, int cmdlen, int is_ipv4, int is_ipv6, struct ip *ip, struct in_addr *dst_ip, struct in_addr *src_ip, uint16_t dst_port, uint16_t src_port, u_short offset, uint8_t proto, int ucred_lookup, ucred_cache, struct ip_fw_chain *chain)
+{
+	if (is_ipv4) {
+	    uint32_t key =
+		(cmd->opcode == O_IP_DST_LOOKUP) ?
+		    dst_ip.s_addr : src_ip.s_addr;
+	    uint32_t v = 0;
+
+	    if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) {
+		/* generic lookup. The key must be
+		 * in 32bit big-endian format.
+		 */
+		v = ((ipfw_insn_u32 *)cmd)->d[1];
+		if (v == 0)
+		    key = dst_ip.s_addr;
+		else if (v == 1)
+		    key = src_ip.s_addr;
+		else if (v == 6) /* dscp */
+		    key = (ip->ip_tos >> 2) & 0x3f;
+		else if (offset != 0)
+		    break;
+		else if (proto != IPPROTO_TCP &&
+			proto != IPPROTO_UDP)
+		    break;
+		else if (v == 2)
+		    key = htonl(dst_port);
+		else if (v == 3)
+		    key = htonl(src_port);
+#ifndef USERSPACE
+		else if (v == 4 || v == 5) {
+		    check_uidgid(
+			(ipfw_insn_u32 *)cmd,
+			args, &ucred_lookup,
+#ifdef __FreeBSD__
+			&ucred_cache);
+		    if (v == 4 /* O_UID */)
+			key = ucred_cache->cr_uid;
+		    else if (v == 5 /* O_JAIL */)
+			key = ucred_cache->cr_prison->pr_id;
+#else /* !__FreeBSD__ */
+			(void *)&ucred_cache);
+		    if (v ==4 /* O_UID */)
+			key = ucred_cache.uid;
+		    else if (v == 5 /* O_JAIL */)
+			key = ucred_cache.xid;
+#endif /* !__FreeBSD__ */
+		    key = htonl(key);
+		} else
+#endif /* !USERSPACE */
+		    break;
+	    }
+	    *match = ipfw_lookup_table(chain,
+		cmd->arg1, key, &v);
+	    if (!(*match))
+		break;
+	    if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
+		*match =
+		    ((ipfw_insn_u32 *)cmd)->d[0] == v;
+	    else
+		tablearg = v;
+	} else if (is_ipv6) {
+		uint32_t v = 0;
+		void *pkey = (cmd->opcode == O_IP_DST_LOOKUP) ?
+			&args->f_id.dst_ip6: &args->f_id.src_ip6;
+		*match = ipfw_lookup_table_extended(chain,
+				cmd->arg1, pkey, &v,
+				IPFW_TABLE_CIDR);
+		if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
+			*match = ((ipfw_insn_u32 *)cmd)->d[0] == v;
+		if (*match)
+			tablearg = v;
+	}
+}
+
+
+//XXX Speak with mentor about passing both dst_ip and src_ip.
+inline void
+rule_ip_dst_mask(int *match, int is_ipv4, ipfw_insn *cmd, int cmdlen, struct in_addr *dst_ip, struct in_addr *src_ip)
+{
+	if (is_ipv4) {
+	    uint32_t a =
+		(cmd->opcode == O_IP_DST_MASK) ?
+		    dst_ip.s_addr : src_ip.s_addr;
+	    uint32_t *p = ((ipfw_insn_u32 *)cmd)->d;
+	    int i = cmdlen-1;
+
+	    for (; !match && i>0; i-= 2, p+= 2)
+		*match = (p[0] == (a & p[1]));
+	}
+}
+
+inline void
+rule_ip_src_me(int *match, struct in_addr *src_ip, struct ip_fw_args *args)
+{
+	if (is_ipv4) {
+		struct ifnet *tif;
+
+		INADDR_TO_IFP(src_ip, tif);
+		*match = (tif != NULL);
+		return;
+	}
+	/* The next behavior has been also added to the next action */
+	*match= is_ipv6 && search_ip6_addr_net(&args->f_id.src_ip6);
+}
+
+inline void
+rule_ip6_src_me(int *match, int is_ipv6, struct ip_fw_args *args)
+{
+	*match= is_ipv6 && search_ip6_addr_net(&args->f_id.src_ip6);
+}
+
+inline void
+rule_ip_src_set(int *match, int is_ipv4, ipfw_insn *cmd, struct ip_fw_args *args)
+{
+	if (is_ipv4) {
+		u_int32_t *d = (u_int32_t *)(cmd+1);
+		u_int32_t addr =
+		    cmd->opcode == O_IP_DST_SET ?
+			args->f_id.dst_ip :
+			args->f_id.src_ip;
+
+		    if (addr < d[0])
+			    break;
+		    addr -= d[0]; /* subtract base */
+		    *match = (addr < cmd->arg1) &&
+			( d[ 1 + (addr>>5)] &
+			  (1<<(addr & 0x1f)) );
+	}
+}
+
+inline void
+rule_ip_dst(int *match, is_ipv4, ipfw_insn *cmd, struct in_addr *dst_ip)
+{
+	*match = is_ipv4 &&
+	    (((ipfw_insn_ip *)cmd)->addr.s_addr ==
+	    dst_ip->s_addr);
+}
+
+inline void
+rule_ip_dst_me(int *match, is_ipv4, is_ipv6, struct in_addr *dst_ip, dst_ip6)
+{
+	if (is_ipv4) {
+		struct ifnet *tif;
+
+		INADDR_TO_IFP(dst_ip, tif);
+		*match = (tif != NULL);
+		return;
+	}
+	*match= is_ipv6 && search_ip6_addr_net(&args->f_id.dst_ip6);
+}
+
+inline void
+rule_ip6_dst_me(int *match, struct ip_fw_args *args)
+{
+	*match= is_ipv6 && search_ip6_addr_net(&args->f_id.dst_ip6);
+}
+
+inline void
+rule_ip_dstport(int *match, uint8_t proto, u_short offset, ipfw_insn *cmd, int cmdlen)
+{
+	/*
+	 * offset == 0 && proto != 0 is enough
+	 * to guarantee that we have a
+	 * packet with port info.
+	 */
+	if ((proto==IPPROTO_UDP || proto==IPPROTO_TCP)
+	    && offset == 0) {
+		u_int16_t x =
+		    (cmd->opcode == O_IP_SRCPORT) ?
+			src_port : dst_port ;
+		u_int16_t *p =
+		    ((ipfw_insn_u16 *)cmd)->ports;
+		int i;
+
+		for (i = cmdlen - 1; !match && i>0;
+		    i--, p += 2)
+			*match = (x>=p[0] && x<=p[1]);
+	}
+}
+
+inline void
+rule_icmptype(int *match, u_short offset, uint8_t proto, void *ulp, ipfw_insn *cmd )
+{
+	*match = (offset == 0 && proto==IPPROTO_ICMP &&
+	    icmptype_match(ICMP(ulp), (ipfw_insn_u32 *)cmd) );
+}
+
+inline void
+rule_ipopt(int *match, int is_ipv4, struct ip *ip, ipfw_insn *cmd)
+{
+	*match = (is_ipv4 &&
+    	ipopts_match(ip, cmd) );
+
+}
+
+inline void
+rule_ipver(int *match, int is_ipv4, ipfw_insn *cmd, struct ip *ip)
+{
+	match = (is_ipv4 &&
+		cmd->arg1 == ip->ip_v);
+}
+
+inline void
+rule_ipttl(int *match, int is_ipv4 ipfw_insn *cmd, int cmdlen, struct ip *ip, uint16_t iplen)
+{
+	if (is_ipv4) {	/* only for IP packets */
+	    uint16_t x;
+	    uint16_t *p;
+	    int i;
+
+	    if (cmd->opcode == O_IPLEN)
+			x = iplen;
+	    else if (cmd->opcode == O_IPTTL)
+			x = ip->ip_ttl;
+	    else /* must be IPID */
+			x = ntohs(ip->ip_id);
+	    if (cmdlen == 1) {
+			*match = (cmd->arg1 == x);
+			return;
+	    }
+	    /* otherwise we have ranges */
+	    p = ((ipfw_insn_u16 *)cmd)->ports;
+	    i = cmdlen - 1;
+	    for (; !match && i>0; i--, p += 2)
+			*match = (x >= p[0] && x <= p[1]);
+	}
+}
+
+inline void
+rule_ipprecedence(int *match, int is_ipv4, ipfw_insn *cmd, struct ip *ip)
+{
+	*match = (is_ipv4 &&
+	    (cmd->arg1 == (ip->ip_tos & 0xe0)) );
+}
+
+inline void
+rule_iptos(int *match, int is_ipv4 ipfw_insn *cmd, struct ip *ip)
+{
+	*match = (is_ipv4 &&
+	    flags_match(cmd, ip->ip_tos));
+}
+
+inline void
+rule_dscp(int *match, int is_ipv4, int is_ipv6, ipfw_insn *cmd, struct ip *ip)
+{
+	uint32_t *p;
+	uint16_t x;
+
+	p = ((ipfw_insn_u32 *)cmd)->d;
+
+	if (is_ipv4)
+		x = ip->ip_tos >> 2;
+	else if (is_ipv6) {
+		uint8_t *v;
+		v = &((struct ip6_hdr *)ip)->ip6_vfc;
+		x = (*v & 0x0F) << 2;
+		v++;
+		x |= *v >> 6;
+	} else
+		break;
+
+	/* DSCP bitmask is stored as low_u32 high_u32 */
+	if (x > 32)
+		*match = *(p + 1) & (1 << (x - 32));
+	else
+		*match = *p & (1 << x);
+}
+
+inline void
+rule_tcpdatalen(int *match, uint8_t proto, u_short offset, void *ulp, uint16_t iplen int *cmdlen, ipfw_insn *cmd)
+{
+	if (proto == IPPROTO_TCP && offset == 0) {
+	    struct tcphdr *tcp;
+	    uint16_t x;
+	    uint16_t *p;
+	    int i;
+
+	    tcp = TCP(ulp);
+	    x = iplen -
+		    ((ip->ip_hl + tcp->th_off) << 2);
+	    if (cmdlen == 1) {
+			match = (cmd->arg1 == x);
+			return;
+	    }
+	    /* otherwise we have ranges */
+	    p = ((ipfw_insn_u16 *)cmd)->ports;
+	    i = cmdlen - 1;
+	    for (; !match && i>0; i--, p += 2)
+			*match = (x >= p[0] && x <= p[1]);
+	}
+}
+
+inline void
+rule_tcpflags(int *match, uint8_t proto, u_short offset, ipfw_insn *cmd, void *ulp)
+{
+	*match = (proto == IPPROTO_TCP && offset == 0 &&
+	    flags_match(cmd, TCP(ulp)->th_flags));
+}
+
+inline void
+rule_tcpopts(int *match, hlen, void *ulp, uint8_t proto, u_short offset, ipfw_insn *cmd);
+{
+	PULLUP_LEN(hlen, ulp, (TCP(ulp)->th_off << 2));
+	*match = (proto == IPPROTO_TCP && offset == 0 &&
+	    tcpopts_match(TCP(ulp), cmd));
+}
+
+inline void
+rule_tcpseq(int *match, uint8_t proto, u_short offset, ipfw_insn *cmd, void *ulp)
+{
+	match = (proto == IPPROTO_TCP && offset == 0 &&
+	    ((ipfw_insn_u32 *)cmd)->d[0] ==
+		TCP(ulp)->th_seq);
+}
+
+inline void
+rule_tcpack(int *match, uint8_t proto, u_short offset, ipfw_insn *cmd, void *ulp)
+{
+	*match = (proto == IPPROTO_TCP && offset == 0 &&
+	    ((ipfw_insn_u32 *)cmd)->d[0] ==
+		TCP(void *ulp)->th_ack);
+}
+
+inline void
+rule_tcpwin(int *match, uint8_t proto, u_short offset, ipfw_insn *cmd, void *ulp)
+{
+	if (proto == IPPROTO_TCP && offset == 0) {
+	    uint16_t x;
+	    uint16_t *p;
+	    int i;
+
+	    x = ntohs(TCP(ulp)->th_win);
+	    if (cmdlen == 1) {
+			*match = (cmd->arg1 == x);
+			return;
+	    }
+	    /* Otherwise we have ranges. */
+	    p = ((ipfw_insn_u16 *)cmd)->ports;
+	    i = cmdlen - 1;
+	    for (; !(*match) && i > 0; i--, p += 2)
+		*match = (x >= p[0] && x <= p[1]);
+	}
+}
+
+inline void
+rule_estab(int *match, uint8_t proto, u_short offset, void *ulp)
+{
+	/* reject packets which have SYN only */
+	/* XXX should i also check for TH_ACK ? */
+	*match = (proto == IPPROTO_TCP && offset == 0 &&
+	    (TCP(ulp)->th_flags &
+	     (TH_RST | TH_ACK | TH_SYN)) != TH_SYN);
+}
+
+inline void
+rule_altq(int *match, ipfw_insn *cmd, struct mbuf *m, tag /*PACKET_TAG_PF*/, size_t size, num)
+{
+}
+
+inline void
+rule_log(int *match, f, hlen, struct ip_fw_args *args, struct mbuf *m, struct ifnet *oif, u_short offset, ip6f_mf, uint32_t *tablearg, struct ip *ip)
+{
+}
+
+inline void
+rule_prob(int *match, ipfw_insn *cmd)
+{
+}
+
+inline void
+rule_verrevpath(int *match, struct ifnet *oif, struct mbuf *m, int is_ipv6 struct ip_fw_args *args, struct in_addr *src_ip)
+{
+}
+
+inline void
+rule_versrcreach(int *match, int is_ipv6 struct ip_fw_args *args, struct in_addr *src_ip)
+{
+}
+
+inline void
+rule_antispoof(int *match, struct ifnet *oif, hlen, int is_ipv4 struct in_addr *src_ip, int is_ipv6 struct ip_fw_args *args, m)
+{
+}
+
+inline void
+rule_ip4(int *match, is_ipv4)
+{
+}
+
+inline void
+rule_tag(int *match, ipfw_insn *cmd, struct mbuf *m, tag, )
+{
+}
+
+inline void
+rule_fib(int *match, struct ip_fw_args *args, ipfw_insn *cmd)
+{
+}
+
+inline void
+rule_tagged(int *match, ipfw_insn *cmd, int *cmdlen, struct mbuf *m, ipfw, tag)
+{
+}
+
 
 #ifdef INET6
-inline void rule_icmp6type(int *match, offset, proto, icmp6_type, cmd);
-inline void rule_ip6_src(int *match, is_ipv6, src_ip6, addr6);
-inline void rule_ip6_dst(int *match, is_ipv6, dst_ip6, addr6);
-inline void rule_ip6_dst_mask(int *match, args, cmd, cmdlen, is_ipv6, dst_ip6, addr6);
-inline void rule_ip6_dst(int *match, is_ipv6, flow_id6, cmd);
-inline void rule_is_ipv6(int *match, is_ipv6, ext_hd, cmd);
-inline void rule_ip6(int *match, is_ipv6);
+inline void
+rule_icmp6type(int *match, u_short offset, uint8_t proto, void *void *ulp, ipfw_insn *cmd)
+{
+	*match = is_ipv6 && offset == 0 &&
+	    proto==IPPROTO_ICMPV6 &&
+	    icmp6type_match(
+		ICMP6(void *ulp)->icmp6_type,
+		(ipfw_insn_u32 *)cmd);
+}
+
+inline void
+rule_ip6_src(int *match, int is_ipv6 struct in_addr *src_ip6, addr6)
+{
+}
+
+inline void
+rule_ip6_dst(int *match, int is_ipv6 dst_ip6, addr6)
+{
+}
+
+inline void
+rule_ip6_dst_mask(int *match, struct ip_fw_args *args, ipfw_insn *cmd, int *cmdlen, int is_ipv6 dst_ip6, addr6)
+{
+}
+
+inline void
+rule_ip6_dst(int *match, int is_ipv6 flow_id6, ipfw_insn *cmd)
+{
+}
+
+inline void
+rule_is_ipv6(int *match, int is_ipv6 ext_hd, ipfw_insn *cmd)
+{
+}
+
+inline void
+rule_ip6(int *match, is_ipv6)
+{
+}
+

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-soc-all mailing list