下面是分析tcp_v4_init的時候了,這個函數在net/ipv4/tcp_ipv4.c裡面:
__initfunc(voidtcp_v4_init(structnet_proto_family*ops))
{
interr;
tcp_inode.i_mode=S_IFSOCK;
tcp_inode.i_sock=1;
tcp_inode.i_uid=0;
tcp_inode.i_gid=0;
tcp_socket->inode=&tcp_inode;
tcp_socket->state=SS_UNCONNECTED;
tcp_socket->type=SOCK_RAW;
if((err=ops->create(tcp_socket,IPPROTO_TCP))<0)
panic("FailedtocreatetheTCPcontrolsocket./n");
tcp_socket->sk->allocation=GFP_ATOMIC;
tcp_socket->sk->num=256;
tcp_socket->sk->ip_ttl=MAXTTL;
}
tcp_inode當然就是一個inode節點了,而tcp_socket等於tcp_inode.u.socket_i,
通過一個指標他們指向同一個記憶體.
tcp_socket是用來通訊使用的,可以叫TCP的controlsocket或者是communication
socket,當TCP通訊沒有相應的socket的時候這個socket就充當了socket的角色.比如在一個關閉連接埠上收到SYN時發送RST,或者是在三向交握的時候發送SYN(還沒有accept產生新的socket)
值得注意的是ops->create函數的調用,我們前面見過對於AF_INET來說這個回呼函數是net/ipv4/af_inet.c的inet_create函數,這個函數是用來建立一個socket的時候用的,由於函數比較長,這裡先略過分析,這第一次的分析只是一個大致流程的熟悉而已.
由於有socket建立和通訊,所以這段代碼是協議相關的,所以把這段代碼從原來的tcp.c裡面提取了出來
下面是tcp_init函數,它在net/ipv4/tcp.c裡面,大體上來說就是建立了幾個hash表和bucket.這段代碼建立了下面幾個全域對象:
tcp_openreq_cachep
tcp_bucket_cachep
tcp_timewait_cachep
tcp_ehash
tcp_bhash
其中ehash代表establishedhash,bhash代表bindhash,它們當然分別是所有的滿足TCP_ESTABLISHED<=sk->state<TCP_CLOSE狀態的SOCK.但是我不清楚bucket在這裡是什麼意思.anyoneknows?那幾個cachep的作用也不是很清楚,特別是第二個,根本摸不著頭腦.由於整個函數主要是記憶體配置和錯誤處理,這裡不貼了.
再下來就是icmp_init函數了,在net/ipv4/icmp.c裡面,事實上,如果把tcp_v4_init裡面的IPPROTO_TCP替換成IPPROTO_ICMP,基本都是一樣的.剩下的proc_net_register函數前面已經講過了,這裡就不說了.
到這裡為止,Linux下面IP棧的開始的工作我們基本應該有了個瞭解,其中有幾個關鍵的函數:
dev_add_pack:註冊一個鏈路層以上的處理函數,一般是用來使用新的網路層協議的,不過如果註冊時重複也是可以的,這時候系統會設定一個copy位.如果是ETH_P_ALL則會接收所有的資料包.加入的元素儲存在ptype_all鏈表和ptype_basehash鏈表中間.
inet_add_protocol:註冊一個建立在IP層以上的協議,例如TCP和UDP等
proc_net_register(還有類似的proc_register):
在/proc/net目錄下面建立一個子目錄項來使管理者能通過檔案系統得到統計資訊
現在迷惑的地方還有很多,一個是結構體sk_buff的每個成員的意義,一個是結構體sock的意義,不過這兩個問題應該在以後看多了就知道了.下面我就打算一個個分析每個協議的處理了,包括狀態轉化/資料發送/接收.
--
Wishyourskybesunny,
Wishyourheartbehappy,
Wishyourbodybehealthy,
WishUneverbelazy.
:):>;);>:-):->;-);->