Raw_Ethernet

 
This was a good discovery - ability to send raw ethernet packets. I am sure,
there are many out there who are eager to understand how networking really
works. This is something you've got to try. The main.cc below sends an ARP
request. My plan is to extend this program to be able to send PING (echo
request) packets!

EthernetRadio.cc
----------------

 1  #include <linux/if_packet.h>
 2  #include <net/if.h>

 3  #include <netinet/ether.h>
 4  #include <netinet/in.h>
 5  #include <stdio.h>

 6  #include <stdlib.h>
 7  #include <string.h>
 8  #include <sys/ioctl.h>

 9  #include <sys/socket.h>
10  #include <unistd.h>
11
12
13  #include <EthernetRadio.h>

14  #include <iostream>
15
16
17  EthernetRadio* EthernetRadio::instance;
18
19
20  int eth_open(){

21          struct sockaddr_ll sa;
22          struct ifreq ifr;
23          int i;
24          int sockfd=-1;

25
26          sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
27          if (sockfd < 0){
28                  perror("socket");

29                  return -1;
30          }
31
32          memset(&sa, 0, sizeof sa);

33          sa.sll_family   = AF_PACKET;
34          sa.sll_protocol = htons(ETH_P_ALL);
35          sa.sll_ifindex  = if_nametoindex(ETHERNET_INTERFACE);
36
37          if (bind(sockfd, (struct sockaddr*) &sa, sizeof sa) < 0){

38                  perror("bind");
39                  return -1;
40          }
41          return sockfd;

42  }
43
44  EthernetRadio::EthernetRadio(){
45          int i;
46          sock_fd=eth_open();
47  }

48
49
50  EthernetRadio* EthernetRadio::getHandle(){
51          if(instance==0){
52                  instance=new EthernetRadio();

53          }
54          return instance;
55  }
56
57  int EthernetRadio::send(char* buffer,unsigned short protocol, int length){

58          int i;
59          unsigned short *ptr;
60
61          //for(i=0;i<12;i++)buffer[i]=0xff;

62          ptr=(unsigned short*)&buffer[12];
63          //*ptr=htons(protocol);
64          return write(sock_fd,buffer,length);

65  }
66
67  int EthernetRadio::receive(char* buffer,unsigned short protocol){

68          unsigned short *ptr;
69          int bytes_read;
70          protocol=htons(protocol);
71          bytes_read=read(sock_fd,buffer,ETH_FRAME_LEN);

72          ptr=(unsigned short *)&buffer[12];
73          if(*ptr==protocol)return bytes_read;

74          else return -1;
75  }

EthernetRadio.h
---------------

 1  #ifndef __EthernetRadio_H__

 2  #define __EthernetRadio_H__
 3
 4  #define ETHERNET_INTERFACE      "eth0"
 5

 6  class EthernetRadio{
 7          int sock_fd;
 8          static EthernetRadio *instance;

 9          EthernetRadio();
10          public:
11                  static EthernetRadio *getHandle();
12                  int send(char* buffer,unsigned short protocol,int length);

13                  int receive(char* buffer,unsigned short protocol);
14  };
15

16  #endif//__EthernetRadio_H__


main.cc
-------

 1  #include <EthernetRadio.h>
 2

 3  typedef struct
 4  {
 5          unsigned short  ar_hrd;         /* format of hardware address   */

 6          unsigned short  ar_pro;         /* format of protocol address   */
 7          unsigned char   ar_hln;         /* length of hardware address   */

 8          unsigned char   ar_pln;         /* length of protocol address   */
 9          unsigned short  ar_op;          /* ARP opcode (command)         */

10  }* ARPHeaderPointer __attribute__((packed));
11
12  unsigned short HTONS(unsigned short s){

13          unsigned char *p;
14          unsigned char temp;
15          p=(unsigned char*)&s;

16          temp=p[0];
17          p[0]=p[1];
18          p[1]=temp;

19          return s;
20  }
21
22
23  int main(){

24
25          int i;
26          char b[1024];
27          EthernetRadio *s;

28
29
30          for(i=0;i<1024;i++)b[i]=0;
31
32          s=EthernetRadio::getHandle();

33
34          ARPHeaderPointer arpHeaderPointer;
35
36          arpHeaderPointer=(ARPHeaderPointer)&b[14];
37          arpHeaderPointer->ar_hrd=HTONS(1);

38          arpHeaderPointer->ar_pro=HTONS(0x800);
39          arpHeaderPointer->ar_hln=6;
40          arpHeaderPointer->ar_pln=4;

41          arpHeaderPointer->ar_op=HTONS(1);
42
43          for(i=0;i<6;i++)b[i]=0xff;

44
45          b[6]=0x00;
46          b[7]=0x07;
47          b[8]=0xe9;

48          b[9]=0x82;
49          b[10]=0x00;
50          b[11]=0x49;

51
52          b[22]=0x00;
53          b[23]=0x07;
54          b[24]=0xe9;

55          b[25]=0x82;
56          b[26]=0x00;
57          b[27]=0x49;

58
59          b[28]=192;
60          b[29]=168;
61          b[30]=8;

62          b[31]=56;
63
64          b[38]=192;
65          b[39]=168;

66          b[40]=8;
67          b[41]=63;
68
69          s->send(b,0x806,42);

70
71          return 0;
72  }