Re: get ALL ip addresses for my host
Web Server forum
Back To The Forum Home!Search!Private Messaging System

Web Server Talk Web Server Talk > Unix and Linux reviews > Free Unix support > Unix Programming > Re: get ALL ip addresses for my host




  Last Thread   Next Thread Next
  Show Printable Version Email this Page Subscribe to this Thread      Post New Thread    Post A Reply      

    Re: get ALL ip addresses for my host  
Floyd L. Davidson


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
09-02-04 11:51 PM

vertigo <none@dev.null> wrote: 
>
>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





[ Post a follow-up to this message ]



    Sponsored Links  




 





   All times are GMT. The time now is 09:54 AM.      Post New Thread    Post A Reply      
  Last Thread   Next Thread Next


Most Popular forums 

Forum Jump:
Rate This Thread:

Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
 
Medical and Health forum | Computer Games Reviews | Graphics design forum

Back To The Top
Home | Usercp | Faq | Register