Need help on ioctl calls

Need help on ioctl calls

Post by Avina » Thu, 05 Dec 2002 13:30:14



Hi to everyone out there.

I need to write ioctl calls to access ethernet address of my NIC. This
is as a part of my project on implementing ARP protocol for linux.
Will someone please guide me on writng the function? The man pages are
of little or no help....

 
 
 

Need help on ioctl calls

Post by CrayzeeWul » Thu, 05 Dec 2002 17:16:50



> Hi to everyone out there.

> I need to write ioctl calls to access ethernet address of my NIC. This
> is as a part of my project on implementing ARP protocol for linux.
> Will someone please guide me on writng the function? The man pages are
> of little or no help....

ARP has already been implemented in linux (long long time ago). You need
to provide more information on what you are trying to do and why?  Is this
a class project ? Are you trying to write an alternate implementation of
ARP for the Linux kernel ? Why ? If you want to understand how the kernel
implements ARP, why not look at net/ipv4/arp.c in the latest linux kernel
source tree ? What kind of "function" are you trying to write ? Which man
pages did you look at so far ?  

--
CrayzeeWulf

 
 
 

Need help on ioctl calls

Post by Floyd Davidso » Thu, 05 Dec 2002 18:56:35



>Hi to everyone out there.

>I need to write ioctl calls to access ethernet address of my NIC. This
>is as a part of my project on implementing ARP protocol for linux.
>Will someone please guide me on writng the function? The man pages are
>of little or no help....

Here is a demo program that shows how to use ioctl calls to
obtain information about network interfaces, including the
hardware address.

/*
 * display info about network interfaces
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <net/if_arp.h>

#define inaddrr(x) (*(struct in_addr *) &ifr->x[sizeof sa.sin_port])
#define IFRSIZE   ((int)(size * sizeof (struct ifreq)))

int main(void)
{
  unsigned char      *u;
  int                sockfd, size  = 1;
  struct ifreq       *ifr;
  struct ifconf      ifc;
  struct sockaddr_in sa;

  if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
          fprintf(stderr, "Cannot open socket.\n");
    exit(EXIT_FAILURE);
  }

  ifc.ifc_len = IFRSIZE;
  ifc.ifc_req = NULL;

  do {
    ++size;
    /* realloc buffer size until no overflow occurs  */
    if (NULL == (ifc.ifc_req = realloc(ifc.ifc_req, IFRSIZE))) {
      fprintf(stderr, "Out of memory.\n");
      exit(EXIT_FAILURE);
    }
    ifc.ifc_len = IFRSIZE;
    if (ioctl(sockfd, SIOCGIFCONF, &ifc)) {
      perror("ioctl SIOCFIFCONF");
      exit(EXIT_FAILURE);
    }
  } while  (IFRSIZE <= ifc.ifc_len);

  ifr = ifc.ifc_req;
  for (;(char *) ifr < (char *) ifc.ifc_req + ifc.ifc_len; ++ifr) {

    if (ifr->ifr_addr.sa_data == (ifr+1)->ifr_addr.sa_data) {
      continue;  /* duplicate, skip it */
    }

    if (ioctl(sockfd, SIOCGIFFLAGS, ifr)) {
      continue;  /* failed to get flags, skip it */
    }

    printf("Interface:  %s\n", ifr->ifr_name);
    printf("IP Address: %s\n", inet_ntoa(inaddrr(ifr_addr.sa_data)));

    if (0 == ioctl(sockfd, SIOCGIFHWADDR, ifr)) {

      /* Select which  hardware types to process.
       *    See /usr/include/linux/if_arp.h
       */
      switch (ifr->ifr_hwaddr.sa_family) {
      default:
        printf("\n");
        continue;
      case  ARPHRD_NETROM:  case  ARPHRD_ETHER:  case  ARPHRD_PPP:
      case  ARPHRD_EETHER:  case  ARPHRD_IEEE802: break;
      }

      u = (unsigned char *) &ifr->ifr_addr.sa_data;

      if (u[0] + u[1] + u[2] + u[3] + u[4] + u[5]) {
        printf("HW Address: %2.2x.%2.2x.%2.2x.%2.2x.%2.2x.%2.2x\n",
             u[0], u[1], u[2], u[3], u[4], u[5]);
      }

    }

    if (0 == ioctl(sockfd, SIOCGIFNETMASK, ifr) &&
        strcmp("255.255.255.255", inet_ntoa(inaddrr(ifr_addr.sa_data)))) {
      printf("Netmask:    %s\n", inet_ntoa(inaddrr(ifr_addr.sa_data)));
    }

    if (ifr->ifr_flags & IFF_BROADCAST) {
      if (0 == ioctl(sockfd, SIOCGIFBRDADDR, ifr) &&
          strcmp("0.0.0.0", inet_ntoa(inaddrr(ifr_addr.sa_data)))) {
        printf("Broadcast:  %s\n", inet_ntoa(inaddrr(ifr_addr.sa_data)));
      }
    }

    if (0 == ioctl(sockfd, SIOCGIFMTU, ifr)) {
      printf("MTU:        %u\n",  ifr->ifr_mtu);
    }

    if (0 == ioctl(sockfd, SIOCGIFMETRIC, ifr)) {
      printf("Metric:     %u\n",  ifr->ifr_metric);
    }
    printf("\n");
  }

  close(sockfd);
  return EXIT_SUCCESS;

Quote:}

--
Floyd L. Davidson         <http://www.ptialaska.net/~floyd>