]> mj.ucw.cz Git - netgrind.git/blob - netgrind/netgrind.c
... splitting ...
[netgrind.git] / netgrind / netgrind.c
1 /*
2  *      Netgrind -- The Network Traffic 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 /*
11  *  FIXME: TCP stats
12  */
13
14 #include "lib/lib.h"
15 #include "netgrind/pkt.h"
16 #include "netgrind/netgrind.h"
17
18 #include <stdio.h>
19 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include <pcap.h>
24
25 void die(byte *msg, ...)
26 {
27   va_list args;
28
29   va_start(args, msg);
30   fputs("netgrind: ", stderr);
31   vfprintf(stderr, msg, args);
32   fputs("\n", stderr);
33   exit(1);
34 }
35
36 /*** PCAP INTERFACE ***/
37
38 static void (*link_handler)(struct pkt *);
39 static struct pkt_stats stat_pcap_incomplete;
40
41 static int link_setup_handler(int dlt)
42 {
43   switch (dlt)
44     {
45     case DLT_EN10MB:    link_handler = link_eth_got_packet; return 1;
46     default:            return 0;
47     }
48 }
49
50 static void got_pcap_packet(u_char *userdata UNUSED, const struct pcap_pkthdr *hdr, const u_char *pkt)
51 {
52   if (hdr->caplen != hdr->len)
53     {
54       stat_pcap_incomplete.packets++;
55       stat_pcap_incomplete.bytes += hdr->len - hdr->caplen;
56       return;
57     }
58   struct pkt *p = pkt_new(0, hdr->len);
59   memcpy(pkt_append(p, hdr->len), pkt, hdr->len);
60   p->timestamp = (u64)hdr->ts.tv_sec * 1000000 + hdr->ts.tv_usec;
61   link_handler(p);
62 }
63
64 int main(int argc, char **argv)
65 {
66   char errbuf[PCAP_ERRBUF_SIZE];
67   pcap_t *pcap;
68   int dlt;
69
70   if (argc != 2)
71     die("Usage: netgrind <capture-file>");
72
73   tcp_init();
74
75   if (!(pcap = pcap_open_offline(argv[1], errbuf)))
76     die("Unable to open %s: %s", argv[1], errbuf);
77   dlt = pcap_datalink(pcap);
78   if (!link_setup_handler(dlt))
79     die("Don't know how to handle data link type %d", dlt);
80   if (pcap_loop(pcap, -1, got_pcap_packet, NULL) < 0)
81     die("Capture failed: %s", pcap_geterr(pcap));
82   tcp_cleanup();
83 #if 0
84   struct pcap_stat stats;
85   if (pcap_stats(pcap, &stats))
86     die("pcap_stats: %s", pcap_geterr(pcap));
87   printf("libpcap stats: %d packets received, %d dropped\n", stats.ps_recv, stats.ps_drop);
88 #endif
89   printf("Pcap: %Ld(%Ld) incomplete\n",
90          stat_pcap_incomplete.packets, stat_pcap_incomplete.bytes);
91   printf("Link: %Ld(%Ld) in, %Ld(%Ld) dwarves, %Ld(%Ld) strangers, %Ld(%Ld) ARPs\n",
92          stat_link_in.packets, stat_link_in.bytes,
93          stat_link_dwarf.packets, stat_link_dwarf.bytes,
94          stat_link_unknown.packets, stat_link_unknown.bytes,
95          stat_link_arp.packets, stat_link_arp.bytes);
96   printf("IP: %Ld(%Ld) in, %Ld(%Ld) invalid, %Ld(%Ld) boring, %Ld(%Ld) fragmented, %Ld(%Ld) bad checksum\n",
97          stat_ip_in.packets, stat_ip_in.bytes,
98          stat_ip_invalid.packets, stat_ip_invalid.bytes,
99          stat_ip_uninteresting.packets, stat_ip_uninteresting.bytes,
100          stat_ip_fragmented.packets, stat_ip_fragmented.bytes,
101          stat_ip_badsum.packets, stat_ip_badsum.bytes);
102   printf("TCP: %Ld(%Ld) in, %Ld(%Ld) invalid, %Ld(%Ld) bad checksum\n",
103          stat_tcp_in.packets, stat_tcp_in.bytes,
104          stat_tcp_invalid.packets, stat_tcp_invalid.bytes,
105          stat_tcp_badsum.packets, stat_tcp_badsum.bytes);
106   pcap_close(pcap);
107   return 0;
108 }