Deleted Added
full compact
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 ---