Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Finding out your ip address from a C program

245 views
Skip to first unread message

pancho

unread,
Jul 23, 2004, 7:07:58 AM7/23/04
to
Hello

I would like to know if there is a way to know my ip address of each
interface from a C program, if them are up or down...

Of course, I can do it scanningf the output of "ifconfig", (more
concretelly "ifconfig ppp0 | grep inetaddr"), but it would be great if
exists the possibility of reading a structure with this information with a
system call, just like sysinfo allows me to know how many free memory I
have, for example.

I have looked for such a function, but I havent found it. (I also have
tried to look at the ifconfig code for a hint, but for me it is too
complicated).

Best regards and thanks in advance,

Jorge

Phil Frisbie, Jr.

unread,
Jul 23, 2004, 12:34:33 PM7/23/04
to
pancho wrote:

> Hello
>
> I would like to know if there is a way to know my ip address of each
> interface from a C program, if them are up or down...

You can use the socket API to get a list of all assigned IP addresses by calling
gethostname() followed by gethostbyname().

--
Phil Frisbie, Jr.
Hawk Software
http://www.hawksoft.com

Floyd L. Davidson

unread,
Jul 23, 2004, 1:46:59 PM7/23/04
to

Below is a demo program that has been posted a few times previously.

/* 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....@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) fl...@barrow.com

Kasper Dupont

unread,
Jul 24, 2004, 9:46:50 AM7/24/04
to
"Floyd L. Davidson" wrote:
>
> Below is a demo program that has been posted a few times previously.

Has it? I don't recall seeing this particular example
program before. But it is a nice example. Who's the
author? I'd like to put it in my FAQ:

http://www.daimi.au.dk/~kasperd/comp.os.linux.development.faq.html#IP

--
Kasper Dupont -- der bruger for meget tid paa usenet.
I'd rather be a hammer than a nail.

Floyd L. Davidson

unread,
Jul 24, 2004, 10:37:47 AM7/24/04
to
Kasper Dupont <remove....@nospam.lir.dk.invalid> wrote:
>"Floyd L. Davidson" wrote:
>>
>> Below is a demo program that has been posted a few times previously.
>
>Has it? I don't recall seeing this particular example
>program before. But it is a nice example. Who's the
>author? I'd like to put it in my FAQ:
>
>http://www.daimi.au.dk/~kasperd/comp.os.linux.development.faq.html#IP

Oh, I've posted it half a dozen times in a variety of newsgroups
over the past 3-4 years (that is actually version number 11).

As you can see from at least one comment, it has been modified
as others have pointed out errors and omissions! It appears,
given the dates I have, that David Peter posted his comments
to comp.unix.programmer in November 2000, and that may have been
the first time I posted the program. That post was in response
to a "How do you get the MAC address?" query. Seemed like a
little broader example was more useful!

You have permission to use it in any way you see fit.

I've considered, for example, having rolls of soft tissue paper
made up with my coding printed on 6" squares. The code is
entertainment; the soft paper, however, is functional...

pancho

unread,
Jul 26, 2004, 6:58:17 AM7/26/04
to
El Fri, 23 Jul 2004 09:46:59 -0800, Floyd L. Davidson escribió:

>
> Below is a demo program that has been posted a few times
> previously.
>

Lot of thanks for the code. (I didnt find it when I googled this
issue, sorry for ask an already answered question)


Jorge

Floyd L. Davidson

unread,
Jul 26, 2004, 7:28:28 AM7/26/04
to

That's a tricky one to google. You have to know how it's done
to find examples of how to do it... :-)

There are a couple parts of it which might not be obvious,
depending on your background. If something isn't obvious,
ask about it and probably two or three people will provide
views on what the code does and why it's done that way.

0 new messages