Next: Server
Up: Comunicazione bidirezionale
Previous: Comunicazione bidirezionale
Indice
#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 */
#define ETH_MAC_LEN ETH_ALEN
#define ETH_HEADER_LEN ETH_HLEN
#define ETH_MIN_FRAME_LEN ETH_ZLEN
#define ETH_USER_DATA_LEN ETH_DATA_LEN
#define ETH_MAX_FRAME_LEN ETH_FRAME_LEN
#define ETH_FRAME_TOTALLEN 1518
#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;
return ifindex;
}
int main (int argc, char **argv) {
int s = 0; // socket descriptor
int i, sent, length,j,k=0,temp;
int *counter;
double start,stop,timetot=0;
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!=17){
printf("Usare: %s [Size] [Times] [MAC SRC]
[MAC DST] [Local Device] [K]\n",argv[0]);
exit(-1);
}
strcpy(DEVICE,argv[15]);
k=atoi(argv[16]);
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;
if ( (s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1 ) {
perror("socket():");
exit(1);
}
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];
/* copy dest mac address */
memcpy ( buffer, dst_mac, ETH_MAC_LEN );
/* copy source mac address */
memcpy ( (buffer+ETH_MAC_LEN), src_mac, ETH_MAC_LEN );
/* set ptotocol to NULL */
*(buffer+(2*ETH_MAC_LEN)) = ETH_P_NULL;
/* fill the buffer with random data to trasmit ... */
for (i = 0; i < 1500; i++) {
*(buffer+i+(2*ETH_MAC_LEN)+2) = i%255;
}
counter=buffer+ETH_HEADER_LEN;
for(j=0;j<times;j++){
start=wallclocktime(); // START
for(i=0;i<k-1;i++){
*counter=i;
if ( sendto ( s,
buffer,
ETH_HEADER_LEN+size,
0,
(struct sockaddr*) &socket_address,
sizeof(socket_address) ) == -1 ) {
perror("sendto():");
exit(1);
}
}
*counter=0xffffffff;
if ( sendto ( s,
buffer,
ETH_HEADER_LEN+size,
0,
(struct sockaddr*) &socket_address,
sizeof(socket_address) ) == -1 ) {
perror("sendto():");
exit(1);
}
/* PACK CAMEBACK */
for(i=0;i<k;i++){
length=recvfrom(s, tmp, 14+size, 0, NULL, NULL);
if(length==-1){
perror("recvfrom():");
exit(1);
}
*counter=*(tmp+ETH_HEADER_LEN);
if(*counter == 0xffffffff){
break;
}
}
stop=wallclocktime();
timetot=(stop-start); // STOP!
}
nbytetot=(double)((ETH_HEADER_LEN+size)*k*times*2);
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: %.3f byte ",nbytetot);
fprintf(stderr,"bw: %.3f Mbyte/sec ",bandwith/(1024.0*1024.0));
fprintf(stderr,"bw: %.3f Mbit/sec ",bandwithbit);
fprintf(stderr,"ping: %d ",times);
fprintf(stderr,"k: %d\n",k);
}
Mario Cavicchi
2004-07-22