I need to obtain the IP address of the default gateway in an iPhone application. I cannot find the proper API. Anyone know if iPhone exposes this information?
5 Answers
I have solved this, though i dunno if this solution is valid (wont be rejected by apple)
first i'll give you the sources i used to build my solution upon:
http://code.google.com/p/doubango/source/browse/trunk/thirdparties/iphone/include/net/route.h?r=348
It would be great to get some feedback if you think apple will allow this kind of code.
getgateway.h
#ifndef __GETGATEWAY_H__
#define __GETGATEWAY_H__
/* getdefaultgateway() :
* return value :
* 0 : success
* -1 : failure */
int getdefaultgateway(in_addr_t * addr);
#endif
getgateway.c
#include <stdio.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <sys/sysctl.h>
#include "getgateway.h"
#include "route.h"
#include <net/if.h>
#include <string.h>
#define CTL_NET 4 /* network, see socket.h */
#if defined(BSD) || defined(__APPLE__)
#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
int getdefaultgateway(in_addr_t * addr)
{
int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET,
NET_RT_FLAGS, RTF_GATEWAY};
size_t l;
char * buf, * p;
struct rt_msghdr * rt;
struct sockaddr * sa;
struct sockaddr * sa_tab[RTAX_MAX];
int i;
int r = -1;
if(sysctl(mib, sizeof(mib)/sizeof(int), 0, &l, 0, 0) < 0) {
return -1;
}
if(l>0) {
buf = malloc(l);
if(sysctl(mib, sizeof(mib)/sizeof(int), buf, &l, 0, 0) < 0) {
return -1;
}
for(p=buf; p<buf+l; p+=rt->rtm_msglen) {
rt = (struct rt_msghdr *)p;
sa = (struct sockaddr *)(rt + 1);
for(i=0; i<RTAX_MAX; i++) {
if(rt->rtm_addrs & (1 << i)) {
sa_tab[i] = sa;
sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len));
} else {
sa_tab[i] = NULL;
}
}
if( ((rt->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY))
&& sa_tab[RTAX_DST]->sa_family == AF_INET
&& sa_tab[RTAX_GATEWAY]->sa_family == AF_INET) {
if(((struct sockaddr_in *)sa_tab[RTAX_DST])->sin_addr.s_addr == 0) {
char ifName[128];
if_indextoname(rt->rtm_index,ifName);
if(strcmp("en0",ifName)==0){
*addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr;
r = 0;
}
}
}
}
free(buf);
}
return r;
}
#endif

- 1,126
- 3
- 16
- 38
-
192.168 is not the only IP address space reserved for private networks, so the if clause you added is really detrimental. This code will miss gateway IPs on 10.x and 172.16.x, which are just as valid as 192.168.x. Consider using the original code instead. – AriX Oct 05 '12 at 22:06
-
Using the original code as I suggested may cause problems, since on an iPhone you may get the carrier's internal network gateway instead of the one for Wi-Fi. I assume this is why you added the check for 192.168.x in the first place. I am working on a way to get the interface name for these gateways, so that you can verify that the gateway corresponds to the Wi-Fi interface. – AriX Oct 05 '12 at 23:02
-
please consider updateing the answer once you found a solution – Jakob Oct 22 '12 at 14:29
-
1i edited the code to check for en0 (wifi interface) instead of a local ip – Jakob May 13 '13 at 13:48
-
Just a note to anyone trying this out on the simulator: "en1" might be the active network connection rather than "en0". – newenglander Oct 08 '13 at 11:43
-
Jakob, how do you call this? What add do you pass in? Also, did it pass App Review? – Darren Nov 06 '14 at 12:08
-
1@Darren that is an in-out parameter, much like how NSError is used in many cases. You would call it like so: in_addr_t gateway = 0; int success = getdefaultgateway(&gateway); then you check the value of gateway. – Zoltán Matók Mar 04 '15 at 14:15
-
@Darren that is an in-out parameter, much like how NSError is used in many cases. You would call it like so: in_addr_t gateway = 0; int success = getdefaultgateway(&gateway); then you check the value of gateway. – Zoltán Matók Mar 04 '15 at 14:15
-
@Jakob this might be a noob question, but i got "151323914" as the value of the gateway. How do I convert this number into the dotted gateway representation? Thanks – Zoltán Matók Mar 04 '15 at 14:16
I was successful obtaining the address from SSDP protocol by sending a UDP packet out looking for service type "urn:schemas-upnp-org:device:InternetGatewayDevice:1" and noting the first device (if any) that replies (ignoring the payload, since I only want the IP address of the gateway).
This works for my application, but requires that the router implement SSDP, which is not perfect, although works in my case.
Since this is a special-purpose iPhone App (in-house, only), I am going to go with this. I won't mark this as "the answer" because it is not a general purpose solution. If I come back to this and look for a general purpose solution (such as using ICMP), or figuring out how to use the iPhone SDK configuration APIs to query for this information, I will post here.

- 2,381
- 4
- 21
- 24
-
1Hi Bill, any pointers on sending and and receiving UDP packets? I'm getting lost in the docs at the moment and some clarity would really help. I am trying to use the iPhone to discover SSDP devices and it looks like you've done just that. Cheers Dave. – Magic Bullet Dave Jul 07 '10 at 07:08
for those who need human readable IP, i modified my getgateway.c as follow:
add to includes:
#include <arpa/inet.h>
inside the last if statement, between *addr and r=0;
if(strcmp("en0",ifName)==0){
*addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr;
char str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr), str, INET_ADDRSTRLEN); // supports IPv6
printf("IP: %s\n", str); // prints "192.0.2.33"
r = 0;
}

- 39
- 4
On iOS ≥ 12, you can use the Network
framework.
The NWPath
you get from the NWPathMonitor.pathUpdateHandler
will have the NWPath.gateways
variable set to the gateways IPs.
let monitor = NWPathMonitor(requiredInterfaceType: .wifi)
monitor.pathUpdateHandler = { path in
print(path.gateways)
}
monitor.start(queue: DispatchQueue(label: "nwpathmonitor.queue"))

- 1,791
- 1
- 16
- 21
If I'm not mistaken, the gateway IP is always whatever your device IP address is, with the last octet set to "1", isn't it? If that's what you're looking for, you should be able to find the hints you need from the localhostAddresses.m file which is part of the samples in CocoaHTTPServer sources. I use the project to add an internal webserver within my app and I get the devices IP from that source file's methods.
Dr. Touch talks about it at this link.

- 3,865
- 3
- 25
- 24
-
5This is incorrect. While it is common convention, placing the router at x.y.z.1 it is not required or guaranteed by the spec. I have seen many live networks where the router was x.y.z.254, and I have seen live networks where the the default gateway is NOT in the device's subnet (most OSes will attempt to send to the gateway IP address unconditionally if the IP they sent to is not routable, even if the gateway is unroutable... some ISPs depend on this behavior). Also, things tend to be configured differently on Class A and B subnets. – Louis Gerbarg Feb 20 '10 at 01:34
-
Thanks for enlightening me. I look forward (for curiosity's sake) to hearing what you discover. – wkw Feb 20 '10 at 01:43