LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Get IP Address System call (http://www.linuxquestions.org/questions/programming-9/get-ip-address-system-call-425637/)

oulevon 03-17-2006 12:51 AM

Get IP Address System call
 
Hello,


Is there a way to get my IP address using a system call of some sort? I've looked at the man page for gethostbyaddr, but there isn't an example how to use it in practice. Thanks for any help.

nx5000 03-17-2006 05:05 AM

This is one method, there are others but less portable:

Code:

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

#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>

#include <arpa/inet.h>
#include <net/if.h>

#include <unistd.h>


#define inaddrr(x) (*(struct in_addr *) &ifr->x[sizeof sa.sin_port])
#define IFRSIZE  ((int)(size * sizeof (struct ifreq)))

typedef char ip_address[15+1];

static int
get_addr(char * ifname,ip_address theip) {

  struct ifreq                *ifr;
  struct ifreq                ifrr;
  struct sockaddr_in        sa;
  struct sockaddr        ifaddr;
  int                        sockfd;

  if((sockfd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==-1)
  {
        printf ("Socket for DGRAM cannot be created\n");
        return -1;
  }

  ifr = &ifrr;

  ifrr.ifr_addr.sa_family = AF_INET;

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

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

  ifaddr = ifrr.ifr_addr;
    strncpy(theip,inet_ntoa(inaddrr(ifr_addr.sa_data)),sizeof(ip_address));

  return 0;

}

int main(void){
ip_address        theip;


        if (get_addr("eth0",theip)==0)
              printf("The ip for eth0 is:%s\n",theip);
        else 
              printf("Couldn't get ip adress for eth0\n");
        return 0;
}


nx5000 03-17-2006 05:10 AM

By the way, I hope its for a UNIX system?
Otherwise for Winblows I dunno. transform socket to Socket maybe :)

jlliagre 03-17-2006 08:51 AM

Quote:

Originally Posted by nx5000
By the way, I hope its for a UNIX system?
Otherwise for Winblows I dunno. transform socket to Socket maybe :)

Your program neither works as is for Unix.

It is Linux specific, as it assumes the ethernet interface name is "eth0".
It can easily be ported to non-Linux Unix systems though.

kshkid 03-17-2006 08:51 AM

with,
the teletype line that you are currently working and
the id from which you are executing

parse the /var/adm/wtmpx file
you can retrieve the ip address

kshkid 03-17-2006 08:58 AM

nx,

you missed out /usr/include/sys/sockio.h to include
SIOCGIFADDR

nx5000 03-17-2006 09:25 AM

jlliagre you're right its maybe not portable to unix as I use ioctl... its been some time I have no access to Unix stations and all these differents implementations.

mmm eth0 is for the example... remove it if you prefer :)

Maybe you could post a more-portable solution?

Works perfectly for me without any more includes.

jlliagre 03-17-2006 04:30 PM

Quote:

Originally Posted by nx5000
jlliagre you're right its maybe not portable to unix as I use ioctl... its been some time I have no access to Unix stations and all these differents implementations.

In fact not, your program is quite portable, and works for me with Solaris.

Quote:

mmm eth0 is for the example... remove it if you prefer :)
But if I remove it, the program stops working ...

That's the point here, the OP question was about how retrieving one's own IP address.

The problem is that there is no standard way to figure out what is your own network interface, not to mention which one to choose when there are many of them.
Quote:

Maybe you could post a more-portable solution?
Sure, here's one.
Unfortunately it fails in many cases, if the naming is incorrect (like setting the hostname as a localhost alias) or is dynamic and not updated.
Code:

#include <stdio.h>
#include <stdlib.h>
#include <sys/utsname.h>
#include <netdb.h>
#include <sys/types.h>
#include <errno.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
  struct utsname utsname;
  struct hostent *h;

  uname(&utsname);

  if(!(h=gethostbyname(utsname.nodename)))
  {
    fprintf(stderr,"%s\n", hstrerror(h_errno));
    exit(1);
  }
  printf("%s\n", inet_ntoa(*((struct in_addr *)h->h_addr)));
  return 0;
}

Quote:

Works perfectly for me without any more includes.
I too had to add "#include <sys/sockio.h>" for having it compilable.
BSD and Solaris need this, Linux has SIOCGIFADDR defined in more than one place.

kshkid 03-18-2006 02:32 AM

Quote:

printf("%s\n", inet_ntoa(*((struct in_addr *)h->h_addr)));
i believe this is more readable,
Code:

printf("%s\n", inet_ntoa(*((struct in_addr *)h->h_addr_list[0])));
or this,

Code:

printf("%s\n", inet_ntoa(**((struct in_addr **)h->h_addr_list)));

jlliagre 03-18-2006 02:42 AM

May be ...

Rodrex Lee 04-08-2010 04:29 AM

Network IP Address of own machine inside C code
 
One more solution which I found much better than the above one, to know the network IP address of own machine inside C code is as follows:--

FILE *fd;
char ip_addr[20];
system("cmd=`/sbin/ifconfig`;y=${cmd#*inet addr:};y=${y%% *};echo $y >ipaddr");
fd = fopen("ipaddr", "r+");
fscanf(fd, "%s", &ip_addr);
fclose(fd);
fprintf(stderr,"IP Address:%s", ip_addr);

This works fine for me.
Kindly put your suggestions for above solution.

Thanks & Regards,
Rodrex.


PS: one more solution after such a long time

rndm_luser 04-09-2010 05:32 PM

Check out getaddrinfo.


All times are GMT -5. The time now is 12:37 AM.