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

Code to discover interfaces and IP address

1 view
Skip to first unread message

Nick Lindridge

unread,
Sep 7, 2002, 5:18:22 AM9/7/02
to
This post is just for historical record and may be helpful to others
if a google search finds its way here. It's based on the code from
Ujay back in July, but with modfied calling semantics and bug fixes.
The calling code is for illustration purposes only. Thanks to Ujay for
the original lead.

// defines the ifconf, ifreq structures
#include <net/if.h>

// required for socket operations and address resolution
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <memory.h>

// contains declaration of close()
#include <unistd.h>

//
// Returns the address pointer with IP address stored if the
// interface is found else 0
//
const char* getIP(const char *interface, char* address)
{
int sock = socket(PF_INET, SOCK_DGRAM, 0);
char* res = 0;

address[0] = 0;

if (sock >= 0) {
struct ifconf ifc;
struct ifreq* buf;

// the ioctl call requires a preallocated buffer

ifc.ifc_len = 32 * sizeof(*buf);
buf = (struct ifreq*)malloc(ifc.ifc_len);
ifc.ifc_buf = (void*)buf;

if (ioctl(sock, SIOCGIFCONF, &ifc) >= 0) {
int i,n;
for (i = 0, n = ifc.ifc_len / sizeof(*buf); i < n && !res; i++)
{
if (!strcmp(buf[i].ifr_name, interface)) {
struct sockaddr_in* ipaddr = (struct sockaddr_in
*)&(buf[i].ifr_addr);
strcpy(address, inet_ntoa(ipaddr->sin_addr));
res = address;
}
}
}

free(buf);
close(sock);
}

return res;
}

int main(int argc, char** argv)
{
char address[16];

if (getIP(argv[1], address)) {
printf("Addr %s\n", address);
} else {
printf("iface not found\n");
}

return 0;
}

Markus Raab

unread,
Sep 7, 2002, 7:10:34 AM9/7/02
to
thanks for posting, i would really need it. But the fact is, it doesnt work.
I get this error: "Speicherzugriffsfehler" which means translated that
there was an error with allocating or reading in memory.

I use Suse 8.0, Kernel 2.4.19, Athlon 700

would be nice if you could fix the problem! I will try to find out where the
problem is.

Markus

ujay

unread,
Sep 7, 2002, 3:35:45 PM9/7/02
to
Markus Raab wrote:

Odd, I compiled and ran the code without any errors, though I did have
to insert the following 2 lines

// contains declaration of malloc(), free()
#include <stdlib.h>
// contains declaration of printf()
#include <stdio.h>


try running the code under GDB, and see where your problem occurs, and
track it down from that point.

BTW: Nick did a nice job on improving the original code sample


Michael Heiming

unread,
Sep 7, 2002, 4:19:42 PM9/7/02
to
Markus Raab
(<3d79ddbe$0$21436$91ce...@newsreader02.highway.telekom.at>):

You can try this:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>

int main( int argc, char *argv[])
{
FILE *f=fopen("/proc/net/dev","r");
char buf[4096];
char *p;
struct ifreq ifr;
int fd;
if (!f) {
perror("/proc/net/dev");
exit(1);
}
fd = socket(AF_INET,SOCK_DGRAM, 0);
if (fd==-1) {
perror("socket");
exit(1);
}
while (fgets(buf,4096,f)) {
if ((p=strchr(buf,':'))) {
*p=0;
for (p=buf;*p == ' ';++p);
strcpy(ifr.ifr_name, p);
if (ioctl(fd, SIOCGIFADDR, &ifr)) {
perror(p);
} else {
printf( "%s: %s\n", p,inet_ntoa(*(struct
in_addr*)(ifr.ifr_ifru.ifru_addr.sa_data+2)));
}
}
} return 0;
}


Michael Heiming
--
Remove the +SIGNS case mail bounces.

Nils O. Selåsdal

unread,
Sep 7, 2002, 8:00:29 PM9/7/02
to
In reply to Nick Lindridge:

if(argc != 2){
puts("You must specify the interface, e.g. eth0");
return 1;


}

> if (getIP(argv[1], address)) {
> printf("Addr %s\n", address);
> } else {
> printf("iface not found\n");
> }
>
> return 0;
> }

--
Nils Olav Selåsdal <N...@Utel.no>
System Developer, UtelSystems a/s
w w w . u t e l s y s t e m s . c o m

Markus Raab

unread,
Sep 8, 2002, 5:02:29 AM9/8/02
to

works perfectly, thanks!

Markus

Sputnik

unread,
Sep 8, 2002, 3:42:31 PM9/8/02
to
wouldnt a simple perl script grepping the output from /sbin/ifcongig do
the same????

Sputnik

unread,
Sep 8, 2002, 4:37:19 PM9/8/02
to
On Sun, 08 Sep 2002 15:42:31 -0400, Sputnik wrote:

> wouldnt a simple perl script grepping the output from /sbin/ifcongig do
> the same????

... or a bash script?

Michael Heiming

unread,
Sep 8, 2002, 4:50:45 PM9/8/02
to
Sputnik (<pan.2002.09.08.16....@windows-sucks.com>):

Sure it would. Perhaps, you don't wan't/can't call a
shell/perl/foobar script.

DanH

unread,
Sep 8, 2002, 5:41:29 PM9/8/02
to
Sputnik wrote:

> On Sun, 08 Sep 2002 15:42:31 -0400, Sputnik wrote:
>
>
>> wouldnt a simple perl script grepping the output from
>> /sbin/ifcongig do the same????
>>
>

> .... or a bash script?
>

#!/bin/sh

NETWORKDEVICES=$(ifconfig |egrep -v "^ |^$"|awk '{print $1}')
for INTERFACE in ${NETWORKDEVICES}; do
echo ${INTERFACE}" "$(/sbin/ifconfig $INTERFACE | grep inet | \
cut -d : -f 2 | cut -d \ -f 1)
done


--
UNIX - Not just for Vestal Virgins anymore
Linux - Choice of a GNU generation

Sputnik

unread,
Sep 9, 2002, 12:45:41 AM9/9/02
to
> #!/bin/sh
>
> NETWORKDEVICES=$(ifconfig |egrep -v "^ |^$"|awk '{print $1}')
> for INTERFACE in ${NETWORKDEVICES}; do echo ${INTERFACE}"
> "$(/sbin/ifconfig $INTERFACE | grep inet | \ cut -d : -f 2 | cut -d \ -f
> 1)
> done
>
>
someything like this. aint it easier??

Nick Lindridge

unread,
Sep 9, 2002, 5:28:16 PM9/9/02
to
> > int main(int argc, char** argv)
> > {
> > char address[16];
> if(argc != 2){
> puts("You must specify the interface, e.g. eth0");
> return 1;
> }
>

Indeed, and hence my comment about the driver being lacking (I think I
wrote that in the original post), but omitted for brevity as the post
was already long enough and the main() is throw away code and not
meant to be used as a utility. I'm using a modified version of the
routine in an embedded license request generator in some of my
software. The main is just for test purposes.

Not sure about the memory errors someone was having. Perhaps the
program was called without an argument. The routine is correct.

Re the other comments. Using /proc is indeed an alternative, but the
lower level routine to me is preferable as it's ultimately much
simpler to use and may be more portable.

0 new messages