Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

hiddenpremise

macrumors regular
Original poster
I am trying to accomplish something so very simple, and yet I can't seem to figure it out. What I need: a NSString containing the IP address given to a particular interface. Most importantly, I want to accomplish this programmaticly, not through some sort of shell script. I have searched for several days, and no one else seems to have had this problem.... which means it is probably so simple no one had to ask...

I am rather unskilled in C. My approach so far has been this
Code:
char hostname[30];
	gethostname(hostname, 30);
	hostent * record = gethostbyname(hostname);
	in_addr * address=(in_addr * )record->h_addr;
	std::string ipstring = inet_ntoa(* address);
	NSString *addressstr = [NSString stringWithCString:ipstring.c_str() encoding:NSUTF8StringEncoding];
Unfortunately, this does not give me a specific interface and it does not give me anything but my bonjour ip. My gethostname() returns iWhit.local. I end up with something like 10.211.55.2 instead of 192.168.2.1

In a shell script I would use
Code:
ifconfig en1 | grep -E "inet ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})" | awk '{print $2}'
but I don't want to use a shell script if at all possible... Plus I haven't been able to figure out how to get the output from
Code:
system("my shell script");
into a string..

Any help is much appreciated :)
Thanks,
Whit
 

jpyc7

macrumors 6502
Mar 8, 2009
276
0
Denver, CO
Maybe try the getifaddrs function? The man page says it will return a list of interfaces and information about those interfaces. I don't know how/if you know which interface you are interested in consistently.

If you were to look for source code for the "ifconfig" utility, I suspect it uses the getifaddrs function.

If you aren't familiar with using man, basically just type "man getifaddrs" in a Terminal window.

Here is a link on Apple's website too:
http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/getifaddrs.3.html
 

idelovski

macrumors regular
Sep 11, 2008
235
0
This should work on both the Mac & iPhone:

Code:
-(NSString *)getIPAddress
{
   char             baseHostName[256], fullHostName[256];
   struct hostent  *host;
   struct in_addr **hList;
   
   gethostname (baseHostName, 255);
   if (!strstr(baseHostName, ".local"))
      sprintf (fullHostName, "%s.local", baseHostName);
   else
      strcpy (fullHostName, baseHostName);
   
   host = gethostbyname (fullHostName);
   
   if (!host)
      return (@"");
   
   hList = (struct in_addr **)host->h_addr_list;
   return ([NSString stringWithCString:inet_ntoa(*hList[0])]);
}
 

hiddenpremise

macrumors regular
Original poster
This should work on both the Mac & iPhone:
This only gives me the bonjour address which is something like 10.52.22.1 instead of the 192.168.2.1 that I am looking for

Maybe try the getifaddrs function?

Thanks mate, I've got this semi-working now.
Code:
struct ifaddrs * addrs, * ifloop; 
	char buf[64];
	struct sockaddr_in *s4;
	const char * en0 = "en0";
	getifaddrs(&addrs);
	for (ifloop = addrs; ifloop != NULL; ifloop = ifloop->ifa_next)
	{
		s4 = (struct sockaddr_in *)(ifloop->ifa_addr);
		inet_ntop(ifloop->ifa_addr->sa_family, (void *)&(s4->sin_addr), buf, sizeof(buf)) == NULL;
		const char * ifname = ifloop->ifa_name;
		if (strncmp(ifname, en0, 2) == 1)
		{
			printf("%s: %s\n", ifloop->ifa_name, buf);
		}
	}
Problem is strncmp(ifname, en0, 2) doesn't give me en0, it gives me en1 and fw0. It is the most bizzare thing. Am I missing something basic about string comparisons?
 

Guiyon

macrumors 6502a
Mar 19, 2008
771
4
Cambridge, MA
'10.211.55.2' is not a bonjour address, it is a valid local IP address! All link-local IP addresses (self-configured, zeroconf, etc.) are in the 169.254.0.0/16 range. Any IP in the 10.0.0.0/8, 192.168.0.0/16 or 172.16.0.0/12 ranges is designated for private use and either manually assigned or assigned by a DHCP server. if you have not manually configured anything and you don't have a 169.254.0.0/16 address then there is a DHCP server on your network somewhere handing out addresses in that range.

Edit: Looked at your code. First of all, you're leaking memory from the getifaddrs() call. Second, that strncmp function isn't doing what you think it's doing (and your 'n' value is off by one); you might want to check the manpage on it (hint: what does it return?)
 

hiddenpremise

macrumors regular
Original poster
Thanks for the replys all
Edit: Looked at your code. First of all, you're leaking memory from the getifaddrs() call. Second, that strncmp function isn't doing what you think it's doing (and your 'n' value is off by one); you might want to check the manpage on it (hint: what does it return?)

I am blind as to how getifaddrs() is leaking memory, sorry I'm piss poor with C. How would I fix that or could you point me to a good article on C memory management? Thanks for the pointer on strncmp, i actually just converted to NSStrings and used obj-c's isEqualToString: function.
 

Guiyon

macrumors 6502a
Mar 19, 2008
771
4
Cambridge, MA
I am blind as to how getifaddrs() is leaking memory

Check out the manpage for getifaddrs, specifically the last sentence in the "Description" section. As for C's memory management, it can be summed up in one short sentence: If you allocate it, you need to free it. Generally, unless their documentation states otherwise, anything which returns a pointer or takes a double-indirect pointer as an argument is probably allocating something.
 

jpyc7

macrumors 6502
Mar 8, 2009
276
0
Denver, CO
Thanks for the replys all


I am blind as to how getifaddrs() is leaking memory, sorry I'm piss poor with C. How would I fix that or could you point me to a good article on C memory management? Thanks for the pointer on strncmp, i actually just converted to NSStrings and used obj-c's isEqualToString: function.

From the manpage (toward the end of Description section):
"The data returned by getifaddrs() is dynamically allocated and should be freed using freeifaddrs() when no longer needed."

So just call freeifaddrs(addrs) when done.
 

bliblablo

macrumors newbie
Oct 20, 2008
26
0
Does anybody got a solution to get the IP Address if you are on a 3G network and connected to a router via VPN (PPTP).
In the VPN menu i can see my ip address given from my router (192.168.1.100) but when i try to get it programmatically i can't get anything...
getifaddrs(...) does not seem to work :(

Thanks for your help
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.