Skip to content
Snippets Groups Projects
Select Git revision
  • 54248fc1809b39c5542adba7d96b15339897fe2b
  • master default
  • labcomm2006
  • typedefs
  • anders.blomdell
  • typeref
  • pragma
  • compiler-refactoring
  • labcomm2013
  • v2014.4
  • v2006.0
  • v2014.3
  • v2014.2
  • v2014.1
  • v2014.0
  • v2013.0
16 results

ethernet_drv.c

Blame
  • Forked from Anders Blomdell / LabComm
    576 commits behind the upstream repository.
    user avatar
    Sven Robertz authored
    8c8b4a81
    History
    ethernet_drv.c 6.90 KiB
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <errno.h>
    #include <sys/socket.h>
    #include <sys/ioctl.h>
    #include <linux/if_ether.h>
    #include <linux/if_packet.h>
    #include <linux/if_arp.h>
    #include <netinet/in.h>
    #include "ethernet_drv.h"
    #include "display.h"
    
    
    /** LOCAL FUNCTIONS **/
    
    /* local type for the ethernet interface */
    struct eth_int_t
    {
    	unsigned char mac_adr[ETH_ALEN];  /* MAC address                */
    	int socket_id;                    /* socket file descriptor     */
    	int index;                        /* index of the eth interface */
    	unsigned char validity;
    };
    
    /***
    Open an Ethernet Raw packet connection
    ***/
    struct eth_int_t* eth_open(const char* eth_int_name)
    {
       struct eth_int_t* tmp_eth = NULL; /* pointer to ethernet interface struct */
       struct ifreq ifr;                 /* struct used by ioctl function        */
    
       /* TO-DO: check if a ethernet socket has already been created for eth_int_name interface */
    
       /* Ethernet interface name pointer valid ? */
       if (NULL == eth_int_name)
       {
          errno = EINVAL;
          DISPLAY_ERR("Input parameter NULL");
       }
       else
       {
          /* allocate memory for the Ethernet Interface */
          tmp_eth = (struct eth_int_t*)malloc(sizeof(struct eth_int_t));
          if (NULL == tmp_eth)
          {
       	    DISPLAY_ERR("Error allocating memory!");
          }
          else
          {
       	   /* creates a Packet Socket, raw delivery, accept all protocol */
             tmp_eth->socket_id = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
             if (-1 == tmp_eth->socket_id) /* error occurred during socket creation ? */
             {
                free(tmp_eth); /* deallocate the memory */
                tmp_eth = NULL;
                DISPLAY_ERR("Error in creating socket");
             }
             else
             {
                /* retrieve the Ethernet card MAC address */
                strcpy(ifr.ifr_name, eth_int_name);
                if (ioctl(tmp_eth->socket_id, SIOCGIFHWADDR, &ifr) == -1) /* error during the retrieve of  MAC address ? */
                {
                   close(tmp_eth->socket_id); /* close the socket      */
                   free(tmp_eth);             /* deallocate the memory */
                   tmp_eth = NULL;
                   DISPLAY_ERR("ioctl error SIOCGIFHWADDR");
                }
                else
                {
                   /* copy the MAC address into the eth interface struct */
                   memcpy(tmp_eth->mac_adr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
    
                   /*retrieve the Ethernet interface index*/
                   if (ioctl(tmp_eth->socket_id, SIOCGIFINDEX, &ifr) == -1)/* error during the retrieve of index */
                   {
                      close(tmp_eth->socket_id); /* close the socket      */
                      free(tmp_eth);             /* deallocate the memory */
                      tmp_eth = NULL;
                      DISPLAY_ERR("ioctl error SIOCGIFINDEX");
                   }
                   else
                   {
                      /* copy the interface index into the eth interface struct */
                      tmp_eth->index = ifr.ifr_ifindex;
                      printf("Successfully got our MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
                              tmp_eth->mac_adr[0],tmp_eth->mac_adr[1],tmp_eth->mac_adr[2],tmp_eth->mac_adr[3],tmp_eth->mac_adr[4],tmp_eth->mac_adr[5]);
                      printf("Successfully got interface index for %s: %i\n",eth_int_name, tmp_eth->index);
                   }
                }
             }
          }
       }
       return(tmp_eth);
    }
    
    /***
    Close the Ethernet Raw packet connection
    ***/
    int eth_close(struct eth_int_t* eth_int)
    {
       int ret = 0;
    
       /* Ethernet interface pointer valid ? */
       if (NULL == eth_int)
       {
          ret = -1;
          errno = EINVAL;
          DISPLAY_ERR("Input parameter NULL");
       }
       else
       {
          if (-1 == close(eth_int->socket_id)) /* error during the closure of the socket ? */
          {
             ret = -1;
             DISPLAY_ERR("Socket closure error");
          }
          else
          {
             free(eth_int);  /* deallocate the memory */
             eth_int = NULL;
          }
       }
       return(ret);
    }
    
    /***
    Returns the MAC address of the Ethernet Interface
    ***/
    int eth_getMACadr(const struct eth_int_t* eth_int, unsigned char* mac_adr)
    {
       int ret = 0;
    
       if ((NULL == eth_int) || (NULL == mac_adr))  /* Input parameters valid ? */
       {
          ret = -1;
          errno = EINVAL;
          DISPLAY_ERR("Input parameter(s) NULL");
       }
       else
       {
          /* TO-DO: introduce a validity flag to be check before accessing to eth_int (better a crc) */
          memcpy(mac_adr, eth_int->mac_adr, ETH_ALEN);
       }
       return(ret);
    }
    
    
    /***
    send a complete Ethernet Raw Packet
    ***/
    int eth_send(const struct eth_int_t* eth_int, const unsigned char* eth_frame, unsigned short length)
    {
       struct ethhdr *eth_header = NULL;  /* Pointer to Ethernet frame header (Dest,Source,Type) */
       struct sockaddr_ll socket_address;
       int ret;
    
       if ((NULL == eth_int) || (NULL == eth_frame))
       {
          ret = -1;
          errno = EINVAL;
          DISPLAY_ERR("Input parameter(s) Null!");
       }
       else
       {
          eth_header = (struct ethhdr*)eth_frame;
    
          /*prepare sockaddr_ll (address structure for PACKET_SOCKET) */
          socket_address.sll_family   = AF_PACKET;
          socket_address.sll_protocol = htons(ETH_P_IP);  /* Physical layer protocol           */
          socket_address.sll_ifindex  = eth_int->index;   /* Ethernet Interface index          */
          socket_address.sll_hatype   = ARPHRD_ETHER;     /* ARP hardware identifier: Ethernet */
          socket_address.sll_pkttype  = PACKET_OTHERHOST; /* Packet type: Another host         */
          socket_address.sll_halen    = ETH_ALEN;         /* Length of the MAC address         */
          socket_address.sll_addr[0]  = eth_header->h_dest[0];
          socket_address.sll_addr[1]  = eth_header->h_dest[1];
          socket_address.sll_addr[2]  = eth_header->h_dest[2];
          socket_address.sll_addr[3]  = eth_header->h_dest[3];
          socket_address.sll_addr[4]  = eth_header->h_dest[4];
          socket_address.sll_addr[5]  = eth_header->h_dest[5];
          socket_address.sll_addr[6]  = 0x00; /* not used */
          socket_address.sll_addr[7]  = 0x00; /* not used */
    
          /*send the Ethernet frame */
          ret = sendto(eth_int->socket_id, eth_frame, length, 0, (struct sockaddr*)&socket_address, sizeof(socket_address));
          if (ret == -1) /* error during the trasmission of the Ethernet frame ? */
          {
             DISPLAY_ERR("sendto error!");
          }
       }
       return(ret);
    }
    
    /***
    receive a complete Ethernet Raw Packet
    ***/
    int eth_receive (const struct eth_int_t* eth_int, unsigned char* eth_frame, unsigned short length)
    {
       int ret;
    
       if ((NULL == eth_int) || (NULL == eth_frame))
       {
          ret = -1;
          errno = EINVAL;
          DISPLAY_ERR("Input parameter(s) Null!");
       }
       else
       {
          /*Wait for incoming packet...*/
          ret = recvfrom(eth_int->socket_id, (void*)eth_frame, length, 0, NULL, NULL);
          if (ret == -1) /* error during the reception of the Ethernet frame ? */
          {
             DISPLAY_ERR("recvfrom error!");
          }
       }
       return(ret);
    }