Include <epan/resolv.h> to declare "get_hostname()".
[obnox/wireshark/wip.git] / tap-iousers.c
1 /* tap-iousers.c
2  * iostat   2003 Ronnie Sahlberg
3  *
4  * $Id: tap-iousers.c,v 1.2 2003/01/22 07:28:29 guy Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@ethereal.com>
8  * Copyright 1998 Gerald Combs
9  * 
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  * 
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  * 
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <stdio.h>
30
31 #ifdef HAVE_SYS_TYPES_H
32 # include <sys/types.h>
33 #endif
34
35 #include <string.h>
36 #include <epan/packet_info.h>
37 #include <epan/packet.h>
38 #include <epan/resolv.h>
39 #include "tap.h"
40 #include "register.h"
41 #include "packet-ip.h"
42 #include "packet-eth.h"
43 #include "packet-tr.h"
44 #include <string.h>
45
46 typedef struct _io_users_t {
47         char *type;
48         char *filter;
49         struct _io_users_item_t *items;
50 } io_users_t;
51
52 typedef struct _io_users_item_t {
53         struct _io_users_item_t *next;
54         char *name1;
55         char *name2;
56         void *addr1;
57         void *addr2; 
58         guint32 frames1;
59         guint32 frames2;
60         guint32 bytes1;
61         guint32 bytes2;
62 } io_users_item_t;
63
64 static int
65 iousers_ip_packet(io_users_t *iu, packet_info *pinfo, epan_dissect_t *edt _U_, void *vip)
66 {
67         e_ip *iph=vip;
68         guint32 addr1, addr2;
69         io_users_item_t *iui;
70
71         if(iph->ip_src>iph->ip_dst){
72                 addr1=iph->ip_src;
73                 addr2=iph->ip_dst;
74         } else {
75                 addr2=iph->ip_src;
76                 addr1=iph->ip_dst;
77         }
78
79         for(iui=iu->items;iui;iui=iui->next){
80                 if((!memcmp(iui->addr1, &addr1, 4))
81                 &&(!memcmp(iui->addr2, &addr2, 4)) ){
82                         break;
83                 }
84         }
85
86         if(!iui){
87                 iui=g_malloc(sizeof(io_users_item_t));
88                 iui->next=iu->items;
89                 iu->items=iui;
90                 iui->addr1=g_malloc(4);
91                 memcpy(iui->addr1, &addr1, 4);
92                 iui->name1=strdup(get_hostname(addr1));
93                 iui->addr2=g_malloc(4);
94                 memcpy(iui->addr2, &addr2, 4);
95                 iui->name2=strdup(get_hostname(addr2));
96                 iui->frames1=0;
97                 iui->frames2=0;
98                 iui->bytes1=0;
99                 iui->bytes2=0;
100         }
101
102         if(!memcmp(&iph->ip_src,iui->addr1,4)){
103                 iui->frames1++;
104                 iui->bytes1+=pinfo->fd->pkt_len;
105         } else {
106                 iui->frames2++;
107                 iui->bytes2+=pinfo->fd->pkt_len;
108         }
109
110         return 1;
111 }
112
113 static int
114 iousers_eth_packet(io_users_t *iu, packet_info *pinfo, epan_dissect_t *edt _U_, void *veth)
115 {
116         eth_hdr *ehdr=veth;
117         gchar *addr1, *addr2;
118         io_users_item_t *iui;
119
120         if(memcmp(ehdr->src, ehdr->dst, 6)<0){
121                 addr1=ehdr->src;
122                 addr2=ehdr->dst;
123         } else {
124                 addr2=ehdr->src;
125                 addr1=ehdr->dst;
126         }
127
128         for(iui=iu->items;iui;iui=iui->next){
129                 if((!memcmp(iui->addr1, addr1, 6))
130                 &&(!memcmp(iui->addr2, addr2, 6)) ){
131                         break;
132                 }
133         }
134
135         if(!iui){
136                 iui=g_malloc(sizeof(io_users_item_t));
137                 iui->next=iu->items;
138                 iu->items=iui;
139                 iui->addr1=g_malloc(6);
140                 memcpy(iui->addr1, addr1, 6);
141                 iui->name1=strdup(ether_to_str(addr1));
142                 iui->addr2=g_malloc(6);
143                 memcpy(iui->addr2, addr2, 6);
144                 iui->name2=strdup(ether_to_str(addr2));
145                 iui->frames1=0;
146                 iui->frames2=0;
147                 iui->bytes1=0;
148                 iui->bytes2=0;
149         }
150
151         if(!memcmp(ehdr->dst,iui->addr1,6)){
152                 iui->frames1++;
153                 iui->bytes1+=pinfo->fd->pkt_len;
154         } else {
155                 iui->frames2++;
156                 iui->bytes2+=pinfo->fd->pkt_len;
157         }
158
159         return 1;
160 }
161
162
163 static int
164 iousers_tr_packet(io_users_t *iu, packet_info *pinfo, epan_dissect_t *edt _U_, void *vtr)
165 {
166         tr_hdr *trhdr=vtr;
167         gchar *addr1, *addr2;
168         io_users_item_t *iui;
169
170         if(memcmp(trhdr->src, trhdr->dst, 6)<0){
171                 addr1=trhdr->src;
172                 addr2=trhdr->dst;
173         } else {
174                 addr2=trhdr->src;
175                 addr1=trhdr->dst;
176         }
177
178         for(iui=iu->items;iui;iui=iui->next){
179                 if((!memcmp(iui->addr1, addr1, 6))
180                 &&(!memcmp(iui->addr2, addr2, 6)) ){
181                         break;
182                 }
183         }
184
185         if(!iui){
186                 iui=g_malloc(sizeof(io_users_item_t));
187                 iui->next=iu->items;
188                 iu->items=iui;
189                 iui->addr1=g_malloc(6);
190                 memcpy(iui->addr1, addr1, 6);
191                 iui->name1=strdup(ether_to_str(addr1));
192                 iui->addr2=g_malloc(6);
193                 memcpy(iui->addr2, addr2, 6);
194                 iui->name2=strdup(ether_to_str(addr2));
195                 iui->frames1=0;
196                 iui->frames2=0;
197                 iui->bytes1=0;
198                 iui->bytes2=0;
199         }
200
201         if(!memcmp(trhdr->dst,iui->addr1,6)){
202                 iui->frames1++;
203                 iui->bytes1+=pinfo->fd->pkt_len;
204         } else {
205                 iui->frames2++;
206                 iui->bytes2+=pinfo->fd->pkt_len;
207         }
208
209         return 1;
210 }
211
212 static void
213 iousers_draw(io_users_t *iu)
214 {
215         io_users_item_t *iui;
216         guint32 last_frames, max_frames;
217
218         printf("================================================================================\n");
219         printf("IO-USERS Statistics\n");
220         printf("Type:%s\n",iu->type);
221         printf("Filter:%s\n",iu->filter?iu->filter:"<No Filter>");
222         printf("                                               |       <-      | |       ->      | |     Total     |\n");
223         printf("                                               | Frames  Bytes | | Frames  Bytes | | Frames  Bytes |\n");
224         max_frames=0xffffffff;
225         do {
226                 last_frames=0;
227                 for(iui=iu->items;iui;iui=iui->next){
228                         guint32 tot_frames;
229                         tot_frames=iui->frames1+iui->frames2;
230
231                         if((tot_frames>last_frames)
232                         &&(tot_frames<max_frames)){
233                                 last_frames=tot_frames;
234                         }
235                 }
236                 for(iui=iu->items;iui;iui=iui->next){
237                         guint32 tot_frames;
238                         tot_frames=iui->frames1+iui->frames2;
239
240                         if(tot_frames==last_frames){
241                                 printf("%-20s <-> %-20s  %6d %9d  %6d %9d  %6d %9d\n",
242                                         iui->name1, iui->name2,
243                                         iui->frames1, iui->bytes1,
244                                         iui->frames2, iui->bytes2,
245                                         iui->frames1+iui->frames2,
246                                         iui->bytes1+iui->bytes2
247                                 );
248                         }
249                 }
250                 max_frames=last_frames;
251         } while(last_frames);
252         printf("================================================================================\n");
253 }
254
255 void
256 iousers_init(char *optarg)
257 {
258         char *filter=NULL;
259         char *tap_type;
260         static int (*packet_func)(io_users_t *, packet_info *, epan_dissect_t *, void *);
261         io_users_t *iu=NULL;
262
263         if(!strncmp(optarg,"io,users,eth",12)){
264                 if(optarg[12]==','){
265                         filter=optarg+13;
266                 } else {
267                         filter=NULL;
268                 }
269                 tap_type="eth";
270                 packet_func=iousers_eth_packet;
271         } else if(!strncmp(optarg,"io,users,tr",11)){
272                 if(optarg[11]==','){
273                         filter=optarg+12;
274                 } else {
275                         filter=NULL;
276                 }
277                 tap_type="tr";
278                 packet_func=iousers_tr_packet;
279         } else if(!strncmp(optarg,"io,users,ip",11)){
280                 if(optarg[11]==','){
281                         filter=optarg+12;
282                 } else {
283                         filter=NULL;
284                 }
285                 tap_type="ip";
286                 packet_func=iousers_ip_packet;
287         } else {
288                 fprintf(stderr, "tethereal: invalid \"-z io,users,<type>[,<filter>]\" argument\n");
289                 fprintf(stderr,"   <type> must be one of\n");
290                 fprintf(stderr,"      \"eth\"\n");
291                 fprintf(stderr,"      \"ip\"\n");
292                 fprintf(stderr,"      \"tr\"\n");
293                 exit(1);
294         }
295
296
297         iu=g_malloc(sizeof(io_users_t));
298         iu->items=NULL;
299         iu->type=tap_type;
300         if(filter){
301                 iu->filter=strdup(filter);
302         } else {
303                 iu->filter=NULL;
304         }
305
306         if(register_tap_listener(tap_type, iu, filter, NULL, (void*)packet_func, (void*)iousers_draw)){
307                 if(iu->items){
308                         g_free(iu->items);
309                 }
310                 g_free(iu);
311                 fprintf(stderr,"tethereal: iousers_init() failed to attach tap\n");
312                 exit(1);
313         }
314
315 }
316
317 void
318 register_tap_listener_iousers(void)
319 {
320         register_ethereal_tap("io,users,", iousers_init, NULL, NULL);
321 }
322