更新時(shí)間:2016年08月24日10時(shí)33分 來(lái)源:傳智播客C++培訓(xùn)學(xué)院 瀏覽次數(shù):
概述
通過(guò)《原始套接字實(shí)例:發(fā)送 UDP 數(shù)據(jù)包》的學(xué)習(xí),我們組 UDP 數(shù)據(jù)包時(shí)常考慮字節(jié)流順序、校驗(yàn)和計(jì)算等問(wèn)題,有時(shí)候會(huì)比較繁瑣,那么,有沒(méi)有一種更簡(jiǎn)單的方法呢?答案是:借助 libnet 函數(shù)庫(kù)。 libnet 是一個(gè)小型的接口函數(shù)庫(kù),主要用 C 語(yǔ)言寫成,提供了低層網(wǎng)絡(luò)數(shù)據(jù)包的構(gòu)造、處理和發(fā)送功能。 libnet 的開(kāi)發(fā)目的是:建立一個(gè)簡(jiǎn)單統(tǒng)一的網(wǎng)絡(luò)編程接口以屏蔽不同操作系統(tǒng)底層網(wǎng)絡(luò)編程的差別,使得程序員將精力集中在解決關(guān)鍵問(wèn)題上。 libnet 庫(kù)提供的接口函數(shù)包含 15 種數(shù)據(jù)包生成器和兩種數(shù)據(jù)包發(fā)送器(IP 層和數(shù)據(jù)鏈路層)。 1)內(nèi)存管理(分配和釋放)函數(shù) |
利用libnet函數(shù)庫(kù)開(kāi)發(fā)應(yīng)用程序的基本步驟:
1)數(shù)據(jù)包內(nèi)存初始化
2)構(gòu)造數(shù)據(jù)包
3)發(fā)送數(shù)據(jù)
4)釋放資源
以發(fā)送 UDP 數(shù)據(jù)包為例,流程圖如下:
這里需要注意的是組包的順序,由上層再到底層,這里為 udp -> ip -> mac,不能反過(guò)來(lái)。
以下函數(shù)的使用需要包含頭文件: libnet.h
libnet_t *libnet_init(int injection_type, char *device, char *err_buf);
功能:
數(shù)據(jù)包內(nèi)存初始化及環(huán)境建立
參數(shù):
injection_type:構(gòu)造的類型
LIBNET_LINK,鏈路層LIBNET_RAW4,網(wǎng)絡(luò)接口層(網(wǎng)絡(luò)層)
LIBNET_LINK_ADV,鏈路層高級(jí)版本
LIBNET_RAW4_ADV, 網(wǎng)絡(luò)層高級(jí)版本
device:網(wǎng)絡(luò)接口,如 "eth0",或 IP 地址,亦可為 NULL (自動(dòng)查詢搜索)
err_buf:存放出錯(cuò)的信息
返回值:
成功:一個(gè) libnet * 類型的指針,后面的操作都得使用這個(gè)指針
失?。篘ULL
void libnet_destroy(libnet_t *l);
功能:
釋放資源
參數(shù):
l:libnet_init() 返回的 libnet * 指針
返回值:
無(wú)
char* libnet_addr2name4(u_int32_t in, u_int8_t use_name);
功能:
將網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換成點(diǎn)分十進(jìn)制數(shù)串
參數(shù):
in:網(wǎng)絡(luò)字節(jié)序的 ip 地址
use_name:
LIBNET_RESOLVE, 對(duì)應(yīng)主機(jī)名LIBNET_DONT_RESOLVE,對(duì)應(yīng)點(diǎn)分十進(jìn)制 IPv4 地址
返回值:
成功:點(diǎn)分十進(jìn)制 ip 地址
失?。篘ULL
u_int32_t libnet_name2addr4(libnet_t *l, char *host_name, u_int8_t use_name);
功能:
將點(diǎn)分十進(jìn)制數(shù)串轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序 ip 地址
參數(shù):
l:libnet_init() 返回的 libnet * 指針
host_name:
LIBNET_RESOLVE, 對(duì)應(yīng)主機(jī)名LIBNET_DONT_RESOLVE,對(duì)應(yīng)點(diǎn)分十進(jìn)制 IPv4 地址
返回值:
成功:網(wǎng)絡(luò)字節(jié)序 ip 地址
失?。?1
u_int32_t libnet_get_ipaddr4(libnet_t *l);
功能:
獲取接口設(shè)備 ip 地址
參數(shù):
l:libnet_init() 返回的 libnet * 指針
返回值:
成功:網(wǎng)絡(luò)字節(jié)序的 ip 地址
失敗:-1
struct libnet_ether_addr* libnet_get_hwaddr(libnet_t *l);
功能:
獲取接口設(shè)備硬件地址
參數(shù):
l:libnet_init() 返回的 libnet * 指針
返回值:
成功:指向 MAC 地址的指針
失?。篘ULL
libnet_ptag_t libnet_build_udp(
u_int16_t sp, u_int16_t dp,u_int16_t len, u_int16_t sum,u_int8_t *payload, u_int32_t payload_s,libnet_t *l, libnet_ptag_t ptag);
功能:
構(gòu)造 udp 數(shù)據(jù)包
參數(shù):
sp: 源端口號(hào)
dp:目的端口號(hào)
len:udp 包總長(zhǎng)度
sum:校驗(yàn)和,設(shè)為 0,libnet 自動(dòng)填充
payload:負(fù)載,為給應(yīng)用程序發(fā)送的文本內(nèi)容,沒(méi)有內(nèi)容時(shí)可設(shè)置為 NULL
payload_s:負(fù)載長(zhǎng)度,給應(yīng)用程序發(fā)送文本內(nèi)容的長(zhǎng)度,或?yàn)?0
l:libnet_init() 返回的 libnet * 指針
ptag:協(xié)議標(biāo)記,第一次組新的發(fā)送包時(shí),這里寫 0,同一個(gè)應(yīng)用程序,下一次再組包時(shí),這個(gè)位置的值寫此函數(shù)的返回值。
返回值:
成功:協(xié)議標(biāo)記
失敗:-1
libnet_ptag_t libnet_build_tcp(
u_int16_t sp, u_int16_t dp,u_int32_t seq, u_int32_t ack,u_int8_t control, u_int16_t winu_int16_t sum, u_int16_t urg,u_int16_t len, u_int8_t *payload,u_int32_t payload_s, libnet_t *l,libnet_ptag_t ptag );
本文版權(quán)歸傳智播客C++培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!
作者:傳智播客C/C++培訓(xùn)學(xué)院
首發(fā):http://m.fskzgqt.cn/c/
北京校區(qū)