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 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" |
45#include "opt_ipsec.h" |
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 |
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 |
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 |
131#ifdef DIAGNOSTIC 132static int ipprintfs = 0; 133#endif 134 135extern struct domain inetdomain; |
136extern struct ipprotosw inetsw[]; |
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 |
208static struct mbuf *ip_reass __P((struct mbuf *, |
209 struct ipq *, struct ipq *, u_int32_t *, u_int16_t *)); 210#else |
211static struct mbuf *ip_reass __P((struct mbuf *, struct ipq *, struct ipq *)); |
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{ |
223 register struct ipprotosw *pr; |
224 register int i; 225 226 TAILQ_INIT(&in_ifaddrhead); |
227 pr = (struct ipprotosw *)pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW); |
228 if (pr == 0) 229 panic("ip_init"); 230 for (i = 0; i < IPPROTO_MAX; i++) 231 ip_protox[i] = pr - inetsw; |
232 for (pr = (struct ipprotosw *)inetdomain.dom_protosw; 233 pr < (struct ipprotosw *)inetdomain.dom_protoswNPROTOSW; pr++) |
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 */ |
414 dummynet_io(i&0xffff,DN_TO_IP_IN,m,NULL,NULL,0, rule, 415 0); |
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 |
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 /* |
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 */ |
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 |
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 |
663 m = ip_reass(m, |
664 fp, &ipq[sum], &divert_info, &divert_cookie); 665#else |
666 m = ip_reass(m, fp, &ipq[sum]); |
667#endif |
668 if (m == 0) { |
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++; |
677 ip = mtod(m, struct ip *); |
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++; |
736 { 737 int off = hlen, nh = ip->ip_p; 738 739 (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, off, nh); |
740#ifdef IPFIREWALL_FORWARD 741 ip_fw_fwd_addr = NULL; /* tcp needed it */ 742#endif 743 return; |
744 } |
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 |
782static struct mbuf * |
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; |
852 m_adj(m, i); |
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; |
959 for (t = m; t; t = t->m_next) 960 plen += t->m_len; 961 m->m_pkthdr.len = plen; |
962 } |
963 return (m); |
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 |
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 |
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*/ |
1632 ipstat.ips_cantfrag++; 1633 break; 1634 1635 case ENOBUFS: 1636 type = ICMP_SOURCEQUENCH; 1637 code = 0; 1638 break; 1639 } --- 118 unchanged lines hidden --- |