From 71981dcfc1b6466cfa57b665299edc160bc51d7f Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Wed, 13 Oct 1999 07:49:13 +0000 Subject: [PATCH] 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 --- usr.sbin/ppp/slcompress.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/usr.sbin/ppp/slcompress.c b/usr.sbin/ppp/slcompress.c index 16912a6d452..19bbb4ac945 100644 --- a/usr.sbin/ppp/slcompress.c +++ b/usr.sbin/ppp/slcompress.c @@ -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; + 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; - for (changes = 0; hlen > 0; hlen -= 2) - changes += *bp++; - changes = (changes & 0xffff) + (changes >> 16); - changes = (changes & 0xffff) + (changes >> 16); + /* And copy the result into our buffer */ + memcpy(*bufp, &cs->cs_ip, cs->cs_hlen); - /* Watch out for alighment problems.... */ - sum = ~changes; - bp = (u_short *)(cp + (int)&((struct ip *)0)->ip_sum); - memcpy(bp, &sum, sizeof *bp); - } return (len); bad: comp->flags |= SLF_TOSS;