日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux 内核抓包功能实现基础(三) 抓包服务器的实现

發布時間:2025/4/5 linux 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux 内核抓包功能实现基础(三) 抓包服务器的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上回博客我們講到了內核抓包內核端的實現,通過上篇博客的例子我們就能夠開始抓包了,整個抓包的拓撲圖如下:


當開始抓包后,抓包機器將抓到的報文送到服務器上,假設服務器地址是192.168.199.123:8099,如果在抓包服務器上打開wireshark可以看到送過來的報文,如下圖這樣子:


可以看到抓包服務器上收到了報文,但是這樣子的報文我們是無法直接拿來分析的,因為實際的報文是封裝起來的,需要把數據提取出來封裝成wireshark能夠識別的格式才行,本篇博客就介紹一下抓包服務器的實現原理。

在看實際的代碼之前,我們先來看一下抓包服務器開啟后的樣子,首先監聽本地8099端口


其次將送到該端口的數據封裝成pcap格式,使用wireshark打開后如下:


這是實際抓到的報文,能夠清楚看到報文里面的各項數據。

下面介紹抓包服務器實現的原理。

抓包服務器功能大致如下:

1. 啟動后監聽報文送來的地址,在本例中是8099

2. 收到數據后將數據保存到文件中并以wireshark可識別的格式保存。

通常使用wireshark抓包保存的文件都已.pcap為后綴名。里面存儲報文的實際數據。pcap文件格式如下:


每個pcap文件都有一個pcap首部,占24字節,之后就是pcap報文頭和報文數據,報文頭存儲了抓包的時間戳等信息。

抓包服務器的任務就是新建一個pcap文件,寫入pcap文件頭后,之后每收到一個數據就寫入一個pcap報文頭和報文數據。這樣等保存文件后就可以直接使用wireshark打開了。

winpcap是windows版本的開源抓包庫,里面提供了包括pcap文件創建、保存等一系列接口,可以直接拿來使用,我這里的例子是windows64位的 golang版本的,Linux版本下有libpcap庫可供使用。

代碼如下:

// main.go package mainimport ("fmt""net""os""os/signal""strconv""syscall""time""github.com/google/gopacket""github.com/google/gopacket/layers"//"github.com/google/gopacket/pcap""github.com/google/gopacket/pcapgo" )type CaptureManager struct {F *os.File //抓包文件W *pcapgo.Writer //用于寫文件conn *net.UDPConn //udp連接 }func CaptureSaveFile() {for {//套接字接收緩存buffer := make([]byte, 65535)//接收數據num, _, err := CapMng.conn.ReadFromUDP(buffer)if nil != err {continue} else {captureInfo := gopacket.CaptureInfo{Timestamp: time.Now().UTC(),CaptureLength: num,Length: num,InterfaceIndex: 0,}//寫入pcap數據包頭以及數據CapMng.W.WritePacket(captureInfo, buffer[:num])CapMng.F.Seek(0, os.SEEK_END)}} }var CapMng *CaptureManagerfunc main() {//全局管理控制塊CapMng = &CaptureManager{}//創建目錄os.MkdirAll("capture_packet", 0777)//創建文件名字t := time.Now()fil := "capture_packet" + "/" + "capture" + "_" + t.Format("20060102150405") + ".pcap"//創建文件CapMng.F, _ = os.Create(fil)//填充pcap文件頭部24字節CapMng.W = pcapgo.NewWriter(CapMng.F)CapMng.W.WriteFileHeader(1024, layers.LinkTypeEthernet)//設置監聽地址Addr, err := net.ResolveUDPAddr("udp", "0.0.0.0:"+strconv.Itoa(8099))if nil != err {fmt.Println("resulve udp addr fail")return} else {//創建udp連接CapMng.conn, err = net.ListenUDP("udp", Addr)if nil != err {fmt.Println("create conn fail")return} else {fmt.Println("Capture Start")go CaptureSaveFile()}}chSignal := make(chan os.Signal, 5)//signal.Notify(chSignal)//監聽指定信號signal.Notify(chSignal, syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT,syscall.SIGSEGV, syscall.SIGABRT)fmt.Println("capture server start")//阻塞直至有信號傳入sig := <-chSignalswitch sig {case syscall.SIGSEGV, syscall.SIGABRT:default:}fmt.Println("*************Server Recive signal %s, program exit", sig.String())CapMng.F.Close()CapMng.conn.Close()fmt.Println("CLOSE")time.After(1 * time.Second) }

代碼在github上,下載后可在安裝了go環境下的windows上直接運行。

git@github.com:FuYuanDe/capture_demo.git

編譯go程序可能有點麻煩,但既然都看到這了,估計這點麻煩也不會難道你?

到目前位置,內核抓包功能基本的框架已經搭起來了,但是和tcpdump相比,還有很多不足之處,比方說能否根據過濾條件抓取報文?其次,送到遠端服務器上的時候如果mtu值很小怎么辦?要不要分片?還有就是在POST_ROUTING上的hook函數抓到的報文是沒有mac地址的!!!啥?沒MAC地址! 沒錯,本機出去的報文在IP層還沒有填寫MAC地址,這時候抓包的話是無法得到目的mac地址的。有空的話再聊聊這些問題的解決方法。有問題的同志想要交流的話可以加群討論一下奧

參考資料:

1.

Winpcap的安裝使用方法和問題總結

https://blog.csdn.net/yu314092706/article/details/52937189

2.?

golang使用gopacket包進行數據包捕獲,注入和分析

https://blog.csdn.net/ptmozhu/article/details/72652310?utm_source=itdadao&utm_medium=referral


3. pcap文件格式分析

https://www.cnblogs.com/2017Crown/p/7162303.html


またね!


《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的Linux 内核抓包功能实现基础(三) 抓包服务器的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。