1 // http://www.phj.hu/freesoft.asp
13 char name[16]; /* name (e.g. eth0) */
15 int reset; /* do we have to reset it on exit ? */
16 struct ifreq oldifr; /* old settings */
18 struct promisc_device *next;
23 DWORD dwIoControlCode=SIO_RCVALL;
24 DWORD dwProtocol=IPPROTO_IP, dwInterface=0;
33 unsigned int uiSourceAddr=0, uiDestAddr=0, uiXAddr=0;
34 unsigned short usSourcePort = 0, usDestPort = 0, usXPort = 0;
35 unsigned short usSourceNet = 32, usDestNet = 32, usXNet = 32;
36 unsigned long ulDestNet=0xffffffff, ulSourceNet=0xffffffff, ulXNet=0xffffffff;
43 int sortbysize,fromip,toip;
46 extern char filename[128];
48 extern char intlist[128];
51 void PrintInterfaceList( void );
52 int GetInterface(SOCKET , SOCKADDR_IN *, int );
54 extern int InitIPAcc( void );
55 extern int CloseIPAcc( void );
65 extern char execname[];
69 int set_raw_mode(void)
71 int fd = STDIN_FILENO;
74 if (tcgetattr(fd, &t) < 0) { perror("tcgetattr"); return -1; }
76 if (tcsetattr(fd, TCSANOW, &t) < 0) { perror("tcsetattr"); return -1; }
83 // Prints usage information.
87 void usage(char *progname)
89 printf(" usage: %s options\n where options:\n", progname);
90 printf(" [-c:sec] Dump cycle in sec (10)\n");
91 printf(" [-f:file[-e:program]] Results into a file [and exec program](-)\n");
92 printf(" [-n:db] Execute just db cycle (0)\n");
93 printf(" [-l:lineno] Print lineno lines of hosts(25)\n");
94 printf(" [-k] Sort result by packet count (size)\n");
95 printf(" [-1] Ignore source IP (don't ignore)\n");
96 printf(" [-2] Ignore destination IP (don't ignore)\n");
97 printf(" [-h] Print just the header(use -a!)\n");
98 printf(" [-a] Print packet info&data (-)\n");
99 printf(" [-p] Print just summary info (-)\n");
100 printf(" Otherwise print sum&ip pairs\n");
102 printf(" [-t:[tcp|udp|icmp|....|number]] Filter on IP protocoll (ALL)\n");
104 printf(" [-g] Make GRE encapsulation trasparent (-)\n");
105 printf(" [-v] Skip VLAN headers (-)\n");
106 printf(" [-sa:IP[/Net]] Filter on source address (-)/net\n");
107 printf(" [-sp:Port] Filter on source port (-)\n");
108 printf(" [-da:IP[/Net]] Filter on dest address/net (-)\n");
109 printf(" [-dp:Port] Filter on dest port(-)\n");
110 printf(" [-xa:IP[/Net]] Filter on src|dest address/net (-)\n");
111 printf(" [-xp:Port] Filter on src|dest port (-)\n");
112 printf(" [-pa:pattern] String match (0), last param!!!\n");
114 printf(" [-i:int] Capture on this interface (0)\n");
115 printf(" Available interfaces:\n");
116 PrintInterfaceList();
118 printf(" [-i:int[,int]] Capture on this interface (eth0)\n");
120 printf(" Filtering rules: t && (sa|da|xa) && (sp|dp|xp)");
121 printf("\nVer. %d.%d (c):2000-2006, P l¢czi-Horv th J nos\n",MAXVER,MINVER);
131 // Function: ValidateArgs
134 // This function parses the command line arguments and
135 // sets global variables to indicate how the app should act.
137 void ValidateArgs(int argc, char **argv)
142 sortbysize=1; fromip=1; toip=1;
144 if (argc <2) { usage(argv[0]); return; }
145 if (*(author+2) != 'j') { usage(argv[0]); return; }
146 for(i=1; i < argc ;i++) {
147 if ((argv[i][0] == '-') || (argv[i][0] == '/')) {
148 switch (tolower(argv[i][1])) {
149 case 't': // traffic type
151 while (*++ptr) *ptr = toupper(*ptr);
153 for ( j=0;j<134;j++) {
154 if (!strcmp(ptr, szProto[j])) {
155 // dwIoControlCode = SIO_RCVALL;
163 if ((j>133) && atoi(&argv[i][3])) {
164 // dwIoControlCode = SIO_RCVALL;
166 dwProtocol = atoi(&argv[i][3]);
168 iProto=atoi(&argv[i][3]);
169 } else if (j>133) usage(argv[0]);
171 case 'i': // interface number
173 dwInterface = atoi(&argv[i][3]);
175 strcpy(intlist,&argv[i][3]);
176 ptr=strchr(intlist,' ');
183 case 'c': // cycle time
184 iCycle = atoi(&argv[i][3]);
186 case 'a': // cycle time
189 case 'h': // cycle time
190 iDetail = justheader = 1;
192 case 'n': // just n cycle
193 lNum = atol(&argv[i][3]);
195 case 'l': // lineno lines
196 iline = atoi(&argv[i][3]);
198 case 'p': // just summary
199 if ((tolower(argv[i][2]) == 'a')) {
200 strcpy(pattern,&argv[i][4]); printf("\n Pattern: \'%s",&argv[i][4]);
201 while (++i<argc) { strcat(pattern," "); strcat(pattern,&argv[i][0]); printf(" %s",argv[i]); }
205 case 'f': // filename to write
206 strcpy(filename,&argv[i][3]);
207 iFile=1; //iScreen=0;
209 case 'e': // execname
210 strcpy(execname,&argv[i][3]);
212 case 'k': // sor by count
215 case '1': // ignore src
218 case '2': // ignore dst
221 case 'v': // sor by count
223 if ((tolower(argv[i][2]) == ':')) {
224 skipvlan=atoi(&argv[i][3]);
227 case 's': // Filter on source ip or port
228 if (tolower(argv[i][2]) == 'a') {
229 ptr=strchr(&argv[i][4],'/');
230 if (ptr) { usSourceNet=atoi(ptr+1); *ptr=0;}
231 uiSourceAddr = ntohl(inet_addr(&argv[i][4]));
232 } else if (tolower(argv[i][2]) == 'p')
233 usSourcePort = (unsigned short)atoi(&argv[i][4]);
238 case 'd': // Filter on dest ip or port
239 if (tolower(argv[i][2]) == 'a') {
240 ptr=strchr(&argv[i][4],'/');
241 if (ptr) { usDestNet=atoi(ptr+1); *ptr=0; }
242 uiDestAddr = ntohl(inet_addr(&argv[i][4]));
243 } else if (tolower(argv[i][2]) == 'p')
244 usDestPort = (unsigned short)atoi(&argv[i][4]);
249 case 'x': // Filter on source or dest ip or port
250 if (tolower(argv[i][2]) == 'a') {
251 ptr=strchr(&argv[i][4],'/');
252 if (ptr) { usXNet=atoi(ptr+1); *ptr=0; }
253 uiXAddr = ntohl(inet_addr(&argv[i][4]));
254 } else if (tolower(argv[i][2]) == 'p')
255 usXPort = (unsigned short)atoi(&argv[i][4]);
263 } else usage(argv[0]);
271 // Function: PrintInterfaceList
274 // This function prints all local IP interfaces.
276 void PrintInterfaceList()
278 SOCKET_ADDRESS_LIST *slist=NULL;
285 s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
286 if (s == SOCKET_ERROR) {
287 printf("socket() failed: %d\n", WSAGetLastError());
290 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buf, 2048,&dwBytesRet, NULL, NULL);
291 if (ret == SOCKET_ERROR){
292 printf("WSAIoctl(SIO_ADDRESS_LIST_QUERY) failed: %d\n",WSAGetLastError());
295 slist = (SOCKET_ADDRESS_LIST *)buf;
296 for(i=0; i < slist->iAddressCount ;i++) {
297 printf(" %-2d ........ [%s]\n", i,
298 inet_ntoa(((SOCKADDR_IN *)slist->Address[i].lpSockaddr)->sin_addr));
305 // Function: GetInterface
308 // This function retrieves a zero based index and returns
309 // the IP interface corresponding to that.
311 int GetInterface(SOCKET s, SOCKADDR_IN *ifx, int num)
313 SOCKET_ADDRESS_LIST *slist=NULL;
318 ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buf, 2048,&dwBytesRet, NULL, NULL);
319 if (ret == SOCKET_ERROR) {
320 printf("WSAIoctl(SIO_ADDRESS_LIST_QUERY) failed: %d\n",WSAGetLastError());
323 slist = (SOCKET_ADDRESS_LIST *)buf;
324 if (num >= slist->iAddressCount) return -1;
325 ifx->sin_addr.s_addr = ((SOCKADDR_IN *)slist->Address[num].lpSockaddr)->sin_addr.s_addr;
326 if (*author != 'p') return -1;
331 struct promisc_device *prom;
333 void init_capture( void )
335 * 1) Open our capture socket
336 * 2) Set all the promisc devices to promiscous mode
340 struct promisc_device *p,*pp;
344 if ((s = socket (AF_INET, SOCK_PACKET, htons (ETH_P_ALL))) < 0)
346 printf(" can't get socket: \n");
349 strcpy(myipname,intlist);
353 p = malloc(sizeof(struct promisc_device));
354 if (pp) pp->next=p; else prom=p;
355 if ( (p2=strchr(p1,','))) *p2++=0;
356 strcpy(&p->name,p1); p->next=NULL;
357 printf(" %s",p->name); fflush(stdout);
360 strcpy (p -> oldifr.ifr_name, p -> name);
362 if (ioctl (s, SIOCGIFFLAGS, &(p -> oldifr)) < 0) {
363 printf(" can't get flags: \n");
368 if (ifr.ifr_flags & IFF_PROMISC) printf(" already promisc! \n");
369 ifr.ifr_flags |= IFF_PROMISC;
370 if (ioctl (s, SIOCSIFFLAGS, &ifr) < 0) {
371 printf(" can't set flags: \n");
378 void exit_capture(void)
380 struct promisc_device *p;
382 /* do we have to check (capture_sd >= 0) ? */
387 if (ioctl (s, SIOCSIFFLAGS, &(p -> oldifr)) < 0) {
388 printf("can't reset flags: \n");
400 int main(int argc, char **argv) {
408 char rcvbuf[MAX_IP_SIZE];
414 if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
415 printf(" WSAStartup() failed: %d\n", GetLastError());
420 struct promisc_device *p;
427 // Parse the command line
429 strcpy(intlist,"eth0");
430 for(i=100;i<255;i++) szProto[i]="?!?";
432 szProto[108]="IPCOMP";
439 ValidateArgs(argc, argv);
442 if ( i || usSourcePort)
443 printf(" Source: %03d.%03d.%03d.%03d/%d:%d\n",(i&0xff000000)>>24,(i&0x00ff0000)>>16,(i&0x0000ff00)>>8,i&0xff,uiSourceAddr?usSourceNet:0, usSourcePort);
445 if ( i || usDestPort)
446 printf(" Dest. : %03d.%03d.%03d.%03d/%d:%d\n",(i&0xff000000)>>24,(i&0x00ff0000)>>16,(i&0x0000ff00)>>8,i&0xff,uiDestAddr?usDestNet:0, usDestPort);
449 printf(" IP. : %03d.%03d.%03d.%03d/%d:%d\n",(i&0xff000000)>>24,(i&0x00ff0000)>>16,(i&0x0000ff00)>>8,i&0xff,uiXAddr?usXNet:0, usXPort);
451 if (iFile) printf(" To file : %s\n",filename);
452 if (iProto) printf(" Protocol: %s (%d)\n",szProto[iProto],iProto);
453 // Create a raw socket for receiving IP datagrams
456 s = WSASocket(AF_INET, SOCK_RAW, dwProtocol, NULL, 0, WSA_FLAG_OVERLAPPED);
457 if (s == INVALID_SOCKET)
459 printf("WSASocket() failed: %d\n", WSAGetLastError());
462 // Get an interface to read IP packets on
464 memset(&if0,0,sizeof(if0));
465 if0.sin_family = AF_INET;
466 if0.sin_port = htons(0);
467 if (GetInterface(s, &if0, dwInterface) != 0)
469 printf("Unable to obtain an interface\n");
472 sprintf(myipname,"%-16s",inet_ntoa(if0.sin_addr));
474 printf("starting capture ...."); fflush(stdout);
476 printf(" capture started ....\n"); fflush(stdout);
478 printf(" Binding to IF: %s\n", myipname);
481 // This socket MUST be bound before calling the ioctl
484 if (bind(s, (SOCKADDR *)&if0, sizeof(if0)) == SOCKET_ERROR) {
485 printf("bind() failed: %d\n", WSAGetLastError());
489 // Set the SIO_RCVALLxxx ioctl
492 if (WSAIoctl(s, dwIoControlCode, &optval, sizeof(optval),
493 NULL, 0, &dwBytesRet, NULL, NULL) == SOCKET_ERROR) {
494 printf("WSAIotcl() set raw socket failed; %d\n", WSAGetLastError());
497 if (WSAIoctl(s, dwIoControlCode, &optval, sizeof(optval),
498 NULL, 0, &dwBytesRet, NULL, NULL) == SOCKET_ERROR) {
499 printf("WSAIotcl() set raw socket only failed; %d\n", WSAGetLastError());
505 tv.tv_sec=0; tv.tv_usec=0;
508 FD_SET(STDIN_FILENO,&ready);
510 input = fopen("/dev/tty", "r"); //open the terminal keyboard
511 if (uiSourceAddr==0) ulSourceNet=0;
512 else for ( i=0; i<32-usSourceNet; i++) ulSourceNet <<= 1;
513 if (uiDestAddr==0) ulDestNet=0;
514 else for ( i=0; i<32-usDestNet; i++) ulDestNet <<= 1;
515 if (uiXAddr==0) ulXNet=0;
516 else for ( i=0; i<32-usXNet; i++) ulXNet <<= 1;
517 if (uiXAddr) uiSourceAddr=uiDestAddr=uiXAddr;
518 if (usXPort) usSourcePort=usDestPort=usXPort;
519 if (ulXNet) ulSourceNet=ulDestNet=ulXNet;
521 // Start receiving IP datagrams until interrupted
524 if (iFile && iDetail) f=fopen(filename,"w+");
525 if (iProto) bFilter=1;
526 if (*(author+1) != 'h') iRun=0;
528 rcvbuf[MAX_IP_SIZE]=0;
529 wbuf.len = MAX_IP_SIZE;
533 ret = WSARecv(s, &wbuf, 1, &dwBytesRet, &dwFlags, NULL, NULL);
534 if (ret == SOCKET_ERROR) {
535 printf("WSARecv() failed: %d\n", WSAGetLastError());
540 dwFlags = sizeof(ssaddr);
542 ret = recvfrom (s, wbuf.buf, MAX_IP_SIZE, 0, &ssaddr, (int *) &dwFlags);
543 if (ret == -1) continue;
544 dwBytesRet=wbuf.len=ret;
547 if (!strcmp(p -> name, ssaddr.sa_data)) break;
551 // printf("\n%s: ignored",ssaddr.sa_data); fflush(stdout);
555 FD_SET(STDIN_FILENO,&ready);
556 if (select(STDIN_FILENO+1,&ready,NULL,NULL,&tv)>0) {
557 // if (FD_ISSET(STDIN_FILENO,&ready)) {
559 switch (getchar()) { /* branch to appropiate key handler */
566 } //end of switch key
569 // Deccode the IP header
571 if (!(nproc = DecodeIPHeader(&wbuf, uiSourceAddr, usSourcePort, ulSourceNet,
572 uiDestAddr, usDestPort, ulDestNet, dwBytesRet,usXPort,uiXAddr,ulXNet)))
574 // printf("Error decoding IP header!\n");
580 if (iRun && !iDetail) CloseIPAcc();