2 * iostat 2003 Ronnie Sahlberg
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/addr_resolv.h>
41 #include <epan/dissectors/packet-ip.h>
42 #include <epan/dissectors/packet-ipx.h>
43 #include <epan/dissectors/packet-tcp.h>
44 #include <epan/dissectors/packet-udp.h>
45 #include <epan/dissectors/packet-eth.h>
46 #include <epan/dissectors/packet-tr.h>
47 #include <epan/dissectors/packet-fc.h>
48 #include <epan/dissectors/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(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vudph)
74 const e_udphdr *udph=vudph;
75 char name1[256],name2[256];
79 if(udph->uh_sport>udph->uh_dport){
81 snprintf(name1,256,"%s:%s",address_to_str(&udph->ip_src),get_udp_port(udph->uh_sport));
82 snprintf(name2,256,"%s:%s",address_to_str(&udph->ip_dst),get_udp_port(udph->uh_dport));
83 } else if(udph->uh_sport<udph->uh_dport){
85 snprintf(name2,256,"%s:%s",address_to_str(&udph->ip_src),get_udp_port(udph->uh_sport));
86 snprintf(name1,256,"%s:%s",address_to_str(&udph->ip_dst),get_udp_port(udph->uh_dport));
87 } else if(CMP_ADDRESS(&udph->ip_src, &udph->ip_dst)>0){
89 snprintf(name1,256,"%s:%s",address_to_str(&udph->ip_src),get_udp_port(udph->uh_sport));
90 snprintf(name2,256,"%s:%s",address_to_str(&udph->ip_dst),get_udp_port(udph->uh_dport));
93 snprintf(name2,256,"%s:%s",address_to_str(&udph->ip_src),get_udp_port(udph->uh_sport));
94 snprintf(name1,256,"%s:%s",address_to_str(&udph->ip_dst),get_udp_port(udph->uh_dport));
97 for(iui=iu->items;iui;iui=iui->next){
98 if((!strcmp(iui->name1, name1))
99 && (!strcmp(iui->name2, name2)) ){
105 iui=g_malloc(sizeof(io_users_item_t));
108 /* iui->addr1=NULL;*/
109 iui->name1=strdup(name1);
110 /* iui->addr2=NULL;*/
111 iui->name2=strdup(name2);
120 iui->bytes1+=pinfo->fd->pkt_len;
123 iui->bytes2+=pinfo->fd->pkt_len;
131 iousers_tcpip_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vtcph)
134 const struct tcpheader *tcph=vtcph;
135 char name1[256],name2[256];
136 io_users_item_t *iui;
139 if(tcph->th_sport>tcph->th_dport){
141 snprintf(name1,256,"%s:%s",address_to_str(&tcph->ip_src),get_tcp_port(tcph->th_sport));
142 snprintf(name2,256,"%s:%s",address_to_str(&tcph->ip_dst),get_tcp_port(tcph->th_dport));
143 } else if(tcph->th_sport<tcph->th_dport){
145 snprintf(name2,256,"%s:%s",address_to_str(&tcph->ip_src),get_tcp_port(tcph->th_sport));
146 snprintf(name1,256,"%s:%s",address_to_str(&tcph->ip_dst),get_tcp_port(tcph->th_dport));
147 } else if(CMP_ADDRESS(&tcph->ip_src, &tcph->ip_dst)>0){
149 snprintf(name1,256,"%s:%s",address_to_str(&tcph->ip_src),get_tcp_port(tcph->th_sport));
150 snprintf(name2,256,"%s:%s",address_to_str(&tcph->ip_dst),get_tcp_port(tcph->th_dport));
153 snprintf(name2,256,"%s:%s",address_to_str(&tcph->ip_src),get_tcp_port(tcph->th_sport));
154 snprintf(name1,256,"%s:%s",address_to_str(&tcph->ip_dst),get_tcp_port(tcph->th_dport));
157 for(iui=iu->items;iui;iui=iui->next){
158 if((!strcmp(iui->name1, name1))
159 && (!strcmp(iui->name2, name2)) ){
165 iui=g_malloc(sizeof(io_users_item_t));
168 /* iui->addr1=NULL;*/
169 iui->name1=strdup(name1);
170 /* iui->addr2=NULL;*/
171 iui->name2=strdup(name2);
180 iui->bytes1+=pinfo->fd->pkt_len;
183 iui->bytes2+=pinfo->fd->pkt_len;
191 iousers_ip_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip)
195 const address *addr1, *addr2;
196 io_users_item_t *iui;
198 if(CMP_ADDRESS(&iph->ip_src, &iph->ip_dst)>0){
206 for(iui=iu->items;iui;iui=iui->next){
207 if((!CMP_ADDRESS(&iui->addr1, addr1))
208 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
214 iui=g_malloc(sizeof(io_users_item_t));
217 COPY_ADDRESS(&iui->addr1, addr1);
218 iui->name1=strdup(address_to_str(addr1));
219 COPY_ADDRESS(&iui->addr2, addr2);
220 iui->name2=strdup(address_to_str(addr2));
227 if(!CMP_ADDRESS(&iph->ip_dst, &iui->addr1)){
229 iui->bytes1+=pinfo->fd->pkt_len;
232 iui->bytes2+=pinfo->fd->pkt_len;
239 iousers_ipx_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vipx)
242 const ipxhdr_t *ipxh=vipx;
243 const address *addr1, *addr2;
244 io_users_item_t *iui;
246 if(CMP_ADDRESS(&ipxh->ipx_src, &ipxh->ipx_dst)>0){
247 addr1=&ipxh->ipx_src;
248 addr2=&ipxh->ipx_dst;
250 addr2=&ipxh->ipx_src;
251 addr1=&ipxh->ipx_dst;
254 for(iui=iu->items;iui;iui=iui->next){
255 if((!CMP_ADDRESS(&iui->addr1, addr1))
256 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
262 iui=g_malloc(sizeof(io_users_item_t));
265 COPY_ADDRESS(&iui->addr1, addr1);
266 iui->name1=strdup(address_to_str(addr1));
267 COPY_ADDRESS(&iui->addr2, addr2);
268 iui->name2=strdup(address_to_str(addr2));
275 if(!CMP_ADDRESS(&ipxh->ipx_dst, &iui->addr1)){
277 iui->bytes1+=pinfo->fd->pkt_len;
280 iui->bytes2+=pinfo->fd->pkt_len;
287 iousers_fc_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vfc)
290 const fc_hdr *fchdr=vfc;
291 const address *addr1, *addr2;
292 io_users_item_t *iui;
294 if(CMP_ADDRESS(&fchdr->s_id, &fchdr->d_id)<0){
302 for(iui=iu->items;iui;iui=iui->next){
303 if((!CMP_ADDRESS(&iui->addr1, addr1))
304 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
310 iui=g_malloc(sizeof(io_users_item_t));
313 COPY_ADDRESS(&iui->addr1, addr1);
314 iui->name1=strdup(address_to_str(addr1));
315 COPY_ADDRESS(&iui->addr2, addr2);
316 iui->name2=strdup(address_to_str(addr2));
323 if(!CMP_ADDRESS(&fchdr->d_id,&iui->addr1)){
325 iui->bytes1+=pinfo->fd->pkt_len;
328 iui->bytes2+=pinfo->fd->pkt_len;
335 iousers_eth_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *veth)
338 const eth_hdr *ehdr=veth;
339 const address *addr1, *addr2;
340 io_users_item_t *iui;
342 if(CMP_ADDRESS(&ehdr->src, &ehdr->dst)<0){
350 for(iui=iu->items;iui;iui=iui->next){
351 if((!CMP_ADDRESS(&iui->addr1, addr1))
352 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
358 iui=g_malloc(sizeof(io_users_item_t));
361 COPY_ADDRESS(&iui->addr1, addr1);
362 iui->name1=strdup(address_to_str(addr1));
363 COPY_ADDRESS(&iui->addr2, addr2);
364 iui->name2=strdup(address_to_str(addr2));
371 if(!CMP_ADDRESS(&ehdr->dst,&iui->addr1)){
373 iui->bytes1+=pinfo->fd->pkt_len;
376 iui->bytes2+=pinfo->fd->pkt_len;
383 iousers_fddi_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *veth)
386 const fddi_hdr *ehdr=veth;
387 const address *addr1, *addr2;
388 io_users_item_t *iui;
390 if(CMP_ADDRESS(&ehdr->src, &ehdr->dst)<0){
398 for(iui=iu->items;iui;iui=iui->next){
399 if((!CMP_ADDRESS(&iui->addr1, addr1))
400 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
406 iui=g_malloc(sizeof(io_users_item_t));
409 COPY_ADDRESS(&iui->addr1, addr1);
410 iui->name1=strdup(address_to_str(addr1));
411 COPY_ADDRESS(&iui->addr2, addr2);
412 iui->name2=strdup(address_to_str(addr2));
419 if(!CMP_ADDRESS(&ehdr->dst,&iui->addr1)){
421 iui->bytes1+=pinfo->fd->pkt_len;
424 iui->bytes2+=pinfo->fd->pkt_len;
431 iousers_tr_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vtr)
434 const tr_hdr *trhdr=vtr;
435 const address *addr1, *addr2;
436 io_users_item_t *iui;
438 if(CMP_ADDRESS(&trhdr->src, &trhdr->dst)<0){
446 for(iui=iu->items;iui;iui=iui->next){
447 if((!CMP_ADDRESS(&iui->addr1, addr1))
448 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
454 iui=g_malloc(sizeof(io_users_item_t));
457 COPY_ADDRESS(&iui->addr1, addr1);
458 iui->name1=strdup(address_to_str(addr1));
459 COPY_ADDRESS(&iui->addr2, addr2);
460 iui->name2=strdup(address_to_str(addr2));
467 if(!CMP_ADDRESS(&trhdr->dst,&iui->addr1)){
469 iui->bytes1+=pinfo->fd->pkt_len;
472 iui->bytes2+=pinfo->fd->pkt_len;
479 iousers_draw(void *arg)
481 io_users_t *iu = arg;
482 io_users_item_t *iui;
483 guint32 last_frames, max_frames;
485 printf("================================================================================\n");
486 printf("%s Conversations\n",iu->type);
487 printf("Filter:%s\n",iu->filter?iu->filter:"<No Filter>");
488 printf(" | <- | | -> | | Total |\n");
489 printf(" | Frames Bytes | | Frames Bytes | | Frames Bytes |\n");
490 max_frames=0xffffffff;
493 for(iui=iu->items;iui;iui=iui->next){
495 tot_frames=iui->frames1+iui->frames2;
497 if((tot_frames>last_frames)
498 &&(tot_frames<max_frames)){
499 last_frames=tot_frames;
502 for(iui=iu->items;iui;iui=iui->next){
504 tot_frames=iui->frames1+iui->frames2;
506 if(tot_frames==last_frames){
507 printf("%-20s <-> %-20s %6d %9d %6d %9d %6d %9d\n",
508 iui->name1, iui->name2,
509 iui->frames1, iui->bytes1,
510 iui->frames2, iui->bytes2,
511 iui->frames1+iui->frames2,
512 iui->bytes1+iui->bytes2
516 max_frames=last_frames;
517 } while(last_frames);
518 printf("================================================================================\n");
522 iousers_init(char *optarg)
525 char *tap_type, *tap_type_name;
526 tap_packet_cb packet_func;
528 GString *error_string;
530 if(!strncmp(optarg,"conv,eth",8)){
537 tap_type_name="Ethernet";
538 packet_func=iousers_eth_packet;
539 } else if(!strncmp(optarg,"conv,fc",7)){
546 tap_type_name="Fibre Channel";
547 packet_func=iousers_fc_packet;
548 } else if(!strncmp(optarg,"conv,fddi",9)){
555 tap_type_name="FDDI";
556 packet_func=iousers_fddi_packet;
557 } else if(!strncmp(optarg,"conv,tcp",8)){
565 packet_func=iousers_tcpip_packet;
566 } else if(!strncmp(optarg,"conv,udp",8)){
574 packet_func=iousers_udpip_packet;
575 } else if(!strncmp(optarg,"conv,tr",7)){
582 tap_type_name="Token Ring";
583 packet_func=iousers_tr_packet;
584 } else if(!strncmp(optarg,"conv,ipx",8)){
592 packet_func=iousers_ipx_packet;
593 } else if(!strncmp(optarg,"conv,ip",7)){
600 tap_type_name="IPv4";
601 packet_func=iousers_ip_packet;
603 fprintf(stderr, "tethereal: invalid \"-z conv,<type>[,<filter>]\" argument\n");
604 fprintf(stderr," <type> must be one of\n");
605 fprintf(stderr," \"eth\"\n");
606 fprintf(stderr," \"fc\"\n");
607 fprintf(stderr," \"fddi\"\n");
608 fprintf(stderr," \"ip\"\n");
609 fprintf(stderr," \"ipx\"\n");
610 fprintf(stderr," \"tcp\"\n");
611 fprintf(stderr," \"tr\"\n");
612 fprintf(stderr," \"udp\"\n");
617 iu=g_malloc(sizeof(io_users_t));
619 iu->type=tap_type_name;
621 iu->filter=strdup(filter);
626 error_string=register_tap_listener(tap_type, iu, filter, NULL, packet_func, iousers_draw);
632 fprintf(stderr, "tethereal: Couldn't register conversations tap: %s\n",
634 g_string_free(error_string, TRUE);
641 register_tap_listener_iousers(void)
643 register_ethereal_tap("conv,", iousers_init);