DIY TCP IP 網路裝置模組1

2021-09-21 02:05:50 字數 4331 閱讀 5271

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對雙絞線的連線制定了標準,使用資料通訊...