2 * Netgrind -- The Network Traffic Analyser
4 * (c) 2003 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"
22 void die(byte *msg, ...)
27 fputs("netgrind: ", stderr);
28 vfprintf(stderr, msg, args);
33 /*** PCAP INTERFACE ***/
35 static void (*link_handler)(struct pkt *);
36 static struct pkt_stats stat_pcap_incomplete;
38 static int link_setup_handler(int dlt)
42 case DLT_EN10MB: link_handler = link_eth_got_packet; return 1;
47 static void got_pcap_packet(u_char *userdata UNUSED, const struct pcap_pkthdr *hdr, const u_char *pkt)
49 if (hdr->caplen != hdr->len)
51 stat_pcap_incomplete.packets++;
52 stat_pcap_incomplete.bytes += hdr->len - hdr->caplen;
55 struct pkt *p = pkt_new(0, hdr->len);
56 memcpy(pkt_append(p, hdr->len), pkt, hdr->len);
57 p->timestamp = (u64)hdr->ts.tv_sec * 1000000 + hdr->ts.tv_usec;
61 static void usage(void)
63 fprintf(stderr, "Usage: netgrind [<switches>] <capture-file>\n\
65 -a TCP: Record arrival times instead of processing times\n\
66 -c <count> Stop after processing <count> packets\n\
67 -d <dir> Dump connections to a given directory\n\
68 -D <dir> Dump connections with more details\n\
69 -f <filter> Apply filter expression\n\
70 -w TCP: Wait for ACK before processing packets\n\
75 int main(int argc, char **argv)
77 char errbuf[PCAP_ERRBUF_SIZE];
82 struct bpf_program filter_prog;
84 tcp_default_appl = &appl_sink;
85 while ((c = getopt(argc, argv, "ac:d:D:f:w")) >= 0)
89 tcp_arrival_times = 1;
92 max_packets = atol(optarg);
95 tcp_default_appl = &appl_save;
99 tcp_default_appl = &appl_asave;
106 tcp_wait_for_ack = 1;
111 if (optind != argc - 1)
116 if (!(pcap = pcap_open_offline(argv[optind], errbuf)))
117 die("Unable to open %s", errbuf);
118 dlt = pcap_datalink(pcap);
119 if (!link_setup_handler(dlt))
120 die("Don't know how to handle data link type %d", dlt);
123 if (pcap_compile(pcap, &filter_prog, filter, 1, 0) < 0)
124 die("Error compiling filter: %s", pcap_geterr(pcap));
125 pcap_setfilter(pcap, &filter_prog);
127 if (pcap_loop(pcap, max_packets, got_pcap_packet, NULL) < 0)
128 die("Capture failed: %s", pcap_geterr(pcap));
130 printf("Pcap: %Ld(%Ld) incomplete\n",
131 stat_pcap_incomplete.packets, stat_pcap_incomplete.bytes);
132 printf("Link: %Ld(%Ld) in, %Ld(%Ld) dwarves, %Ld(%Ld) strangers, %Ld(%Ld) ARPs\n",
133 stat_link_in.packets, stat_link_in.bytes,
134 stat_link_dwarf.packets, stat_link_dwarf.bytes,
135 stat_link_unknown.packets, stat_link_unknown.bytes,
136 stat_link_arp.packets, stat_link_arp.bytes);
137 printf("IP: %Ld(%Ld) in, %Ld(%Ld) invalid, %Ld(%Ld) boring, %Ld(%Ld) fragmented, %Ld(%Ld) bad checksum; %d flows\n",
138 stat_ip_in.packets, stat_ip_in.bytes,
139 stat_ip_invalid.packets, stat_ip_invalid.bytes,
140 stat_ip_uninteresting.packets, stat_ip_uninteresting.bytes,
141 stat_ip_fragmented.packets, stat_ip_fragmented.bytes,
142 stat_ip_badsum.packets, stat_ip_badsum.bytes,
144 printf("TCP: %Ld(%Ld) in, %Ld(%Ld) invalid, %Ld(%Ld) bad checksum, %Ld(%Ld) unmatched, %Ld(%Ld) on closed connections, %Ld(%Ld) in unexpected state\n",
145 stat_tcp_in.packets, stat_tcp_in.bytes,
146 stat_tcp_invalid.packets, stat_tcp_invalid.bytes,
147 stat_tcp_badsum.packets, stat_tcp_badsum.bytes,
148 stat_tcp_unmatched.packets, stat_tcp_unmatched.bytes,
149 stat_tcp_on_closed.packets, stat_tcp_on_closed.bytes,
150 stat_tcp_bad_state.packets, stat_tcp_bad_state.bytes);