2 * Netgrind -- IP Layer Analyser
4 * (c) 2003--2013 Martin Mares <mj@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU General Public License.
11 #include "netgrind/pkt.h"
12 #include "netgrind/netgrind.h"
15 #include <netinet/in.h>
16 #include <netinet/ip.h>
18 uns accept_broken_checksums;
20 uns tcpip_calc_checksum(void *data, uns len, uns csum)
22 /* FIXME: This is awfully slow and it probably consumes most of our run time */
27 csum += (x[0] << 8) | x[1];
28 if (csum & 0xffff0000)
39 if (csum & 0xffff0000)
48 uns tcpip_verify_checksum(uns csum)
50 if (accept_broken_checksums)
53 return (csum == 0xffff);
56 struct pkt_stats stat_ip_in, stat_ip_invalid, stat_ip_uninteresting, stat_ip_fragmented, stat_ip_badsum;
58 void ip_got_packet(struct pkt *p)
62 pkt_account(&stat_ip_in, p);
63 if (!(iph = pkt_peek(p, sizeof(*iph))))
67 if (iph->version != 4)
69 uns hdrlen = 4*iph->ihl;
70 if (pkt_len(p) < hdrlen)
72 if (!tcpip_verify_checksum(tcpip_calc_checksum(p->data, hdrlen, 0)))
74 pkt_account(&stat_ip_badsum, p);
77 uns len = ntohs(iph->tot_len);
78 if (len < hdrlen || len > pkt_len(p))
80 pkt_unappend(p, pkt_len(p) - len);
83 if (iph->protocol != IPPROTO_TCP)
85 pkt_account(&stat_ip_uninteresting, p);
88 /* XXX: Fragmentation not supported yet, but well-behaved TCP stacks don't use it anyway */
89 if (ntohs(iph->frag_off) & 0x3fff)
91 pkt_account(&stat_ip_fragmented, p);
94 tcp_got_packet(iph, p);
98 pkt_account(&stat_ip_invalid, p);