Thread: Libnet performance sending RAW ethernet frames

  1. #1
    Registered User
    Join Date
    Mar 2012
    Posts
    5

    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
    Last edited by Salem; 05-05-2012 at 12:09 PM. Reason: wrap long lines

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > bytes_sent = libnet_write(lt);
    The first thing to do would be to check for errors.

    To eliminate the possibility that it's all been buffered, perhaps arrange that the receiver sends a short "ACK" message when all the packets have been received.
    You time between the first "send" and the receipt of the "ACK".
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Krulle View Post
    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.
    Seriously?
    That's like taking apart your Prius because you want to build and install a more efficient engine in it.

    Could you please explain a bit about what you want to use this for? What will it do that UDP or TCP can't do?
    You'll get a lot more support if we can see for ourselves that this is not a fool's errand.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #4
    Registered User
    Join Date
    Mar 2012
    Posts
    5
    Hi all,

    @Salem: error checking is in my program, but I stripped it from unnecessary features to post the code here...


    @iMalc: the 6-7 Gbps will be the buffer filling speed. When I check the NIC with "iftop", it sends data with a speed of 980 Mbps.
    Quote Originally Posted by iMalc
    Seriously?
    That's like taking apart your Prius because you want to build and install a more efficient engine in it.
    What do you mean? To be honest, that's the most powerful combination I can think of for network programming...
    A bit more powerful perhaps: Linux + C + socket programming, but Libnet itself uses socket programming of course...
    Can you recommend me another combination?

    I'm doing an university project, and the goal is to implement a form of TDMA (Time division multiple access).

    I'm not throwing away TCP, i'm just throwing away the IP protocol: I have to follow a standard ethernet frame payload format for the GATE and REPORT control messages.

    All other data packets may be standard IPv4 packets; however, for testing purposes, I still use raw ethernet frames that are time-stamped when they are put in a buffer (not the NIC buffer). That way I can measure the performance of the network.

    The buffer will be filled following a self similar process also implemented in my program.

    That's a bit more info

    Thank you for answering,
    Krulle

  5. #5
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Oh okay, it's for a Uni project. Now it makes much more sense. Thankyou for your clarification.

    Well I think it needs saying that in order to actually measure transfer speed, receiving the data on the other end is an absolute must.
    Afterall, you can't measure the speed of mail delivery by just putting your envelope into a postbox.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  6. #6
    Registered User
    Join Date
    Mar 2012
    Posts
    5
    Quote Originally Posted by iMalc View Post
    Oh okay, it's for a Uni project. Now it makes much more sense. Thankyou for your clarification.

    Well I think it needs saying that in order to actually measure transfer speed, receiving the data on the other end is an absolute must.
    Afterall, you can't measure the speed of mail delivery by just putting your envelope into a postbox.
    You're right. To measure it exactly, i'll need to do that at the receiver. But networktools like iftop and nethogs also give a good measurement.

    Thank you for your time iMalc

    Krulle

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Packet Spoofing using Libnet (Issue)
    By rehman12390 in forum Networking/Device Communication
    Replies: 3
    Last Post: 02-28-2012, 07:10 AM
  2. Sdi? Mdi? Frames?
    By execute in forum Windows Programming
    Replies: 4
    Last Post: 05-16-2006, 08:05 PM
  3. Sending data to an ethernet port
    By Patman in forum C Programming
    Replies: 1
    Last Post: 08-04-2004, 07:37 PM
  4. What libnet libraries to include with compile?
    By failure_to in forum C Programming
    Replies: 3
    Last Post: 06-16-2004, 06:42 AM
  5. Getting the FPS (Frames Per Second)
    By Unregistered in forum Game Programming
    Replies: 12
    Last Post: 05-05-2002, 10:58 AM