Sync with the new ipfw3 version.
[ipfw.git] / dummynet2 / ip_fw2.c
index 3cc08e7..b646245 100644 (file)
@@ -142,6 +142,11 @@ ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr;
 ipfw_nat_cfg_t *ipfw_nat_get_log_ptr;
 
 #ifdef SYSCTL_NODE
+uint32_t dummy_def = IPFW_DEFAULT_RULE;
+uint32_t dummy_tables_max = IPFW_TABLES_MAX;
+
+SYSBEGIN(f3)
+
 SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, one_pass,
     CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_one_pass), 0,
@@ -155,11 +160,9 @@ SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose,
 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit,
     CTLFLAG_RW, &VNET_NAME(verbose_limit), 0,
     "Set upper limit of matches of ipfw rules logged");
-uint32_t dummy_def = IPFW_DEFAULT_RULE;
 SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, default_rule, CTLFLAG_RD,
     &dummy_def, 0,
     "The default/max possible rule number.");
-uint32_t dummy_tables_max = IPFW_TABLES_MAX;
 SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, tables_max, CTLFLAG_RD,
     &dummy_tables_max, 0,
     "The maximum number of tables.");
@@ -179,6 +182,8 @@ SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, deny_unknown_exthdrs,
     "Deny packets with unknown IPv6 Extension Headers");
 #endif /* INET6 */
 
+SYSEND
+
 #endif /* SYSCTL_NODE */
 
 
@@ -346,7 +351,7 @@ iface_match(struct ifnet *ifp, ipfw_insn_if *cmd)
                                return(1);
                }
        } else {
-#if !defined( __linux__ ) && !defined( _WIN32 )
+#ifdef __FreeBSD__     /* and OSX too ? */
                struct ifaddr *ia;
 
                if_addr_rlock(ifp);
@@ -360,7 +365,7 @@ iface_match(struct ifnet *ifp, ipfw_insn_if *cmd)
                        }
                }
                if_addr_runlock(ifp);
-#endif
+#endif /* __FreeBSD__ */
        }
        return(0);      /* no match, fail ... */
 }
@@ -389,7 +394,7 @@ iface_match(struct ifnet *ifp, ipfw_insn_if *cmd)
 static int
 verify_path(struct in_addr src, struct ifnet *ifp, u_int fib)
 {
-#if defined( __linux__ ) || defined( _WIN32 )
+#ifndef __FreeBSD__
        return 0;
 #else
        struct route ro;
@@ -434,7 +439,7 @@ verify_path(struct in_addr src, struct ifnet *ifp, u_int fib)
        /* found valid route */
        RTFREE(ro.ro_rt);
        return 1;
-#endif
+#endif /* __FreeBSD__ */
 }
 
 #ifdef INET6
@@ -642,10 +647,10 @@ send_reject(struct ip_fw_args *args, int code, int iplen, struct ip *ip)
 static int
 check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
     struct in_addr dst_ip, u_int16_t dst_port, struct in_addr src_ip,
-    u_int16_t src_port, struct ucred **uc, int *ugid_lookupp,
-    struct inpcb *inp)
+    u_int16_t src_port, int *ugid_lookupp,
+    struct ucred **uc, struct inpcb *inp)
 {
-#ifdef __linux__
+#ifndef __FreeBSD__
        return cred_check(insn, proto, oif,
        dst_ip, dst_port, src_ip, src_port,
        (struct bsd_ucred *)uc, ugid_lookupp, ((struct mbuf *)inp)->m_skb);
@@ -716,7 +721,7 @@ check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
        else if (insn->o.opcode == O_JAIL)
                match = ((*uc)->cr_prison->pr_id == (int)insn->d[0]);
        return match;
-#endif
+#endif /* __FreeBSD__ */
 }
 
 /*
@@ -808,7 +813,7 @@ ipfw_chk(struct ip_fw_args *args)
         * these types of constraints, as well as decrease contention
         * on pcb related locks.
         */
-#ifdef __linux__
+#ifndef __FreeBSD__
        struct bsd_ucred ucred_cache;
 #else
        struct ucred *ucred_cache = NULL;
@@ -881,10 +886,13 @@ ipfw_chk(struct ip_fw_args *args)
         * ulp is NULL if not found.
         */
        void *ulp = NULL;               /* upper layer protocol pointer. */
+
        /* XXX ipv6 variables */
        int is_ipv6 = 0;
-       u_int16_t ext_hd = 0;   /* bits vector for extension header filtering */
+       uint8_t icmp6_type = 0;
+       uint16_t ext_hd = 0;    /* bits vector for extension header filtering */
        /* end of ipv6 variables */
+
        int is_ipv4 = 0;
 
        int done = 0;           /* flag to exit the outer loop */
@@ -936,14 +944,15 @@ do {                                                              \
                        switch (proto) {
                        case IPPROTO_ICMPV6:
                                PULLUP_TO(hlen, ulp, struct icmp6_hdr);
-                               args->f_id.flags = ICMP6(ulp)->icmp6_type;
+                               icmp6_type = ICMP6(ulp)->icmp6_type;
                                break;
 
                        case IPPROTO_TCP:
                                PULLUP_TO(hlen, ulp, struct tcphdr);
                                dst_port = TCP(ulp)->th_dport;
                                src_port = TCP(ulp)->th_sport;
-                               args->f_id.flags = TCP(ulp)->th_flags;
+                               /* save flags for dynamic rules */
+                               args->f_id._flags = TCP(ulp)->th_flags;
                                break;
 
                        case IPPROTO_SCTP:
@@ -1007,7 +1016,7 @@ do {                                                              \
                                            return (IP_FW_DENY);
                                        break;
                                }
-                               args->f_id.frag_id6 =
+                               args->f_id.extra =
                                    ntohl(((struct ip6_frag *)ulp)->ip6f_ident);
                                ulp = NULL;
                                break;
@@ -1110,7 +1119,8 @@ do {                                                              \
                                PULLUP_TO(hlen, ulp, struct tcphdr);
                                dst_port = TCP(ulp)->th_dport;
                                src_port = TCP(ulp)->th_sport;
-                               args->f_id.flags = TCP(ulp)->th_flags;
+                               /* save flags for dynamic rules */
+                               args->f_id._flags = TCP(ulp)->th_flags;
                                break;
 
                        case IPPROTO_UDP:
@@ -1121,7 +1131,7 @@ do {                                                              \
 
                        case IPPROTO_ICMP:
                                PULLUP_TO(hlen, ulp, struct icmphdr);
-                               args->f_id.flags = ICMP(ulp)->icmp_type;
+                               //args->f_id.flags = ICMP(ulp)->icmp_type;
                                break;
 
                        default:
@@ -1251,8 +1261,13 @@ do {                                                             \
                                                    (ipfw_insn_u32 *)cmd,
                                                    proto, oif,
                                                    dst_ip, dst_port,
-                                                   src_ip, src_port, (void *)&ucred_cache,
-                                                   &ucred_lookup, (struct inpcb *)args->m);
+                                                   src_ip, src_port, &ucred_lookup,
+#ifdef __FreeBSD__
+                                                   &ucred_cache, args->inp);
+#else
+                                                   (void *)&ucred_cache,
+                                                   (struct inpcb *)args->m);
+#endif
                                break;
 
                        case O_RECV:
@@ -1352,6 +1367,8 @@ do {                                                              \
                                            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 &&
@@ -1366,19 +1383,21 @@ do {                                                            \
                                                (ipfw_insn_u32 *)cmd,
                                                proto, oif,
                                                dst_ip, dst_port,
-                                               src_ip, src_port, (void *)&ucred_cache,
-                                               &ucred_lookup, (struct inpcb *)args->m);
-#ifdef __linux__
-                                           if (v ==4 /* O_UID */)
-                                               key = ucred_cache.uid;
-                                           else if (v == 5 /* O_JAIL */)
-                                               key = ucred_cache.xid;
-#else
+                                               src_ip, src_port, &ucred_lookup,
+#ifdef __FreeBSD__
+                                               &ucred_cache, args->inp);
                                            if (v == 4 /* O_UID */)
                                                key = ucred_cache->cr_uid;
                                            else if (v == 5 /* O_JAIL */)
                                                key = ucred_cache->cr_prison->pr_id;
-#endif
+#else /* !__FreeBSD__ */
+                                               (void *)&ucred_cache,
+                                               (struct inpcb *)args->m);
+                                           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
                                            break;
@@ -1415,7 +1434,13 @@ do {                                                             \
 
                                        INADDR_TO_IFP(src_ip, tif);
                                        match = (tif != NULL);
+                                       break;
                                }
+#ifdef INET6
+                               /* FALLTHROUGH */
+                       case O_IP6_SRC_ME:
+                               match= is_ipv6 && search_ip6_addr_net(&args->f_id.src_ip6);
+#endif
                                break;
 
                        case O_IP_DST_SET:
@@ -1448,9 +1473,16 @@ do {                                                             \
 
                                        INADDR_TO_IFP(dst_ip, tif);
                                        match = (tif != NULL);
+                                       break;
                                }
+#ifdef INET6
+                               /* FALLTHROUGH */
+                       case O_IP6_DST_ME:
+                               match= is_ipv6 && search_ip6_addr_net(&args->f_id.dst_ip6);
+#endif
                                break;
 
+
                        case O_IP_SRCPORT:
                        case O_IP_DSTPORT:
                                /*
@@ -1716,14 +1748,6 @@ do {                                                             \
                                }
                                break;
 
-                       case O_IP6_SRC_ME:
-                               match= is_ipv6 && search_ip6_addr_net(&args->f_id.src_ip6);
-                               break;
-
-                       case O_IP6_DST_ME:
-                               match= is_ipv6 && search_ip6_addr_net(&args->f_id.dst_ip6);
-                               break;
-
                        case O_FLOW6ID:
                                match = is_ipv6 &&
                                    flow6id_match(args->f_id.flow_id6,
@@ -2017,7 +2041,7 @@ do {                                                              \
                                if (hlen > 0 && is_ipv6 &&
                                    ((offset & IP6F_OFF_MASK) == 0) &&
                                    (proto != IPPROTO_ICMPV6 ||
-                                    (is_icmp6_query(args->f_id.flags) == 1)) &&
+                                    (is_icmp6_query(icmp6_type) == 1)) &&
                                    !(m->m_flags & (M_BCAST|M_MCAST)) &&
                                    !IN6_IS_ADDR_MULTICAST(&args->f_id.dst_ip6)) {
                                        send_reject6(
@@ -2183,7 +2207,7 @@ do {                                                              \
                printf("ipfw: ouch!, skip past end of rules, denying packet\n");
        }
        IPFW_RUNLOCK(chain);
-#ifndef __linux__
+#ifdef __FreeBSD__
        if (ucred_cache != NULL)
                crfree(ucred_cache);
 #endif
@@ -2375,7 +2399,7 @@ vnet_ipfw_uninit(const void *unused)
        IPFW_WLOCK(chain);
 
        ipfw_dyn_uninit(0);     /* run the callout_drain */
-       ipfw_flush_tables(chain);
+       ipfw_destroy_tables(chain);
        reap = NULL;
        for (i = 0; i < chain->n_rules; i++) {
                rule = chain->map[i];