get ip addresses

  • Follow


Hello
I want to read all ip addresses connected with local machine. I did:

     if (gethostname(hostname,MAX_STRING_SIZE)!=0){
         exit(0);
     }
     struct hostent *h=gethostbyname((const char*)hostname);
     int n=0;
     for (char** ptr=h->h_addr_list; *ptr; ++ptr,n++){
         printf("%s\n",inet_ntoa(*(struct in_addr*)h->h_addr_list[n]));
     }

but i received only one ip address connected with eth0.
Morover on freebsd i received only 127.0.0.1.
What about aliases ? On linux i have eth0:1 and i did not received
that ip this way.
Where's my mistake ?

Thanx
Michal

0
Reply vertigo 9/2/2004 2:06:11 PM

So i want to read all ip addresses connected with my host.
How can i do that ?

Thanx
Michal

0
Reply vertigo 9/2/2004 2:48:37 PM


"vertigo" <none@dev.null> wrote in message
news:ch79d8$ert$1@atlantis.news.tpi.pl...
> Hello
> I want to read all ip addresses connected with local machine. I did:
>
>      if (gethostname(hostname,MAX_STRING_SIZE)!=0){
>          exit(0);
>      }
>      struct hostent *h=gethostbyname((const char*)hostname);
>      int n=0;
>      for (char** ptr=h->h_addr_list; *ptr; ++ptr,n++){
>          printf("%s\n",inet_ntoa(*(struct in_addr*)h->h_addr_list[n]));
>      }
>
> but i received only one ip address connected with eth0.
> Morover on freebsd i received only 127.0.0.1.
> What about aliases ? On linux i have eth0:1 and i did not received
> that ip this way.
> Where's my mistake ?
>
> Thanx
> Michal
>

The program "netstat" knows how to get the answer.  Try looking at the
FreeBSD source for netstat.  I'm sure you can get some hints from that.
However, whenever you're looking for information about stuff that is not
part of your own process, be prepared to have to be root in order to get the
info.

--

Fletcher Glenn


0
Reply Fletcher 9/2/2004 3:06:48 PM

vertigo <none@dev.null> wrote:
>So i want to read all ip addresses connected with my host.
>How can i do that ?

In a shell script?  In a C program?  And on what platform?

-- 
FloydL. Davidson           <http://web.newsguy.com/floyd_davidson>
Ukpeagvik (Barrow, Alaska)                         floyd@barrow.com
0
Reply floyd 9/2/2004 5:59:37 PM

On Thu, 02 Sep 2004 16:48:37 +0200 vertigo <none@dev.null> wrote:
> So i want to read all ip addresses connected with my host.
> How can i do that ?

On Solaris,

SIOCGLIFNUM
SIOCGLIFADDR

See if_tcp(7p).

/fc
0
Reply Frank 9/2/2004 6:22:08 PM


> In a shell script?  In a C program?  And on what platform?
> 

in a C program, i do not want to use /proc, i need it working
on at least linux and *BSD.

Thanx
Michal

0
Reply vertigo 9/2/2004 6:41:08 PM

vertigo <none@dev.null> wrote:
>> In a shell script?  In a C program?  And on what platform?
>>
>
>in a C program, i do not want to use /proc, i need it working
>on at least linux and *BSD.

Here is a demo program that should provide enough information to
figure out how to extract just about any type of information you
want about an IP interface.

This was developed on Linux; however it should work on any BSD
system with perhaps a few adjustements on which header files are
included.

/*
 * display info about network interfaces
 */

#define _BSD_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <net/if.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)))

static int
get_addr(int sock, char * ifname, struct sockaddr * ifaddr) {

  struct ifreq *ifr;
  struct ifreq ifrr;
  struct sockaddr_in sa;

  ifr = &ifrr;

  ifrr.ifr_addr.sa_family = AF_INET;

  strncpy(ifrr.ifr_name, ifname, sizeof(ifrr.ifr_name));

  if (ioctl(sock, SIOCGIFADDR, ifr) < 0) {
    printf("No %s interface.\n", ifname);
    return -1;
  }

  *ifaddr = ifrr.ifr_addr;
  printf("Address for %s: %s\n", ifname, inet_ntoa(inaddrr(ifr_addr.sa_data)));
  return 0;
}

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);

  /* this is an alternate way to get info... */
  {
    struct sockaddr ifa;
    get_addr(sockfd, "ppp0", &ifa);
  }

  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

      From: David Peter <dave.peter@eu.citrix.com>
     */

    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;
}


-- 
FloydL. Davidson           <http://web.newsguy.com/floyd_davidson>
Ukpeagvik (Barrow, Alaska)                         floyd@barrow.com
0
Reply floyd 9/2/2004 7:07:07 PM

Hello
This works fine on linux, but on freebsd it shows only text:
No ppp0 interface.

Only thing which i adjusted was adding definitions:
#define SIOCGIFHWADDR 0x8927
#define ARPHRD_PPP 512
#define ARPHRD_NETROM 0
#define ARPHRD_EETHER 2

(because i could not find them on my freebsd).
Is it the problem with SIOCGIFHWADDR ?

Thanx
Michal

0
Reply vertigo 9/3/2004 2:03:11 PM

i found that alternative function get_addr() is working on *BSD, but
i have to know interface name (and i do not know it)...

0
Reply vertigo 9/3/2004 2:10:53 PM

8 Replies
197 Views

(page loaded in 0.123 seconds)

Similiar Articles:













7/21/2012 6:58:58 AM


Reply: