diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-03-03 05:25:00 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-03-03 05:25:00 +0100 |
commit | 5b972a9aea9383fbb66142a6a9958e01f7028a89 (patch) | |
tree | e66a1ec299f3ed8a9dc7f0b39a9dea29e4cfbcde /sys/src/9/ip/ipaux.c | |
parent | 0aac600fb3b659b5b9a2a8aaefb821774cf38bd2 (diff) |
devip: fix ip fragmentation handling issues with header options
some protocols assume that Ip4hdr.length[] and Ip6hdr.ploadlen[]
are valid and not out of range within the block but this has
not been verified. also, the ipv4 and ipv6 headers can have variable
length options, which was not considered in the fragmentation and
reassembly code.
to make this sane, ipiput4() and ipiput6() now verify that everything
is in range and trims to block to the expected size before it does
any further processing. now blocklen() and Ip4hdr.length[] are conistent.
ipoput4() and ipoput6() are simpler now, as they can rely on
blocklen() only, not having a special routing case.
ip fragmentation reassembly has to consider that fragments could
arrive with different ip header options, so we store the header+option
size in new Ipfrag.hlen field.
unfraglen() has to make sure not to run past the buffer, and hadle
the case when it encounters multiple fragment headers.
Diffstat (limited to 'sys/src/9/ip/ipaux.c')
-rw-r--r-- | sys/src/9/ip/ipaux.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/sys/src/9/ip/ipaux.c b/sys/src/9/ip/ipaux.c index e16249546..549df1f6e 100644 --- a/sys/src/9/ip/ipaux.c +++ b/sys/src/9/ip/ipaux.c @@ -151,7 +151,7 @@ ptclcsum(Block *bp, int offset, int len) if(bp->next == nil) { if(blocklen < len) len = blocklen; - return ~ptclbsum(addr, len) & 0xffff; + return ptclbsum(addr, len) ^ 0xffff; } losum = 0; @@ -183,7 +183,7 @@ ptclcsum(Block *bp, int offset, int len) while((csum = losum>>16) != 0) losum = csum + (losum & 0xffff); - return ~losum & 0xffff; + return losum ^ 0xffff; } enum |