15

I need to get the gateway address of the wifi network I connect with the iPhone. Anyone knows how to get that ?

Just to clarify, I am looking for the information of this screen :

enter image description here

Thanks.

eemceebee
  • 2,637
  • 9
  • 38
  • 49
  • One technique, though perhaps a little specialised, is outlined here http://stackoverflow.com/questions/2300149/how-can-i-determine-the-default-gateway-on-iphone – Paul Dixon Feb 02 '11 at 08:31

4 Answers4

14

Add to your project route.h file from http://opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/net/route.h

Create getgateway.h

int getdefaultgateway(in_addr_t * addr);

Create getgateway.c

#include <stdio.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <sys/sysctl.h>
#include "getgateway.h"

#include "TargetConditionals.h"
#if TARGET_IPHONE_SIMULATOR
    #include <net/route.h>
    #define TypeEN    "en1"
#else
    #include "route.h"
    #define TypeEN    "en0"
#endif

#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(TypeEN,ifName)==0){
                            *addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr;
                                r = 0;                        
                        }
                }
            }
        }
        free(buf);
    }
    return r;
}
#endif

Through the following snippet, this example will be good work on the simulator and the devise.

#include "TargetConditionals.h"
#if TARGET_IPHONE_SIMULATOR
    #include <net/route.h>
    #define TypeEN    "en1"
#else
    #include "route.h"
    #define TypeEN    "en0"
#endif

Use this code in your Objective C project

#import "getgateway.h"
#import <arpa/inet.h>

- (NSString *)getGatewayIP {
    NSString *ipString = nil;
    struct in_addr gatewayaddr;
    int r = getdefaultgateway(&(gatewayaddr.s_addr));
    if(r >= 0) {
        ipString = [NSString stringWithFormat: @"%s",inet_ntoa(gatewayaddr)];
        NSLog(@"default gateway : %@", ipString );
    } else {
        NSLog(@"getdefaultgateway() failed");
    }

    return ipString;

}
Alex0072005
  • 151
  • 1
  • 2
12

The following works for me, but a copy of route.h is required.

My general understanding is that this code queries and retrieves the systems routing table. It uses its entries to determine the default route aka gateway ip

/* $Id: getgateway.c,v 1.6 2007/12/13 14:46:06 nanard Exp $ */
/* libnatpmp
 * Copyright (c) 2007, Thomas BERNARD <miniupnp@free.fr>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#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
Jakob
  • 1,086
  • 3
  • 16
  • 36
  • Thank you very much! Your code saved me :) – mohamede1945 May 09 '13 at 18:29
  • 2
    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:45
  • 2
    You can get route.h from here: http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/net/route.h And then get the gate way like: `struct in_addr gatewayaddr; int r = getdefaultgateway(&(gatewayaddr.s_addr)); if(r>=0){ NSString * ipString = [NSString stringWithFormat: @"%s",inet_ntoa(gatewayaddr)]; NSLog(@"default gateway : %@", ipString ); } else { NSLog(@"getdefaultgateway() failed"); }` – ddiego Aug 14 '14 at 21:23
  • Jakob, what argument do you pass into this method? It asks for in_addr_t but where does this come from? Thanks – Darren Nov 07 '14 at 10:47
  • Got it working with ddiego's comment. Thanks guys :) – Darren Nov 08 '14 at 11:30
  • Hi it is not working with 3g can you help? – souvickcse May 25 '15 at 11:21
  • I'm getting this error: Undefined symbols for archutecture arm64 "getdefaultgateway(unsigned int*)" can you help me please? – Jongers Jul 27 '16 at 07:18
  • How can I update it to support ipv6 network only? – Jongers Aug 24 '16 at 08:16
  • why not: a break when the address is fetched? – Karsten Apr 10 '18 at 15:48
2

After checking back with Apple, the SDK does not offer an easy way to do that. The hard way, if any, is to dig deep into the system or use a traceroute.

I filed a bug report, maybe they will add it in the future.

eemceebee
  • 2,637
  • 9
  • 38
  • 49
-2

Take a look at the answers to Objective-C : How to fetch the router address?

Perhaps only tangentially related, but see the technique outlined in this blog post: http://blog.zachwaugh.com/post/309927273/programmatically-retrieving-ip-address-of-iphone

It obtains the IP address of the Wi-Fi interface, and might be a another jumping off point to finding another solution....

- (NSString *)getIPAddress
{
  NSString *address = @"error";
  struct ifaddrs *interfaces = NULL;
  struct ifaddrs *temp_addr = NULL;
  int success = 0;

  // retrieve the current interfaces - returns 0 on success
  success = getifaddrs(&interfaces);
  if (success == 0)
  {
    // Loop through linked list of interfaces
    temp_addr = interfaces;
    while(temp_addr != NULL)
    {
      if(temp_addr->ifa_addr->sa_family == AF_INET)
      {
        // Check if interface is en0 which is the wifi connection on the iPhone
        if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"])
        {
          // Get NSString from C String
          address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
        }
      }

      temp_addr = temp_addr->ifa_next;
    }
  }

  // Free memory
  freeifaddrs(interfaces);

  return address;
}
Community
  • 1
  • 1
Paul Dixon
  • 287,944
  • 49
  • 307
  • 343