summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ppp/slcompress.c
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>1999-10-13 07:49:13 +0000
committerbrian <brian@FreeBSD.org>1999-10-13 07:49:13 +0000
commitc1de2e69b94f0d98027eb56f83408c57ad570eb2 (patch)
tree8b3e7735282a5f1e7b18e950675101902537d815 /usr.sbin/ppp/slcompress.c
parent1e09a99ada53a192649596eefdff0d435852ea59 (diff)
downloadFreeBSD-src-c1de2e69b94f0d98027eb56f83408c57ad570eb2.zip
FreeBSD-src-c1de2e69b94f0d98027eb56f83408c57ad570eb2.tar.gz
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/slcompress.c')
-rw-r--r--usr.sbin/ppp/slcompress.c30
1 files changed, 13 insertions, 17 deletions
diff --git a/usr.sbin/ppp/slcompress.c b/usr.sbin/ppp/slcompress.c
index 16912a6..19bbb4a 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;
-
- 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;
OpenPOWER on IntegriCloud