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/net | |
parent | e4575c1ca699d4eba1c2ebb28715c779ef686446 (diff) |
do not flip ip_len/ip_off in netinet stack. deraadt ok.
(please test, especially PF portion)
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if_gre.c | 5 | ||||
-rw-r--r-- | sys/net/pf.c | 30 | ||||
-rw-r--r-- | sys/net/pf_norm.c | 81 |
3 files changed, 61 insertions, 55 deletions
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c index b291dfbe948..9e76a114461 100644 --- a/sys/net/if_gre.c +++ b/sys/net/if_gre.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_gre.c,v 1.26 2003/03/25 18:10:06 millert Exp $ */ +/* $OpenBSD: if_gre.c,v 1.27 2003/07/09 22:03:15 itojun Exp $ */ /* $NetBSD: if_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */ /* @@ -302,8 +302,7 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, /* Copy Mobility header */ inp = mtod(m, struct ip *); bcopy(&mob_h, (caddr_t)(inp + 1), (unsigned) msiz); - NTOHS(inp->ip_len); - inp->ip_len += msiz; + inp->ip_len = htons(ntohs(inp->ip_len) + msiz); } else { /* AF_INET */ IF_DROP(&ifp->if_snd); m_freem(m); diff --git a/sys/net/pf.c b/sys/net/pf.c index f925e7d92c6..0d28792927e 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.375 2003/07/04 10:57:27 markus Exp $ */ +/* $OpenBSD: pf.c,v 1.376 2003/07/09 22:03:15 itojun Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -1191,8 +1191,8 @@ pf_send_tcp(const struct pf_rule *r, sa_family_t af, h->ip_v = 4; h->ip_hl = sizeof(*h) >> 2; h->ip_tos = IPTOS_LOWDELAY; - h->ip_len = len; - h->ip_off = ip_mtudisc ? IP_DF : 0; + h->ip_len = htons(len); + h->ip_off = htons(ip_mtudisc ? IP_DF : 0); h->ip_ttl = ttl ? ttl : ip_defttl; h->ip_sum = 0; ip_output(m, (void *)NULL, (void *)NULL, 0, (void *)NULL, @@ -3844,7 +3844,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct ifnet *ifp, * ICMP error messages don't refer to non-first * fragments */ - if (ntohs(h2.ip_off) & IP_OFFMASK) + if (h2.ip_off & htons(IP_OFFMASK)) return (PF_DROP); /* offset of protocol header that follows h2 */ @@ -4327,7 +4327,7 @@ pf_pull_hdr(struct mbuf *m, int off, void *p, int len, #ifdef INET case AF_INET: { struct ip *h = mtod(m, struct ip *); - u_int16_t fragoff = (h->ip_off & IP_OFFMASK) << 3; + u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3; if (fragoff) { if (fragoff >= len) @@ -4338,7 +4338,7 @@ pf_pull_hdr(struct mbuf *m, int off, void *p, int len, } return (NULL); } - if (m->m_pkthdr.len < off + len || h->ip_len < off + len) { + if (m->m_pkthdr.len < off + len || ntohs(h->ip_len) < off + len) { ACTION_SET(actionp, PF_DROP); REASON_SET(reasonp, PFRES_SHORT); return (NULL); @@ -4493,7 +4493,7 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, } /* Copied from ip_output. */ - if (ip->ip_len <= ifp->if_mtu) { + if (ntohs(ip->ip_len) <= ifp->if_mtu) { ip->ip_len = htons((u_int16_t)ip->ip_len); ip->ip_off = htons((u_int16_t)ip->ip_off); if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && @@ -4517,7 +4517,7 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, * Too large for interface; fragment if possible. * Must be able to put at least 8 bytes per fragment. */ - if (ip->ip_off & IP_DF) { + if (ip->ip_off & htons(IP_DF)) { ipstat.ips_cantfrag++; if (r->rt != PF_DUPTO) { icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, @@ -4824,10 +4824,10 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0) pd.proto = h->ip_p; pd.af = AF_INET; pd.tos = h->ip_tos; - pd.tot_len = h->ip_len; + pd.tot_len = ntohs(h->ip_len); /* handle fragments that didn't get reassembled by normalization */ - if (h->ip_off & (IP_MF | IP_OFFMASK)) { + if (h->ip_off & htons(IP_MF | IP_OFFMASK)) { action = pf_test_fragment(&r, dir, ifp, m, h, &pd, &a, &ruleset); goto done; @@ -4845,7 +4845,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0) goto done; } if (dir == PF_IN && pf_check_proto_cksum(m, off, - h->ip_len - off, IPPROTO_TCP, AF_INET)) { + ntohs(h->ip_len) - off, IPPROTO_TCP, AF_INET)) { action = PF_DROP; goto done; } @@ -4876,7 +4876,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0) goto done; } if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m, - off, h->ip_len - off, IPPROTO_UDP, AF_INET)) { + off, ntohs(h->ip_len) - off, IPPROTO_UDP, AF_INET)) { action = PF_DROP; goto done; } @@ -4901,7 +4901,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0) goto done; } if (dir == PF_IN && pf_check_proto_cksum(m, off, - h->ip_len - off, IPPROTO_ICMP, AF_INET)) { + ntohs(h->ip_len) - off, IPPROTO_ICMP, AF_INET)) { action = PF_DROP; goto done; } @@ -4909,11 +4909,11 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0) if (action == PF_PASS) { r = s->rule.ptr; r->packets++; - r->bytes += h->ip_len; + r->bytes += ntohs(h->ip_len); a = s->anchor.ptr; if (a != NULL) { a->packets++; - a->bytes += h->ip_len; + a->bytes += ntohs(h->ip_len); } log = s->log; } else if (s == NULL) diff --git a/sys/net/pf_norm.c b/sys/net/pf_norm.c index d855df991b5..1ea0b5619db 100644 --- a/sys/net/pf_norm.c +++ b/sys/net/pf_norm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_norm.c,v 1.63 2003/07/09 07:18:50 dhartmei Exp $ */ +/* $OpenBSD: pf_norm.c,v 1.64 2003/07/09 22:03:16 itojun Exp $ */ /* * Copyright 2001 Niels Provos <provos@citi.umich.edu> @@ -322,8 +322,8 @@ pf_reassemble(struct mbuf **m0, struct pf_fragment *frag, struct pf_frent *frep = NULL; struct ip *ip = frent->fr_ip; int hlen = ip->ip_hl << 2; - u_int16_t off = ip->ip_off; - u_int16_t max = ip->ip_len + off; + u_int16_t off = ntohs(ip->ip_off); + u_int16_t max = ntohs(ip->ip_len) + off; KASSERT(frag == NULL || BUFFER_FRAGMENTS(frag)); @@ -363,35 +363,43 @@ pf_reassemble(struct mbuf **m0, struct pf_fragment *frag, * - off contains the real shifted offset. */ LIST_FOREACH(frea, &frag->fr_queue, fr_next) { - if (frea->fr_ip->ip_off > off) + if (ntohs(frea->fr_ip->ip_off) > off) break; frep = frea; } KASSERT(frep != NULL || frea != NULL); - if (frep != NULL && frep->fr_ip->ip_off + frep->fr_ip->ip_len > off) { + if (frep != NULL && + ntohs(frep->fr_ip->ip_off) + ntohs(frep->fr_ip->ip_len) > off) + { u_int16_t precut; - precut = frep->fr_ip->ip_off + frep->fr_ip->ip_len - off; - if (precut >= ip->ip_len) + precut = ntohs(frep->fr_ip->ip_off) + + ntohs(frep->fr_ip->ip_len) - off; + if (precut >= ntohs(ip->ip_len)) goto drop_fragment; m_adj(frent->fr_m, precut); DPFPRINTF(("overlap -%d\n", precut)); /* Enforce 8 byte boundaries */ - off = ip->ip_off += precut; - ip->ip_len -= precut; + ip->ip_off = htons(ntohs(ip->ip_off) + precut); + off = ntohs(ip->ip_off); + ip->ip_len = htons(ntohs(ip->ip_len) - precut); } - for (; frea != NULL && ip->ip_len + off > frea->fr_ip->ip_off; - frea = next) { + for (; frea != NULL && ntohs(ip->ip_len) + off > ntohs(frea->fr_ip->ip_off); + frea = next) + { u_int16_t aftercut; - aftercut = (ip->ip_len + off) - frea->fr_ip->ip_off; + aftercut = (ntohs(ip->ip_len) + off) - ntohs(frea->fr_ip->ip_off); DPFPRINTF(("adjust overlap %d\n", aftercut)); - if (aftercut < frea->fr_ip->ip_len) { - frea->fr_ip->ip_len -= aftercut; - frea->fr_ip->ip_off += aftercut; + if (aftercut < ntohs(frea->fr_ip->ip_len)) + { + frea->fr_ip->ip_len = + htons(ntohs(frea->fr_ip->ip_len) - aftercut); + frea->fr_ip->ip_off = + htons(ntohs(frea->fr_ip->ip_off) + aftercut); m_adj(frea->fr_m, aftercut); break; } @@ -426,11 +434,12 @@ pf_reassemble(struct mbuf **m0, struct pf_fragment *frag, for (frep = LIST_FIRST(&frag->fr_queue); frep; frep = next) { next = LIST_NEXT(frep, fr_next); - off += frep->fr_ip->ip_len; + off += ntohs(frep->fr_ip->ip_len); if (off < frag->fr_max && - (next == NULL || next->fr_ip->ip_off != off)) { + (next == NULL || ntohs(next->fr_ip->ip_off) != off)) + { DPFPRINTF(("missing fragment at %d, next %d, max %d\n", - off, next == NULL ? -1 : next->fr_ip->ip_off, + off, next == NULL ? -1 : ntohs(next->fr_ip->ip_off), frag->fr_max)); return (NULL); } @@ -473,7 +482,7 @@ pf_reassemble(struct mbuf **m0, struct pf_fragment *frag, pf_remove_fragment(frag); hlen = ip->ip_hl << 2; - ip->ip_len = off + hlen; + ip->ip_len = htons(off + hlen); m->m_len += hlen; m->m_data -= hlen; @@ -486,7 +495,7 @@ pf_reassemble(struct mbuf **m0, struct pf_fragment *frag, m->m_pkthdr.len = plen; } - DPFPRINTF(("complete: %p(%d)\n", m, ip->ip_len)); + DPFPRINTF(("complete: %p(%d)\n", m, ntohs(ip->ip_len))); return (m); drop_fragment: @@ -503,8 +512,8 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment *frag, int mff, { struct mbuf *m = *m0; struct pf_frcache *frp, *fra, *cur = NULL; - int ip_len = h->ip_len - (h->ip_hl << 2); - u_int16_t off = h->ip_off << 3; + int ip_len = ntohs(h->ip_len) - (h->ip_hl << 2); + u_int16_t off = ntohs(h->ip_off) << 3; u_int16_t max = ip_len + off; int hosed = 0; @@ -620,10 +629,10 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment *frag, int mff, h = mtod(m, struct ip *); - KASSERT((int)m->m_len == h->ip_len - precut); - h->ip_off += precut >> 3; - h->ip_len -= precut; + KASSERT((int)m->m_len == ntohs(h->ip_len) - precut); + h->ip_off = htons(ntohs(h->ip_off) + (precut >> 3)); + h->ip_len = htons(ntohs(h->ip_len) - precut); } else { hosed++; } @@ -676,8 +685,8 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment *frag, int mff, m->m_pkthdr.len = plen; } h = mtod(m, struct ip *); - KASSERT((int)m->m_len == h->ip_len - aftercut); - h->ip_len -= aftercut; + KASSERT((int)m->m_len == ntohs(h->ip_len) - aftercut); + h->ip_len = htons(ntohs(h->ip_len) - aftercut); } else { hosed++; } @@ -796,9 +805,9 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason) struct pf_frent *frent; struct pf_fragment *frag = NULL; struct ip *h = mtod(m, struct ip *); - int mff = (h->ip_off & IP_MF); + int mff = (ntohs(h->ip_off) & IP_MF); int hlen = h->ip_hl << 2; - u_int16_t fragoff = (h->ip_off & IP_OFFMASK) << 3; + u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3; u_int16_t max; int ip_len; int ip_off; @@ -833,12 +842,12 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason) if (hlen < (int)sizeof(struct ip)) goto drop; - if (hlen > h->ip_len) + if (hlen > ntohs(h->ip_len)) goto drop; /* Clear IP_DF if the rule uses the no-df option */ if (r->rule_flag & PFRULE_NODF) - h->ip_off &= ~IP_DF; + h->ip_off &= htons(~IP_DF); /* We will need other tests here */ if (!fragoff && !mff) @@ -848,13 +857,13 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason) * with IP_DF to enter the cache. If the flag was cleared by * no-df above, fine. Otherwise drop it. */ - if (h->ip_off & IP_DF) { + if (h->ip_off & htons(IP_DF)) { DPFPRINTF(("IP_DF\n")); goto bad; } - ip_len = h->ip_len - hlen; - ip_off = h->ip_off << 3; + ip_len = ntohs(h->ip_len) - hlen; + ip_off = ntohs(h->ip_off) << 3; /* All fragments are 8 byte aligned */ if (mff && (ip_len & 0x7)) { @@ -872,8 +881,6 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason) if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0) { /* Fully buffer all of the fragments */ - h->ip_len = ip_len; /* logic need muddled off/len */ - h->ip_off = ip_off; frag = pf_find_fragment(h, &pf_frag_tree); /* Check if we saw the last fragment already */ @@ -950,7 +957,7 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason) no_fragment: /* At this point, only IP_DF is allowed in ip_off */ - h->ip_off &= IP_DF; + h->ip_off &= htons(IP_DF); /* Enforce a minimum ttl, may cause endless packet loops */ if (r->min_ttl && h->ip_ttl < r->min_ttl) |