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/emem.h>
39 #include <epan/addr_resolv.h>
41 #include <epan/stat_cmd_args.h>
43 #include <epan/dissectors/packet-ip.h>
44 #include <epan/dissectors/packet-ipx.h>
45 #include <epan/dissectors/packet-tcp.h>
46 #include <epan/dissectors/packet-udp.h>
47 #include <epan/dissectors/packet-eth.h>
48 #include <epan/dissectors/packet-sctp.h>
49 #include <epan/dissectors/packet-tr.h>
50 #include <epan/dissectors/packet-fc.h>
51 #include <epan/dissectors/packet-fddi.h>
53 typedef struct _io_users_t {
56 struct _io_users_item_t *items;
59 typedef struct _io_users_item_t {
60 struct _io_users_item_t *next;
73 iousers_udpip_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vudph)
76 const e_udphdr *udph=vudph;
77 char name1[256],name2[256];
81 if(udph->uh_sport>udph->uh_dport){
83 g_snprintf(name1,256,"%s:%s",address_to_str(&udph->ip_src),get_udp_port(udph->uh_sport));
84 g_snprintf(name2,256,"%s:%s",address_to_str(&udph->ip_dst),get_udp_port(udph->uh_dport));
85 } else if(udph->uh_sport<udph->uh_dport){
87 g_snprintf(name2,256,"%s:%s",address_to_str(&udph->ip_src),get_udp_port(udph->uh_sport));
88 g_snprintf(name1,256,"%s:%s",address_to_str(&udph->ip_dst),get_udp_port(udph->uh_dport));
89 } else if(CMP_ADDRESS(&udph->ip_src, &udph->ip_dst)>0){
91 g_snprintf(name1,256,"%s:%s",address_to_str(&udph->ip_src),get_udp_port(udph->uh_sport));
92 g_snprintf(name2,256,"%s:%s",address_to_str(&udph->ip_dst),get_udp_port(udph->uh_dport));
95 g_snprintf(name2,256,"%s:%s",address_to_str(&udph->ip_src),get_udp_port(udph->uh_sport));
96 g_snprintf(name1,256,"%s:%s",address_to_str(&udph->ip_dst),get_udp_port(udph->uh_dport));
99 for(iui=iu->items;iui;iui=iui->next){
100 if((!strcmp(iui->name1, name1))
101 && (!strcmp(iui->name2, name2)) ){
107 iui=g_malloc(sizeof(io_users_item_t));
110 /* iui->addr1=NULL;*/
111 iui->name1=strdup(name1);
112 /* iui->addr2=NULL;*/
113 iui->name2=strdup(name2);
122 iui->bytes1+=pinfo->fd->pkt_len;
125 iui->bytes2+=pinfo->fd->pkt_len;
133 iousers_sctp_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vsctp)
136 const struct _sctp_info* sctph = vsctp;
137 char name1[256],name2[256], s_sport[10], s_dport[10];
138 io_users_item_t *iui;
141 g_snprintf(s_sport, sizeof s_sport, "%d",sctph->sport);
142 g_snprintf(s_dport, sizeof s_dport, "%d",sctph->dport);
144 if(sctph->sport > sctph->dport) {
146 g_snprintf(name1,256,"%s:%s",address_to_str(&sctph->ip_src),s_sport);
147 g_snprintf(name2,256,"%s:%s",address_to_str(&sctph->ip_dst),s_dport);
148 } else if(sctph->sport < sctph->dport) {
150 g_snprintf(name1,256,"%s:%s",address_to_str(&sctph->ip_src),s_sport);
151 g_snprintf(name2,256,"%s:%s",address_to_str(&sctph->ip_dst),s_dport);
154 g_snprintf(name1,256,"%s:%s",address_to_str(&sctph->ip_src),s_sport);
155 g_snprintf(name2,256,"%s:%s",address_to_str(&sctph->ip_dst),s_dport);
158 for(iui=iu->items;iui;iui=iui->next){
159 if((!strcmp(iui->name1, name1))
160 && (!strcmp(iui->name2, name2)) ){
166 iui=g_malloc(sizeof(io_users_item_t));
169 /* iui->addr1=NULL;*/
170 iui->name1=strdup(name1);
171 /* iui->addr2=NULL;*/
172 iui->name2=strdup(name2);
181 iui->bytes1+=pinfo->fd->pkt_len;
184 iui->bytes2+=pinfo->fd->pkt_len;
192 iousers_tcpip_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vtcph)
195 const struct tcpheader *tcph=vtcph;
196 char name1[256],name2[256];
197 io_users_item_t *iui;
200 if(tcph->th_sport>tcph->th_dport){
202 g_snprintf(name1,256,"%s:%s",address_to_str(&tcph->ip_src),get_tcp_port(tcph->th_sport));
203 g_snprintf(name2,256,"%s:%s",address_to_str(&tcph->ip_dst),get_tcp_port(tcph->th_dport));
204 } else if(tcph->th_sport<tcph->th_dport){
206 g_snprintf(name2,256,"%s:%s",address_to_str(&tcph->ip_src),get_tcp_port(tcph->th_sport));
207 g_snprintf(name1,256,"%s:%s",address_to_str(&tcph->ip_dst),get_tcp_port(tcph->th_dport));
208 } else if(CMP_ADDRESS(&tcph->ip_src, &tcph->ip_dst)>0){
210 g_snprintf(name1,256,"%s:%s",address_to_str(&tcph->ip_src),get_tcp_port(tcph->th_sport));
211 g_snprintf(name2,256,"%s:%s",address_to_str(&tcph->ip_dst),get_tcp_port(tcph->th_dport));
214 g_snprintf(name2,256,"%s:%s",address_to_str(&tcph->ip_src),get_tcp_port(tcph->th_sport));
215 g_snprintf(name1,256,"%s:%s",address_to_str(&tcph->ip_dst),get_tcp_port(tcph->th_dport));
218 for(iui=iu->items;iui;iui=iui->next){
219 if((!strcmp(iui->name1, name1))
220 && (!strcmp(iui->name2, name2)) ){
226 iui=g_malloc(sizeof(io_users_item_t));
229 /* iui->addr1=NULL;*/
230 iui->name1=strdup(name1);
231 /* iui->addr2=NULL;*/
232 iui->name2=strdup(name2);
241 iui->bytes1+=pinfo->fd->pkt_len;
244 iui->bytes2+=pinfo->fd->pkt_len;
252 iousers_ip_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip)
256 const address *addr1, *addr2;
257 io_users_item_t *iui;
259 if(CMP_ADDRESS(&iph->ip_src, &iph->ip_dst)>0){
267 for(iui=iu->items;iui;iui=iui->next){
268 if((!CMP_ADDRESS(&iui->addr1, addr1))
269 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
275 iui=g_malloc(sizeof(io_users_item_t));
278 COPY_ADDRESS(&iui->addr1, addr1);
279 iui->name1=strdup(address_to_str(addr1));
280 COPY_ADDRESS(&iui->addr2, addr2);
281 iui->name2=strdup(address_to_str(addr2));
288 if(!CMP_ADDRESS(&iph->ip_dst, &iui->addr1)){
290 iui->bytes1+=pinfo->fd->pkt_len;
293 iui->bytes2+=pinfo->fd->pkt_len;
300 iousers_ipx_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vipx)
303 const ipxhdr_t *ipxh=vipx;
304 const address *addr1, *addr2;
305 io_users_item_t *iui;
307 if(CMP_ADDRESS(&ipxh->ipx_src, &ipxh->ipx_dst)>0){
308 addr1=&ipxh->ipx_src;
309 addr2=&ipxh->ipx_dst;
311 addr2=&ipxh->ipx_src;
312 addr1=&ipxh->ipx_dst;
315 for(iui=iu->items;iui;iui=iui->next){
316 if((!CMP_ADDRESS(&iui->addr1, addr1))
317 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
323 iui=g_malloc(sizeof(io_users_item_t));
326 COPY_ADDRESS(&iui->addr1, addr1);
327 iui->name1=strdup(address_to_str(addr1));
328 COPY_ADDRESS(&iui->addr2, addr2);
329 iui->name2=strdup(address_to_str(addr2));
336 if(!CMP_ADDRESS(&ipxh->ipx_dst, &iui->addr1)){
338 iui->bytes1+=pinfo->fd->pkt_len;
341 iui->bytes2+=pinfo->fd->pkt_len;
348 iousers_fc_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vfc)
351 const fc_hdr *fchdr=vfc;
352 const address *addr1, *addr2;
353 io_users_item_t *iui;
355 if(CMP_ADDRESS(&fchdr->s_id, &fchdr->d_id)<0){
363 for(iui=iu->items;iui;iui=iui->next){
364 if((!CMP_ADDRESS(&iui->addr1, addr1))
365 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
371 iui=g_malloc(sizeof(io_users_item_t));
374 COPY_ADDRESS(&iui->addr1, addr1);
375 iui->name1=strdup(address_to_str(addr1));
376 COPY_ADDRESS(&iui->addr2, addr2);
377 iui->name2=strdup(address_to_str(addr2));
384 if(!CMP_ADDRESS(&fchdr->d_id,&iui->addr1)){
386 iui->bytes1+=pinfo->fd->pkt_len;
389 iui->bytes2+=pinfo->fd->pkt_len;
396 iousers_eth_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *veth)
399 const eth_hdr *ehdr=veth;
400 const address *addr1, *addr2;
401 io_users_item_t *iui;
403 if(CMP_ADDRESS(&ehdr->src, &ehdr->dst)<0){
411 for(iui=iu->items;iui;iui=iui->next){
412 if((!CMP_ADDRESS(&iui->addr1, addr1))
413 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
419 iui=g_malloc(sizeof(io_users_item_t));
422 COPY_ADDRESS(&iui->addr1, addr1);
423 iui->name1=strdup(address_to_str(addr1));
424 COPY_ADDRESS(&iui->addr2, addr2);
425 iui->name2=strdup(address_to_str(addr2));
432 if(!CMP_ADDRESS(&ehdr->dst,&iui->addr1)){
434 iui->bytes1+=pinfo->fd->pkt_len;
437 iui->bytes2+=pinfo->fd->pkt_len;
444 iousers_fddi_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *veth)
447 const fddi_hdr *ehdr=veth;
448 const address *addr1, *addr2;
449 io_users_item_t *iui;
451 if(CMP_ADDRESS(&ehdr->src, &ehdr->dst)<0){
459 for(iui=iu->items;iui;iui=iui->next){
460 if((!CMP_ADDRESS(&iui->addr1, addr1))
461 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
467 iui=g_malloc(sizeof(io_users_item_t));
470 COPY_ADDRESS(&iui->addr1, addr1);
471 iui->name1=strdup(address_to_str(addr1));
472 COPY_ADDRESS(&iui->addr2, addr2);
473 iui->name2=strdup(address_to_str(addr2));
480 if(!CMP_ADDRESS(&ehdr->dst,&iui->addr1)){
482 iui->bytes1+=pinfo->fd->pkt_len;
485 iui->bytes2+=pinfo->fd->pkt_len;
492 iousers_tr_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vtr)
495 const tr_hdr *trhdr=vtr;
496 const address *addr1, *addr2;
497 io_users_item_t *iui;
499 if(CMP_ADDRESS(&trhdr->src, &trhdr->dst)<0){
507 for(iui=iu->items;iui;iui=iui->next){
508 if((!CMP_ADDRESS(&iui->addr1, addr1))
509 &&(!CMP_ADDRESS(&iui->addr2, addr2)) ){
515 iui=g_malloc(sizeof(io_users_item_t));
518 COPY_ADDRESS(&iui->addr1, addr1);
519 iui->name1=strdup(address_to_str(addr1));
520 COPY_ADDRESS(&iui->addr2, addr2);
521 iui->name2=strdup(address_to_str(addr2));
528 if(!CMP_ADDRESS(&trhdr->dst,&iui->addr1)){
530 iui->bytes1+=pinfo->fd->pkt_len;
533 iui->bytes2+=pinfo->fd->pkt_len;
540 iousers_draw(void *arg)
542 io_users_t *iu = arg;
543 io_users_item_t *iui;
544 guint32 last_frames, max_frames;
546 printf("================================================================================\n");
547 printf("%s Conversations\n",iu->type);
548 printf("Filter:%s\n",iu->filter?iu->filter:"<No Filter>");
549 printf(" | <- | | -> | | Total |\n");
550 printf(" | Frames Bytes | | Frames Bytes | | Frames Bytes |\n");
551 max_frames=0xffffffff;
554 for(iui=iu->items;iui;iui=iui->next){
556 tot_frames=iui->frames1+iui->frames2;
558 if((tot_frames>last_frames)
559 &&(tot_frames<max_frames)){
560 last_frames=tot_frames;
563 for(iui=iu->items;iui;iui=iui->next){
565 tot_frames=iui->frames1+iui->frames2;
567 if(tot_frames==last_frames){
568 printf("%-20s <-> %-20s %6d %9d %6d %9d %6d %9d\n",
569 iui->name1, iui->name2,
570 iui->frames1, iui->bytes1,
571 iui->frames2, iui->bytes2,
572 iui->frames1+iui->frames2,
573 iui->bytes1+iui->bytes2
577 max_frames=last_frames;
578 } while(last_frames);
579 printf("================================================================================\n");
583 iousers_init(const char *optarg, void* userdata _U_)
585 const char *filter=NULL;
586 const char *tap_type, *tap_type_name;
587 tap_packet_cb packet_func;
589 GString *error_string;
591 if(!strncmp(optarg,"conv,eth",8)){
598 tap_type_name="Ethernet";
599 packet_func=iousers_eth_packet;
600 } else if(!strncmp(optarg,"conv,fc",7)){
607 tap_type_name="Fibre Channel";
608 packet_func=iousers_fc_packet;
609 } else if(!strncmp(optarg,"conv,fddi",9)){
616 tap_type_name="FDDI";
617 packet_func=iousers_fddi_packet;
618 } else if(!strncmp(optarg,"conv,tcp",8)){
626 packet_func=iousers_tcpip_packet;
627 } else if(!strncmp(optarg,"conv,udp",8)){
635 packet_func=iousers_udpip_packet;
636 } else if(!strncmp(optarg,"conv,tr",7)){
643 tap_type_name="Token Ring";
644 packet_func=iousers_tr_packet;
645 } else if(!strncmp(optarg,"conv,ipx",8)){
653 packet_func=iousers_ipx_packet;
654 } else if(!strncmp(optarg,"conv,ip",7)){
661 tap_type_name="IPv4";
662 packet_func=iousers_ip_packet;
663 } else if(!strncmp(optarg,"conv,sctp",9)) {
670 tap_type_name="SCTP";
671 packet_func=iousers_sctp_packet;
673 fprintf(stderr, "tethereal: invalid \"-z conv,<type>[,<filter>]\" argument\n");
674 fprintf(stderr," <type> must be one of\n");
675 fprintf(stderr," \"eth\"\n");
676 fprintf(stderr," \"fc\"\n");
677 fprintf(stderr," \"fddi\"\n");
678 fprintf(stderr," \"ip\"\n");
679 fprintf(stderr," \"ipx\"\n");
680 fprintf(stderr," \"sctp\"\n");
681 fprintf(stderr," \"tcp\"\n");
682 fprintf(stderr," \"tr\"\n");
683 fprintf(stderr," \"udp\"\n");
688 iu=g_malloc(sizeof(io_users_t));
690 iu->type=tap_type_name;
692 iu->filter=strdup(filter);
697 error_string=register_tap_listener(tap_type, iu, filter, NULL, packet_func, iousers_draw);
703 fprintf(stderr, "tethereal: Couldn't register conversations tap: %s\n",
705 g_string_free(error_string, TRUE);
712 register_tap_listener_iousers(void)
714 register_stat_cmd_arg("conv,", iousers_init, NULL);