473,382 Members | 1,775 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

Trouble with implementing a C program that sends and receives raw ethernet frames

Hi everyone,

First off, I am fairly new to the topic of the ethernet and the data link layer and I am trying to write a C program which allows the sending and receiving of ethernet frames.

I am trying to have my program send the ethernet frame to myself, so the program will have the same source and destination mac addresses.

The program that I'm using is a modified version of the code from http://hacked10bits.blogspot.com/201...in-6-easy.html.

I keep having trouble with the recvfrom() function, it seems to just be blocking and the program doesn't terminate. From the code, I am trying send the ethernet frame and have the recvfrom() function be able to retrieve the frame and store it in a buffer. But because recvfrom() function is just blocking, it seems to me that the sendto() function was not able to successfully send the frame.

Any ideas how I can fix this?

Here is my code:
Expand|Select|Wrap|Line Numbers
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/socket.h>    /* Must precede if*.h */
  5. #include <linux/if.h>
  6. #include <linux/if_ether.h>
  7. #include <linux/if_packet.h>
  8. #include <sys/ioctl.h>
  9.  
  10. union ethframe
  11. {
  12.   struct
  13.   {
  14.     struct ethhdr    header;
  15.     unsigned char    data[ETH_DATA_LEN];
  16.   } field;
  17.   unsigned char    buffer[ETH_FRAME_LEN];
  18. };
  19.  
  20. int main(int argc, char **argv) {
  21.   char *iface = "eth0";
  22.   unsigned char dest[ETH_ALEN]
  23.            = { 0x00, 0x12, 0x34, 0x56, 0x78, 0x90 };
  24.   unsigned short proto = 0x1234;
  25.   unsigned char *data = "hello world";
  26.   unsigned short data_len = strlen(data);
  27.  
  28.   int s;
  29.   if ((s = socket(AF_PACKET, SOCK_RAW, htons(proto))) < 0) {
  30.     printf("Error: could not open socket\n");
  31.     return -1;
  32.   }
  33.  
  34.   struct ifreq buffer;
  35.   int ifindex;
  36.   memset(&buffer, 0x00, sizeof(buffer));
  37.   strncpy(buffer.ifr_name, iface, IFNAMSIZ);
  38.   if (ioctl(s, SIOCGIFINDEX, &buffer) < 0) {
  39.     printf("Error: could not get interface index\n");
  40.     close(s);
  41.     return -1;
  42.   }
  43.   ifindex = buffer.ifr_ifindex;
  44.  
  45.   unsigned char source[ETH_ALEN];
  46.   if (ioctl(s, SIOCGIFHWADDR, &buffer) < 0) {
  47.     printf("Error: could not get interface address\n");
  48.     close(s);
  49.     return -1;
  50.   }
  51.  
  52.   memcpy((void*)source, (void*)(buffer.ifr_hwaddr.sa_data),
  53.          ETH_ALEN);
  54.  
  55.   //edited part... here we have it so that the destination mac address is
  56.   //the same as the source mac address
  57.   memcpy((void*)dest, (void*)(buffer.ifr_hwaddr.sa_data),
  58.        ETH_ALEN);
  59.  
  60.   //probe source mac address
  61.   int k;
  62.   for(k = 0; k !=ETH_ALEN; k++)
  63.   {
  64.     printf("%x\n",source[k]);
  65.     printf("%x\n",dest[k]);
  66.   }
  67.  
  68.   union ethframe frame;
  69.   memcpy(frame.field.header.h_dest, dest, ETH_ALEN);
  70.   memcpy(frame.field.header.h_source, source, ETH_ALEN);
  71.   frame.field.header.h_proto = htons(proto);
  72.   memcpy(frame.field.data, data, data_len);
  73.  
  74.   unsigned int frame_len = data_len + ETH_HLEN;
  75.  
  76.   struct sockaddr_ll saddrll;
  77.   memset((void*)&saddrll, 0, sizeof(saddrll));
  78.   saddrll.sll_family = PF_PACKET;   
  79.   saddrll.sll_ifindex = ifindex;
  80.   saddrll.sll_halen = ETH_ALEN;
  81.   memcpy((void*)(saddrll.sll_addr), (void*)dest, ETH_ALEN);
  82.  
  83.   if (sendto(s, frame.buffer, frame_len, 0,
  84.              (struct sockaddr*)&saddrll, sizeof(saddrll)) > 0)
  85.     printf("Frame successfully sent!\n");
  86.   else
  87.     printf("Error, could not send\n");
  88.  
  89.  
  90.   struct sockaddr_ll saddrll_receive;
  91.   memset((void*)&saddrll_receive, 0, sizeof(saddrll_receive));
  92.   socklen_t sll_len = (socklen_t)sizeof(saddrll_receive);
  93.  
  94.   int recv_result;
  95.   char buffer_receive[ETH_FRAME_LEN];
  96.   recv_result = recvfrom(s, buffer_receive, ETH_FRAME_LEN, 0,
  97.              (struct sockaddr*)&saddrll_receive, &sll_len);
  98.  
  99.  
  100.   close(s);
  101.  
  102.   return 0;
  103. }
  104.  
  105.  
edit: this is on a linux machine by the way.
Apr 15 '13 #1
2 2357
Banfa
9,065 Expert Mod 8TB
I think the mistake you are making is trying to do all this on 1 thread/process.

You are assuming that when you call sendto at line 83 the data sent is somehow stored somewhere so you can retrieve it with a recvfrom at line 96. However there is no such buffering, when you call sendto the frame is sent, if anyone is listening right then they receive it.

At the time you call sendto you are not waiting to receive it so the frame is lost, then you call recvfrom and block waiting for a frame that has already been received and discarded.

If you look at the code in the article you reference it only does the send not the receive for this reason.

You need to make sure that you have already called recvfrom and are blocking when you make the sendto call. If this is a single process that implies multiple threads otherwise you could not call sendto while you are blocked on recvfrom, hence my first comment. Another option would be to split this into 2 applications, 1 that received and 1 that sent.
Apr 15 '13 #2
Hi Banfa,

Thanks for helping a beginner. So I've just tried out what you recommended: split the recvfrom and sendto functions into two applications, lets call them "receive_program" and "send_program".

The way in which I was tested the two applications was by 1. setting up two command windows 2. then having the receive_program be run and be blocking on one of the command windows 3. and have the send_program run on the other.

It turns out that the receive_program is still blocking, which means that it never received any data. I'm pretty sure I've set the correct mac address and everything, I think I'm missing something.

Here are my two programs:

send_program:

Expand|Select|Wrap|Line Numbers
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/socket.h>    /* Must precede if*.h */
  5. #include <linux/if.h>
  6. #include <linux/if_ether.h>
  7. #include <linux/if_packet.h>
  8. #include <sys/ioctl.h>
  9.  
  10. union ethframe
  11. {
  12.   struct
  13.   {
  14.     struct ethhdr    header;
  15.     unsigned char    data[ETH_DATA_LEN];
  16.   } field;
  17.   unsigned char    buffer[ETH_FRAME_LEN];
  18. };
  19.  
  20. int main(int argc, char **argv) {
  21.   char *iface = "eth0";
  22.   unsigned char dest[ETH_ALEN]
  23.     = { 0x00, 0x12, 0x34, 0x56, 0x78, 0x90 };
  24.   unsigned short proto = 0x1234;
  25.   unsigned char *data = "hello world";
  26.   unsigned short data_len = strlen(data);
  27.  
  28.   int s;
  29.   if ((s = socket(AF_PACKET, SOCK_RAW, htons(proto))) < 0) {
  30.     printf("Error: could not open socket\n");
  31.     return -1;
  32.   }
  33.  
  34.   struct ifreq buffer;
  35.   int ifindex;
  36.   memset(&buffer, 0x00, sizeof(buffer));
  37.   strncpy(buffer.ifr_name, iface, IFNAMSIZ);
  38.   if (ioctl(s, SIOCGIFINDEX, &buffer) < 0) {
  39.     printf("Error: could not get interface index\n");
  40.     close(s);
  41.     return -1;
  42.   }
  43.   ifindex = buffer.ifr_ifindex;
  44.  
  45.   unsigned char source[ETH_ALEN];
  46.   if (ioctl(s, SIOCGIFHWADDR, &buffer) < 0) {
  47.     printf("Error: could not get interface address\n");
  48.     close(s);
  49.     return -1;
  50.   }
  51.  
  52.   memcpy((void*)source, (void*)(buffer.ifr_hwaddr.sa_data),
  53.          ETH_ALEN);
  54.  
  55.   //edited part... here we have it so that the destination mac address is
  56.   //the same as the source mac address
  57.  
  58.  
  59.   //probe source mac address
  60.   int k;
  61.   for(k = 0; k !=ETH_ALEN; k++)
  62.   {
  63.     printf("%x\n",dest[k]);
  64.   }
  65.  
  66.   union ethframe frame;
  67.   memcpy(frame.field.header.h_dest, dest, ETH_ALEN);
  68.   memcpy(frame.field.header.h_source, source, ETH_ALEN);
  69.   frame.field.header.h_proto = htons(proto);
  70.   memcpy(frame.field.data, data, data_len);
  71.  
  72.   unsigned int frame_len = data_len + ETH_HLEN;
  73.  
  74.   struct sockaddr_ll saddrll;
  75.   memset((void*)&saddrll, 0, sizeof(saddrll));
  76.   saddrll.sll_family = PF_PACKET;   
  77.   saddrll.sll_ifindex = ifindex;
  78.   saddrll.sll_halen = ETH_ALEN;
  79.   memcpy((void*)(saddrll.sll_addr), (void*)dest, ETH_ALEN);
  80.  
  81.   if (sendto(s, frame.buffer, frame_len, 0,
  82.              (struct sockaddr*)&saddrll, sizeof(saddrll)) > 0)
  83.     printf("Frame successfully sent!\n");
  84.   else
  85.     printf("Error, could not send\n");
  86.  
  87.  
  88.   close(s);
  89.  
  90.   return 0;
  91. }
  92.  
  93.  
receive_program:

Expand|Select|Wrap|Line Numbers
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/socket.h>    /* Must precede if*.h */
  5. #include <linux/if.h>
  6. #include <linux/if_ether.h>
  7. #include <linux/if_packet.h>
  8. #include <sys/ioctl.h>
  9.  
  10. union ethframe
  11. {
  12.   struct
  13.   {
  14.     struct ethhdr    header;
  15.     unsigned char    data[ETH_DATA_LEN];
  16.   } field;
  17.   unsigned char    buffer[ETH_FRAME_LEN];
  18. };
  19.  
  20. int main(int argc, char **argv) {
  21.   char *iface = "eth0";
  22.   unsigned char dest[ETH_ALEN]
  23.            = { 0x00, 0x12, 0x34, 0x56, 0x78, 0x90 };
  24.   unsigned short proto = 0x1234;
  25.   unsigned char *data = "hello world";
  26.   unsigned short data_len = strlen(data);
  27.  
  28.   int s;
  29.   if ((s = socket(AF_PACKET, SOCK_RAW, htons(proto))) < 0) {
  30.     printf("Error: could not open socket\n");
  31.     return -1;
  32.   }
  33.  
  34.   struct ifreq buffer;
  35.   int ifindex;
  36.   memset(&buffer, 0x00, sizeof(buffer));
  37.   strncpy(buffer.ifr_name, iface, IFNAMSIZ);
  38.   if (ioctl(s, SIOCGIFINDEX, &buffer) < 0) {
  39.     printf("Error: could not get interface index\n");
  40.     close(s);
  41.     return -1;
  42.   }
  43.   ifindex = buffer.ifr_ifindex;
  44.  
  45.   unsigned char source[ETH_ALEN];
  46.   if (ioctl(s, SIOCGIFHWADDR, &buffer) < 0) {
  47.     printf("Error: could not get interface address\n");
  48.     close(s);
  49.     return -1;
  50.   }
  51.  
  52.   memcpy((void*)source, (void*)(buffer.ifr_hwaddr.sa_data),
  53.          ETH_ALEN);
  54.  
  55.   //edited part... here we have it so that the destination mac address is
  56.   //the same as the source mac address
  57.   memcpy((void*)dest, (void*)(buffer.ifr_hwaddr.sa_data),
  58.        ETH_ALEN);
  59.  
  60.   //probe source mac address
  61.   int k;
  62.   for(k = 0; k !=ETH_ALEN; k++)
  63.   {
  64.     printf("%x\n",source[k]);
  65.     printf("%x\n",dest[k]);
  66.   }
  67.  
  68.   union ethframe frame;
  69.   memcpy(frame.field.header.h_dest, dest, ETH_ALEN);
  70.   memcpy(frame.field.header.h_source, source, ETH_ALEN);
  71.   frame.field.header.h_proto = htons(proto);
  72.   memcpy(frame.field.data, data, data_len);
  73.  
  74.   unsigned int frame_len = data_len + ETH_HLEN;
  75.  
  76.   struct sockaddr_ll saddrll;
  77.   memset((void*)&saddrll, 0, sizeof(saddrll));
  78.   socklen_t sll_len = (socklen_t)sizeof(saddrll);
  79.  
  80.   int recv_result;
  81.   char buffer_receive[ETH_FRAME_LEN];
  82.   recv_result = recvfrom(s, buffer_receive, ETH_FRAME_LEN, 0,
  83.              (struct sockaddr*)&saddrll, &sll_len);
  84.  
  85.   if(recv_result > 0)
  86.     printf("frame successfully received\n");
  87.   close(s);
  88.  
  89.   return 0;
  90. }
  91.  
Apr 16 '13 #3

Sign in to post your reply or Sign up for a free account.

Similar topics

7
by: Chaser | last post by:
Hi folks, Just wondering if anyone knows where I can find modules for NI-488.2 GPIB and for a generic ethercard? Thanks.
5
by: Merrill & Michele | last post by:
I can get files into my progs on the command line. For example if I wanted a text file to act as if they were my keystrokes I would type the executable name and then <text1.txt (I think that's...
1
by: Don | last post by:
I have a class which contains a collection of objects that I want to be able to bind to things like Combobox controls. As I understand it, I would need to implement the IList interface to be able...
0
by: Cleyton | last post by:
Hello! Someone knows what is happening?... My program doesn't work running in guest account. My program is registrated in msconfig and starts with windows...Ok... So, it stays waiting for a...
7
by: raghu | last post by:
Hello everyone, My task is to capture a data from the port and to find what type of data it is. That is wheather it is a IPV4 or a Ethernet frame. Initially I worked it using Pcap but this one...
1
by: Tom Brown | last post by:
Hi, I have a windows application, written in delphi, that communicates to our devices using raw ethernet frames. I am trying to port this application to linux using python. However, when I try...
2
by: joebenjamin | last post by:
I am trying to write a program that will generate 100 random numbers between 1 and 50. Using these numbers, generate a list that will tell the number of random numbers that fell between 1-5, 6-10,...
2
by: Jonas Maurus | last post by:
Hello everybody, I'm pondering the following problem: I want to write a Python program that receives messages via SMTP and stores them in a dict or an array. For my purposes it would be...
1
by: kavok | last post by:
I am writing a software that needs to sniff packets in the network (raw ethernet) and also, with another thread send regular UDP packets with the common socket API's. However, when the RAW...
3
by: plbaldri | last post by:
I have written a very simple and basic program for an intro Comp Sci class and am having trouble with it crashing. The program needs to accept a filename on the command line at the prompt and has to...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.