2 * iostat 2003 Ronnie Sahlberg
4 * $Id: tap-iousers.c,v 1.15 2003/09/05 01:33:40 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-ipx.h"
43 #include "packet-tcp.h"
44 #include "packet-udp.h"
45 #include "packet-eth.h"
46 #include "packet-tr.h"
47 #include "packet-fc.h"
48 #include "packet-fddi.h"
51 typedef struct _io_users_t {
54 struct _io_users_item_t *items;
57 typedef struct _io_users_item_t {
58 struct _io_users_item_t *next;
71 iousers_udpip_packet(io_users_t *iu, packet_info *pinfo, epan_dissect_t *edt _U_, void *vudph)
74 char name1[256],name2[256];
78 if(udph->uh_sport>udph->uh_dport){
80 snprintf(name1,256,"%s:%s",address_to_str(&udph->ip_src),get_udp_port(udph->uh_sport));
81 snprintf(name2,256,"%s:%s",address_to_str(&udph->ip_dst),get_udp_port(udph->uh_dport));
82 } else if(udph->uh_sport<udph->uh_dport){
84 snprintf(name2,256,"%s:%s",address_to_str(&udph->ip_src),get_udp_port(udph->uh_sport));
85 snprintf(name1,256,"%s:%s",address_to_str(&udph->ip_dst),get_udp_port(udph->uh_dport));
86 } else if(CMP_ADDRESS(&udph->ip_src, &udph->ip_dst)>0){
88 snprintf(name1,256,"%s:%s",address_to_str(&udph->ip_src),get_udp_port(udph->uh_sport));
89 snprintf(name2,256,"%s:%s",address_to_str(&udph->ip_dst),get_udp_port(udph->uh_dport));
92 snprintf(name2,256,"%s:%s",address_to_str(&udph->ip_src),get_udp_port(udph->uh_sport));
93 snprintf(name1,256,"%s:%s",address_to_str(&udph->ip_dst),get_udp_port(udph->uh_dport));
96 for(iui=iu->items;iui;iui=iui->next){
97 if((!strcmp(iui->name1, name1))
98 && (!strcmp(iui->name2, name2)) ){
104 iui=g_malloc(sizeof(io_users_item_t));
107 /* iui->addr1=NULL;*/
108 iui->name1=strdup(name1);
109 /* iui->addr2=NULL;*/
110 iui->name2=strdup(name2);
119 iui->bytes1+=pinfo->fd->pkt_len;
122 iui->bytes2+=pinfo->fd->pkt_len;
130 iousers_tcpip_packet(io_users_t *iu, packet_info *pinfo, epan_dissect_t *edt _U_, void *vtcph)
132 struct tcpheader *tcph=vtcph;
133 char name1[256],name2[256];
134 io_users_item_t *iui;
137 if(tcph->th_sport>tcph->th_dport){
139 snprintf(name1,256,"%s:%s",address_to_str(&tcph->ip_src),get_tcp_port(tcph->th_sport));
140 snprintf(name2,256,"%s:%s",address_to_str(&tcph->ip_dst),get_tcp_port(tcph->th_dport));
141 } else if(tcph->th_sport<tcph->th_dport){
143 snprintf(name2,256,"%s:%s",address_to_str(&tcph->ip_src),get_tcp_port(tcph->th_sport));
144 snprintf(name1,256,"%s:%s",address_to_str(&tcph->ip_dst),get_tcp_port(tcph->th_dport));
145 } else if(CMP_ADDRESS(&tcph->ip_src, &tcph->ip_dst)>0){
147 snprintf(name1,256,"%s:%s",address_to_str(&tcph->ip_src),get_tcp_port(tcph->th_sport));
148 snprintf(name2,256,"%s:%s",address_to_str(&tcph->ip_dst),get_tcp_port(tcph->th_dport));
151 snprintf(name2,256,"%s:%s",address_to_str(&tcph->ip_src),get_tcp_port(tcph->th_sport));
152 snprintf(name1,256,"%s:%s",address_to_str(&tcph->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));
166 /* iui->addr1=NULL;*/
167 iui->name1=strdup(name1);
168 /* iui->addr2=NULL;*/
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 address *addr1, *addr2;
193 io_users_item_t *iui;
195 if(CMP_ADDRESS(&iph->ip_src, &iph->ip_dst)>0){
203 for(iui=iu->items;iui;iui=iui->next){
204 if((!CMP_ADDRESS(&iui->addr1, addr1))
205 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
211 iui=g_malloc(sizeof(io_users_item_t));
214 COPY_ADDRESS(&iui->addr1, addr1);
215 iui->name1=strdup(address_to_str(addr1));
216 COPY_ADDRESS(&iui->addr2, addr2);
217 iui->name2=strdup(address_to_str(addr2));
224 if(!CMP_ADDRESS(&iph->ip_dst, &iui->addr1)){
226 iui->bytes1+=pinfo->fd->pkt_len;
229 iui->bytes2+=pinfo->fd->pkt_len;
236 iousers_ipx_packet(io_users_t *iu, packet_info *pinfo, epan_dissect_t *edt _U_, void *vipx)
239 address *addr1, *addr2;
240 io_users_item_t *iui;
242 if(CMP_ADDRESS(&ipxh->ipx_src, &ipxh->ipx_dst)>0){
243 addr1=&ipxh->ipx_src;
244 addr2=&ipxh->ipx_dst;
246 addr2=&ipxh->ipx_src;
247 addr1=&ipxh->ipx_dst;
250 for(iui=iu->items;iui;iui=iui->next){
251 if((!CMP_ADDRESS(&iui->addr1, addr1))
252 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
258 iui=g_malloc(sizeof(io_users_item_t));
261 COPY_ADDRESS(&iui->addr1, addr1);
262 iui->name1=strdup(address_to_str(addr1));
263 COPY_ADDRESS(&iui->addr2, addr2);
264 iui->name2=strdup(address_to_str(addr2));
271 if(!CMP_ADDRESS(&ipxh->ipx_dst, &iui->addr1)){
273 iui->bytes1+=pinfo->fd->pkt_len;
276 iui->bytes2+=pinfo->fd->pkt_len;
283 iousers_fc_packet(io_users_t *iu, packet_info *pinfo, epan_dissect_t *edt _U_, void *vfc)
286 address *addr1, *addr2;
287 io_users_item_t *iui;
289 if(CMP_ADDRESS(&fchdr->s_id, &fchdr->d_id)<0){
297 for(iui=iu->items;iui;iui=iui->next){
298 if((!CMP_ADDRESS(&iui->addr1, addr1))
299 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
305 iui=g_malloc(sizeof(io_users_item_t));
308 COPY_ADDRESS(&iui->addr1, addr1);
309 iui->name1=strdup(address_to_str(addr1));
310 COPY_ADDRESS(&iui->addr2, addr2);
311 iui->name2=strdup(address_to_str(addr2));
318 if(!CMP_ADDRESS(&fchdr->d_id,&iui->addr1)){
320 iui->bytes1+=pinfo->fd->pkt_len;
323 iui->bytes2+=pinfo->fd->pkt_len;
330 iousers_eth_packet(io_users_t *iu, packet_info *pinfo, epan_dissect_t *edt _U_, void *veth)
333 address *addr1, *addr2;
334 io_users_item_t *iui;
336 if(CMP_ADDRESS(&ehdr->src, &ehdr->dst)<0){
344 for(iui=iu->items;iui;iui=iui->next){
345 if((!CMP_ADDRESS(&iui->addr1, addr1))
346 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
352 iui=g_malloc(sizeof(io_users_item_t));
355 COPY_ADDRESS(&iui->addr1, addr1);
356 iui->name1=strdup(address_to_str(addr1));
357 COPY_ADDRESS(&iui->addr2, addr2);
358 iui->name2=strdup(address_to_str(addr2));
365 if(!CMP_ADDRESS(&ehdr->dst,&iui->addr1)){
367 iui->bytes1+=pinfo->fd->pkt_len;
370 iui->bytes2+=pinfo->fd->pkt_len;
377 iousers_fddi_packet(io_users_t *iu, packet_info *pinfo, epan_dissect_t *edt _U_, void *veth)
380 address *addr1, *addr2;
381 io_users_item_t *iui;
383 if(CMP_ADDRESS(&ehdr->src, &ehdr->dst)<0){
391 for(iui=iu->items;iui;iui=iui->next){
392 if((!CMP_ADDRESS(&iui->addr1, addr1))
393 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
399 iui=g_malloc(sizeof(io_users_item_t));
402 COPY_ADDRESS(&iui->addr1, addr1);
403 iui->name1=strdup(address_to_str(addr1));
404 COPY_ADDRESS(&iui->addr2, addr2);
405 iui->name2=strdup(address_to_str(addr2));
412 if(!CMP_ADDRESS(&ehdr->dst,&iui->addr1)){
414 iui->bytes1+=pinfo->fd->pkt_len;
417 iui->bytes2+=pinfo->fd->pkt_len;
424 iousers_tr_packet(io_users_t *iu, packet_info *pinfo, epan_dissect_t *edt _U_, void *vtr)
427 address *addr1, *addr2;
428 io_users_item_t *iui;
430 if(CMP_ADDRESS(&trhdr->src, &trhdr->dst)<0){
438 for(iui=iu->items;iui;iui=iui->next){
439 if((!CMP_ADDRESS(&iui->addr1, addr1))
440 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
446 iui=g_malloc(sizeof(io_users_item_t));
449 COPY_ADDRESS(&iui->addr1, addr1);
450 iui->name1=strdup(address_to_str(addr1));
451 COPY_ADDRESS(&iui->addr2, addr2);
452 iui->name2=strdup(address_to_str(addr2));
459 if(!CMP_ADDRESS(&trhdr->dst,&iui->addr1)){
461 iui->bytes1+=pinfo->fd->pkt_len;
464 iui->bytes2+=pinfo->fd->pkt_len;
471 iousers_draw(io_users_t *iu)
473 io_users_item_t *iui;
474 guint32 last_frames, max_frames;
476 printf("================================================================================\n");
477 printf("%s Conversations\n",iu->type);
478 printf("Filter:%s\n",iu->filter?iu->filter:"<No Filter>");
479 printf(" | <- | | -> | | Total |\n");
480 printf(" | Frames Bytes | | Frames Bytes | | Frames Bytes |\n");
481 max_frames=0xffffffff;
484 for(iui=iu->items;iui;iui=iui->next){
486 tot_frames=iui->frames1+iui->frames2;
488 if((tot_frames>last_frames)
489 &&(tot_frames<max_frames)){
490 last_frames=tot_frames;
493 for(iui=iu->items;iui;iui=iui->next){
495 tot_frames=iui->frames1+iui->frames2;
497 if(tot_frames==last_frames){
498 printf("%-20s <-> %-20s %6d %9d %6d %9d %6d %9d\n",
499 iui->name1, iui->name2,
500 iui->frames1, iui->bytes1,
501 iui->frames2, iui->bytes2,
502 iui->frames1+iui->frames2,
503 iui->bytes1+iui->bytes2
507 max_frames=last_frames;
508 } while(last_frames);
509 printf("================================================================================\n");
513 iousers_init(char *optarg)
516 char *tap_type, *tap_type_name;
517 static int (*packet_func)(io_users_t *, packet_info *, epan_dissect_t *, void *);
519 GString *error_string;
521 if(!strncmp(optarg,"conv,eth",8)){
528 tap_type_name="Ethernet";
529 packet_func=iousers_eth_packet;
530 } else if(!strncmp(optarg,"conv,fc",7)){
537 tap_type_name="Fibre Channel";
538 packet_func=iousers_fc_packet;
539 } else if(!strncmp(optarg,"conv,fddi",9)){
546 tap_type_name="FDDI";
547 packet_func=iousers_fddi_packet;
548 } else if(!strncmp(optarg,"conv,tcp",8)){
556 packet_func=iousers_tcpip_packet;
557 } else if(!strncmp(optarg,"conv,udp",8)){
565 packet_func=iousers_udpip_packet;
566 } else if(!strncmp(optarg,"conv,tr",7)){
573 tap_type_name="Token Ring";
574 packet_func=iousers_tr_packet;
575 } else if(!strncmp(optarg,"conv,ipx",8)){
583 packet_func=iousers_ipx_packet;
584 } else if(!strncmp(optarg,"conv,ip",7)){
591 tap_type_name="IPv4";
592 packet_func=iousers_ip_packet;
594 fprintf(stderr, "tethereal: invalid \"-z conv,<type>[,<filter>]\" argument\n");
595 fprintf(stderr," <type> must be one of\n");
596 fprintf(stderr," \"eth\"\n");
597 fprintf(stderr," \"fc\"\n");
598 fprintf(stderr," \"fddi\"\n");
599 fprintf(stderr," \"ip\"\n");
600 fprintf(stderr," \"ipx\"\n");
601 fprintf(stderr," \"tcp\"\n");
602 fprintf(stderr," \"tr\"\n");
603 fprintf(stderr," \"udp\"\n");
608 iu=g_malloc(sizeof(io_users_t));
610 iu->type=tap_type_name;
612 iu->filter=strdup(filter);
617 error_string=register_tap_listener(tap_type, iu, filter, NULL, (void*)packet_func, (void*)iousers_draw);
623 fprintf(stderr, "tethereal: Couldn't register conversations tap: %s\n",
625 g_string_free(error_string, TRUE);
632 register_tap_listener_iousers(void)
634 register_ethereal_tap("conv,", iousers_init);