2 * iostat 2003 Ronnie Sahlberg
4 * $Id: tap-iousers.c,v 1.7 2003/05/19 11:16:29 sahlberg Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
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.
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.
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.
31 #ifdef HAVE_SYS_TYPES_H
32 # include <sys/types.h>
36 #include <epan/packet_info.h>
37 #include <epan/packet.h>
38 #include <epan/resolv.h>
41 #include "packet-ip.h"
42 #include "packet-tcp.h"
43 #include "packet-udp.h"
44 #include "packet-eth.h"
45 #include "packet-tr.h"
48 typedef struct _io_users_t {
51 struct _io_users_item_t *items;
54 typedef struct _io_users_item_t {
55 struct _io_users_item_t *next;
67 /* XXX for now we only handle ipv4 as transport for udp.
68 should extend in the future to also handle ipv6
71 iousers_udpip_packet(io_users_t *iu, packet_info *pinfo, epan_dissect_t *edt _U_, void *vudph)
74 char name1[256],name2[256];
79 ipv4_header=udph->ip_header;
80 switch(ipv4_header->ip_v_hl>>4){
82 if(ipv4_header->ip_src>ipv4_header->ip_dst){
83 snprintf(name1,256,"%s:%s",get_hostname(ipv4_header->ip_src),get_udp_port(udph->uh_sport));
84 snprintf(name2,256,"%s:%s",get_hostname(ipv4_header->ip_dst),get_udp_port(udph->uh_dport));
87 snprintf(name2,256,"%s:%s",get_hostname(ipv4_header->ip_src),get_udp_port(udph->uh_sport));
88 snprintf(name1,256,"%s:%s",get_hostname(ipv4_header->ip_dst),get_udp_port(udph->uh_dport));
95 for(iui=iu->items;iui;iui=iui->next){
96 if((!strcmp(iui->name1, name1))
97 && (!strcmp(iui->name2, name2)) ){
103 iui=g_malloc(sizeof(io_users_item_t));
107 iui->name1=strdup(name1);
109 iui->name2=strdup(name2);
118 iui->bytes1+=pinfo->fd->pkt_len;
121 iui->bytes2+=pinfo->fd->pkt_len;
127 /* XXX for now we only handle ipv4 as transport for tcp.
128 should extend in the future to also handle ipv6
131 iousers_tcpip_packet(io_users_t *iu, packet_info *pinfo, epan_dissect_t *edt _U_, void *vtcph)
133 struct tcpheader *tcph=vtcph;
134 char name1[256],name2[256];
135 io_users_item_t *iui;
139 ipv4_header=tcph->ip_header;
140 switch(ipv4_header->ip_v_hl>>4){
142 if(ipv4_header->ip_src>ipv4_header->ip_dst){
143 snprintf(name1,256,"%s:%s",get_hostname(ipv4_header->ip_src),get_tcp_port(tcph->th_sport));
144 snprintf(name2,256,"%s:%s",get_hostname(ipv4_header->ip_dst),get_tcp_port(tcph->th_dport));
147 snprintf(name2,256,"%s:%s",get_hostname(ipv4_header->ip_src),get_tcp_port(tcph->th_sport));
148 snprintf(name1,256,"%s:%s",get_hostname(ipv4_header->ip_dst),get_tcp_port(tcph->th_dport));
155 for(iui=iu->items;iui;iui=iui->next){
156 if((!strcmp(iui->name1, name1))
157 && (!strcmp(iui->name2, name2)) ){
163 iui=g_malloc(sizeof(io_users_item_t));
167 iui->name1=strdup(name1);
169 iui->name2=strdup(name2);
178 iui->bytes1+=pinfo->fd->pkt_len;
181 iui->bytes2+=pinfo->fd->pkt_len;
189 iousers_ip_packet(io_users_t *iu, packet_info *pinfo, epan_dissect_t *edt _U_, void *vip)
192 guint32 addr1, addr2;
193 io_users_item_t *iui;
195 if(iph->ip_src>iph->ip_dst){
203 for(iui=iu->items;iui;iui=iui->next){
204 if((!memcmp(iui->addr1, &addr1, 4))
205 &&(!memcmp(iui->addr2, &addr2, 4)) ){
211 iui=g_malloc(sizeof(io_users_item_t));
214 iui->addr1=g_malloc(4);
215 memcpy(iui->addr1, &addr1, 4);
216 iui->name1=strdup(get_hostname(addr1));
217 iui->addr2=g_malloc(4);
218 memcpy(iui->addr2, &addr2, 4);
219 iui->name2=strdup(get_hostname(addr2));
226 if(!memcmp(&iph->ip_dst,iui->addr1,4)){
228 iui->bytes1+=pinfo->fd->pkt_len;
231 iui->bytes2+=pinfo->fd->pkt_len;
238 iousers_eth_packet(io_users_t *iu, packet_info *pinfo, epan_dissect_t *edt _U_, void *veth)
241 gchar *addr1, *addr2;
242 io_users_item_t *iui;
244 if(memcmp(ehdr->src, ehdr->dst, 6)<0){
252 for(iui=iu->items;iui;iui=iui->next){
253 if((!memcmp(iui->addr1, addr1, 6))
254 &&(!memcmp(iui->addr2, addr2, 6)) ){
260 iui=g_malloc(sizeof(io_users_item_t));
263 iui->addr1=g_malloc(6);
264 memcpy(iui->addr1, addr1, 6);
265 iui->name1=strdup(ether_to_str(addr1));
266 iui->addr2=g_malloc(6);
267 memcpy(iui->addr2, addr2, 6);
268 iui->name2=strdup(ether_to_str(addr2));
275 if(!memcmp(ehdr->dst,iui->addr1,6)){
277 iui->bytes1+=pinfo->fd->pkt_len;
280 iui->bytes2+=pinfo->fd->pkt_len;
288 iousers_tr_packet(io_users_t *iu, packet_info *pinfo, epan_dissect_t *edt _U_, void *vtr)
291 gchar *addr1, *addr2;
292 io_users_item_t *iui;
294 if(memcmp(trhdr->src, trhdr->dst, 6)<0){
302 for(iui=iu->items;iui;iui=iui->next){
303 if((!memcmp(iui->addr1, addr1, 6))
304 &&(!memcmp(iui->addr2, addr2, 6)) ){
310 iui=g_malloc(sizeof(io_users_item_t));
313 iui->addr1=g_malloc(6);
314 memcpy(iui->addr1, addr1, 6);
315 iui->name1=strdup(ether_to_str(addr1));
316 iui->addr2=g_malloc(6);
317 memcpy(iui->addr2, addr2, 6);
318 iui->name2=strdup(ether_to_str(addr2));
325 if(!memcmp(trhdr->dst,iui->addr1,6)){
327 iui->bytes1+=pinfo->fd->pkt_len;
330 iui->bytes2+=pinfo->fd->pkt_len;
337 iousers_draw(io_users_t *iu)
339 io_users_item_t *iui;
340 guint32 last_frames, max_frames;
342 printf("================================================================================\n");
343 printf("IO-USERS Statistics\n");
344 printf("Type:%s\n",iu->type);
345 printf("Filter:%s\n",iu->filter?iu->filter:"<No Filter>");
346 printf(" | <- | | -> | | Total |\n");
347 printf(" | Frames Bytes | | Frames Bytes | | Frames Bytes |\n");
348 max_frames=0xffffffff;
351 for(iui=iu->items;iui;iui=iui->next){
353 tot_frames=iui->frames1+iui->frames2;
355 if((tot_frames>last_frames)
356 &&(tot_frames<max_frames)){
357 last_frames=tot_frames;
360 for(iui=iu->items;iui;iui=iui->next){
362 tot_frames=iui->frames1+iui->frames2;
364 if(tot_frames==last_frames){
365 printf("%-20s <-> %-20s %6d %9d %6d %9d %6d %9d\n",
366 iui->name1, iui->name2,
367 iui->frames1, iui->bytes1,
368 iui->frames2, iui->bytes2,
369 iui->frames1+iui->frames2,
370 iui->bytes1+iui->bytes2
374 max_frames=last_frames;
375 } while(last_frames);
376 printf("================================================================================\n");
380 iousers_init(char *optarg)
384 static int (*packet_func)(io_users_t *, packet_info *, epan_dissect_t *, void *);
386 GString *error_string;
388 if(!strncmp(optarg,"io,users,eth",12)){
395 packet_func=iousers_eth_packet;
396 } else if(!strncmp(optarg,"io,users,tcpip",14)){
403 packet_func=iousers_tcpip_packet;
404 } else if(!strncmp(optarg,"io,users,udpip",14)){
411 packet_func=iousers_udpip_packet;
412 } else if(!strncmp(optarg,"io,users,tr",11)){
419 packet_func=iousers_tr_packet;
420 } else if(!strncmp(optarg,"io,users,ip",11)){
427 packet_func=iousers_ip_packet;
429 fprintf(stderr, "tethereal: invalid \"-z io,users,<type>[,<filter>]\" argument\n");
430 fprintf(stderr," <type> must be one of\n");
431 fprintf(stderr," \"eth\"\n");
432 fprintf(stderr," \"ip\"\n");
433 fprintf(stderr," \"tcpip\"\n");
434 fprintf(stderr," \"tr\"\n");
435 fprintf(stderr," \"udpip\"\n");
440 iu=g_malloc(sizeof(io_users_t));
444 iu->filter=strdup(filter);
449 error_string=register_tap_listener(tap_type, iu, filter, NULL, (void*)packet_func, (void*)iousers_draw);
455 fprintf(stderr, "tethereal: Couldn't register io,users tap: %s\n",
457 g_string_free(error_string, TRUE);
464 register_tap_listener_iousers(void)
466 register_ethereal_tap("io,users,", iousers_init);