2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2010 Emmanuel Roullit.
4 * Subject to the GPL, version 2.
10 #include <netinet/in.h>
11 #include <netinet/ip.h>
15 static inline unsigned short csum(unsigned short *buf
, int nwords
)
19 for (sum
= 0; nwords
> 0; nwords
--)
21 sum
= (sum
>> 16) + (sum
& 0xffff);
27 static inline uint16_t calc_csum(void *addr
, size_t len
,
28 int ccsum __maybe_unused
)
30 return csum(addr
, len
>> 1);
33 static inline uint16_t csum_expected(uint16_t sum
, uint16_t computed_sum
)
38 shouldbe
+= ntohs(computed_sum
);
39 shouldbe
= (shouldbe
& 0xFFFF) + (shouldbe
>> 16);
40 shouldbe
= (shouldbe
& 0xFFFF) + (shouldbe
>> 16);
45 /* Taken and modified from tcpdump, Copyright belongs to them! */
53 do { if ((x) > 65535) \
60 sum = l_util.s[0] + l_util.s[1]; \
64 static inline u16
__in_cksum(const struct cksum_vec
*vec
, int veclen
)
67 int sum
= 0, mlen
= 0;
78 for (; veclen
!= 0; vec
++, veclen
--) {
82 w
= (const u16
*) (void *) vec
->ptr
;
85 s_util
.c
[1] = *(const u8
*) w
;
87 w
= (const u16
*) (void *) ((const u8
*) w
+ 1);
92 if ((1 & (unsigned long) w
) && (mlen
> 0)) {
95 s_util
.c
[0] = *(const u8
*) w
;
96 w
= (const u16
*) (void *) ((const u8
*) w
+ 1);
101 while ((mlen
-= 32) >= 0) {
102 sum
+= w
[0]; sum
+= w
[1]; sum
+= w
[2]; sum
+= w
[3];
103 sum
+= w
[4]; sum
+= w
[5]; sum
+= w
[6]; sum
+= w
[7];
104 sum
+= w
[8]; sum
+= w
[9]; sum
+= w
[10]; sum
+= w
[11];
105 sum
+= w
[12]; sum
+= w
[13]; sum
+= w
[14]; sum
+= w
[15];
111 while ((mlen
-= 8) >= 0) {
112 sum
+= w
[0]; sum
+= w
[1]; sum
+= w
[2]; sum
+= w
[3];
118 if (mlen
== 0 && byte_swapped
== 0)
123 while ((mlen
-= 2) >= 0) {
133 s_util
.c
[1] = *(const u8
*) w
;
138 } else if (mlen
== -1)
139 s_util
.c
[0] = *(const u8
*) w
;
149 return (~sum
& 0xffff);
152 static inline u16
p4_csum(const struct ip
*ip
, const u8
*data
, u16 len
,
155 struct cksum_vec vec
[2];
164 memset(&ph
, 0, sizeof(ph
));
167 ph
.proto
= next_proto
;
168 ph
.src
= ip
->ip_src
.s_addr
;
169 ph
.dst
= ip
->ip_dst
.s_addr
;
171 vec
[0].ptr
= (const u8
*) (void *) &ph
;
172 vec
[0].len
= sizeof(ph
);
177 return __in_cksum(vec
, 2);