close

最近用的專案有使用到  特此分享出來

因為apple 實在是把wifi 的權限搞得太死了

搜尋網路很久很久才找到了這個方法

主要是透過Apple的open source code: http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/net/route.h

這個東西來取得

不過都是英文或許很難看得懂

但是照copy下來就是了

接下來就是照下面這串  拿去用

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <netinet/in.h>
#include <sys/param.h>
#include "getgateway.h"
#include "route.h" /*the very same from google-code*/
#import <sys/sysctl.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))

char * getdefaultgateway(in_addr_t * addr)
{
#if 0
    /* net.route.0.inet.dump.0.0 ? */
    int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET,
        NET_RT_DUMP, 0, 0/*tableid*/};
#endif
    /* net.route.0.inet.flags.gateway */
    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;
     static char tmp[20];

    if(sysctl(mib, sizeof(mib)/sizeof(int), 0, &l, 0, 0) < 0) {
        return tmp;
    }
    if(l>0) {
        buf = malloc(l);
        if(sysctl(mib, sizeof(mib)/sizeof(int), buf, &l, 0, 0) < 0) {
            return tmp;
        }
        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) {
                
                unsigned char octet[4]  = {0,0,0,0};
                for (int i=0; i<4; i++){
                    octet[i] = ( ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr >> (i*8) ) & 0xFF;
                }
                
                if(((struct sockaddr_in *)sa_tab[RTAX_DST])->sin_addr.s_addr == 0) {
                         
                        *addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr;
                        r = 0;
                         sprintf(tmp,"%d.%d.%d.%d",octet[0],octet[1],octet[2],octet[3]);
                         printf("gateway : %s\n",tmp);
                         printf("gateway address--%d.%d.%d.%d\n",octet[0],octet[1],octet[2],octet[3]);
                        return tmp;
                }
            }
        }
        free(buf);
    }
    return tmp;
}
#endif

其中迴圈裡面有一個關鍵句 return tmp; 這是我自己加的 主要是因為 這個程式碼在撈資料的時候是 陣列 且  3G Wifi的IP都會取得  更可惡的是 最後只會吐 3G的 router IP 並不是我要的

經過google 搜尋後  發現不管如何  抓陣列的順序都會是一樣  先wifi  在 3G  那麼我只要判斷現在是wifi 並且  只找第一個陣列的資訊就可以了

大致上理由會是如此

當然這程式碼拿去你可能還會遇到implicit declaration of function 'sysctl' is invalid in C99

這邊附上別人寫的解法 http://fanli7.net/a/bianchengyuyan/C__/20130225/312409.html

因為整個用法都不是本人寫的

最後再附上  這些程式碼整理的人的git檔案位置  

https://github.com/WrathLi/iOS_WIFI_Information.git

arrow
arrow
    文章標籤
    iOS Wifi Router IP
    全站熱搜
    創作者介紹
    創作者 cwa1022 的頭像
    cwa1022

    整個城市都是我的開發館

    cwa1022 發表在 痞客邦 留言(0) 人氣()