diff options
author | Martin Mares <mj@ucw.cz> | 1999-05-10 23:37:39 +0200 |
---|---|---|
committer | Martin Mares <mj@ucw.cz> | 1999-05-10 23:37:39 +0200 |
commit | 1a54d44a23de7b0bf0dfe62dd3d09d8167e5a597 (patch) | |
tree | 1192620688836472b96c2d1a1eecf11c167c2d27 /lib/checksum.c | |
parent | a2697f02ac5109e749bff4d07bee6cedd0ab650b (diff) | |
download | bird-1a54d44a23de7b0bf0dfe62dd3d09d8167e5a597.tar bird-1a54d44a23de7b0bf0dfe62dd3d09d8167e5a597.zip |
Added packet checksumming code. Watch the comments for an explanation.
Diffstat (limited to 'lib/checksum.c')
-rw-r--r-- | lib/checksum.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/lib/checksum.c b/lib/checksum.c new file mode 100644 index 0000000..4dfa252 --- /dev/null +++ b/lib/checksum.c @@ -0,0 +1,59 @@ +/* + * BIRD Library -- IP One-Complement Checksum + * + * (c) 1999 Martin Mares <mj@ucw.cz> + * + * Can be freely distributed and used under the terms of the GNU GPL. + */ + +#include <stdarg.h> + +#include "nest/bird.h" +#include "checksum.h" + +static u16 +ipsum_calc(void *frag, unsigned len, va_list args) +{ + u16 sum = 0; + + for(;;) + { + u16 *x = frag; + ASSERT(!(len % 2)); + while (len) + { + u16 z = sum + *x++; + sum = z + (z < sum); + len -= 2; + } + frag = va_arg(args, void *); + if (!frag) + break; + len = va_arg(args, unsigned); + } + return sum; +} + +int +ipsum_verify(void *frag, unsigned len, ...) +{ + va_list args; + u16 sum; + + va_start(args, len); + sum = ipsum_calc(frag, len, args); + va_end(args); + return sum == 0xffff; +} + +u16 +ipsum_calculate(void *frag, unsigned len, ...) +{ + va_list args; + u16 sum; + + va_start(args, len); + sum = ipsum_calc(frag, len, args); + va_end(args); + return 0xffff - sum; +} |