相比較第17章用ioctl函式獲取整個路由表,利用sysctl函式也是可以做到而且無需超級使用者許可權。
i、程序可以通過寫出到路由套接字而往核心傳送訊息。路徑的增加和刪除採用這種操作實現。
ii、程序可以通過從路由套接字讀入來自核心接收訊息。核心採用這種操作通知程序已收到並處理乙個icmp重定向訊息,或者請求外部路由程序解析乙個路徑。
iii、程序可以使用sysctl函式傾瀉出路由表或列出所有已配置的介面。
資料鏈路套接字位址結構(定義在net/if_dl.h檔案中,我的機器上沒有這檔案,所以本章的程式都無法編譯通過,需要的可以參考if_dl.h檔案,如果已有的話,可以發份我,感激不盡!)
struct sockaddr_dl ; //contains i/f name and link-layer address
i、通過路由套接字交換的訊息型別(見書上p383)
ii、在路由訊息中用於指稱套接字位址結構的常值(見書上p385)
iii、獲取並輸出乙個路由表項的**實現(沒有用sysctl函式實現)
以下程式通過命令引數取得乙個ipv4點分十進位制數字址,並就這個位址向核心傳送乙個rtm_get訊息。核心在它的ipv4路由表中查詢這個位址,並作為乙個rtm_get訊息返回相應路由表項的資訊。先見圖,再見**。
get_rtaddrs(rtm->rtm_addrs, sa, rti_info);//此函式將構造指向路由訊息中各個套接字位址結構的指標陣列,由於篇幅,此處不再給出,具體見書上p389
if ((sa = rti_info[rtax_dst]) != null)
printf("dest: %s\n", sock_ntop_host(sa, sa->sa_len));
if ((sa = rti_info[rtax_gateway]) != null)
printf("gateway: %s\n", sock_ntop_host(sa, sa->sa_len));
if ((sa = rti_info[rtax_netmask]) != null)
printf("netmask: %s\n", sock_masktop(sa, sa->sa_len));
if ((sa = rti_info[rtax_genmask]) != null)
printf("genmask: %s\n", sock_masktop(sa, sa->sa_len));
exit(0);
}
#include#include//oldp供核心存放值的buffer,oldlenp代表buffer大小(值-結果引數)
int sysctl(int *name, u_int namelen, void* oldp, size_t* oldlenp,
void* newp, size_t newlen);//若成功則為0,若出錯則為-1
上述函式中的形參還需要著重強調一下name,name引數是指定名字的乙個整數陣列,namelen引數指定該陣列中的元素數目。該陣列中的第乙個指定本請求定向到核心的哪個子系統。第二個及其後元素逐次細化指定該子系統的某個部分。
當name陣列的第二個元素為af_route時,第三個元素(協議號)總是為0(因為af_route族不像比如說af_inet族那樣其中有協議),第四個元素是乙個位址族,第五和第六級指定做什麼。如下圖所示:
name
返回ipv4路由表
返回ipv4arp快取記憶體
返回ipv6路由表
返回介面清單
0ctl_net
ctl_net
ctl_net
ctl_net
1af_route
af_route
af_route
af_route20
0003
af_inet
af_inet
af_inet604
net_rt_dump
net_rt_flags
net_rt_dump
net_rt_iflist50
rtf_llinfo
0net_rt_dump返回由name[3]指定的位址族的路由表。如果所指定的位址族為0,那麼返回所有位址族的路由表。
net_rt_flags返回由name[3]指定的位址族的路由表,但是僅限於那些所帶標誌(若干個rtf_***常值的邏輯或)與name[5]指定的標誌相匹配的路由表項。路由表中所有arp快取記憶體表項均設定了rtf_llinfo標誌位。
net_rt_iflist返回所有已配置介面的資訊。如果name[5]不為0,它就是某個介面的索引號,於是僅僅返回該介面的資訊。已賦予每個介面的所有位址也同時返回,不過如果name[3]不為0,那麼僅限於返回指定位址族的位址。
利用sysctl函式實現char* net_rt_iflist(int family,int flags,size_t *lenp);**如下:
#include "unproute.h"
char *
net_rt_iflist(int family, int flags, size_t *lenp)
return(buf);
}
由於本人所裝ubuntu14.04實現不了本章的程式,所以此處利用sysctl函式實現get_ifi_info函式不再給出,具體見書上p395-p396。
每個介面都有乙個唯一的名字和乙個唯一的正值索引(0從不用作索引)。
#includeunsigned in if_nametoindex(const char* ifname);//返回:若成功則為正的介面索引,若出錯則為0;
char* if_indextoname(unsigned int ifindex, char* ifname);//返回:若成功則為指向介面名字的指標,若出錯則為null
struct if_nameindex* if_nameindex(void);//返回:若成功則為非空指標,若出錯則為null
void if_freenameindex(struct if_nameindex* ptr);
上述四個介面名字和索引函式均通過net_rt_iflist函式實現,具體實現見書上p397-p400。
以上知識點來均來自steven先生所著unp卷一(version3),剛開始學習網路程式設計,如有不正確之處請大家多多指正。
UNP卷一chapter20 廣播
型別ipv4 ipv6 tcpudp 所標識介面數 遞送到介面數單播y yyy乙個 乙個任播 y 尚沒有y 一組一組中的乙個 多播可選yy 一組一組中的全體廣播y y全體全體表中要點 i 多播支援在ipv4中是可選的,在ipv6中卻是必需的 ii ipv6不支援廣播。使用廣播的任何ipv4應用程式一...
UNP卷一chapter8 基本UDP套接字程式設計
以下知識點來均來自steven先生所著unp卷一 version3 剛開始學習網路程式設計,如有不正確之處請大家多多指正。需要注意的是,udp不面向連線,故不需要使用connect函式,但使用connect也是可以的,只是作用不再是三次握手建立連線,其作用表現在檢測非同步錯誤 asychronous...
UNP卷一chapter2相關概念
以下知識點來均來自steven先生所著unp卷一 version3 剛開始學習網路程式設計,如有不正確之處請大家多多指正。1 tcp是乙個提供面向連線 可靠 無差錯 不丟失 不重複 按序到達的資料流傳輸協議。頭部開銷為20位元組。全雙工邏輯通道。支援的上層應用協議為telnet ftp smtp h...