* Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino, CACE Technologies * nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */
#include <stdio.h>
#include "pcap.h"
#ifndef WIN32 #include <sys/socket.h> #include <netinet/in.h> #else #include <winsock.h> #endif
// Function prototypes void ifprint(pcap_if_t *d); char *iptos(u_long in); char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen); void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
int main() { pcap_if_t *alldevs; pcap_if_t *d; char errbuf[PCAP_ERRBUF_SIZE+1]; char source[PCAP_ERRBUF_SIZE+1] = {'0'}; int inum; int i = 0; // Winpcap Test 05 struct pcap_pkthdr *header; int res; struct tm ltime; char timestr[16]; const u_char *pkt_data; time_t local_tv_sec;
pcap_t *adhandle;
if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -1) { fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf); exit(1); }
/* Scan the list printing every entry */ for(d=alldevs;d;d=d->next) { ifprint(d); i++; }
printf("Enter the interface number (1-%d):",i); scanf_s("%d", &inum);
if(inum < 1 || inum > i) { printf("\nInterface number out of range.\n"); /* Free the device list */ pcap_freealldevs(alldevs); return -1; }
/* Jump to the selected adapter */ for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
/* Open the device */ if ( (adhandle= pcap_open(d->name, // name of the device 65536, // portion of the packet to capture // 65536 guarantees that the whole packet will be captured on all the link layers PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode 1000, // read timeout NULL, // authentication on the remote machine errbuf // error buffer ) ) == NULL) { fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name); /* Free the device list */ pcap_freealldevs(alldevs); return -1; }
printf("\nlistening on %s...\n", d->description);
/* At this point, we don't need any more the device list. Free it */ pcap_freealldevs(alldevs); // Winpcap Test 05 /* Retrieve the packets */ while((res = pcap_next_ex( adhandle, &header, &pkt_data)) >= 0){ if(res == 0) /* Timeout elapsed */ continue; /* convert the timestamp to readable format */ local_tv_sec = header->ts.tv_sec; localtime_s(<ime, &local_tv_sec); strftime( timestr, sizeof timestr, "%H:%M:%S", <ime); printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len); } if(res == -1){ printf("Error reading the packets: %s\n", pcap_geterr(adhandle)); return -1; }
return 1; }
/* Print all the available information on the given interface */ void ifprint(pcap_if_t *d) { pcap_addr_t *a; char ip6str[128];
/* Name */ printf("\tName: %s\n",d->name);
/* Description */ if (d->description) printf("\tDescription: %s\n",d->description);
/* Loopback Address*/ printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");
/* IP addresses */ for(a=d->addresses;a;a=a->next) { if(a->addr->sa_family != AF_INET) continue;
printf("\tAddress Family Name: AF_INET\n"); if (a->addr) printf("\tAddress: %s\n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr)); if (a->netmask) printf("\tNetmask: %s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr)); if (a->broadaddr) printf("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr)); if (a->dstaddr) printf("\tDestination Address: %s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr)); } printf("\n"); }
/* From tcptraceroute, convert a numeric IP address to a string */ #define IPTOSBUFFERS 12 char *iptos(u_long in) { static char output[IPTOSBUFFERS][3*4+3+1]; static short which; u_char *p;
p = (u_char *)∈ which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1); _snprintf_s(output[which], sizeof(output[which]), sizeof(output[which]),"%d.%d.%d.%d", p[0], p[1], p[2], p[3]); return output[which]; }
char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen) { socklen_t sockaddrlen;
#ifdef WIN32 sockaddrlen = sizeof(struct sockaddr_in6); #else sockaddrlen = sizeof(struct sockaddr_storage); #endif
if(getnameinfo(sockaddr, sockaddrlen, address, addrlen, NULL, 0, NI_NUMERICHOST) != 0) address = NULL;
return address; }
/* Callback function invoked by libpcap for every incoming packet */ void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) { struct tm ltime; char timestr[16]; time_t local_tv_sec;
/* * unused variables */ (VOID)(param); (VOID)(pkt_data);
/* convert the timestamp to readable format */ local_tv_sec = header->ts.tv_sec; localtime_s(<ime, &local_tv_sec); strftime( timestr, sizeof timestr, "%H:%M:%S", <ime);
printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
} |