Wireshark - tshark支持iptables提供數據包

tshark現在的數據包獲取方式有兩種,分別是讀文件、網口監聽(af-packet原始套接字)。兩種方式在包獲取上,都是通過讀文件的形式;存在文件io操作,在專門處理大流量的情境下, 我們復用wireshark去做功能開發是不適合的,在文件io這部分很消耗性能。

此前什么iptables和轉發nat需要配置

準備工作

../build/CMakeFiles/tshark.dir/link.txt 鏈接-lnetfilter_queue庫

通過iptables提供數據包,跳過文件讀寫的過程,可以大大提升性能(沒有進行性能測試)

一、將iptables加到收包方式中

在原始代碼中,real_main接口為tshark工具的入口函數,前半部分都是參數解析(我們不關注),在中間部分找到,收包代碼;

其中第一個條件if (cf_name)這里是讀文件的形式,使用是通過-r *.pcap判斷的,第二個else位置,里面是capture用來監聽網口通過-I eth0使用。

追加第三個iptables收包方式。

直接固定通過iptables收包。

cf_init_iptables接口完成初始化工作,cf是全局的數據,數據包信息,數據包狀態相關,比如處理多少,丟掉多少,提供的解碼工具等外來數據。里面還加了一個wtap空間,這里是關聯到每個數據包的,保存數據包內容。

cf_status_t

cf_init_iptables(capture_file *cf,unsigned int type, gboolean is_tempfile, int *err)

{

? wtap? *wth;

? gchar *err_info;

? wth = iptables_get_wtap_init();

?

? /* The open succeeded.? Fill in the information for this file. */

? /* Create new epan session for dissection. */

? epan_free(cf->epan);

? cf->epan = tshark_epan_new(cf);

? cf->provider.wth = wth;

? cf->f_datalen = 0; /* not used, but set it anyway */

? /* Set the file name because we need it to set the follow stream filter.

???? XXX - is that still true?? We need it for other reasons, though,

???? in any case. */

? /* Indicate whether it's a permanent or temporary file. */

? cf->is_tempfile = is_tempfile;

? /* No user changes yet. */

? cf->unsaved_changes = FALSE;

? cf->cd_t????? = WTAP_FILE_TYPE_SUBTYPE_PCAP;

? cf->open_type = type;

? cf->count???? = 0;

? cf->drops_known = FALSE;

? cf->drops???? = 0;

? cf->snap????? = 262144;

? nstime_set_zero(&cf->elapsed_time);

? cf->provider.ref = NULL;

? cf->provider.prev_dis = NULL;

? cf->provider.prev_cap = NULL;

? cf->state = FILE_READ_IN_PROGRESS;

? wtap_set_cb_new_ipv4(cf->provider.wth, add_ipv4_name);

? wtap_set_cb_new_ipv6(cf->provider.wth, (wtap_new_ipv6_callback_t) add_ipv6_name);

? // 輸出格式初始化

? write_preamble(cf);

? return CF_OK;

}

running_get_pkt_from_nfqueue0接口完成iptables初始化,創建接收隊列數據包的回調,將數據包接入到tshrak的解密解碼邏輯。

void running_get_pkt_from_nfqueue0(void)

{

struct nfq_handle *h;

struct nfq_q_handle *qh;

struct nfnl_handle *nh;

int fd;

int rv;

char buf[4096] __attribute__ ((aligned));

printf("opening library handle\n");

h = nfq_open();//創建 netfilter_queue

if (!h) {//創建失敗

fprintf(stderr, "error during nfq_open()\n");

exit(1);

}

printf("unbinding existing nf_queue handler for AF_INET (if any)\n");//解綁已經存在的隊列

if (nfq_unbind_pf(h, AF_INET) < 0) {

fprintf(stderr, "error during nfq_unbind_pf()\n");

exit(1);

}

printf("binding nfnetlink_queue as nf_queue handler for AF_INET\n");//綁定上我們創建的隊列

if (nfq_bind_pf(h, AF_INET) < 0) {

fprintf(stderr, "error during nfq_bind_pf()\n");

exit(1);

}

printf("binding this socket to queue '0'\n");//cb是回調函數

qh = nfq_create_queue(h,? 0, &cb, NULL);

if (!qh) {

fprintf(stderr, "error during nfq_create_queue()\n");

exit(1);

}

printf("setting copy_packet mode\n");

if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) {//設置的包處理模式

fprintf(stderr, "can't set packet_copy mode\n");

exit(1);

}

fd = nfq_fd(h);

for (;;) {

if ((rv = recv(fd, buf, sizeof(buf), 0)) >= 0) {

//printf("pkt received\n");

nfq_handle_packet(h, buf, rv);

continue;

}

/* if your application is too slow to digest the packets that

?* are sent from kernel-space, the socket buffer that we use

?* to enqueue packets may fill up returning ENOBUFS. Depending

?* on your application, this error may be ignored. Please, see

?* the doxygen documentation of this library on how to improve

?* this situation.

?*/

if (rv < 0 && errno == ENOBUFS) {

printf("losing packets!\n");

continue;

}

perror("recv failed");

break;

}

printf("unbinding from queue 0\n");

nfq_destroy_queue(qh);//摧毀隊列,退出

#ifdef INSANE

/* normally, applications SHOULD NOT issue this command, since

?* it detaches other programs/sockets from AF_INET, too ! */

printf("unbinding from AF_INET\n");

nfq_unbind_pf(h, AF_INET);

#endif

printf("closing library handle\n");

nfq_close(h);

exit(0);

}

回調函數,這里需要做個額外的事情,因為iptables是一個三層工具,拿不到mac信息,所以這里需要加一個mac頭,位置看注釋。將數據包發給處理函數

int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,

????????? struct nfq_data *nfa, void *data) {

//printf("entering callback\n");

struct nfqnl_msg_packet_hdr *ph;

int id = 0;

ph = nfq_get_msg_packet_hdr(nfa);

if (ph) {

??? id = ntohl(ph->packet_id);

}

struct iphdr *ip_header;

unsigned char *data_buf;

int data_len = nfq_get_payload(nfa, &data_buf);

if (data_len > 0) {

??? ip_header = (struct iphdr *)data_buf;

??? //printf("Source IP: %s\n", inet_ntoa(*(struct in_addr *)&ip_header->saddr));

??? //printf("Destination IP: %s\n", inet_ntoa(*(struct in_addr *)&ip_header->daddr));

// 構造新的緩沖區

??? int new_buf_len = 14 + data_len;

??? unsigned char *new_buf = (unsigned char *)malloc(new_buf_len);

??? if (new_buf == NULL) {

??????? perror("malloc");

??????? return nfq_set_verdict(qh, id, NF_DROP, 0, NULL);

??? }

??? // 將MAC頭復制到新的緩沖區

??? memcpy(new_buf, temp_mac_header, 14);

??? // 將data_buf復制到新的緩沖區中緊隨MAC頭的位置

??? memcpy(new_buf + 14, data_buf, data_len);

process_iptables_queue_packet_signle(new_buf_len,new_buf);

??

?? free(new_buf);

}

??? return nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);

}

處理函數,初始化一個空間,數據包的所有內容保存在這里,用完釋放

void process_iptables_queue_packet_signle(int datalen, unsigned char *data)

{

capture_file *cf = &cfile;

int create_proto_tree = 1; // 是否生成解析樹

int print_detile = 1;????? // 是否打印詳細信息

epan_dissect_t *edt = epan_dissect_new(cf->epan, create_proto_tree, print_detile);

iptables_set_wth_rec_values(cf->provider.wth,datalen);

process_packet_single_pass(cf,edt,0,wtap_get_rec(cf->provider.wth),data,0);

if (edt) {

????? epan_dissect_free(edt);

????? edt = NULL;

??? }

}

這里對iptables的patch就完成了,試驗一下

Run/tshark執行,提示綁定隊列

重放數據包正常打印解析結果

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/39428.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/39428.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/39428.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Windows編程上

Windows編程[上] 一、Windows API1.控制臺大小設置1.1 GetStdHandle1.2 SetConsoleWindowInfo1.3 SetConsoleScreenBufferSize1.4 SetConsoleTitle1.5 封裝為Innks 2.控制臺字體設置以及光標調整2.1 GetConsoleCursorInfo2.2 SetConsoleCursorPosition2.3 GetCurrentConsoleFon…

python如何輸出list

直接輸出list_a中的元素三種方法&#xff1a; list_a [1,2,3,313,1] 第一種 for i in range(len(list_a)):print(list_a[i]) 1 2 3 313 1 第二種 for i in list_a:print(i) 1 2 3 313 1 第三種&#xff0c;使用enumerate輸出list_a方法&#xff1a; for i&#xff0c;j in enum…

Redis的使用(二)redis的命令總結

1.概述 這一小節&#xff0c;我們主要來研究一下redis的五大類型的基本使用&#xff0c;數據類型如下&#xff1a; redis我們接下來看一看這八種類型的基本使用。我們可以在redis的官網查詢這些命令:Commands | Docs,同時我們也可以用help 數據類型查看命令的幫助文檔。 2. 常…

數據結構 - C/C++ - 串

字符處理 C 特性 C語言中字符串存儲在字符數組中&#xff0c;以空字符\0結束。 字符串常量&#xff0c;const char* str "Hello"&#xff0c;存儲在只讀的數據段中。 布局 字符串在內存中是字符連續存儲的集合&#xff0c;最后一個字符為空字符(ASCII值為0)&…

opencascade AIS_InteractiveContext源碼學習7 debug visualization

AIS_InteractiveContext 前言 交互上下文&#xff08;Interactive Context&#xff09;允許您在一個或多個視圖器中管理交互對象的圖形行為和選擇。類方法使這一操作非常透明。需要記住的是&#xff0c;對于已經被交互上下文識別的交互對象&#xff0c;必須使用上下文方法進行…

【問題已解決】Vue管理后臺,點擊登錄按鈕,會發起兩次網絡請求(竟然是vscode Compile Hero編譯插件導致的)

問題 VueElement UI 做的管理后臺&#xff0c;點擊登錄按鈕&#xff0c;發現 接口會連續掉兩次&#xff0c;發起兩次網絡請求&#xff0c;但其他接口都是正常調用的&#xff0c;沒有這個問題&#xff0c;并且登錄按鈕也加了loading&#xff0c;防止重復點擊&#xff0c;于是開…

搜索引擎常用語法

引號 (" "): 用雙引號將詞組括起來&#xff0c;搜索引擎將返回包含完全相同短語的結果。 示例&#xff1a;"人工智能發展趨勢" 減號 (-): 在關鍵詞前加上減號可以排除包含特定詞語的結果。 示例&#xff1a;人工智能 -機器學習&#xff08;排除包含 “機器…

樸素貝葉斯解密:sklearn中的分類器工作原理

&#x1f4da; 樸素貝葉斯解密&#xff1a;sklearn中的分類器工作原理 在機器學習領域&#xff0c;樸素貝葉斯分類器因其簡單、高效而廣受歡迎。特別是在處理大量特征數據時&#xff0c;樸素貝葉斯表現出了卓越的性能。scikit-learn&#xff08;簡稱sklearn&#xff09;是Pyth…

JavaMySQL 學習(基礎)

目錄 Java CMD Java發展 計算機存儲規則 Java學習 switch新用法&#xff08;可以當做if來使用&#xff09; 數組定義 隨機數 Java內存分配 MySQL MySQL概述 啟動和停止 客戶端連接 數據模型 關系型數據庫 SQL SQL通用語法 SQL分類 DDL--數據定義語言 數據庫…

瀏覽器開發者工具輔助爬蟲開發

文章目錄 瀏覽器開發者工具輔助爬蟲開發打開開發者工具使用Network面板分析請求數據示例步驟&#xff1a; 使用Elements面板查看和修改DOM結構示例步驟&#xff1a; 使用Console面板調試JavaScript代碼示例步驟&#xff1a;示例代碼&#xff1a;1. 輸出日志信息2. 輸出對象信息…

Vue 與 React 區別

Vue.js和React是現代Web開發中兩種非常流行的前端框架&#xff0c;兩者在**核心概念、組件以及生態系統擴展性**等方面存在區別。具體分析如下&#xff1a; 1. **核心概念** - **Vue**&#xff1a;Vue是一個漸進式JavaScript框架&#xff0c;它致力于視圖層&#xff0c;易于上手…

左值右值, 左值引用右值引用,完美轉發

一. 左值和右值 左值: 可以取地址的對象 右值: 不可以取地址的對象 double x1.0, y 2.0; 1; // 字面量, 不可取地址, 是右值 x y; // 表達式返回值, 不可取地址, 是右值 max(x, y); // 傳值返回函數的返回值 (非引用返回)總結就是: 根據是否可以取地址來區分是左值還…

線程池666666

1. 作用 線程池內部維護了多個工作線程&#xff0c;每個工作線程都會去任務隊列中拿取任務并執行&#xff0c;當執行完一個任務后不是馬上銷毀&#xff0c;而是繼續保留執行其它任務。顯然&#xff0c;線程池提高了多線程的復用率&#xff0c;減少了創建和銷毀線程的時間。 2…

git修改已提交的commit注釋

在Git中修改已經提交的commit注釋通常有以下幾種情況和相應的方法&#xff1a; 1. 修改最后一次提交的注釋&#xff08;快速修正&#xff09; 如果你想要修改的是最后一次提交的注釋&#xff0c;可以使用 --amend 選項&#xff1a; git commit --amend這個命令會將你的暫存區…

基于深度學習的光度檢測

基于深度學習的光度檢測&#xff08;Photometric Detection&#xff09;涉及從圖像中檢測和分析光照信息&#xff0c;用于多種應用&#xff0c;如場景理解、照明調節、增強現實&#xff08;AR&#xff09;、圖像增強等。以下是關于這一領域的系統介紹&#xff1a; 1. 任務和目…

JAVA基礎教程DAY1-類與方法及形參實參

首先經過C語言的學習&#xff0c;我們已經學會了基本的編程方法&#xff0c;我們知道C語言是面向過程的編程語言&#xff0c;而JAVA是面向對象的編程語言&#xff0c;所以接下來我們通過對比和舉例來進行JAVA語言的學習 首先我們來講類的概念 類&#xff1a;類是一個模板&…

Ubuntu開通5005端口 記錄

Ubuntu版本&#xff1a;20.04 使用systemctl status firewalld查看防火墻狀態&#xff0c;報錯Unit firewalld.service could not be found 報錯的原因是沒有安裝firewall&#xff0c;安裝命令為sudo apt install firewalld&#xff0c;然后進行安裝 安裝完成后輸入systemctl…

vscode jupyter選擇Python環境時找不到我安裝的Python

在一些情況下&#xff0c;我們需要自己安裝一個Python&#xff0c;在選擇內核是可能找不到指定的Python版本&#xff0c; 再次打開內核選擇頁面就能看到Python環境了 注意先到指定環境下安裝依賴包&#xff1a; ./python3 pip install ipykernel notebook jupyter

人工智能-NLP簡單知識匯總01

人工智能-NLP簡單知識匯總01 1.1自然語言處理的基本概念 自然語言處理難點&#xff1a; 語音歧義句子切分歧義詞義歧義結構歧義代指歧義省略歧義語用歧義 總而言之&#xff1a;&#xff01;&#xff01;語言無處不歧義 1.2自然語言處理的基本范式 1.2.1基于規則的方法 通…

[DataWhale大模型應用開發]學習筆記1-嘗試搭建向量數據庫

1.詞向量 1.定義 詞向量&#xff08;Word Vector&#xff09;是將單詞表示為向量形式的技術&#xff0c;是自然語言處理&#xff08;NLP&#xff09;中的一種常用方法。通過將單詞轉化為向量&#xff0c;計算機能夠更好地理解和處理語言。簡單來說&#xff0c;詞向量就是將單…