0

I'm trying to get the gateway ip address of the wifi I'm connected to. I'm using the answer in this question but I'm getting an error on the codes.

When I use this in my project

- (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;
}

I get this error when I try to build my project:

Undefined symbols for architecture arm64: "getdefaultgateway(unsigned int*)"

Here is the getgateway.c

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;
}

Do I need to add frameworks? I've got no idea how to make it work.

Community
  • 1
  • 1
Jongers
  • 595
  • 1
  • 9
  • 29
  • 1
    You should probably check to see if the .c file is even being compiled by Xcode. if you put a line of garbage code into the `getdefaultgateway` function, does Xcode stop compiling and throw an error there? – Michael Dautermann Jul 27 '16 at 08:58
  • Yup , I just checked it and .c gets compiled. Maybe it has to do something with my class having .mm extensions? I had problems before when my class doesn't accept automatic casting. – Jongers Jul 27 '16 at 09:08

1 Answers1

1

Yes. .mm was my next question to you.

You're running into C++ name mangling issues.

In whichever .h file where you define and ultimately include/import the getdefaultgateway function, add this before:

#ifdef __cplusplus
extern "C" {
#endif

and after:

#ifdef __cplusplus
}
#endif
Community
  • 1
  • 1
Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
  • That's great bro! Where did you learn that? I tried adding codes that I think of to make something work like casting, etc. but I probably couldn't think of doing that. High five! – Jongers Jul 27 '16 at 09:15