summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2003-07-09 22:03:17 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2003-07-09 22:03:17 +0000
commit2283674da28e5dafc9ce3467ef20c59a96b9e900 (patch)
treeebb49711fe1edf0247e2acb7b65e705fd4a922b9 /sys/net
parente4575c1ca699d4eba1c2ebb28715c779ef686446 (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.c5
-rw-r--r--sys/net/pf.c30
-rw-r--r--sys/net/pf_norm.c81
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)