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>
This commit is contained in:
parent
6ed62da4d9
commit
71981dcfc1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=52197
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user