Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/netinet/ip_input.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/netinet/ip_input.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.130.2.14 retrieving revision 1.149 diff -u -p -r1.130.2.14 -r1.149 --- src/sys/netinet/ip_input.c 2002/10/18 02:45:17 1.130.2.14 +++ src/sys/netinet/ip_input.c 2002/05/12 15:48:39 1.149 @@ -1,9 +1,9 @@ -/* $NetBSD: ip_input.c,v 1.130.2.14 2002/10/18 02:45:17 nathanw Exp $ */ +/* $NetBSD: ip_input.c,v 1.149 2002/05/12 15:48:39 wiz Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -15,7 +15,7 @@ * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -102,7 +102,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.130.2.14 2002/10/18 02:45:17 nathanw Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.149 2002/05/12 15:48:39 wiz Exp $"); #include "opt_gateway.h" #include "opt_pfil_hooks.h" @@ -168,7 +168,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip_input.c,v #define IPALLOWSRCRT 1 /* allow source-routed packets */ #endif #ifndef IPMTUDISC -#define IPMTUDISC 1 +#define IPMTUDISC 0 #endif #ifndef IPMTUDISCTIMEOUT #define IPMTUDISCTIMEOUT (10 * 60) /* as per RFC 1191 */ @@ -192,7 +192,7 @@ int ip_forwsrcrt = IPFORWSRCRT; int ip_directedbcast = IPDIRECTEDBCAST; int ip_allowsrcrt = IPALLOWSRCRT; int ip_mtudisc = IPMTUDISC; -int ip_mtudisc_timeout = IPMTUDISCTIMEOUT; +u_int ip_mtudisc_timeout = IPMTUDISCTIMEOUT; #ifdef DIAGNOSTIC int ipprintfs = 0; #endif @@ -201,8 +201,6 @@ struct rttimer_queue *ip_mtudisc_timeout extern struct domain inetdomain; int ipqmaxlen = IFQ_MAXLEN; -u_long in_ifaddrhash; /* size of hash table - 1 */ -int in_ifaddrentries; /* total number of addrs */ struct in_ifaddrhead in_ifaddr; struct in_ifaddrhashhead *in_ifaddrhashtbl; struct ifqueue ipintrq; @@ -339,7 +337,7 @@ ip_init() in_ifaddrhashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, M_IFADDR, M_WAITOK, &in_ifaddrhash); if (ip_mtudisc != 0) - ip_mtudisc_timeout_q = + ip_mtudisc_timeout_q = rt_timer_queue_create(ip_mtudisc_timeout); #ifdef GATEWAY ipflow_init(); @@ -420,24 +418,10 @@ ip_input(struct mbuf *m) if (TAILQ_FIRST(&in_ifaddr) == 0) goto bad; ipstat.ips_total++; - /* - * If the IP header is not aligned, slurp it up into a new - * mbuf with space for link headers, in the event we forward - * it. Otherwise, if it is aligned, make sure the entire - * base IP header is in the first mbuf of the chain. - */ - if (IP_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) { - if ((m = m_copyup(m, sizeof(struct ip), - (max_linkhdr + 3) & ~3)) == NULL) { - /* XXXJRT new stat, please */ - ipstat.ips_toosmall++; - return; - } - } else if (__predict_false(m->m_len < sizeof (struct ip))) { - if ((m = m_pullup(m, sizeof (struct ip))) == NULL) { - ipstat.ips_toosmall++; - return; - } + if (m->m_len < sizeof (struct ip) && + (m = m_pullup(m, sizeof (struct ip))) == 0) { + ipstat.ips_toosmall++; + return; } ip = mtod(m, struct ip *); if (ip->ip_v != IPVERSION) { @@ -572,6 +556,12 @@ ip_input(struct mbuf *m) #endif /* + * Convert fields to host representation. + */ + NTOHS(ip->ip_len); + NTOHS(ip->ip_off); + + /* * Process options and, if not destined for us, * ship it on. ip_dooptions returns 1 when an * error was detected (causing an icmp message @@ -716,15 +706,7 @@ ours: * if the packet was previously fragmented, * but it's not worth the time; just let them time out.) */ - if (ip->ip_off & ~htons(IP_DF|IP_RF)) { - if (M_READONLY(m)) { - if ((m = m_pullup(m, hlen)) == NULL) { - ipstat.ips_toosmall++; - goto bad; - } - ip = mtod(m, struct ip *); - } - + if (ip->ip_off & ~(IP_DF|IP_RF)) { /* * Look for queue of fragments * of this datagram. @@ -744,28 +726,27 @@ found: * set ipqe_mff if more fragments are expected, * convert offset of this to bytes. */ - ip->ip_len = htons(ntohs(ip->ip_len) - hlen); - mff = (ip->ip_off & htons(IP_MF)) != 0; + ip->ip_len -= hlen; + mff = (ip->ip_off & IP_MF) != 0; if (mff) { /* * Make sure that fragments have a data length * that's a non-zero multiple of 8 bytes. */ - if (ntohs(ip->ip_len) == 0 || - (ntohs(ip->ip_len) & 0x7) != 0) { + if (ip->ip_len == 0 || (ip->ip_len & 0x7) != 0) { ipstat.ips_badfrags++; IPQ_UNLOCK(); goto bad; } } - ip->ip_off = htons((ntohs(ip->ip_off) & IP_OFFMASK) << 3); + ip->ip_off <<= 3; /* * If datagram marked as having more fragments * or if this is not the first fragment, * attempt reassembly; if it succeeds, proceed. */ - if (mff || ip->ip_off != htons(0)) { + if (mff || ip->ip_off) { ipstat.ips_fragments++; ipqe = pool_get(&ipqent_pool, PR_NOWAIT); if (ipqe == NULL) { @@ -784,7 +765,7 @@ found: ipstat.ips_reassembled++; ip = mtod(m, struct ip *); hlen = ip->ip_hl << 2; - ip->ip_len = htons(ntohs(ip->ip_len) + hlen); + ip->ip_len += hlen; } else if (fp) ip_freef(fp); @@ -809,7 +790,7 @@ found: */ #if IFA_STATS if (ia && ip) - ia->ia_ifa.ifa_data.ifad_inbytes += ntohs(ip->ip_len); + ia->ia_ifa.ifa_data.ifad_inbytes += ip->ip_len; #endif ipstat.ips_delivered++; { @@ -889,7 +870,7 @@ ip_reass(ipqe, fp) */ for (p = NULL, q = TAILQ_FIRST(&fp->ipq_fragq); q != NULL; p = q, q = TAILQ_NEXT(q, ipqe_q)) - if (ntohs(q->ipqe_ip->ip_off) > ntohs(ipqe->ipqe_ip->ip_off)) + if (q->ipqe_ip->ip_off > ipqe->ipqe_ip->ip_off) break; /* @@ -898,16 +879,14 @@ ip_reass(ipqe, fp) * segment. If it provides all of our data, drop us. */ if (p != NULL) { - i = ntohs(p->ipqe_ip->ip_off) + ntohs(p->ipqe_ip->ip_len) - - ntohs(ipqe->ipqe_ip->ip_off); + i = p->ipqe_ip->ip_off + p->ipqe_ip->ip_len - + ipqe->ipqe_ip->ip_off; if (i > 0) { - if (i >= ntohs(ipqe->ipqe_ip->ip_len)) + if (i >= ipqe->ipqe_ip->ip_len) goto dropfrag; m_adj(ipqe->ipqe_m, i); - ipqe->ipqe_ip->ip_off = - htons(ntohs(ipqe->ipqe_ip->ip_off) + i); - ipqe->ipqe_ip->ip_len = - htons(ntohs(ipqe->ipqe_ip->ip_len) - i); + ipqe->ipqe_ip->ip_off += i; + ipqe->ipqe_ip->ip_len -= i; } } @@ -915,16 +894,13 @@ ip_reass(ipqe, fp) * While we overlap succeeding segments trim them or, * if they are completely covered, dequeue them. */ - for (; q != NULL && - ntohs(ipqe->ipqe_ip->ip_off) + ntohs(ipqe->ipqe_ip->ip_len) > - ntohs(q->ipqe_ip->ip_off); q = nq) { - i = (ntohs(ipqe->ipqe_ip->ip_off) + - ntohs(ipqe->ipqe_ip->ip_len)) - ntohs(q->ipqe_ip->ip_off); - if (i < ntohs(q->ipqe_ip->ip_len)) { - q->ipqe_ip->ip_len = - htons(ntohs(q->ipqe_ip->ip_len) - i); - q->ipqe_ip->ip_off = - htons(ntohs(q->ipqe_ip->ip_off) + i); + for (; q != NULL && ipqe->ipqe_ip->ip_off + ipqe->ipqe_ip->ip_len > + q->ipqe_ip->ip_off; q = nq) { + i = (ipqe->ipqe_ip->ip_off + ipqe->ipqe_ip->ip_len) - + q->ipqe_ip->ip_off; + if (i < q->ipqe_ip->ip_len) { + q->ipqe_ip->ip_len -= i; + q->ipqe_ip->ip_off += i; m_adj(q->ipqe_m, i); break; } @@ -947,9 +923,9 @@ insert: next = 0; for (p = NULL, q = TAILQ_FIRST(&fp->ipq_fragq); q != NULL; p = q, q = TAILQ_NEXT(q, ipqe_q)) { - if (ntohs(q->ipqe_ip->ip_off) != next) + if (q->ipqe_ip->ip_off != next) return (0); - next += ntohs(q->ipqe_ip->ip_len); + next += q->ipqe_ip->ip_len; } if (p->ipqe_mff) return (0); @@ -984,7 +960,7 @@ insert: * dequeue and discard fragment reassembly header. * Make header visible. */ - ip->ip_len = htons(next); + ip->ip_len = next; ip->ip_src = fp->ipq_src; ip->ip_dst = fp->ipq_dst; LIST_REMOVE(fp, ipq_q); @@ -1467,7 +1443,7 @@ ip_stripoptions(m, mopt) m->m_len -= olen; if (m->m_flags & M_PKTHDR) m->m_pkthdr.len -= olen; - ip->ip_len = htons(ntohs(ip->ip_len) - olen); + ip->ip_len -= olen; ip->ip_hl = sizeof (struct ip) >> 2; } @@ -1557,7 +1533,7 @@ ip_forward(m, srcrt) * we need to generate an ICMP message to the src. * Pullup to avoid sharing mbuf cluster between m and mcopy. */ - mcopy = m_copym(m, 0, imin(ntohs(ip->ip_len), 68), M_DONTWAIT); + mcopy = m_copym(m, 0, imin((int)ip->ip_len, 68), M_DONTWAIT); if (mcopy) mcopy = m_pullup(mcopy, ip->ip_hl << 2); @@ -1684,8 +1660,6 @@ ip_forward(m, srcrt) ro = &sp->req->sav->sah->sa_route; if (ro->ro_rt && ro->ro_rt->rt_ifp) { dummyifp.if_mtu = - ro->ro_rt->rt_rmx.rmx_mtu ? - ro->ro_rt->rt_rmx.rmx_mtu : ro->ro_rt->rt_ifp->if_mtu; dummyifp.if_mtu -= ipsechdr; destifp = &dummyifp; @@ -1829,7 +1803,7 @@ ip_sysctl(name, namelen, oldp, oldlenp, error = sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtudisc); if (ip_mtudisc != 0 && ip_mtudisc_timeout_q == NULL) { - ip_mtudisc_timeout_q = + ip_mtudisc_timeout_q = rt_timer_queue_create(ip_mtudisc_timeout); } else if (ip_mtudisc == 0 && ip_mtudisc_timeout_q != NULL) { rt_timer_queue_destroy(ip_mtudisc_timeout_q, TRUE); @@ -1863,15 +1837,10 @@ ip_sysctl(name, namelen, oldp, oldlenp, } return (error); case IPCTL_MTUDISCTIMEOUT: - old = ip_mtudisc_timeout; error = sysctl_int(oldp, oldlenp, newp, newlen, &ip_mtudisc_timeout); - if (ip_mtudisc_timeout < 0) { - ip_mtudisc_timeout = old; - return (EINVAL); - } if (ip_mtudisc_timeout_q != NULL) - rt_timer_queue_change(ip_mtudisc_timeout_q, + rt_timer_queue_change(ip_mtudisc_timeout_q, ip_mtudisc_timeout); return (error); #ifdef GATEWAY @@ -1892,13 +1861,13 @@ ip_sysctl(name, namelen, oldp, oldlenp, &hostzeroisbroadcast)); #if NGIF > 0 case IPCTL_GIF_TTL: - return (sysctl_int(oldp, oldlenp, newp, newlen, + return(sysctl_int(oldp, oldlenp, newp, newlen, &ip_gif_ttl)); #endif #if NGRE > 0 case IPCTL_GRE_TTL: - return (sysctl_int(oldp, oldlenp, newp, newlen, + return(sysctl_int(oldp, oldlenp, newp, newlen, &ip_gre_ttl)); #endif