Getting IP Address and Subnet Mask of the local machine in network.

Getting IP Address and Subnet Mask of the local machine in network.

Post by Harsha Kodn » Wed, 17 Jul 2002 19:15:05



Hi,
  I have the name of the remote host in my local network. I will get
the IP address of the remote host by using gethostbyname() function.
  I will get the name of the local machine using gethostname. and IP
address by using gethostbyname.

 Now I want to check that the given IP address ( remote host ) is in
my subnet or not. For that I need to get the Subnet Mask of the
network. Is there any API to get the subnet mask of the network ?

Waiting for the response at the earliest.,

Thanks in advance and Regards.


Tally Solutions Pvt. Ltd.

 
 
 

Getting IP Address and Subnet Mask of the local machine in network.

Post by M?ns Rullg? » Wed, 17 Jul 2002 19:30:04



>   I have the name of the remote host in my local network. I will get
> the IP address of the remote host by using gethostbyname() function.
>   I will get the name of the local machine using gethostname. and IP
> address by using gethostbyname.

>  Now I want to check that the given IP address ( remote host ) is in
> my subnet or not. For that I need to get the Subnet Mask of the
> network. Is there any API to get the subnet mask of the network ?

int sock = socket(...);
ioctl(sock, SIOCGIFNETMASK, struct ifreq *);

This should be fairly portable, I think it comes from BSD.

--
M?ns Rullg?rd


 
 
 

Getting IP Address and Subnet Mask of the local machine in network.

Post by Floyd Davidso » Wed, 17 Jul 2002 20:19:09



>Hi,
>  I have the name of the remote host in my local network. I will get
>the IP address of the remote host by using gethostbyname() function.
>  I will get the name of the local machine using gethostname. and IP
>address by using gethostbyname.

Using gethostname may not provide what you expect.  IP addresses
are assigned to interfaces, so a given host could possibly have
several different interfaces active, and each would have at
least one IP address, and likely at least one host name
associated with it.  Which one you get from gethostname depends
on configuration, and may not be related to the IP address which
the remote host uses to address the local host on your local
network.

Hence, you are probably more interested in getting the IP
address of a specific interface, or at most of all interfaces of
a given type (i.e., in this case most likely eth0 or else all
ethernet interfaces).

Quote:> Now I want to check that the given IP address ( remote host ) is in
>my subnet or not. For that I need to get the Subnet Mask of the
>network. Is there any API to get the subnet mask of the network ?

You can use socket ioctl() calls.  Below is a generic program which
lists a number of parameters for each interface.  It does a lot more
than what you are specifically asking, but in the process demonstrates
how to select on a number of different criteria.  For example, you
can use it to show only information about ethernet interfaces, or only
PPP, or whatever.  You'll need to trim out the parts unnecessary for
you program.

/*
 * display info about network interfaces
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#include <sys/socket.h>
#include <sys/types.h>
#include <net/if.h>

#include <sys/ioctl.h>
#include <net/if_arp.h>
#include <arpa/inet.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)));

    /*
      This won't work on HP-UX 10.20 as there's no SIOCGIFHWADDR ioctl. You'll
      need to use DLPI or the NETSTAT ioctl on /dev/lan0, etc (and you'll need
      to be root to use the NETSTAT ioctl. Also this is deprecated and doesn't
      work on 11.00).

      On Digital Unix you can use the SIOCRPHYSADDR ioctl according to an old
      utility I have. Also on SGI I think you need to use a raw socket, e.g. s
      = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP)

      Dave


     */

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

      /* Select which  hardware types to process.
       *
       *    See list in system include file included from
       *    /usr/include/net/if_arp.h  (For example, on
       *    Linux see file /usr/include/linux/if_arp.h to
       *    get the list.)
       */
      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>

 
 
 

1. Dual IP Single Machine, Subnet mask??

I have 2 ip's and seperate domains setup on a single linux box running
Redhat 4.1 kernel 2.0.27. I have done this before with no problems, but
this time they both work fine on the linux box but the second ip can't be
reached from outside the server itself. It's been proposed the the problem
lay in the netmask, can this be? If so, what should the subnet mask be set
to? the ip's are 208.219.204.92 and 208.219.204.93 both are seperate
domains and SOA for that respective domain, what would a submask be for
this situation?

2. Custom RedHat Install Floppy

3. Changing IP addresses and subnet masks on Solaris 5.5.1 - is this okay?

4. xdm problem.. Help!

5. changing IP,Subnet MASK address and GATEWAYaddress

6. Linux and NFS

7. Linux machine need local network & internet IP address?

8. Wot no comp.os.linux.help ?

9. multiinterface belong to same classic IP network with different subnet mask

10. discovering the ip address of an interface without knowing any network info (like network, subnet, etc)

11. Two ip/subnet address' on 1 machine

12. EzPPP->Mindspring getting "bad local IP address 127.0.0.1"