From owner-svn-soc-all@FreeBSD.ORG Mon Jun 9 15:09:20 2014 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 1B299E5C for ; Mon, 9 Jun 2014 15:09:20 +0000 (UTC) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 067B62DD0 for ; Mon, 9 Jun 2014 15:09:20 +0000 (UTC) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.8/8.14.8) with ESMTP id s59F9Jam020798 for ; Mon, 9 Jun 2014 15:09:19 GMT (envelope-from dpl@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.8/8.14.8/Submit) id s59F9JHm020430 for svn-soc-all@FreeBSD.org; Mon, 9 Jun 2014 15:09:19 GMT (envelope-from dpl@FreeBSD.org) Date: Mon, 9 Jun 2014 15:09:19 GMT Message-Id: <201406091509.s59F9JHm020430@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to dpl@FreeBSD.org using -f From: dpl@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r269305 - soc2014/dpl/netmap-ipfw/sys/netpfil/ipfw MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Jun 2014 15:09:20 -0000 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 ***