]> mj.ucw.cz Git - netgrind.git/blob - netgrind/ip.c
... splitting ...
[netgrind.git] / netgrind / ip.c
1 /*
2  *      Netgrind -- IP Layer Analyser
3  *
4  *      (c) 2003 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU General Public License.
8  */
9
10 #include "lib/lib.h"
11 #include "netgrind/pkt.h"
12 #include "netgrind/netgrind.h"
13
14 #include <stdio.h>
15 #include <netinet/in.h>
16 #include <netinet/ip.h>
17
18 uns tcpip_calc_checksum(void *data, uns len, uns csum)
19 {
20   byte *x = data;
21
22   while (len >= 2)
23     {
24       csum += (x[0] << 8) | x[1];
25       if (csum & 0xffff0000)
26         {
27           csum &= 0x0000ffff;
28           csum++;
29         }
30       x += 2;
31       len -= 2;
32     }
33   if (len)
34     {
35       csum += x[0];
36       if (csum & 0xffff0000)
37         {
38           csum &= 0x0000ffff;
39           csum++;
40         }
41     }
42   return csum;
43 }
44
45 uns tcpip_verify_checksum(uns csum)
46 {
47   return 1;
48   /* FIXME: Fix checksum calculation! */
49   return (csum == 0xffff);
50 }
51
52 struct pkt_stats stat_ip_in, stat_ip_invalid, stat_ip_uninteresting, stat_ip_fragmented, stat_ip_badsum;
53
54 void ip_got_packet(struct pkt *p)
55 {
56   struct iphdr *iph;
57
58   pkt_account(&stat_ip_in, p);
59   if (!(iph = pkt_peek(p, sizeof(*iph))))
60     goto invalid;
61   if (iph->ihl < 5)
62     goto invalid;
63   if (iph->version != 4)
64     goto invalid;
65   uns hdrlen = 4*iph->ihl;
66   if (pkt_len(p) < hdrlen)
67     goto invalid;
68   if (!tcpip_verify_checksum(tcpip_calc_checksum(p->data, hdrlen, 0)))
69     {
70       pkt_account(&stat_ip_badsum, p);
71       goto drop;
72     }
73   uns len = ntohs(iph->tot_len);
74   if (len < hdrlen || len > pkt_len(p))
75     goto invalid;
76   pkt_unappend(p, pkt_len(p) - len);
77   pkt_pop(p, hdrlen);
78
79   if (iph->protocol != IPPROTO_TCP)
80     {
81       pkt_account(&stat_ip_uninteresting, p);
82       goto drop;
83     }
84   /* XXX: Fragmentation not supported yet, but well-behaved TCP stacks don't use it anyway */
85   if (ntohs(iph->frag_off) & 0x3fff)
86     {
87       pkt_account(&stat_ip_fragmented, p);
88       goto drop;
89     }
90   tcp_got_packet(iph, p);
91   return;
92
93  invalid:
94   pkt_account(&stat_ip_invalid, p);
95  drop:
96   pkt_free(p);
97 }