Libnet performance sending RAW ethernet frames
Hi,
I'm using linux 2.6x kernel, debian.
I'm programming in C.
I'm using libnet to send raw ethernet frames to implement my own protocol. What i need is: MAXIMUM SPEED. That's why I wanted to test the speed of libnet.
I have a 1 gigabit per second network card of my computer connected to another computer, also with a 1G NIC.
I made a testing program. Check the code on the bottom of this post. It sends "no_of_packets" raw ethernet frames of 1514bytes and check the elapsed time. Then i can calculate the transmission time seen from C.
When running my performance testing program test_libnet.c, i get unrealistic measurements: ~6-7 Gbps. Far too fast.
I think libnet just puts the packets in a buffer, I'm not really measuring transmission speed.
How can I solve this?
Compile the code with
gcc -O2 -lnet -o test_libnet test_libnet.c
Libnet devel libraries must be installed!
Important remarks:
*static int no_of_packets = number of frames to send
*this program will send the frames with device eth0. Please change if necessary...
This is the code:
test_libnet.c:
Code:
#include <libnet.h>
#include <time.h>
static libnet_t *lt;
static char libnet_errbuf[LIBNET_ERRBUF_SIZE];
int SendEthernetPacket(char *DA, char *SA, short EtherType, char *payload, int payloadLen, int packet_size);
static int no_of_packets=10000;
void main()
{
// Declarations
char *data;
int i;
short etherType=0x8809;
char DA[6], SA[6];
struct timeval tp1,tp2;
long double time_worked=0;
// Init Libnet
if ((lt = libnet_init(LIBNET_LINK, "eth0", libnet_errbuf)) == NULL) {
fprintf (stderr, "ERROR opening interface: %s\n", libnet_errbuf);
fprintf (stderr, "(Check that interface is up (/sbin/ifconfig) and has IP address)\n");
exit(1);
}
// Destination and source mac address
// DA
DA[0] = 0;
DA[1] = 0xd1;
DA[2] = 0xd2;
DA[3] = 0xd3;
DA[4] = 0xd4;
DA[5] = 0x00;
// SA
SA[0] = 0;
SA[1] = 0xd1;
SA[2] = 0xd2;
SA[3] = 0xd3;
SA[4] = 0xd4;
SA[5] = 0x01;
// Making data packet of payload length 1500 with ZEROES
data=(char*)malloc(1500*sizeof(char));
for (i=0;i<1500;i++) { data[i] = '\0'; }
// Sending "no_of_packets" raw ethernet frame each of length 1514 bytes and measure the time
gettimeofday( &tp1, 0 );
//for (i=0;i<no_of_packets;i++)
SendEthernetPacket(DA,SA,etherType, data, 1500, 1514);
gettimeofday( &tp2, 0 );
free(data);
// Report the bitrate to the screen
printf("%d\n",tp2.tv_usec-tp1.tv_usec);
time_worked=(long double)(tp2.tv_sec-tp1.tv_sec)+
(long double)(tp2.tv_usec-tp1.tv_usec)/(long double)1000000;
printf("%d packets in %Lf sec, that's %Lf Mbps...",no_of_packets,time_worked,
((long double)((no_of_packets*1514*8)/(1000000*(long double)time_worked))));
}
int SendEthernetPacket(char *DA,
char *SA,
short EtherType,
char *payload,
int payloadLen,
int packet_size
) {
int bytes_sent;
char * err;
int i;
// clear packet data
libnet_clear_packet(lt);
// build libnet ethernet packet
if (libnet_build_ethernet(DA, SA, EtherType, payload, (long) payloadLen, lt, 0) ==
-1) {
fprintf(stderr, "ERROR: libnet_build_ethernet failed:\n");
if (err = libnet_geterror(lt)) {
fprintf(stderr, "%s\n",err);
}
}
for(i=0;i<no_of_packets;i++)
bytes_sent = libnet_write(lt);
libnet_clear_packet(lt);
return bytes_sent;
}
Thank you for reading this,
Krulle