* 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
// Winpcap Test 07 /* 4 bytes IP address */ typedef struct ip_address{ u_char byte1; u_char byte2; u_char byte3; u_char byte4; }ip_address;
/* IPv4 header */ typedef struct ip_header{ u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits) u_char tos; // Type of service u_short tlen; // Total length u_short identification; // Identification u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits) u_char ttl; // Time to live u_char proto; // Protocol u_short crc; // Header checksum ip_address saddr; // Source address ip_address daddr; // Destination address u_int op_pad; // Option + Padding }ip_header;
/* UDP header*/ typedef struct udp_header{ u_short sport; // Source port u_short dport; // Destination port u_short len; // Datagram length u_short crc; // Checksum }udp_header;
// 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);
// Winpcap Test 09 void usage(); void dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *);
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; // Winpcap Test 07 u_int netmask; char packet_filter[] = "ip and udp"; struct bpf_program fcode; // Winpcap Test 08 pcap_dumper_t *dumpfile ; // Winpcap Test 09 struct timeval st_ts;
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; }
// Winpcap Test 07 /* Check the link layer. We support only Ethernet for simplicity. */ if(pcap_datalink(adhandle) != DLT_EN10MB) { fprintf(stderr,"\nThis program works only on Ethernet networks.\n"); /* Free the device list */ pcap_freealldevs(alldevs); return -1; } if(d->addresses != NULL) /* Retrieve the mask of the first address of the interface */ netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr; else /* If the interface is without addresses we suppose to be in a C class network */ netmask=0xffffff;
//compile the filter if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 ) { fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n"); /* Free the device list */ pcap_freealldevs(alldevs); return -1; } //set the filter if (pcap_setfilter(adhandle, &fcode)<0) { fprintf(stderr,"\nError setting the filter.\n"); /* Free the device list */ pcap_freealldevs(alldevs); return -1; } /* Put the interface in statstics mode */ if (pcap_setmode(adhandle, MODE_STAT)<0) { fprintf(stderr,"\nError setting the mode.\n"); pcap_close(adhandle); /* Free the device list */ return; }
printf("TCP traffic summary:\n");
/* Start the main loop */ pcap_loop(adhandle, 0, dispatcher_handler, (PUCHAR)&st_ts);
pcap_close(adhandle);
return 0; }
/* 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; }
void dispatcher_handler(u_char *state, const struct pcap_pkthdr *header, const u_char *pkt_data) { struct timeval *old_ts = (struct timeval *)state; u_int delay; LARGE_INTEGER Bps,Pps; struct tm ltime; char timestr[16]; time_t local_tv_sec;
/* Calculate the delay in microseconds from the last sample. */ /* This value is obtained from the timestamp that the associated with the sample. */ delay=(header->ts.tv_sec - old_ts->tv_sec) * 1000000 - old_ts->tv_usec + header->ts.tv_usec; /* Get the number of Bits per second */ Bps.QuadPart=(((*(LONGLONG*)(pkt_data + 8)) * 8 * 1000000) / (delay)); /* ^ ^ | | | | | | converts bytes in bits -- | | delay is expressed in microseconds -- */
/* Get the number of Packets per second */ Pps.QuadPart=(((*(LONGLONG*)(pkt_data)) * 1000000) / (delay));
/* 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);
/* Print timestamp*/ printf("%s ", timestr);
/* Print the samples */ printf("BPS=%I64u ", Bps.QuadPart); printf("PPS=%I64u\n", Pps.QuadPart);
//store current timestamp old_ts->tv_sec=header->ts.tv_sec; old_ts->tv_usec=header->ts.tv_usec; }
void usage() { printf("\nShows the TCP traffic load, in bits per second and packets per second.\nCopyright (C) 2002 Loris Degioanni.\n"); printf("\nUsage:\n"); printf("\t tcptop adapter\n"); printf("\t You can use \"WinDump -D\" if you don't know the name of your adapters.\n");
exit(0); } |