X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/eb6b6ca394357805f2bdba989abae309f718b4d8..f427ee49d309d8fc33ebf3042c3a775f2f530ded:/bsd/netinet/ip_input.c diff --git a/bsd/netinet/ip_input.c b/bsd/netinet/ip_input.c index 1c162bf8c..af5c216e3 100644 --- a/bsd/netinet/ip_input.c +++ b/bsd/netinet/ip_input.c @@ -116,22 +116,15 @@ #include #include #include -#include -#include #include #include #include #include -#include #if DUMMYNET #include #endif /* DUMMYNET */ -#if CONFIG_MACF_NET -#include -#endif /* CONFIG_MACF_NET */ - #if IPSEC #include #include @@ -164,7 +157,7 @@ static struct ipq *ipq_alloc(int); static void ipq_free(struct ipq *); static void ipq_updateparams(void); static void ip_input_second_pass(struct mbuf *, struct ifnet *, - u_int32_t, int, int, struct ip_fw_in_args *, int); + int, int, struct ip_fw_in_args *); decl_lck_mtx_data(static, ipqlock); static lck_attr_t *ipqlock_attr; @@ -365,14 +358,6 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, stealth, CTLFLAG_RW | CTLFLAG_LOCKED, &ipstealth, 0, ""); #endif /* IPSTEALTH */ -/* Firewall hooks */ -#if IPFIREWALL -ip_fw_chk_t *ip_fw_chk_ptr; -int fw_enable = 1; -int fw_bypass = 1; -int fw_one_pass = 0; -#endif /* IPFIREWALL */ - #if DUMMYNET ip_dn_io_t *ip_dn_io_ptr; #endif /* DUMMYNET */ @@ -414,15 +399,7 @@ static void save_rte(u_char *, struct in_addr); static int ip_dooptions(struct mbuf *, int, struct sockaddr_in *); static void ip_forward(struct mbuf *, int, struct sockaddr_in *); static void frag_freef(struct ipqhead *, struct ipq *); -#if IPDIVERT -#ifdef IPDIVERT_44 -static struct mbuf *ip_reass(struct mbuf *, u_int32_t *, u_int16_t *); -#else /* !IPDIVERT_44 */ -static struct mbuf *ip_reass(struct mbuf *, u_int16_t *, u_int16_t *); -#endif /* !IPDIVERT_44 */ -#else /* !IPDIVERT */ static struct mbuf *ip_reass(struct mbuf *); -#endif /* !IPDIVERT */ static void ip_fwd_route_copyout(struct ifnet *, struct route *); static void ip_fwd_route_copyin(struct ifnet *, struct route *); static inline u_short ip_cksum(struct mbuf *, int); @@ -673,12 +650,6 @@ inaddr_hashval(u_int32_t key) } } -void -ip_proto_dispatch_in_wrapper(struct mbuf *m, int hlen, u_int8_t proto) -{ - ip_proto_dispatch_in(m, hlen, proto, 0); -} - __private_extern__ void ip_proto_dispatch_in(struct mbuf *m, int hlen, u_int8_t proto, ipfilter_t inject_ipfref) @@ -820,8 +791,8 @@ ip_input_second_pass_loop_tbl(pktchain_elm_t *tbl, struct ip_fw_in_args *args) for (i = 0; i < PKTTBL_SZ; i++) { if (tbl[i].pkte_head != NULL) { struct mbuf *m = tbl[i].pkte_head; - ip_input_second_pass(m, m->m_pkthdr.rcvif, 0, - tbl[i].pkte_npkts, tbl[i].pkte_nbytes, args, 0); + ip_input_second_pass(m, m->m_pkthdr.rcvif, + tbl[i].pkte_npkts, tbl[i].pkte_nbytes, args); if (tbl[i].pkte_npkts > 2) { ipstat.ips_rxc_chainsz_gt2++; @@ -850,19 +821,13 @@ ip_input_cpout_args(struct ip_fw_in_args *args, struct ip_fw_args *args1, bzero(args1, sizeof(struct ip_fw_args)); *done_init = TRUE; } - args1->fwa_next_hop = args->fwai_next_hop; - args1->fwa_ipfw_rule = args->fwai_ipfw_rule; args1->fwa_pf_rule = args->fwai_pf_rule; - args1->fwa_divert_rule = args->fwai_divert_rule; } static void ip_input_cpin_args(struct ip_fw_args *args1, struct ip_fw_in_args *args) { - args->fwai_next_hop = args1->fwa_next_hop; - args->fwai_ipfw_rule = args1->fwa_ipfw_rule; args->fwai_pf_rule = args1->fwa_pf_rule; - args->fwai_divert_rule = args1->fwa_divert_rule; } typedef enum { @@ -899,13 +864,7 @@ ip_input_dispatch_chain(struct mbuf *m) while (tmp_mbuf != NULL) { nxt_mbuf = mbuf_nextpkt(tmp_mbuf); mbuf_setnextpkt(tmp_mbuf, NULL); - - if ((sw_lro) && (ip->ip_p == IPPROTO_TCP)) { - tmp_mbuf = tcp_lro(tmp_mbuf, hlen); - } - if (tmp_mbuf) { - ip_proto_dispatch_in(tmp_mbuf, hlen, ip->ip_p, 0); - } + ip_proto_dispatch_in(tmp_mbuf, hlen, ip->ip_p, 0); tmp_mbuf = nxt_mbuf; if (tmp_mbuf) { ip = mtod(tmp_mbuf, struct ip *); @@ -1000,11 +959,9 @@ ip_input_adjust(struct mbuf *m, struct ip *ip, struct ifnet *inifp) /* * First pass does all essential packet validation and places on a per flow * queue for doing operations that have same outcome for all packets of a flow. - * div_info is packet divert/tee info */ static ipinput_chain_ret_t -ip_input_first_pass(struct mbuf *m, u_int32_t *div_info, - struct ip_fw_in_args *args, int *ours, struct mbuf **modm) +ip_input_first_pass(struct mbuf *m, struct ip_fw_in_args *args, struct mbuf **modm) { struct ip *ip; struct ifnet *inifp; @@ -1012,31 +969,15 @@ ip_input_first_pass(struct mbuf *m, u_int32_t *div_info, int retval = IPINPUT_DOCHAIN; int len = 0; struct in_addr src_ip; -#if IPFIREWALL - int i; -#endif -#if IPFIREWALL || DUMMYNET +#if DUMMYNET struct m_tag *copy; struct m_tag *p; boolean_t delete = FALSE; struct ip_fw_args args1; boolean_t init = FALSE; -#endif +#endif /* DUMMYNET */ ipfilter_t inject_filter_ref = NULL; -#if !IPFIREWALL -#pragma unused (args) -#endif - -#if !IPDIVERT -#pragma unused (div_info) -#pragma unused (ours) -#endif - -#if !IPFIREWALL_FORWARD -#pragma unused (ours) -#endif - /* Check if the mbuf is still valid after interface filter processing */ MBUF_INPUT_CHECK(m, m->m_pkthdr.rcvif); inifp = mbuf_pkthdr_rcvif(m); @@ -1047,8 +988,7 @@ ip_input_first_pass(struct mbuf *m, u_int32_t *div_info, m->m_pkthdr.pkt_flags &= ~PKTF_FORWARDED; -#if IPFIREWALL || DUMMYNET - +#if DUMMYNET /* * Don't bother searching for tag(s) if there's none. */ @@ -1060,34 +1000,13 @@ ip_input_first_pass(struct mbuf *m, u_int32_t *div_info, p = m_tag_first(m); while (p) { if (p->m_tag_id == KERNEL_MODULE_TAG_ID) { -#if DUMMYNET if (p->m_tag_type == KERNEL_TAG_TYPE_DUMMYNET) { struct dn_pkt_tag *dn_tag; dn_tag = (struct dn_pkt_tag *)(p + 1); - args->fwai_ipfw_rule = dn_tag->dn_ipfw_rule; args->fwai_pf_rule = dn_tag->dn_pf_rule; delete = TRUE; } -#endif - -#if IPDIVERT - if (p->m_tag_type == KERNEL_TAG_TYPE_DIVERT) { - struct divert_tag *div_tag; - - div_tag = (struct divert_tag *)(p + 1); - args->fwai_divert_rule = div_tag->cookie; - delete = TRUE; - } -#endif - - if (p->m_tag_type == KERNEL_TAG_TYPE_IPFORWARD) { - struct ip_fwd_tag *ipfwd_tag; - - ipfwd_tag = (struct ip_fwd_tag *)(p + 1); - args->fwai_next_hop = ipfwd_tag->next_hop; - delete = TRUE; - } if (delete) { copy = p; @@ -1107,24 +1026,17 @@ ip_input_first_pass(struct mbuf *m, u_int32_t *div_info, } #endif -#if DUMMYNET - if (args->fwai_ipfw_rule || args->fwai_pf_rule) { + if (args->fwai_pf_rule) { /* dummynet already filtered us */ ip = mtod(m, struct ip *); hlen = IP_VHL_HL(ip->ip_vhl) << 2; inject_filter_ref = ipf_get_inject_filter(m); -#if IPFIREWALL - if (args->fwai_ipfw_rule) { - goto iphack; - } -#endif /* IPFIREWALL */ if (args->fwai_pf_rule) { goto check_with_pf; } } -#endif /* DUMMYNET */ ipfw_tags_done: -#endif /* IPFIREWALL || DUMMYNET */ +#endif /* DUMMYNET */ /* * No need to process packet twice if we've already seen it. @@ -1290,7 +1202,7 @@ ipfw_tags_done: #if DUMMYNET check_with_pf: -#endif +#endif /* DUMMYNET */ #if PF /* Invoke inbound packet filter */ if (PF_IS_ENABLED) { @@ -1330,83 +1242,7 @@ check_with_pf: } #endif -#if IPFIREWALL -#if DUMMYNET -iphack: -#endif /* DUMMYNET */ - /* - * Check if we want to allow this packet to be processed. - * Consider it to be bad if not. - */ - if (fw_enable && IPFW_LOADED) { -#if IPFIREWALL_FORWARD - /* - * If we've been forwarded from the output side, then - * skip the firewall a second time - */ - if (args->fwai_next_hop) { - *ours = 1; - return IPINPUT_DONTCHAIN; - } -#endif /* IPFIREWALL_FORWARD */ - ip_input_cpout_args(args, &args1, &init); - args1.fwa_m = m; - - i = ip_fw_chk_ptr(&args1); - m = args1.fwa_m; - - if ((i & IP_FW_PORT_DENY_FLAG) || m == NULL) { /* drop */ - if (m) { - m_freem(m); - } - ip_input_update_nstat(inifp, src_ip, 1, len); - KERNEL_DEBUG(DBG_LAYER_END, 0, 0, 0, 0, 0); - OSAddAtomic(1, &ipstat.ips_total); - return IPINPUT_FREED; - } - ip = mtod(m, struct ip *); /* just in case m changed */ - *modm = m; - ip_input_cpin_args(&args1, args); - - if (i == 0 && args->fwai_next_hop == NULL) { /* common case */ - goto pass; - } -#if DUMMYNET - if (DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG) != 0) { - /* Send packet to the appropriate pipe */ - ip_dn_io_ptr(m, i & 0xffff, DN_TO_IP_IN, &args1, - DN_CLIENT_IPFW); - ip_input_update_nstat(inifp, src_ip, 1, len); - KERNEL_DEBUG(DBG_LAYER_END, 0, 0, 0, 0, 0); - OSAddAtomic(1, &ipstat.ips_total); - return IPINPUT_FREED; - } -#endif /* DUMMYNET */ -#if IPDIVERT - if (i != 0 && (i & IP_FW_PORT_DYNT_FLAG) == 0) { - /* Divert or tee packet */ - *div_info = i; - *ours = 1; - return IPINPUT_DONTCHAIN; - } -#endif -#if IPFIREWALL_FORWARD - if (i == 0 && args->fwai_next_hop != NULL) { - retval = IPINPUT_DONTCHAIN; - goto pass; - } -#endif - /* - * if we get here, the packet must be dropped - */ - ip_input_update_nstat(inifp, src_ip, 1, len); - KERNEL_DEBUG(DBG_LAYER_END, 0, 0, 0, 0, 0); - m_freem(m); - OSAddAtomic(1, &ipstat.ips_total); - return IPINPUT_FREED; - } -#endif /* IPFIREWALL */ -#if IPSEC | IPFIREWALL +#if IPSEC pass: #endif /* @@ -1416,12 +1252,7 @@ pass: * to be sent and the original packet to be freed). */ ip_nhops = 0; /* for source routed packets */ -#if IPFIREWALL - if (hlen > sizeof(struct ip) && - ip_dooptions(m, 0, args->fwai_next_hop)) { -#else /* !IPFIREWALL */ if (hlen > sizeof(struct ip) && ip_dooptions(m, 0, NULL)) { -#endif /* !IPFIREWALL */ ip_input_update_nstat(inifp, src_ip, 1, len); KERNEL_DEBUG(DBG_LAYER_END, 0, 0, 0, 0, 0); OSAddAtomic(1, &ipstat.ips_total); @@ -1429,9 +1260,7 @@ pass: } /* - * Don't chain fragmented packets as the process of determining - * if it is our fragment or someone else's plus the complexity of - * divert and fw args makes it harder to do chaining. + * Don't chain fragmented packets */ if (ip->ip_off & ~(IP_DF | IP_RF)) { return IPINPUT_DONTCHAIN; @@ -1618,7 +1447,7 @@ ip_input_check_interface(struct mbuf **mp, struct ip *ip, struct ifnet *inifp) inet_ntop(AF_INET, &ip->ip_src, src_str, sizeof(src_str)); inet_ntop(AF_INET, &ip->ip_dst, dst_str, sizeof(dst_str)); - os_log_info(OS_LOG_DEFAULT, + os_log(OS_LOG_DEFAULT, "%s: no interface match for packet from %s to %s proto %u received via %s", __func__, src_str, dst_str, ip->ip_p, inifp->if_xname); } @@ -1635,19 +1464,13 @@ ip_input_check_interface(struct mbuf **mp, struct ip *ip, struct ifnet *inifp) } static void -ip_input_second_pass(struct mbuf *m, struct ifnet *inifp, u_int32_t div_info, - int npkts_in_chain, int bytes_in_chain, struct ip_fw_in_args *args, int ours) +ip_input_second_pass(struct mbuf *m, struct ifnet *inifp, + int npkts_in_chain, int bytes_in_chain, struct ip_fw_in_args *args) { struct mbuf *tmp_mbuf = NULL; unsigned int hlen; -#if !IPFIREWALL #pragma unused (args) -#endif - -#if !IPDIVERT -#pragma unused (div_info) -#endif struct ip *ip = mtod(m, struct ip *); hlen = IP_VHL_HL(ip->ip_vhl) << 2; @@ -1668,10 +1491,6 @@ ip_input_second_pass(struct mbuf *m, struct ifnet *inifp, u_int32_t div_info, ip_input_update_nstat(inifp, ip->ip_src, npkts_in_chain, bytes_in_chain); - if (ours) { - goto ours; - } - /* * Check our list of addresses, to see if the packet is for us. * If we don't have any addresses, assume any unicast packet @@ -1694,8 +1513,7 @@ ip_input_second_pass(struct mbuf *m, struct ifnet *inifp, u_int32_t div_info, * Enable a consistency check between the destination address * and the arrival interface for a unicast packet (the RFC 1122 * strong ES model) if IP forwarding is disabled and the packet - * is not locally generated and the packet is not subject to - * 'ipfw fwd'. + * is not locally generated * * XXX - Checking also should be disabled if the destination * address is ipnat'ed to a different interface. @@ -1746,11 +1564,7 @@ ip_input_second_pass(struct mbuf *m, struct ifnet *inifp, u_int32_t div_info, OSAddAtomic(1, &ipstat.ips_cantforward); m_freem(tmp_mbuf); } else { -#if IPFIREWALL - ip_forward(tmp_mbuf, 0, args->fwai_next_hop); -#else ip_forward(tmp_mbuf, 0, NULL); -#endif } tmp_mbuf = nxt_mbuf; } @@ -1759,41 +1573,17 @@ ip_input_second_pass(struct mbuf *m, struct ifnet *inifp, u_int32_t div_info, ours: ip = mtod(m, struct ip *); /* in case it changed */ /* - * If offset or IP_MF are set, must reassemble. + * If offset is set, must reassemble. */ if (ip->ip_off & ~(IP_DF | IP_RF)) { VERIFY(npkts_in_chain == 1); - /* - * ip_reass() will return a different mbuf, and update - * the divert info in div_info and args->fwai_divert_rule. - */ -#if IPDIVERT - m = ip_reass(m, (u_int16_t *)&div_info, &args->fwai_divert_rule); -#else m = ip_reass(m); -#endif if (m == NULL) { return; } ip = mtod(m, struct ip *); /* Get the header length of the reassembled packet */ hlen = IP_VHL_HL(ip->ip_vhl) << 2; -#if IPDIVERT - /* Restore original checksum before diverting packet */ - if (div_info != 0) { - VERIFY(npkts_in_chain == 1); -#if BYTE_ORDER != BIG_ENDIAN - HTONS(ip->ip_len); - HTONS(ip->ip_off); -#endif - ip->ip_sum = 0; - ip->ip_sum = ip_cksum_hdr_in(m, hlen); -#if BYTE_ORDER != BIG_ENDIAN - NTOHS(ip->ip_off); - NTOHS(ip->ip_len); -#endif - } -#endif } /* @@ -1802,42 +1592,6 @@ ours: */ ip->ip_len -= hlen; -#if IPDIVERT - /* - * Divert or tee packet to the divert protocol if required. - * - * If div_info is zero then cookie should be too, so we shouldn't - * need to clear them here. Assume divert_packet() does so also. - */ - if (div_info != 0) { - struct mbuf *clone = NULL; - VERIFY(npkts_in_chain == 1); - - /* Clone packet if we're doing a 'tee' */ - if (div_info & IP_FW_PORT_TEE_FLAG) { - clone = m_dup(m, M_DONTWAIT); - } - - /* Restore packet header fields to original values */ - ip->ip_len += hlen; - -#if BYTE_ORDER != BIG_ENDIAN - HTONS(ip->ip_len); - HTONS(ip->ip_off); -#endif - /* Deliver packet to divert input routine */ - OSAddAtomic(1, &ipstat.ips_delivered); - divert_packet(m, 1, div_info & 0xffff, args->fwai_divert_rule); - - /* If 'tee', continue with original packet */ - if (clone == NULL) { - return; - } - m = clone; - ip = mtod(m, struct ip *); - } -#endif - #if IPSEC /* * enforce IPsec policy checking if we are seeing last header. @@ -1858,40 +1612,8 @@ ours: */ OSAddAtomic(npkts_in_chain, &ipstat.ips_delivered); -#if IPFIREWALL - if (args->fwai_next_hop && ip->ip_p == IPPROTO_TCP) { - /* TCP needs IPFORWARD info if available */ - struct m_tag *fwd_tag; - struct ip_fwd_tag *ipfwd_tag; - - VERIFY(npkts_in_chain == 1); - fwd_tag = m_tag_create(KERNEL_MODULE_TAG_ID, - KERNEL_TAG_TYPE_IPFORWARD, sizeof(*ipfwd_tag), - M_NOWAIT, m); - if (fwd_tag == NULL) { - goto bad; - } - - ipfwd_tag = (struct ip_fwd_tag *)(fwd_tag + 1); - ipfwd_tag->next_hop = args->fwai_next_hop; - - m_tag_prepend(m, fwd_tag); - - KERNEL_DEBUG(DBG_LAYER_END, ip->ip_dst.s_addr, - ip->ip_src.s_addr, ip->ip_p, ip->ip_off, ip->ip_len); - - /* TCP deals with its own locking */ - ip_proto_dispatch_in(m, hlen, ip->ip_p, 0); - } else { - KERNEL_DEBUG(DBG_LAYER_END, ip->ip_dst.s_addr, - ip->ip_src.s_addr, ip->ip_p, ip->ip_off, ip->ip_len); - - ip_input_dispatch_chain(m); - } -#else /* !IPFIREWALL */ ip_input_dispatch_chain(m); -#endif /* !IPFIREWALL */ KERNEL_DEBUG(DBG_LAYER_END, 0, 0, 0, 0, 0); return; bad: @@ -1907,8 +1629,6 @@ ip_input_process_list(struct mbuf *packet_list) struct mbuf *packet = NULL; struct mbuf *modm = NULL; /* modified mbuf */ int retval = 0; - u_int32_t div_info = 0; - int ours = 0; #if (DEBUG || DEVELOPMENT) struct timeval start_tv; #endif /* (DEBUG || DEVELOPMENT) */ @@ -1953,11 +1673,9 @@ restart_list_process: num_pkts++; modm = NULL; - div_info = 0; bzero(&args, sizeof(args)); - retval = ip_input_first_pass(packet, &div_info, &args, - &ours, &modm); + retval = ip_input_first_pass(packet, &args, &modm); if (retval == IPINPUT_DOCHAIN) { if (modm) { @@ -2001,8 +1719,8 @@ restart_list_process: net_perf_histogram(&net_perf, 1); } #endif /* (DEBUG || DEVELOPMENT) */ - ip_input_second_pass(packet, packet->m_pkthdr.rcvif, div_info, - 1, packet->m_pkthdr.len, &args, ours); + ip_input_second_pass(packet, packet->m_pkthdr.rcvif, + 1, packet->m_pkthdr.len, &args); } if (packet_list) { @@ -2044,7 +1762,7 @@ ip_input(struct mbuf *m) m->m_pkthdr.pkt_flags &= ~PKTF_FORWARDED; -#if IPFIREWALL || DUMMYNET +#if DUMMYNET bzero(&args, sizeof(struct ip_fw_args)); /* @@ -2055,38 +1773,13 @@ ip_input(struct mbuf *m) } /* Grab info from mtags prepended to the chain */ -#if DUMMYNET if ((tag = m_tag_locate(m, KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_DUMMYNET, NULL)) != NULL) { struct dn_pkt_tag *dn_tag; dn_tag = (struct dn_pkt_tag *)(tag + 1); - args.fwa_ipfw_rule = dn_tag->dn_ipfw_rule; args.fwa_pf_rule = dn_tag->dn_pf_rule; - m_tag_delete(m, tag); - } -#endif /* DUMMYNET */ - -#if IPDIVERT - if ((tag = m_tag_locate(m, KERNEL_MODULE_TAG_ID, - KERNEL_TAG_TYPE_DIVERT, NULL)) != NULL) { - struct divert_tag *div_tag; - - div_tag = (struct divert_tag *)(tag + 1); - args.fwa_divert_rule = div_tag->cookie; - - m_tag_delete(m, tag); - } -#endif - - if ((tag = m_tag_locate(m, KERNEL_MODULE_TAG_ID, - KERNEL_TAG_TYPE_IPFORWARD, NULL)) != NULL) { - struct ip_fwd_tag *ipfwd_tag; - - ipfwd_tag = (struct ip_fwd_tag *)(tag + 1); - args.fwa_next_hop = ipfwd_tag->next_hop; - m_tag_delete(m, tag); } @@ -2096,24 +1789,17 @@ ip_input(struct mbuf *m) } #endif -#if DUMMYNET - if (args.fwa_ipfw_rule || args.fwa_pf_rule) { + if (args.fwa_pf_rule) { /* dummynet already filtered us */ ip = mtod(m, struct ip *); hlen = IP_VHL_HL(ip->ip_vhl) << 2; inject_filter_ref = ipf_get_inject_filter(m); -#if IPFIREWALL - if (args.fwa_ipfw_rule) { - goto iphack; - } -#endif /* IPFIREWALL */ if (args.fwa_pf_rule) { goto check_with_pf; } } -#endif /* DUMMYNET */ ipfw_tags_done: -#endif /* IPFIREWALL || DUMMYNET */ +#endif /* DUMMYNET */ /* * No need to process packet twice if we've already seen it. @@ -2295,71 +1981,7 @@ check_with_pf: } #endif -#if IPFIREWALL -#if DUMMYNET -iphack: -#endif /* DUMMYNET */ - /* - * Check if we want to allow this packet to be processed. - * Consider it to be bad if not. - */ - if (fw_enable && IPFW_LOADED) { -#if IPFIREWALL_FORWARD - /* - * If we've been forwarded from the output side, then - * skip the firewall a second time - */ - if (args.fwa_next_hop) { - goto ours; - } -#endif /* IPFIREWALL_FORWARD */ - - args.fwa_m = m; - - i = ip_fw_chk_ptr(&args); - m = args.fwa_m; - - if ((i & IP_FW_PORT_DENY_FLAG) || m == NULL) { /* drop */ - if (m) { - m_freem(m); - } - return; - } - ip = mtod(m, struct ip *); /* just in case m changed */ - - if (i == 0 && args.fwa_next_hop == NULL) { /* common case */ - goto pass; - } -#if DUMMYNET - if (DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG) != 0) { - /* Send packet to the appropriate pipe */ - ip_dn_io_ptr(m, i & 0xffff, DN_TO_IP_IN, &args, - DN_CLIENT_IPFW); - return; - } -#endif /* DUMMYNET */ -#if IPDIVERT - if (i != 0 && (i & IP_FW_PORT_DYNT_FLAG) == 0) { - /* Divert or tee packet */ - div_info = i; - goto ours; - } -#endif -#if IPFIREWALL_FORWARD - if (i == 0 && args.fwa_next_hop != NULL) { - goto pass; - } -#endif - /* - * if we get here, the packet must be dropped - */ - m_freem(m); - return; - } -#endif /* IPFIREWALL */ -#if IPSEC | IPFIREWALL pass: -#endif /* * Process options and, if not destined for us, * ship it on. ip_dooptions returns 1 when an @@ -2367,12 +1989,7 @@ pass: * to be sent and the original packet to be freed). */ ip_nhops = 0; /* for source routed packets */ -#if IPFIREWALL - if (hlen > sizeof(struct ip) && - ip_dooptions(m, 0, args.fwa_next_hop)) { -#else /* !IPFIREWALL */ if (hlen > sizeof(struct ip) && ip_dooptions(m, 0, NULL)) { -#endif /* !IPFIREWALL */ return; } @@ -2437,11 +2054,7 @@ pass: OSAddAtomic(1, &ipstat.ips_cantforward); m_freem(m); } else { -#if IPFIREWALL - ip_forward(m, 0, args.fwa_next_hop); -#else ip_forward(m, 0, NULL); -#endif } return; @@ -2450,36 +2063,13 @@ ours: * If offset or IP_MF are set, must reassemble. */ if (ip->ip_off & ~(IP_DF | IP_RF)) { - /* - * ip_reass() will return a different mbuf, and update - * the divert info in div_info and args.fwa_divert_rule. - */ -#if IPDIVERT - m = ip_reass(m, (u_int16_t *)&div_info, &args.fwa_divert_rule); -#else m = ip_reass(m); -#endif if (m == NULL) { return; } ip = mtod(m, struct ip *); /* Get the header length of the reassembled packet */ hlen = IP_VHL_HL(ip->ip_vhl) << 2; -#if IPDIVERT - /* Restore original checksum before diverting packet */ - if (div_info != 0) { -#if BYTE_ORDER != BIG_ENDIAN - HTONS(ip->ip_len); - HTONS(ip->ip_off); -#endif - ip->ip_sum = 0; - ip->ip_sum = ip_cksum_hdr_in(m, hlen); -#if BYTE_ORDER != BIG_ENDIAN - NTOHS(ip->ip_off); - NTOHS(ip->ip_len); -#endif - } -#endif } /* @@ -2488,40 +2078,6 @@ ours: */ ip->ip_len -= hlen; -#if IPDIVERT - /* - * Divert or tee packet to the divert protocol if required. - * - * If div_info is zero then cookie should be too, so we shouldn't - * need to clear them here. Assume divert_packet() does so also. - */ - if (div_info != 0) { - struct mbuf *clone = NULL; - - /* Clone packet if we're doing a 'tee' */ - if (div_info & IP_FW_PORT_TEE_FLAG) { - clone = m_dup(m, M_DONTWAIT); - } - - /* Restore packet header fields to original values */ - ip->ip_len += hlen; - -#if BYTE_ORDER != BIG_ENDIAN - HTONS(ip->ip_len); - HTONS(ip->ip_off); -#endif - /* Deliver packet to divert input routine */ - OSAddAtomic(1, &ipstat.ips_delivered); - divert_packet(m, 1, div_info & 0xffff, args.fwa_divert_rule); - - /* If 'tee', continue with original packet */ - if (clone == NULL) { - return; - } - m = clone; - ip = mtod(m, struct ip *); - } -#endif #if IPSEC /* @@ -2542,51 +2098,7 @@ ours: */ OSAddAtomic(1, &ipstat.ips_delivered); -#if IPFIREWALL - if (args.fwa_next_hop && ip->ip_p == IPPROTO_TCP) { - /* TCP needs IPFORWARD info if available */ - struct m_tag *fwd_tag; - struct ip_fwd_tag *ipfwd_tag; - - fwd_tag = m_tag_create(KERNEL_MODULE_TAG_ID, - KERNEL_TAG_TYPE_IPFORWARD, sizeof(*ipfwd_tag), - M_NOWAIT, m); - if (fwd_tag == NULL) { - goto bad; - } - - ipfwd_tag = (struct ip_fwd_tag *)(fwd_tag + 1); - ipfwd_tag->next_hop = args.fwa_next_hop; - - m_tag_prepend(m, fwd_tag); - - KERNEL_DEBUG(DBG_LAYER_END, ip->ip_dst.s_addr, - ip->ip_src.s_addr, ip->ip_p, ip->ip_off, ip->ip_len); - - /* TCP deals with its own locking */ - ip_proto_dispatch_in(m, hlen, ip->ip_p, 0); - } else { - KERNEL_DEBUG(DBG_LAYER_END, ip->ip_dst.s_addr, - ip->ip_src.s_addr, ip->ip_p, ip->ip_off, ip->ip_len); - - if ((sw_lro) && (ip->ip_p == IPPROTO_TCP)) { - m = tcp_lro(m, hlen); - if (m == NULL) { - return; - } - } - - ip_proto_dispatch_in(m, hlen, ip->ip_p, 0); - } -#else /* !IPFIREWALL */ - if ((sw_lro) && (ip->ip_p == IPPROTO_TCP)) { - m = tcp_lro(m, hlen); - if (m == NULL) { - return; - } - } ip_proto_dispatch_in(m, hlen, ip->ip_p, 0); -#endif /* !IPFIREWALL */ return; bad: @@ -2672,23 +2184,10 @@ done: * whole datagram. If a chain for reassembly of this datagram already * exists, then it is given as fp; otherwise have to make a chain. * - * When IPDIVERT enabled, keep additional state with each packet that - * tells us if we need to divert or tee the packet we're building. - * * The IP header is *NOT* adjusted out of iplen (but in host byte order). */ static struct mbuf * -#if IPDIVERT -ip_reass(struct mbuf *m, -#ifdef IPDIVERT_44 - u_int32_t *divinfo, -#else /* IPDIVERT_44 */ - u_int16_t *divinfo, -#endif /* IPDIVERT_44 */ - u_int16_t *divcookie) -#else /* IPDIVERT */ ip_reass(struct mbuf *m) -#endif /* IPDIVERT */ { struct ip *ip; struct mbuf *p, *q, *nq, *t; @@ -2731,9 +2230,6 @@ ip_reass(struct mbuf *m) if (ip->ip_id == fp->ipq_id && ip->ip_src.s_addr == fp->ipq_src.s_addr && ip->ip_dst.s_addr == fp->ipq_dst.s_addr && -#if CONFIG_MACF_NET - mac_ipq_label_compare(m, fp) && -#endif ip->ip_p == fp->ipq_p) { goto found; } @@ -2878,14 +2374,6 @@ found: if (fp == NULL) { goto dropfrag; } -#if CONFIG_MACF_NET - if (mac_ipq_label_init(fp, M_NOWAIT) != 0) { - ipq_free(fp); - fp = NULL; - goto dropfrag; - } - mac_ipq_label_associate(m, fp); -#endif TAILQ_INSERT_HEAD(head, fp, ipq_list); nipq++; fp->ipq_nfrags = 1; @@ -2904,29 +2392,10 @@ found: fp->ipq_csum = csum; fp->ipq_csum_flags = csum_flags; } -#if IPDIVERT - /* - * Transfer firewall instructions to the fragment structure. - * Only trust info in the fragment at offset 0. - */ - if (ip->ip_off == 0) { -#ifdef IPDIVERT_44 - fp->ipq_div_info = *divinfo; -#else - fp->ipq_divert = *divinfo; -#endif - fp->ipq_div_cookie = *divcookie; - } - *divinfo = 0; - *divcookie = 0; -#endif /* IPDIVERT */ m = NULL; /* nothing to return */ goto done; } else { fp->ipq_nfrags++; -#if CONFIG_MACF_NET - mac_ipq_label_update(m, fp); -#endif } #define GETIP(m) ((struct ip *)((m)->m_pkthdr.pkt_hdr)) @@ -3019,22 +2488,6 @@ found: fp->ipq_csum_flags = 0; } -#if IPDIVERT - /* - * Transfer firewall instructions to the fragment structure. - * Only trust info in the fragment at offset 0. - */ - if (ip->ip_off == 0) { -#ifdef IPDIVERT_44 - fp->ipq_div_info = *divinfo; -#else - fp->ipq_divert = *divinfo; -#endif - fp->ipq_div_cookie = *divcookie; - } - *divinfo = 0; - *divcookie = 0; -#endif /* IPDIVERT */ /* * Check for complete reassembly and perform frag per packet @@ -3118,22 +2571,6 @@ found: CSUM_IP_CHECKED | CSUM_IP_VALID; } -#if IPDIVERT - /* - * Extract firewall instructions from the fragment structure. - */ -#ifdef IPDIVERT_44 - *divinfo = fp->ipq_div_info; -#else - *divinfo = fp->ipq_divert; -#endif - *divcookie = fp->ipq_div_cookie; -#endif /* IPDIVERT */ - -#if CONFIG_MACF_NET - mac_mbuf_label_associate_ipq(fp, m); - mac_ipq_label_destroy(fp); -#endif /* * Create header for new ip packet by modifying header of first * packet; dequeue and discard fragment reassembly header. @@ -3178,10 +2615,6 @@ done: return NULL; dropfrag: -#if IPDIVERT - *divinfo = 0; - *divcookie = 0; -#endif /* IPDIVERT */ ipstat.ips_fragdropped++; if (fp != NULL) { fp->ipq_nfrags--; @@ -4004,9 +3437,7 @@ ip_fwd_route_copyin(struct ifnet *ifp, struct route *src) static void ip_forward(struct mbuf *m, int srcrt, struct sockaddr_in *next_hop) { -#if !IPFIREWALL #pragma unused(next_hop) -#endif struct ip *ip = mtod(m, struct ip *); struct sockaddr_in *sin; struct rtentry *rt; @@ -4033,15 +3464,7 @@ ip_forward(struct mbuf *m, int srcrt, struct sockaddr_in *next_hop) #endif /* PF */ dest = 0; -#if IPFIREWALL - /* - * Cache the destination address of the packet; this may be - * changed by use of 'ipfw fwd'. - */ - pkt_dst = ((next_hop != NULL) ? next_hop->sin_addr : ip->ip_dst); -#else /* !IPFIREWALL */ pkt_dst = ip->ip_dst; -#endif /* !IPFIREWALL */ #if DIAGNOSTIC if (ipprintfs) { @@ -4161,27 +3584,6 @@ ip_forward(struct mbuf *m, int srcrt, struct sockaddr_in *next_hop) } RT_UNLOCK(rt); -#if IPFIREWALL - if (next_hop != NULL) { - /* Pass IPFORWARD info if available */ - struct m_tag *tag; - struct ip_fwd_tag *ipfwd_tag; - - tag = m_tag_create(KERNEL_MODULE_TAG_ID, - KERNEL_TAG_TYPE_IPFORWARD, - sizeof(*ipfwd_tag), M_NOWAIT, m); - if (tag == NULL) { - error = ENOBUFS; - m_freem(m); - goto done; - } - - ipfwd_tag = (struct ip_fwd_tag *)(tag + 1); - ipfwd_tag->next_hop = next_hop; - - m_tag_prepend(m, tag); - } -#endif /* IPFIREWALL */ /* Mark this packet as being forwarded from another interface */ m->m_pkthdr.pkt_flags |= PKTF_FORWARDED; @@ -4347,7 +3749,7 @@ ip_forward(struct mbuf *m, int srcrt, struct sockaddr_in *next_hop) } break; - case EACCES: /* ipfw denied packet */ + case EACCES: m_freem(mcopy); goto done; } @@ -4396,7 +3798,12 @@ ip_savecontrol(struct inpcb *inp, struct mbuf **mp, struct ip *ip, goto no_mbufs; } } - if (inp->inp_flags & INP_RECVDSTADDR) { + if (inp->inp_flags & INP_RECVDSTADDR +#if CONTENT_FILTER + /* Content Filter needs to see local address */ + || (inp->inp_socket->so_cfil_db != NULL) +#endif + ) { mp = sbcreatecontrol_mbuf((caddr_t)&ip->ip_dst, sizeof(struct in_addr), IP_RECVDSTADDR, IPPROTO_IP, mp); if (*mp == NULL) {