Wireshark-dev: [Wireshark-dev] Wireshark multiview feature demo
From: Mikael Wikström <leakim.wikstrom@xxxxxxxxx>
Date: Thu, 17 May 2012 11:56:20 +0200
Hi, first of all I thank you all for a great piece of software. I'd like to suggest a feature that would make wireshark even more useful, so I thought I would describe it and see if any one else would find it interesting. The basic concept is to be able to view a pcap file in multiple windows and have them track each other. Or more accurately have one track the second one. If I then used display filters in window1 and select a packet, window2 will move to that same packet and by doing so one can easily see the packets close to it. I find this feature very useful when debugging 802.11 traffic as I often want to check ACK frames and timing related to beacons frames, if there are retransmissions and such. So I made a demo of the feature just to show how it would work. I wrote this code as a demo only so no need to point out all the security flaws it has and how it will impact performance. I would be very interested in starting a discussion around this to see in what way it could be improved. I also made a very short screen cast of the demo that perhaps makes it easier to understand what I'm talking about. You can find it here http://www.youtube.com/watch?v=uYyELO8tdto What I did was to make it so that window1 listens on a port and can be controlled from a CLI interface on that port. The only implemented command so far is "goto 2" meaning goto frame number 2. Window2 will then send commands to window1 using that port and tell it to move to the same frame. demo code is in attachment. My experience with GTK is very limited so my choice of using pthreads was simply because it got the job done. Perhaps someone could suggest a better way of hoking in a CLI/socket interface to wireshark? BR, Mikael Wikstrom Sweden
#undef ntohs #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> static int is_cli_master = 0; static int is_cli_slave = 0; static int cli_port = 1100; void jump_to_frame(unsigned int num); int cli_build_sock(struct sockaddr_in *stSockAddr) { int s; memset(stSockAddr, 0, sizeof(*stSockAddr)); stSockAddr->sin_family = AF_INET; stSockAddr->sin_port = htons(cli_port); #if 0 stSockAddr.sin_addr.s_addr = INADDR_ANY; #else s = inet_pton(AF_INET, "127.0.0.1", &stSockAddr->sin_addr); if (0 > s) { perror("error: first parameter is not a valid address family"); return __LINE__; } else if (0 == s) { perror("char string (second parameter does not contain valid ipaddress)"); return __LINE__; } #endif return 0; } static int is_server(int SocketFD, struct sockaddr_in stSockAddr) { if(-1 == bind(SocketFD,(struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) { perror("error bind failed"); return 0; } if(-1 == listen(SocketFD, 10)) { perror("error listen failed"); return 0; } return 1; } void tell_slave(int row) { struct sockaddr_in stSockAddr; int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); int s; char buf[64]; if(is_cli_master) return; printf("%s %d\n", __func__, row); if(-1 == SocketFD) { perror("can not create socket"); return; } s = cli_build_sock(&stSockAddr); if (s != 0) { close(SocketFD); exit(EXIT_FAILURE); } if(is_cli_slave == 0) { if(is_server(SocketFD, stSockAddr)) { printf("we are able to open the listen port so this must be the master, do nothing\n"); close(SocketFD); return; } printf("unable to open listen port so this must be the slave\n"); is_cli_slave = 1; } if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) { perror("connect failed"); close(SocketFD); //exit(EXIT_FAILURE); return; } s = snprintf(buf,sizeof(buf), "goto %u", row); s = write(SocketFD, buf, 1+s); shutdown(SocketFD, SHUT_RDWR); close(SocketFD); } int cli_listen(void) { struct sockaddr_in stSockAddr; int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); int s; if(-1 == SocketFD) { perror("can not create socket"); exit(EXIT_FAILURE); } s = cli_build_sock(&stSockAddr); if (s != 0) { close(SocketFD); exit(EXIT_FAILURE); } if(-1 == bind(SocketFD,(struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) { perror("error bind failed"); close(SocketFD); //exit(EXIT_FAILURE); // may be the master so stop here return 0; } if(-1 == listen(SocketFD, 10)) { perror("error listen failed"); close(SocketFD); //exit(EXIT_FAILURE); // may be the master so stop here //exit(EXIT_FAILURE); return 0; } is_cli_master = 1; printf("slave listening for commands on port %u\n", cli_port); for(;;) { int ConnectFD = accept(SocketFD, NULL, NULL); int num; int r; int s; char buf[128]; if(0 > ConnectFD) { perror("error accept failed"); close(SocketFD); exit(EXIT_FAILURE); } r = read(ConnectFD,buf,sizeof(buf)); if(r > 0 && 0 < sizeof(buf) && strnlen(buf, sizeof(buf)) < sizeof(buf)) { s = sscanf(buf, "goto %u", &num); if(s == 1) { printf("[%s] => %u\n", buf, num); jump_to_frame(num); } else { printf("unable to parse %d %d [%s]\n",r, s, buf); } } shutdown(ConnectFD, SHUT_RDWR); close(ConnectFD); } return EXIT_SUCCESS; } #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> #define NUM_THREADS 1 #include <time.h> void *TaskCode(void *argument) { int tid = *((int *) argument); printf("listen on socket in separate thread %u!\n", tid); cli_listen(); printf("thread is terminating %d!\n", tid); return NULL; } void cli_task_start(void) { pthread_t threads[NUM_THREADS]; int thread_args[NUM_THREADS]; int rc, i; /* create all threads */ for (i=0; i<NUM_THREADS; ++i) { thread_args[i] = i; //printf("In main: creating thread %d\n", i); rc = pthread_create(&threads[i], NULL, TaskCode, (void *) &thread_args[i]); assert(0 == rc); } }
Attachment:
wireshark-multiview.diff
Description: Binary data
- Prev by Date: [Wireshark-dev] Crash in airpcap_ui_dlg.c
- Next by Date: [Wireshark-dev] privilege separation
- Previous by thread: [Wireshark-dev] Crash in airpcap_ui_dlg.c
- Next by thread: [Wireshark-dev] privilege separation
- Index(es):