#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <asm/types.h>
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
/* see linux/if_ether.h */
// Octets in one ethernet addr
#define ETH_MAC_LEN ETH_ALEN
// Total octets in header.
#define ETH_HEADER_LEN ETH_HLEN
// Min. octets in frame without FCS
#define ETH_MIN_FRAME_LEN ETH_ZLEN
// Max. octets in payload
#define ETH_USER_DATA_LEN ETH_DATA_LEN
// Max. octets in frame without FCS
#define ETH_MAX_FRAME_LEN ETH_FRAME_LEN
// Header: 14 + User Data: 1500 + FCS: 4
#define ETH_FRAME_TOTALLEN 1518
/* we are running without any protocol above the Ethernet Layer*/
#define ETH_P_NULL 0x0
struct timeval tv;
struct timezone tz;
char DEVICE[255];
double wallclocktime(){
static int startflag=1;
static double tsecs0, tsecs1, dt;
(void) gettimeofday(&tv,&tz);
tsecs1 = tv.tv_sec + tv.tv_usec*1.0e-6;
return tsecs1;
}
int ifindex (int socket) {
struct ifreq ifr;
int ifindex;
strncpy(ifr.ifr_name, DEVICE, IFNAMSIZ);
if (ioctl(socket, SIOCGIFINDEX, &ifr) == -1) {
perror("SIOCGIFINDEX");
exit(1);
}
ifindex = ifr.ifr_ifindex;
printf("index interface: %i\n", ifindex);
return ifindex;
}
int main (int argc, char **argv) {
int s = 0; // socket descriptor
int i, sent, length,j;
int *counter;
double start,stop,timetot;
double bandwith,bandwithbit;
double nbytetot;
int size,times;
struct sockaddr_ll socket_address;
unsigned char src_mac[8];
unsigned char dst_mac[8];
unsigned char * buffer = (unsigned char *) malloc (ETH_FRAME_LEN);
unsigned char * tmp = (unsigned char *) malloc (ETH_FRAME_LEN);
if(argc!=16){
printf("Usare: %s [Size] [Times] [MAC SRC]
[MAC DST] [Local Device]\n",argv[0]);
exit(-1);
}
strcpy(DEVICE,argv[15]);
for(i=0;i<6;i++){
src_mac[i]=(unsigned char)strtol(argv[i+3], (char **)NULL, 16);
dst_mac[i]=(unsigned char)strtol(argv[i+9], (char **)NULL, 16);
}
src_mac[6]=src_mac[7]=dst_mac[6]=dst_mac[7]=0x00;
size=atoi(argv[1]);
times=atoi(argv[2]);
for(i=0;i<ETH_FRAME_LEN;i++)
buffer[i]=0x00;
/* open socket */
if ( (s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1 ) {
perror("socket():");
exit(1);
}
printf("opened socket: %i\n", s);
/* questa struttura descrive il tipo di socket che si vuole usare */
socket_address.sll_family = PF_PACKET;
socket_address.sll_protocol = htons(ETH_P_IP);
socket_address.sll_ifindex = ifindex(s);
socket_address.sll_hatype = ARPHRD_ETHER;
socket_address.sll_pkttype = PACKET_OTHERHOST;
socket_address.sll_halen = ETH_ALEN;
for (i = 0; i < 8; i++)
socket_address.sll_addr[i] = dst_mac[i]; // Physical layer address
j=k=0;
for(;;) {
length=recvfrom(s, buffer, 14+size, 0, NULL, NULL);
if(length==-1){
perror("recvfrom():");
exit(1);
}
if( ( (*(buffer+ETH_MAC_LEN+5)) == dst_mac[5]) &&
(*(buffer+5)==src_mac[5]) ){
counter=buffer+ETH_HEADER_LEN;
if(*counter==0) start=wallclocktime();
times++;
if( (*counter!=0) && (*counter-prevcount>1) ) {
lost+=(*counter-prevcount);
}
prevcount=*counter;
if(*counter==0xffffffff){
times-=1;
stop=wallclocktime();
timetot=(stop-start);
nbytetot=(double)((ETH_HEADER_LEN+size)*times);
bandwithbit=((nbytetot*8)/(1024.0*1024.0*timetot));
bandwith=(nbytetot/timetot);
fprintf(stderr,"packsize: %d byte, ",size);
fprintf(stderr,"timetot: %f sec, ",timetot);
fprintf(stderr,"nbytetot: %.3fbyte, ",nbytetot);
fprintf(stderr,"bw: %.3f Mbyte/sec, ",bandwith/(1024.0*1024.0));
fprintf(stderr,"bw: %.3f Mbit/sec, ",bandwithbit);
fprintf(stderr,"lost: %d, ",lost);
fprintf(stderr,"ping: %d\n",times);
lost=times=0;
}
}
}