5. 網路裝置模組的實現
本章介紹diy tcp/ip的網路裝置模組的實現。網路裝置層的邏輯包括,接收邏輯和傳送邏輯。接收邏輯:diy tcp/ip通過pf_packet域的socket接收鏈路層資料幀,模擬硬體網絡卡的接收。接收佇列非同步處理鏈路層接收的資料幀,解析乙太網頭部,根據乙太網頭部型別,將資料幀交給diy tcp/ip的上層模組處理。傳送邏輯:接收上層模組傳送的資料幀,交給傳送佇列非同步處理,同樣通過pf_packet域的socket模擬硬體網絡卡的傳送。本章基於第4章(從0開始)device.c的實現,繼續模組化device.c,定義網路裝置資料結構,封裝pcap_loop接收的資料幀,實現接收佇列和接收執行緒,在接收執行緒中非同步處理pcap_loop接收的資料幀,解析資料幀,為呼叫上層模組的介面函式預留**位置。後續章節實現diy tcp/ip上層模組的介面函式後,替換預留的**位置即可。
5.1 網路裝置結構體
本節基於4.5節device.c的實現,繼續模組化device.c,將與網路裝置模組相關的邏輯放在device.c中,無關的邏輯放在其他模組檔案中,先來看device.h中網路裝置結構體的定義。
device.h
#ifndef _device_h_
#define _device_h_
#include #define max_network_segment_size 65535
#define promisc_enable 1
#define promisc_disable 0
#define timeout_ms 512
#define filter_buffer_size 256
typedef struct _net_device net_device_t;
net_device_t *netdev_init(char *ifname);
void netdev_deinit(net_device_t *ndev);
void netdev_start_loop(net_device_t *ndev);
void netdev_stop_loop(net_device_t *ndev);
net_device_t *netdev_get(void);
#endif
line 4-9: 與4.6節一致。
line 11-12: 定義網路裝置結構體net_device_t。便於描述,將pcap_t結構體稱為pcap裝置,網路裝置結構體目前只是封裝了pcap裝置,尚未加入傳送佇列和接收佇列資料結構的定義。
line 15-19: 宣告網路裝置模組暴露給其他模組的介面函式。netdev_init初始化網路裝置;netdev_deinit銷毀網路裝置;netdev_start_loop,開始從鏈路層接收資料幀;netdev_stop_loop,結束從鏈路層接收資料幀;netdev_get獲取網路裝置結構體的指標。根據這些函式介面的定義,重寫device.c,實現這些介面函式,分離與網路裝置層無關的**邏輯。
device.c
#include #include #include #include #include "init.h"
#include "common.h"
#include "device.h"
static net_device_t *gndev = null;
...
line10: 定義靜態net_device_t指標,用於儲存netdev_init初始化的網路裝置結構體的指標。
line11 之後省略掉的**是init_packet_filter與4.5節一致,pcap_callback與4.6節一致。
net_device_t * netdev_init(char *ifname)
gndev = ndev;
printf("network device init\n");
/* obtain packet capture handle */
ndev->pcap_dev = pcap_open_live(default_ifname,
max_network_segment_size, promisc_enable, timeout_ms, err_buf);
if (ndev->pcap_dev == null)
/* set pcap filter */
memset(pcap_packet_filter, 0, filter_buffer_size);
init_packet_filter(pcap_packet_filter, filter_buffer_size);
if (pcap_compile(ndev->pcap_dev, &filter_code,
pcap_packet_filter, 1, ipv4_network_mask) < 0)
if (pcap_setfilter(ndev->pcap_dev, &filter_code) < 0)
return ndev;
out:
netdev_deinit(ndev);
return null;
}
line 8-14: 申請記憶體,建立網路裝置。將網路裝置結構體的指標儲存在靜態指標gndev中。
line 16-39: 網路裝置結構體net_device_t封裝了pcap裝置。後續章節用到的libpcap庫函式,包括本節的pcap_open_live,,pcap_compile和pcap_setfilter均通過網路裝置結構體訪問pcap裝置。在netdev_init函式中,開啟pcap裝置,設定幀過濾條件,返回網路裝置結構體的指標。如果line55-71的libpcap庫函式返回出錯,呼叫netdev_deinit銷毀網路裝置,返回null。
void netdev_deinit(net_device_t *ndev)
void netdev_start_loop(net_device_t *ndev)
void netdev_stop_loop(net_device_t *ndev)
net_device_t *netdev_get(void)
line 1-10: 銷毀網路裝置,呼叫pcap_close關閉pcap裝置,然後釋放netdev_init中為網路裝置申請的記憶體。
line 12-25: netdev_start_loop和netdev_stop_loop,是對pcap_loop和pcap_breakloop的封裝,用於開始接和結束接收鏈路層資料幀。
line 27-30: netdev_get返回網路裝置結構體的指標,gndev供其他模組獲取網路裝置。
5.2 初始化模組
5.1節重寫了device.c,目前device.c只包含與網路裝置相關的邏輯。從零開始**中的訊號處理函式和入口main函式,放在diy tcp/ip的初始化檔案init.c中,init.c是diy tcp/ip執行的入口。
#include #include #include "init.h"
#include "device.h"
void signal_handler(int sig_num)
int main(int argc, char *ar**)
line 7-13: 訊號處理函式,呼叫netdev_get獲取網路裝置結構體的指標,再呼叫netdev_stop_loop結束主迴圈。
line 16-32: main函式是diy tcp/ip的入口函式,先註冊新號處理函式用於捕獲sigint訊號,netdev_init初始化網路裝置模組,呼叫netdev_start_loop開始主迴圈。netdev_start_loop是對pcap_loop的封裝,開始從鏈路層接收資料幀,直到終端鍵入ctrl+c結束迴圈。netdev_start_loop返回後,main函式繼續執行到netdev_deinit銷毀網路裝置層,確保整個過程無記憶體洩漏。
把diy tcp/ip初始化模組init.c加入到makefile中,與device.c一起編譯鏈結。makefile修改如下:
tcp_ip_stack:device.o init.o
gcc -o tcp_ip_stack device.o init.o -lpcap
device.o:device.c device.h init.h common.h
gcc -c device.c
init.o:init.c init.h
gcc -c init.c
clean:
rm -rf *.o
rm -rf tcp_ip_stack
DIY TCP IP 網路裝置模組4
5.3.3 網路裝置模組資料幀 本節結合5.3.2節鍊錶和佇列的實現,定義diy tcp ip網路裝置模組資料幀的資料結構,以便用於佇列操作。在pcap callback返回接收到的資料幀後,將pcap pkthdr封裝成本節定義的資料幀,為實現網路裝置模組的接收佇列做準備。diy tcp ip網路...
VOIP網路裝置
voip 系統的基本元件 終端 閘道器 關守 網管伺服器 記帳伺服器等,下面介紹一下各個元件的功能 1 終端 terminal voip的終端可以有多種型別,其中包括傳統的語音 isdn終端 pc,也可以是集語音 資料和圖象於一體的多 業務終端。由於不同種類的終端產生的資料來源結構是不同的,要在同乙...
連線網路裝置
雙機網際網路絡 集線器網際網路絡 交換機網際網路絡 路由器網際網路絡 雙機網際網路絡 計算機與計算機連線 如果只有兩台計算機進行互連,也可以使用雙絞線將兩台計算機的網絡卡連線在一起,但是必須使用交叉線方法製作的網線,才能正常連線。雙絞線的連線標準 eia tia對雙絞線的連線制定了標準,使用資料通訊...