linux的閘道器資訊儲存在路由表中,獲取閘道器實際上就是路由表的查詢。
使用者空間獲取閘道器位址
有兩種方法,乙個是從/proc/net/route中讀取,這是最簡單,最直接的,route命令就是這麼做的,可以參考net-tools包中route的原始碼實現。
另一種是用netlink來實現。利用netlink_route(rtnetlink.c: routing netlink socket inte***ce)的rtm_getroute指令查詢路由,這是從網上找的**,在debian (2.6.26核心)下測試通過。
c++**
#include //for in_addr
#include //for rtnetlink
#include //for if_namesiz, route_info
#include //for malloc(), free()
#include //for strstr(), memset()
#include
#define bufsize 8192
struct route_info;
int readnlsock(int sockfd, char *bufptr, int seqnum, int pid)
nlhdr = (struct nlmsghdr *)bufptr;
//檢查header是否有效
if((nlmsg_ok(nlhdr, readlen) == 0) || (nlhdr->nlmsg_type == nlmsg_error))
if(nlhdr->nlmsg_type == nlmsg_done)
else
if((nlhdr->nlmsg_flags & nlm_f_multi) == 0)
} while((nlhdr->nlmsg_seq != seqnum) || (nlhdr->nlmsg_pid != pid));
return msglen;
}
//分析返回的路由資訊
void parseroutes(struct nlmsghdr *nlhdr, struct route_info *rtinfo,char *gateway)
}
dst.s_addr = rtinfo->dstaddr;
if (strstr((char *)inet_ntoa(dst), "0.0.0.0"))
free(tempbuf);
return;
}
int get_gateway(char *gateway)
memset(msgbuf, 0, bufsize);
nlmsg = (struct nlmsghdr *)msgbuf;
rtmsg = (struct rtmsg *)nlmsg_data(nlmsg);
nlmsg->nlmsg_len = nlmsg_length(sizeof(struct rtmsg)); // length of message.
nlmsg->nlmsg_type = rtm_getroute; // get the routes from kernel routing table .
nlmsg->nlmsg_flags = nlm_f_dump | nlm_f_request; // the message is a request for dump.
nlmsg->nlmsg_seq = msgseq++; // sequence of the message packet.
nlmsg->nlmsg_pid = getpid(); // pid of process sending the request.
if(send(sock, nlmsg, nlmsg->nlmsg_len, 0) < 0)
if((len = readnlsock(sock, msgbuf, msgseq, getpid())) < 0)
rtinfo = (struct route_info *)malloc(sizeof(struct route_info));
for(;nlmsg_ok(nlmsg,len);nlmsg = nlmsg_next(nlmsg,len))
free(rtinfo);
close(sock);
return 0;
}
int main()
核心空間獲取閘道器位址
使用者空間的實現,其本質上是核心空間的支援,因此核心空間獲取應該更直接點。我參考了netlink_route中的實現來做,即執行乙個從本機ip到外網ip的路由查詢,獲得的路由記錄中自然包括閘道器位址,主要用到ip_route_output_key()函式。下面是我的**:
c++**
…
extern
struct net init_net;
…
inline void printip(__u32 uip)
…
int ******()
,
},
.oif = 0,
};
fl.nl_u.ip4_u.daddr = in_aton("182.168.1.1");
fl.nl_u.ip4_u.saddr = in_aton("192.168.0.186");
err = ip_route_output_key(&init_net, &rt, &fl);
if(rt)
else
printk("rt = null!\n");
…
}
暫時只找到這種實現方式,有新的發現再來更新:)
Linux下閘道器位址的獲取
linux的閘道器資訊儲存在路由表中,獲取閘道器實際上就是路由表的查詢。使用者空間獲取閘道器位址 有兩種方法,乙個是從 proc net route中讀取,這是最簡單,最直接的,route命令就是這麼做的,可以參考net tools包中route的原始碼實現。另一種是用netlink來實現。利用ne...
Linux下網路IP位址的轉換函式
網路ip位址本是用32位二進位制來表示的,為了記憶的方便可以用點分十進位制來表示ip位址,同時,網路ip位址在網路傳輸和計算機內部的儲存方式也不同,需要用函式來進行轉換。1.將點分十進位制字串轉換成十進位製長整型數 in addr t inet addr const char cp in addr ...
Linux下網路IP位址的轉換函式
網路ip位址本是用32位二進位制來表示的,為了記憶的方便可以用點分十進位制來表示ip位址,同時,網路ip位址在網路傳輸和計算機內部的儲存方式也不同,需要用函式來進行轉換。1.將點分十進位制字串轉換成十進位製長整型數 in addr t inet addr const char cp in addr ...