diff options
author | brian <brian@cvs.openbsd.org> | 1999-10-13 07:51:39 +0000 |
---|---|---|
committer | brian <brian@cvs.openbsd.org> | 1999-10-13 07:51:39 +0000 |
commit | 8cbbc77e7ed027c96d21d88e8bd7ede2ccbaa994 (patch) | |
tree | e05cffde1d680f1bd4ee891a1bf568c160051900 /usr.sbin/ppp | |
parent | f2c401a018dc1be92db92d48eaaf5db74316ec00 (diff) |
When uncompressing VJ-compressed frames, fix the ip_sum directly
in struct cstate rather than copying the stored header slot into a
potentially mis-aligned buffer then trying to update the ip_sum
without causing an exception on non-i386 hardware.
I've never been able to reproduce this problem, but it has been
reported by many people... besides, the code is now a bit cleaner.
Testing & patience by: Anthony Solovjoff <asolovjoff@hotmail.com>
Diffstat (limited to 'usr.sbin/ppp')
-rw-r--r-- | usr.sbin/ppp/ppp/slcompress.c | 32 |
1 files changed, 14 insertions, 18 deletions
diff --git a/usr.sbin/ppp/ppp/slcompress.c b/usr.sbin/ppp/ppp/slcompress.c index d000f2e1595..01ab030fb97 100644 --- a/usr.sbin/ppp/ppp/slcompress.c +++ b/usr.sbin/ppp/ppp/slcompress.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: slcompress.c,v 1.8 1999/07/10 00:08:52 brian Exp $ + * $Id: slcompress.c,v 1.9 1999/10/13 07:51:38 brian Exp $ * * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: * - Initial distribution. @@ -414,6 +414,7 @@ sl_uncompress_tcp(u_char ** bufp, int len, u_int type, struct slcompress *comp, register struct tcphdr *th; register struct cstate *cs; register struct ip *ip; + u_short *bp; switch (type) { @@ -437,7 +438,6 @@ sl_uncompress_tcp(u_char ** bufp, int len, u_int type, struct slcompress *comp, if (hlen > MAX_HDR) goto bad; memcpy(&cs->cs_ip, ip, hlen); - cs->cs_ip.ip_sum = 0; cs->cs_hlen = hlen; slstat->sls_uncompressedin++; return (len); @@ -541,26 +541,22 @@ sl_uncompress_tcp(u_char ** bufp, int len, u_int type, struct slcompress *comp, */ goto bad; - cp -= cs->cs_hlen; + *bufp = cp - cs->cs_hlen; len += cs->cs_hlen; cs->cs_ip.ip_len = htons(len); - memcpy(cp, &cs->cs_ip, cs->cs_hlen); - *bufp = cp; /* recompute the ip header checksum */ - { - u_short sum, *bp = (u_short *)&cs->cs_ip; - - for (changes = 0; hlen > 0; hlen -= 2) - changes += *bp++; - changes = (changes & 0xffff) + (changes >> 16); - changes = (changes & 0xffff) + (changes >> 16); - - /* Watch out for alighment problems.... */ - sum = ~changes; - bp = (u_short *)(cp + (int)&((struct ip *)0)->ip_sum); - memcpy(bp, &sum, sizeof *bp); - } + cs->cs_ip.ip_sum = 0; + bp = (u_short *)&cs->cs_ip; + for (changes = 0; hlen > 0; hlen -= 2) + changes += *bp++; + changes = (changes & 0xffff) + (changes >> 16); + changes = (changes & 0xffff) + (changes >> 16); + cs->cs_ip.ip_sum = ~changes; + + /* And copy the result into our buffer */ + memcpy(*bufp, &cs->cs_ip, cs->cs_hlen); + return (len); bad: comp->flags |= SLF_TOSS; |