ip_input.c (54221) | ip_input.c (55009) |
---|---|
1/* 2 * Copyright (c) 1982, 1986, 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)ip_input.c 8.2 (Berkeley) 1/4/94 | 1/* 2 * Copyright (c) 1982, 1986, 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)ip_input.c 8.2 (Berkeley) 1/4/94 |
34 * $FreeBSD: head/sys/netinet/ip_input.c 54221 1999-12-06 20:36:50Z guido $ | 34 * $FreeBSD: head/sys/netinet/ip_input.c 55009 1999-12-22 19:13:38Z shin $ |
35 */ 36 37#define _IP_VHL 38 39#include "opt_bootp.h" 40#include "opt_ipfw.h" 41#include "opt_ipdn.h" 42#include "opt_ipdivert.h" 43#include "opt_ipfilter.h" 44#include "opt_ipstealth.h" | 35 */ 36 37#define _IP_VHL 38 39#include "opt_bootp.h" 40#include "opt_ipfw.h" 41#include "opt_ipdn.h" 42#include "opt_ipdivert.h" 43#include "opt_ipfilter.h" 44#include "opt_ipstealth.h" |
45#include "opt_ipsec.h" |
|
45 46#include <stddef.h> 47 48#include <sys/param.h> 49#include <sys/systm.h> 50#include <sys/mbuf.h> 51#include <sys/malloc.h> 52#include <sys/domain.h> --- 14 unchanged lines hidden (view full) --- 67#include <netinet/in_systm.h> 68#include <netinet/in_var.h> 69#include <netinet/ip.h> 70#include <netinet/in_pcb.h> 71#include <netinet/ip_var.h> 72#include <netinet/ip_icmp.h> 73#include <machine/in_cksum.h> 74 | 46 47#include <stddef.h> 48 49#include <sys/param.h> 50#include <sys/systm.h> 51#include <sys/mbuf.h> 52#include <sys/malloc.h> 53#include <sys/domain.h> --- 14 unchanged lines hidden (view full) --- 68#include <netinet/in_systm.h> 69#include <netinet/in_var.h> 70#include <netinet/ip.h> 71#include <netinet/in_pcb.h> 72#include <netinet/ip_var.h> 73#include <netinet/ip_icmp.h> 74#include <machine/in_cksum.h> 75 |
76#include <netinet/ipprotosw.h> 77 |
|
75#include <sys/socketvar.h> 76 77#include <netinet/ip_fw.h> 78 | 78#include <sys/socketvar.h> 79 80#include <netinet/ip_fw.h> 81 |
82#ifdef IPSEC 83#include <netinet6/ipsec.h> 84#include <netkey/key.h> 85#ifdef IPSEC_DEBUG 86#include <netkey/key_debug.h> 87#else 88#define KEYDEBUG(lev,arg) 89#endif 90#endif 91 92#include "faith.h" 93#if defined(NFAITH) && NFAITH > 0 94#include <net/if_types.h> 95#endif 96 |
|
79#ifdef DUMMYNET 80#include <netinet/ip_dummynet.h> 81#endif 82 83int rsvp_on = 0; 84static int ip_rsvp_on; 85struct socket *ip_rsvpd; 86 --- 12 unchanged lines hidden (view full) --- 99static int ip_dosourceroute = 0; 100SYSCTL_INT(_net_inet_ip, IPCTL_SOURCEROUTE, sourceroute, CTLFLAG_RW, 101 &ip_dosourceroute, 0, "Enable forwarding source routed IP packets"); 102 103static int ip_acceptsourceroute = 0; 104SYSCTL_INT(_net_inet_ip, IPCTL_ACCEPTSOURCEROUTE, accept_sourceroute, 105 CTLFLAG_RW, &ip_acceptsourceroute, 0, 106 "Enable accepting source routed IP packets"); | 97#ifdef DUMMYNET 98#include <netinet/ip_dummynet.h> 99#endif 100 101int rsvp_on = 0; 102static int ip_rsvp_on; 103struct socket *ip_rsvpd; 104 --- 12 unchanged lines hidden (view full) --- 117static int ip_dosourceroute = 0; 118SYSCTL_INT(_net_inet_ip, IPCTL_SOURCEROUTE, sourceroute, CTLFLAG_RW, 119 &ip_dosourceroute, 0, "Enable forwarding source routed IP packets"); 120 121static int ip_acceptsourceroute = 0; 122SYSCTL_INT(_net_inet_ip, IPCTL_ACCEPTSOURCEROUTE, accept_sourceroute, 123 CTLFLAG_RW, &ip_acceptsourceroute, 0, 124 "Enable accepting source routed IP packets"); |
125 126static int ip_keepfaith = 0; 127SYSCTL_INT(_net_inet_ip, IPCTL_KEEPFAITH, keepfaith, CTLFLAG_RW, 128 &ip_keepfaith, 0, 129 "Enable packet capture for FAITH IPv4->IPv6 translater daemon"); 130 |
|
107#ifdef DIAGNOSTIC 108static int ipprintfs = 0; 109#endif 110 111extern struct domain inetdomain; | 131#ifdef DIAGNOSTIC 132static int ipprintfs = 0; 133#endif 134 135extern struct domain inetdomain; |
112extern struct protosw inetsw[]; | 136extern struct ipprotosw inetsw[]; |
113u_char ip_protox[IPPROTO_MAX]; 114static int ipqmaxlen = IFQ_MAXLEN; 115struct in_ifaddrhead in_ifaddrhead; /* first inet address */ 116struct ifqueue ipintrq; 117SYSCTL_INT(_net_inet_ip, IPCTL_INTRQMAXLEN, intr_queue_maxlen, CTLFLAG_RW, 118 &ipintrq.ifq_maxlen, 0, "Maximum size of the IP input queue"); 119SYSCTL_INT(_net_inet_ip, IPCTL_INTRQDROPS, intr_queue_drops, CTLFLAG_RD, 120 &ipintrq.ifq_drops, 0, "Number of packets dropped from the IP input queue"); --- 55 unchanged lines hidden (view full) --- 176 177struct sockaddr_in *ip_fw_fwd_addr; 178 179static void save_rte __P((u_char *, struct in_addr)); 180static int ip_dooptions __P((struct mbuf *)); 181static void ip_forward __P((struct mbuf *, int)); 182static void ip_freef __P((struct ipq *)); 183#ifdef IPDIVERT | 137u_char ip_protox[IPPROTO_MAX]; 138static int ipqmaxlen = IFQ_MAXLEN; 139struct in_ifaddrhead in_ifaddrhead; /* first inet address */ 140struct ifqueue ipintrq; 141SYSCTL_INT(_net_inet_ip, IPCTL_INTRQMAXLEN, intr_queue_maxlen, CTLFLAG_RW, 142 &ipintrq.ifq_maxlen, 0, "Maximum size of the IP input queue"); 143SYSCTL_INT(_net_inet_ip, IPCTL_INTRQDROPS, intr_queue_drops, CTLFLAG_RD, 144 &ipintrq.ifq_drops, 0, "Number of packets dropped from the IP input queue"); --- 55 unchanged lines hidden (view full) --- 200 201struct sockaddr_in *ip_fw_fwd_addr; 202 203static void save_rte __P((u_char *, struct in_addr)); 204static int ip_dooptions __P((struct mbuf *)); 205static void ip_forward __P((struct mbuf *, int)); 206static void ip_freef __P((struct ipq *)); 207#ifdef IPDIVERT |
184static struct ip *ip_reass __P((struct mbuf *, | 208static struct mbuf *ip_reass __P((struct mbuf *, |
185 struct ipq *, struct ipq *, u_int32_t *, u_int16_t *)); 186#else | 209 struct ipq *, struct ipq *, u_int32_t *, u_int16_t *)); 210#else |
187static struct ip *ip_reass __P((struct mbuf *, struct ipq *, struct ipq *)); | 211static struct mbuf *ip_reass __P((struct mbuf *, struct ipq *, struct ipq *)); |
188#endif 189static struct in_ifaddr *ip_rtaddr __P((struct in_addr)); 190static void ipintr __P((void)); 191 192/* 193 * IP initialization: fill in IP protocol switch table. 194 * All protocols not implemented in kernel go to raw IP protocol handler. 195 */ 196void 197ip_init() 198{ | 212#endif 213static struct in_ifaddr *ip_rtaddr __P((struct in_addr)); 214static void ipintr __P((void)); 215 216/* 217 * IP initialization: fill in IP protocol switch table. 218 * All protocols not implemented in kernel go to raw IP protocol handler. 219 */ 220void 221ip_init() 222{ |
199 register struct protosw *pr; | 223 register struct ipprotosw *pr; |
200 register int i; 201 202 TAILQ_INIT(&in_ifaddrhead); | 224 register int i; 225 226 TAILQ_INIT(&in_ifaddrhead); |
203 pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW); | 227 pr = (struct ipprotosw *)pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW); |
204 if (pr == 0) 205 panic("ip_init"); 206 for (i = 0; i < IPPROTO_MAX; i++) 207 ip_protox[i] = pr - inetsw; | 228 if (pr == 0) 229 panic("ip_init"); 230 for (i = 0; i < IPPROTO_MAX; i++) 231 ip_protox[i] = pr - inetsw; |
208 for (pr = inetdomain.dom_protosw; 209 pr < inetdomain.dom_protoswNPROTOSW; pr++) | 232 for (pr = (struct ipprotosw *)inetdomain.dom_protosw; 233 pr < (struct ipprotosw *)inetdomain.dom_protoswNPROTOSW; pr++) |
210 if (pr->pr_domain->dom_family == PF_INET && 211 pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW) 212 ip_protox[pr->pr_protocol] = pr - inetsw; 213 214 for (i = 0; i < IPREASS_NHASH; i++) 215 ipq[i].next = ipq[i].prev = &ipq[i]; 216 217 maxnipq = nmbclusters/4; --- 164 unchanged lines hidden (view full) --- 382 hlen, NULL, &divert_cookie, &m, &rule, &ip_fw_fwd_addr); 383 if (m == NULL) /* Packet discarded by firewall */ 384 return; 385 if (i == 0 && ip_fw_fwd_addr == NULL) /* common case */ 386 goto pass; 387#ifdef DUMMYNET 388 if ((i & IP_FW_PORT_DYNT_FLAG) != 0) { 389 /* Send packet to the appropriate pipe */ | 234 if (pr->pr_domain->dom_family == PF_INET && 235 pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW) 236 ip_protox[pr->pr_protocol] = pr - inetsw; 237 238 for (i = 0; i < IPREASS_NHASH; i++) 239 ipq[i].next = ipq[i].prev = &ipq[i]; 240 241 maxnipq = nmbclusters/4; --- 164 unchanged lines hidden (view full) --- 406 hlen, NULL, &divert_cookie, &m, &rule, &ip_fw_fwd_addr); 407 if (m == NULL) /* Packet discarded by firewall */ 408 return; 409 if (i == 0 && ip_fw_fwd_addr == NULL) /* common case */ 410 goto pass; 411#ifdef DUMMYNET 412 if ((i & IP_FW_PORT_DYNT_FLAG) != 0) { 413 /* Send packet to the appropriate pipe */ |
390 dummynet_io(i&0xffff,DN_TO_IP_IN,m,NULL,NULL,0, rule); | 414 dummynet_io(i&0xffff,DN_TO_IP_IN,m,NULL,NULL,0, rule, 415 0); |
391 return; 392 } 393#endif 394#ifdef IPDIVERT 395 if (i != 0 && (i & IP_FW_PORT_DYNT_FLAG) == 0) { 396 /* Divert or tee packet */ 397 divert_info = i; 398 goto ours; --- 119 unchanged lines hidden (view full) --- 518 } 519 goto ours; 520 } 521 if (ip->ip_dst.s_addr == (u_long)INADDR_BROADCAST) 522 goto ours; 523 if (ip->ip_dst.s_addr == INADDR_ANY) 524 goto ours; 525 | 416 return; 417 } 418#endif 419#ifdef IPDIVERT 420 if (i != 0 && (i & IP_FW_PORT_DYNT_FLAG) == 0) { 421 /* Divert or tee packet */ 422 divert_info = i; 423 goto ours; --- 119 unchanged lines hidden (view full) --- 543 } 544 goto ours; 545 } 546 if (ip->ip_dst.s_addr == (u_long)INADDR_BROADCAST) 547 goto ours; 548 if (ip->ip_dst.s_addr == INADDR_ANY) 549 goto ours; 550 |
551#if defined(NFAITH) && 0 < NFAITH |
|
526 /* | 552 /* |
553 * FAITH(Firewall Aided Internet Translator) 554 */ 555 if (m->m_pkthdr.rcvif && m->m_pkthdr.rcvif->if_type == IFT_FAITH) { 556 if (ip_keepfaith) { 557 if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_ICMP) 558 goto ours; 559 } 560 m_freem(m); 561 return; 562 } 563#endif 564 /* |
|
527 * Not for us; forward if possible and desirable. 528 */ 529 if (ipforwarding == 0) { 530 ipstat.ips_cantforward++; 531 m_freem(m); 532 } else 533 ip_forward(m, 0); 534#ifdef IPFIREWALL_FORWARD --- 6 unchanged lines hidden (view full) --- 541 /* 542 * If offset or IP_MF are set, must reassemble. 543 * Otherwise, nothing need be done. 544 * (We could look in the reassembly queue to see 545 * if the packet was previously fragmented, 546 * but it's not worth the time; just let them time out.) 547 */ 548 if (ip->ip_off & (IP_MF | IP_OFFMASK | IP_RF)) { | 565 * Not for us; forward if possible and desirable. 566 */ 567 if (ipforwarding == 0) { 568 ipstat.ips_cantforward++; 569 m_freem(m); 570 } else 571 ip_forward(m, 0); 572#ifdef IPFIREWALL_FORWARD --- 6 unchanged lines hidden (view full) --- 579 /* 580 * If offset or IP_MF are set, must reassemble. 581 * Otherwise, nothing need be done. 582 * (We could look in the reassembly queue to see 583 * if the packet was previously fragmented, 584 * but it's not worth the time; just let them time out.) 585 */ 586 if (ip->ip_off & (IP_MF | IP_OFFMASK | IP_RF)) { |
587 588#if 0 /* 589 * Reassembly should be able to treat a mbuf cluster, for later 590 * operation of contiguous protocol headers on the cluster. (KAME) 591 */ |
|
549 if (m->m_flags & M_EXT) { /* XXX */ 550 if ((m = m_pullup(m, hlen)) == 0) { 551 ipstat.ips_toosmall++; 552#ifdef IPFIREWALL_FORWARD 553 ip_fw_fwd_addr = NULL; 554#endif 555 return; 556 } 557 ip = mtod(m, struct ip *); 558 } | 592 if (m->m_flags & M_EXT) { /* XXX */ 593 if ((m = m_pullup(m, hlen)) == 0) { 594 ipstat.ips_toosmall++; 595#ifdef IPFIREWALL_FORWARD 596 ip_fw_fwd_addr = NULL; 597#endif 598 return; 599 } 600 ip = mtod(m, struct ip *); 601 } |
602#endif |
|
559 sum = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id); 560 /* 561 * Look for queue of fragments 562 * of this datagram. 563 */ 564 for (fp = ipq[sum].next; fp != &ipq[sum]; fp = fp->next) 565 if (ip->ip_id == fp->ipq_id && 566 ip->ip_src.s_addr == fp->ipq_src.s_addr && --- 44 unchanged lines hidden (view full) --- 611 * If datagram marked as having more fragments 612 * or if this is not the first fragment, 613 * attempt reassembly; if it succeeds, proceed. 614 */ 615 if (mff || ip->ip_off) { 616 ipstat.ips_fragments++; 617 m->m_pkthdr.header = ip; 618#ifdef IPDIVERT | 603 sum = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id); 604 /* 605 * Look for queue of fragments 606 * of this datagram. 607 */ 608 for (fp = ipq[sum].next; fp != &ipq[sum]; fp = fp->next) 609 if (ip->ip_id == fp->ipq_id && 610 ip->ip_src.s_addr == fp->ipq_src.s_addr && --- 44 unchanged lines hidden (view full) --- 655 * If datagram marked as having more fragments 656 * or if this is not the first fragment, 657 * attempt reassembly; if it succeeds, proceed. 658 */ 659 if (mff || ip->ip_off) { 660 ipstat.ips_fragments++; 661 m->m_pkthdr.header = ip; 662#ifdef IPDIVERT |
619 ip = ip_reass(m, | 663 m = ip_reass(m, |
620 fp, &ipq[sum], &divert_info, &divert_cookie); 621#else | 664 fp, &ipq[sum], &divert_info, &divert_cookie); 665#else |
622 ip = ip_reass(m, fp, &ipq[sum]); | 666 m = ip_reass(m, fp, &ipq[sum]); |
623#endif | 667#endif |
624 if (ip == 0) { | 668 if (m == 0) { |
625#ifdef IPFIREWALL_FORWARD 626 ip_fw_fwd_addr = NULL; 627#endif 628 return; 629 } 630 /* Get the length of the reassembled packets header */ 631 hlen = IP_VHL_HL(ip->ip_vhl) << 2; 632 ipstat.ips_reassembled++; | 669#ifdef IPFIREWALL_FORWARD 670 ip_fw_fwd_addr = NULL; 671#endif 672 return; 673 } 674 /* Get the length of the reassembled packets header */ 675 hlen = IP_VHL_HL(ip->ip_vhl) << 2; 676 ipstat.ips_reassembled++; |
633 m = dtom(ip); | 677 ip = mtod(m, struct ip *); |
634#ifdef IPDIVERT 635 /* Restore original checksum before diverting packet */ 636 if (divert_info != 0) { 637 ip->ip_len += hlen; 638 HTONS(ip->ip_len); 639 HTONS(ip->ip_off); 640 HTONS(ip->ip_id); 641 ip->ip_sum = 0; --- 42 unchanged lines hidden (view full) --- 684 ip = mtod(m, struct ip *); 685 } 686#endif 687 688 /* 689 * Switch out to protocol's input routine. 690 */ 691 ipstat.ips_delivered++; | 678#ifdef IPDIVERT 679 /* Restore original checksum before diverting packet */ 680 if (divert_info != 0) { 681 ip->ip_len += hlen; 682 HTONS(ip->ip_len); 683 HTONS(ip->ip_off); 684 HTONS(ip->ip_id); 685 ip->ip_sum = 0; --- 42 unchanged lines hidden (view full) --- 728 ip = mtod(m, struct ip *); 729 } 730#endif 731 732 /* 733 * Switch out to protocol's input routine. 734 */ 735 ipstat.ips_delivered++; |
692 (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen); | 736 { 737 int off = hlen, nh = ip->ip_p; 738 739 (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, off, nh); |
693#ifdef IPFIREWALL_FORWARD 694 ip_fw_fwd_addr = NULL; /* tcp needed it */ 695#endif 696 return; | 740#ifdef IPFIREWALL_FORWARD 741 ip_fw_fwd_addr = NULL; /* tcp needed it */ 742#endif 743 return; |
744 } |
|
697bad: 698#ifdef IPFIREWALL_FORWARD 699 ip_fw_fwd_addr = NULL; 700#endif 701 m_freem(m); 702} 703 704/* --- 21 unchanged lines hidden (view full) --- 726 * Take incoming datagram fragment and try to reassemble it into 727 * whole datagram. If a chain for reassembly of this datagram already 728 * exists, then it is given as fp; otherwise have to make a chain. 729 * 730 * When IPDIVERT enabled, keep additional state with each packet that 731 * tells us if we need to divert or tee the packet we're building. 732 */ 733 | 745bad: 746#ifdef IPFIREWALL_FORWARD 747 ip_fw_fwd_addr = NULL; 748#endif 749 m_freem(m); 750} 751 752/* --- 21 unchanged lines hidden (view full) --- 774 * Take incoming datagram fragment and try to reassemble it into 775 * whole datagram. If a chain for reassembly of this datagram already 776 * exists, then it is given as fp; otherwise have to make a chain. 777 * 778 * When IPDIVERT enabled, keep additional state with each packet that 779 * tells us if we need to divert or tee the packet we're building. 780 */ 781 |
734static struct ip * | 782static struct mbuf * |
735#ifdef IPDIVERT 736ip_reass(m, fp, where, divinfo, divcookie) 737#else 738ip_reass(m, fp, where) 739#endif 740 register struct mbuf *m; 741 register struct ipq *fp; 742 struct ipq *where; --- 53 unchanged lines hidden (view full) --- 796 * segment. If it provides all of our data, drop us, otherwise 797 * stick new segment in the proper place. 798 */ 799 if (p) { 800 i = GETIP(p)->ip_off + GETIP(p)->ip_len - ip->ip_off; 801 if (i > 0) { 802 if (i >= ip->ip_len) 803 goto dropfrag; | 783#ifdef IPDIVERT 784ip_reass(m, fp, where, divinfo, divcookie) 785#else 786ip_reass(m, fp, where) 787#endif 788 register struct mbuf *m; 789 register struct ipq *fp; 790 struct ipq *where; --- 53 unchanged lines hidden (view full) --- 844 * segment. If it provides all of our data, drop us, otherwise 845 * stick new segment in the proper place. 846 */ 847 if (p) { 848 i = GETIP(p)->ip_off + GETIP(p)->ip_len - ip->ip_off; 849 if (i > 0) { 850 if (i >= ip->ip_len) 851 goto dropfrag; |
804 m_adj(dtom(ip), i); | 852 m_adj(m, i); |
805 ip->ip_off += i; 806 ip->ip_len -= i; 807 } 808 m->m_nextpkt = p->m_nextpkt; 809 p->m_nextpkt = m; 810 } else { 811 m->m_nextpkt = fp->ipq_frags; 812 fp->ipq_frags = m; --- 90 unchanged lines hidden (view full) --- 903 remque(fp); 904 nipq--; 905 (void) m_free(dtom(fp)); 906 m->m_len += (IP_VHL_HL(ip->ip_vhl) << 2); 907 m->m_data -= (IP_VHL_HL(ip->ip_vhl) << 2); 908 /* some debugging cruft by sklower, below, will go away soon */ 909 if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */ 910 register int plen = 0; | 853 ip->ip_off += i; 854 ip->ip_len -= i; 855 } 856 m->m_nextpkt = p->m_nextpkt; 857 p->m_nextpkt = m; 858 } else { 859 m->m_nextpkt = fp->ipq_frags; 860 fp->ipq_frags = m; --- 90 unchanged lines hidden (view full) --- 951 remque(fp); 952 nipq--; 953 (void) m_free(dtom(fp)); 954 m->m_len += (IP_VHL_HL(ip->ip_vhl) << 2); 955 m->m_data -= (IP_VHL_HL(ip->ip_vhl) << 2); 956 /* some debugging cruft by sklower, below, will go away soon */ 957 if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */ 958 register int plen = 0; |
911 for (t = m; m; m = m->m_next) 912 plen += m->m_len; 913 t->m_pkthdr.len = plen; | 959 for (t = m; t; t = t->m_next) 960 plen += t->m_len; 961 m->m_pkthdr.len = plen; |
914 } | 962 } |
915 return (ip); | 963 return (m); |
916 917dropfrag: 918#ifdef IPDIVERT 919 *divinfo = 0; 920 *divcookie = 0; 921#endif 922 ipstat.ips_fragdropped++; 923 m_freem(m); --- 470 unchanged lines hidden (view full) --- 1394{ 1395 register struct ip *ip = mtod(m, struct ip *); 1396 register struct sockaddr_in *sin; 1397 register struct rtentry *rt; 1398 int error, type = 0, code = 0; 1399 struct mbuf *mcopy; 1400 n_long dest; 1401 struct ifnet *destifp; | 964 965dropfrag: 966#ifdef IPDIVERT 967 *divinfo = 0; 968 *divcookie = 0; 969#endif 970 ipstat.ips_fragdropped++; 971 m_freem(m); --- 470 unchanged lines hidden (view full) --- 1442{ 1443 register struct ip *ip = mtod(m, struct ip *); 1444 register struct sockaddr_in *sin; 1445 register struct rtentry *rt; 1446 int error, type = 0, code = 0; 1447 struct mbuf *mcopy; 1448 n_long dest; 1449 struct ifnet *destifp; |
1450#ifdef IPSEC 1451 struct ifnet dummyifp; 1452#endif |
|
1402 1403 dest = 0; 1404#ifdef DIAGNOSTIC 1405 if (ipprintfs) 1406 printf("forward: src %lx dst %lx ttl %x\n", 1407 (u_long)ip->ip_src.s_addr, (u_long)ip->ip_dst.s_addr, 1408 ip->ip_ttl); 1409#endif --- 108 unchanged lines hidden (view full) --- 1518 default: 1519 type = ICMP_UNREACH; 1520 code = ICMP_UNREACH_HOST; 1521 break; 1522 1523 case EMSGSIZE: 1524 type = ICMP_UNREACH; 1525 code = ICMP_UNREACH_NEEDFRAG; | 1453 1454 dest = 0; 1455#ifdef DIAGNOSTIC 1456 if (ipprintfs) 1457 printf("forward: src %lx dst %lx ttl %x\n", 1458 (u_long)ip->ip_src.s_addr, (u_long)ip->ip_dst.s_addr, 1459 ip->ip_ttl); 1460#endif --- 108 unchanged lines hidden (view full) --- 1569 default: 1570 type = ICMP_UNREACH; 1571 code = ICMP_UNREACH_HOST; 1572 break; 1573 1574 case EMSGSIZE: 1575 type = ICMP_UNREACH; 1576 code = ICMP_UNREACH_NEEDFRAG; |
1577#ifndef IPSEC |
|
1526 if (ipforward_rt.ro_rt) 1527 destifp = ipforward_rt.ro_rt->rt_ifp; | 1578 if (ipforward_rt.ro_rt) 1579 destifp = ipforward_rt.ro_rt->rt_ifp; |
1580#else 1581 /* 1582 * If the packet is routed over IPsec tunnel, tell the 1583 * originator the tunnel MTU. 1584 * tunnel MTU = if MTU - sizeof(IP) - ESP/AH hdrsiz 1585 * XXX quickhack!!! 1586 */ 1587 if (ipforward_rt.ro_rt) { 1588 struct secpolicy *sp = NULL; 1589 int ipsecerror; 1590 int ipsechdr; 1591 struct route *ro; 1592 1593 sp = ipsec4_getpolicybyaddr(mcopy, 1594 IPSEC_DIR_OUTBOUND, 1595 IP_FORWARDING, 1596 &ipsecerror); 1597 1598 if (sp == NULL) 1599 destifp = ipforward_rt.ro_rt->rt_ifp; 1600 else { 1601 /* count IPsec header size */ 1602 ipsechdr = ipsec4_hdrsiz(mcopy, 1603 IPSEC_DIR_OUTBOUND, 1604 NULL); 1605 1606 /* 1607 * find the correct route for outer IPv4 1608 * header, compute tunnel MTU. 1609 * 1610 * XXX BUG ALERT 1611 * The "dummyifp" code relies upon the fact 1612 * that icmp_error() touches only ifp->if_mtu. 1613 */ 1614 /*XXX*/ 1615 destifp = NULL; 1616 if (sp->req != NULL 1617 && sp->req->sav != NULL 1618 && sp->req->sav->sah != NULL) { 1619 ro = &sp->req->sav->sah->sa_route; 1620 if (ro->ro_rt && ro->ro_rt->rt_ifp) { 1621 dummyifp.if_mtu = 1622 ro->ro_rt->rt_ifp->if_mtu; 1623 dummyifp.if_mtu -= ipsechdr; 1624 destifp = &dummyifp; 1625 } 1626 } 1627 1628 key_freesp(sp); 1629 } 1630 } 1631#endif /*IPSEC*/ |
|
1528 ipstat.ips_cantfrag++; 1529 break; 1530 1531 case ENOBUFS: 1532 type = ICMP_SOURCEQUENCH; 1533 code = 0; 1534 break; 1535 } --- 118 unchanged lines hidden --- | 1632 ipstat.ips_cantfrag++; 1633 break; 1634 1635 case ENOBUFS: 1636 type = ICMP_SOURCEQUENCH; 1637 code = 0; 1638 break; 1639 } --- 118 unchanged lines hidden --- |