diff options
author | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2003-07-09 22:03:17 +0000 |
---|---|---|
committer | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2003-07-09 22:03:17 +0000 |
commit | 2283674da28e5dafc9ce3467ef20c59a96b9e900 (patch) | |
tree | ebb49711fe1edf0247e2acb7b65e705fd4a922b9 /sys/netinet/ip_input.c | |
parent | e4575c1ca699d4eba1c2ebb28715c779ef686446 (diff) |
do not flip ip_len/ip_off in netinet stack. deraadt ok.
(please test, especially PF portion)
Diffstat (limited to 'sys/netinet/ip_input.c')
-rw-r--r-- | sys/netinet/ip_input.c | 75 |
1 files changed, 40 insertions, 35 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index c89ea26b1de..804fa3204f3 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_input.c,v 1.112 2003/06/02 23:28:14 millert Exp $ */ +/* $OpenBSD: ip_input.c,v 1.113 2003/07/09 22:03:16 itojun Exp $ */ /* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */ /* @@ -296,7 +296,7 @@ ipv4_input(m) register struct ipq *fp; struct in_ifaddr *ia; struct ipqent *ipqe; - int hlen, mff; + int hlen, mff, len; in_addr_t pfrdr = 0; #ifdef IPSEC int error, s; @@ -360,15 +360,16 @@ ipv4_input(m) ipstat.ips_inhwcsum++; } + /* Retrieve the packet lenght. */ + len = ntohs(ip->ip_len); + /* * Convert fields to host representation. */ - NTOHS(ip->ip_len); - if (ip->ip_len < hlen) { + if (len < hlen) { ipstat.ips_badlen++; goto bad; } - NTOHS(ip->ip_off); /* * Check that the amount of data in the buffers @@ -376,16 +377,16 @@ ipv4_input(m) * Trim mbufs if longer than we expect. * Drop packet if shorter than we expect. */ - if (m->m_pkthdr.len < ip->ip_len) { + if (m->m_pkthdr.len < len) { ipstat.ips_tooshort++; goto bad; } - if (m->m_pkthdr.len > ip->ip_len) { + if (m->m_pkthdr.len > len) { if (m->m_len == m->m_pkthdr.len) { - m->m_len = ip->ip_len; - m->m_pkthdr.len = ip->ip_len; + m->m_len = len; + m->m_pkthdr.len = len; } else - m_adj(m, ip->ip_len - m->m_pkthdr.len); + m_adj(m, len - m->m_pkthdr.len); } #if NPF > 0 @@ -527,7 +528,7 @@ ours: * if the packet was previously fragmented, * but it's not worth the time; just let them time out.) */ - if (ip->ip_off &~ (IP_DF | IP_RF)) { + if (ip->ip_off &~ htons(IP_DF | IP_RF)) { if (m->m_flags & M_EXT) { /* XXX */ if ((m = m_pullup(m, hlen)) == NULL) { ipstat.ips_toosmall++; @@ -555,20 +556,21 @@ found: * set ipqe_mff if more fragments are expected, * convert offset of this to bytes. */ - ip->ip_len -= hlen; - mff = (ip->ip_off & IP_MF) != 0; + ip->ip_len = htons(ntohs(ip->ip_len) - hlen); + mff = (ip->ip_off & htons(IP_MF)) != 0; if (mff) { /* * Make sure that fragments have a data length * that's a non-zero multiple of 8 bytes. */ - if (ip->ip_len == 0 || (ip->ip_len & 0x7) != 0) { + if (ntohs(ip->ip_len) == 0 || + (ntohs(ip->ip_len) & 0x7) != 0) { ipstat.ips_badfrags++; ipq_unlock(); goto bad; } } - ip->ip_off <<= 3; + ip->ip_off = htons(ntohs(ip->ip_off) << 3); /* * If datagram marked as having more fragments @@ -606,8 +608,7 @@ found: if (fp) ip_freef(fp); ipq_unlock(); - } else - ip->ip_len -= hlen; + } #ifdef IPSEC /* @@ -785,7 +786,7 @@ ip_reass(ipqe, fp) */ for (p = NULL, q = fp->ipq_fragq.lh_first; q != NULL; p = q, q = q->ipqe_q.le_next) - if (q->ipqe_ip->ip_off > ipqe->ipqe_ip->ip_off) + if (ntohs(q->ipqe_ip->ip_off) > ntohs(ipqe->ipqe_ip->ip_off)) break; /* @@ -794,14 +795,16 @@ ip_reass(ipqe, fp) * segment. If it provides all of our data, drop us. */ if (p != NULL) { - i = p->ipqe_ip->ip_off + p->ipqe_ip->ip_len - - ipqe->ipqe_ip->ip_off; + i = ntohs(p->ipqe_ip->ip_off) + ntohs(p->ipqe_ip->ip_len) - + ntohs(ipqe->ipqe_ip->ip_off); if (i > 0) { - if (i >= ipqe->ipqe_ip->ip_len) + if (i >= ntohs(ipqe->ipqe_ip->ip_len)) goto dropfrag; m_adj(ipqe->ipqe_m, i); - ipqe->ipqe_ip->ip_off += i; - ipqe->ipqe_ip->ip_len -= 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); } } @@ -809,13 +812,16 @@ ip_reass(ipqe, fp) * While we overlap succeeding segments trim them or, * if they are completely covered, dequeue them. */ - 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; + 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); m_adj(q->ipqe_m, i); break; } @@ -839,9 +845,9 @@ insert: next = 0; for (p = NULL, q = fp->ipq_fragq.lh_first; q != NULL; p = q, q = q->ipqe_q.le_next) { - if (q->ipqe_ip->ip_off != next) + if (ntohs(q->ipqe_ip->ip_off) != next) return (0); - next += q->ipqe_ip->ip_len; + next += ntohs(q->ipqe_ip->ip_len); } if (p->ipqe_mff) return (0); @@ -878,7 +884,7 @@ insert: * dequeue and discard fragment reassembly header. * Make header visible. */ - ip->ip_len = next; + ip->ip_len = htons(next); ip->ip_src = fp->ipq_src; ip->ip_dst = fp->ipq_dst; LIST_REMOVE(fp, ipq_q); @@ -1192,7 +1198,6 @@ ip_dooptions(m) } return (0); bad: - ip->ip_len -= ip->ip_hl << 2; /* XXX icmp_error adds in hdr length */ icmp_error(m, type, code, 0, 0); ipstat.ips_badoptions++; return (1); @@ -1470,7 +1475,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((int)ip->ip_len, 68), M_DONTWAIT); + mcopy = m_copym(m, 0, imin(ntohs(ip->ip_len), 68), M_DONTWAIT); if (mcopy) mcopy = m_pullup(mcopy, ip->ip_hl << 2); |