1 | #include <netdb.h> |
---|
2 | #include <inttypes.h> |
---|
3 | #include <stdio.h> |
---|
4 | #include <stdlib.h> |
---|
5 | #include <string.h> |
---|
6 | #include "libtrace.h" |
---|
7 | #include "tracereport.h" |
---|
8 | #include "tree.h" |
---|
9 | |
---|
10 | #define MEMDUP(x) memcpy(malloc(sizeof(x)),&x,sizeof(x)) |
---|
11 | |
---|
12 | static tree_t *protocol_tree = NULL; |
---|
13 | |
---|
14 | int protocolcmp(const void *a,const void *b) { |
---|
15 | return *(uint8_t*)a-*(uint8_t*)b; |
---|
16 | } |
---|
17 | int portcmp(const void *a, const void *b) { |
---|
18 | return *(uint16_t*)a-*(uint16_t*)b; |
---|
19 | } |
---|
20 | |
---|
21 | void port_per_packet(struct libtrace_packet_t *packet) |
---|
22 | { |
---|
23 | struct libtrace_ip *ip = trace_get_ip(packet); |
---|
24 | if (!ip) |
---|
25 | return; |
---|
26 | |
---|
27 | int port = trace_get_server_port(ip->ip_p, |
---|
28 | trace_get_source_port(packet), |
---|
29 | trace_get_destination_port(packet))==USE_SOURCE |
---|
30 | ? trace_get_source_port(packet) |
---|
31 | : trace_get_destination_port(packet); |
---|
32 | |
---|
33 | uint8_t *protocol = MEMDUP(ip->ip_p); |
---|
34 | uint16_t *portmem = MEMDUP(port); |
---|
35 | |
---|
36 | |
---|
37 | tree_t *ports=tree_find(&protocol_tree,protocol,protocolcmp); |
---|
38 | |
---|
39 | stat_t *stat =tree_find(&ports,portmem,portcmp); |
---|
40 | if (!stat) { |
---|
41 | stat=calloc(1,sizeof(stat_t)); |
---|
42 | } |
---|
43 | ++stat->count; |
---|
44 | stat->bytes+=trace_get_wire_length(packet); |
---|
45 | if (tree_replace(&ports,portmem,portcmp,stat)) { |
---|
46 | free(portmem); |
---|
47 | } |
---|
48 | if (tree_replace(&protocol_tree,protocol,protocolcmp,ports)) { |
---|
49 | free(protocol); |
---|
50 | } |
---|
51 | } |
---|
52 | |
---|
53 | static void port_visitor(const void *key, void *value, void *data) |
---|
54 | { |
---|
55 | struct servent *ent = getservbyport(htons(*(uint16_t*)key),(char *)data); |
---|
56 | if(ent) |
---|
57 | printf("%20s:\t%12" PRIu64 "\t%12" PRIu64 "\n", |
---|
58 | ent->s_name, |
---|
59 | ((stat_t *)value)->bytes, |
---|
60 | ((stat_t *)value)->count |
---|
61 | ); |
---|
62 | else |
---|
63 | printf("%20i:\t%12" PRIu64 "\t%12" PRIu64 "\n", |
---|
64 | *(uint16_t*)key, |
---|
65 | ((stat_t *)value)->bytes, |
---|
66 | ((stat_t *)value)->count |
---|
67 | ); |
---|
68 | } |
---|
69 | |
---|
70 | static void protocol_visitor(const void *key, void *value, void *data) |
---|
71 | { |
---|
72 | struct protoent *ent = getprotobynumber(*(uint8_t*)key); |
---|
73 | printf("Protocol: %i %s%s%s\n",*(uint8_t*)key, |
---|
74 | ent?"(":"",ent?ent->p_name:"",ent?")":""); |
---|
75 | tree_inorder((tree_t**)&value, |
---|
76 | port_visitor, |
---|
77 | (void*)(ent?ent->p_name:"")); |
---|
78 | } |
---|
79 | |
---|
80 | void port_report(void) |
---|
81 | { |
---|
82 | int i; |
---|
83 | printf("# Port breakdown:\n"); |
---|
84 | printf("%-20s \t%12s\t%12s\n","Port","Bytes","Packets"); |
---|
85 | setservent(1); |
---|
86 | setprotoent(1); |
---|
87 | tree_inorder(&protocol_tree,protocol_visitor,NULL); |
---|
88 | endprotoent(); |
---|
89 | endservent(); |
---|
90 | } |
---|