Sign in to follow this  

Getting local IP

This topic is 4857 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everybody, I am not sure if this question belongs in the Linux or in the Network forum, but I think it is a mire Linux related question: I am trying to determine the IP address of the local computer, so that I can compare it with the IP address a server tells me, my computer has. That way I can find out if I am behind a NAT or not. I tried the following code:
char szHostName[128];
  char ip[16] = "\0";
  struct hostent *pHost;
  int i;
  
  if(gethostname(szHostName, 128) == 0)
    {
      pHost = gethostbyname(szHostName);
      for(i=0; i<pHost->h_length; i++)
	{
	  if(i > 0)
	    sprintf(ip, "%s.", ip);
	  sprintf(ip, "%s%u", ip, (unsigned int)((unsigned char *)pHost->h_addr_list[0])[i]);
	}
      cout << "Address : " << ip << endl;
    }
  return 0;
The output is Address : 127.0.0.1 I also tried this:
 char ac[80];
    gethostname(ac, sizeof(ac));
    
    cout << "Host name is " << ac << "." << endl;

    struct hostent *phe = gethostbyname(ac);
    if (phe == 0) {
        cerr << "Yow! Bad host lookup." << endl;
        return 1;
    }

    for (int i = 0; phe->h_addr_list[i] != 0; ++i) {
        struct in_addr addr;
        memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr));
        cout << "Address " << i << ": " << inet_ntoa(addr) << endl;
    }
And get: Host name is Sam. Address 0: 127.0.0.1 But the IP address of eth0 is 10.10.152.49! How could my programm find out this address??? Thanks! Nathan

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
the 127.0.0.1 IP adress is a standard reserved adress and ALWAYS refers to the local computer. I dunno how to get the 'real'ip adress, but 127.0.0.1 will be your local IP on any computer, anywhere. it's probably there for testing, so you could do some network stuff on just one pc, for compatibility reasons (running the server and the user on the same pc, for instance).

maybe you should look into the inner workings of the Internet Protocol before you continue. No offense, but this is just common knowledge - i dont know much about networking but manage to know this.

Share this post


Link to post
Share on other sites
I know that 127.0.0.1 is always the address of localhost, but that is why this IP is not helping me at all.
I need some way to get all the IP addresses associated with the computer and not just the loopback!

Share this post


Link to post
Share on other sites
the command /sbin/ifconfig provides you, among other things, the IP addresses of your connection. Odds are your looking for the IP address associated with eth0 ( your standard ethernet card) or ppp0, your standard dial-up.

Share this post


Link to post
Share on other sites
Just call ifconfig and parse the output.

It's pretty difficult getting the ip of the computer. If I have 3 ethernet cards (I have at least one with 4), each one can have a different ip address, plus you can have virtual ethernet cards with extra addresses.

Best way is to design your network protocol so it works with or without NAT. NAT is supposed to be transparent. UDP (I don't think it matters for TCP) tells you who sent you the packet [man recvmsg] hence you can find out who to send something back to.

Why do you want to tell if someone is behind NAT anyway? I can't think of a circumstance in which it's actually useful.

Share this post


Link to post
Share on other sites
Firstly, thanks for all your answers!
I need to tell if somebody is behind a NAT (and to know is local IP) so that I can connect two clients which both are behind NATs directly using a technique described on this page:

http://www.mindcontrol.org/~hplus/nat-punch.html

I need the local IPs of the clients because IF they are behind the same NAT, they need to send packages to each other using the local IPs.

Parsing the output of /sbin/ifconfig ... sounds not very easy. It seems strange to me that there is no other way.

Does anybody know where I can get the source-code of ifconfig or to which packages it belongs? I googled, but without success.
Thanks!

Share this post


Link to post
Share on other sites
OK, I found a solution.
For everybody who likes to know too:


int main()
{
//Create a socket
int s=socket(AF_INET,SOCK_DGRAM,0);
sockaddr_in Addr;
Addr.sin_family=AF_INET;
//This needs to be some IP out there (in my case its www.google.de)
Addr.sin_addr.s_addr=inet_addr("66.102.11.99");
Addr.sin_port=htons(999);
//Connect the socket
connect(s,(struct sockaddr*)&Addr,sizeof(Addr));
socklen_t size=sizeof(Addr);
//Get socket name
getsockname(s,(struct sockaddr*)&Addr,&size);
//Print IP
printf("%s\n",inet_ntoa(Addr.sin_addr));
}

Share this post


Link to post
Share on other sites
Um, you're connecting to another machine, jsut to get your IP address?

Here's a better method:

char* default_route_device()
{
FILE* fp = fopen("/proc/net/route", "r");
char buf[256];
static char iface[256];
long destination, gateway, flags, refcnt, use, metric, mask;

if (fp == NULL)
return NULL;
while(fgets(buf, 255, fp)) {
if ( sscanf("%s %.8x %.8x %.4d %d %d %d %.8x", iface, &destination, &gateway, &flags, &refcnt, &use, &metric, &mask) >= 8 && destination == 0 && mask == 0 ) {
fclose(fp);
return iface;
}
}
fclose(fp);
return NULL;
}

int fd;
struct ifreq ifr;
u_char *addr;

fd = socket (AF_INET, SOCK_DGRAM,IPPROTO_IP);
memset (&ifr, 0, sizeof (struct ifreq));
strcpy (ifr.ifr_name, default_route_device());
ifr.ifr_addr.sa_family = AF_INET;
ioctl(fd, SIOCGIFADDR, &ifr);
addr=(u_char*)&(((struct sockaddr_in * )&ifr.ifr_addr)->sin_addr);
printf("eth %s, addr %d.%d.%d.%d\n", ifr.ifr_name,addr[0],addr[1],addr[2],addr[3]);
close(fd);



Adjust as needed. :)

Share this post


Link to post
Share on other sites
OK, cool, that seems like a good way too!
But I am not connection to another machine. I called connect on an UDP socket and as far as I know that only sets the default address to which packeages are send when "send" is called.
But thanks a lot for your code!!! I think I will do it your way.

Share this post


Link to post
Share on other sites
Sign in to follow this