基于 Go 和 gopacket + Fyne 的跨平臺網絡抓包工具開發實錄
一、項目背景
在網絡安全、協議分析、運維排查等場景中,抓包工具是不可或缺的利器。Wireshark 雖然功能強大,但對于部分初學者或有定制需求的開發者來說,學習曲線較陡,且二次開發門檻較高。為此,我基于 Go 語言和 Fyne GUI 框架,開發了一款輕量級、跨平臺的網絡抓包工具——IP_pkg_analyze,旨在提供簡單易用、界面友好、功能實用的抓包體驗。
很久之前做的畢設項目,現在翻出來重新投稿一下
二、技術選型
- Go 語言:并發能力強,跨平臺,生態豐富,適合底層網絡編程。
- Fyne:Go 生態下優秀的 GUI 框架,支持 Windows、Linux、macOS,界面美觀,開發效率高。
- gopacket:Google 開源的 Go 抓包庫,功能強大,支持多種協議解析。
- go-findfont:自動查找系統字體,保證界面中文顯示友好。
三、項目結構
項目結構清晰,便于維護和擴展:
ip_package-master/├── main.go // 程序入口├── app/│ ├── ip/ // 核心抓包與界面邏輯│ └── util/ // 字體等工具└── func/ // 設備選擇等輔助功能
四、核心功能與界面
1. 網絡設備選擇與抓包
程序啟動后自動檢測本機所有網絡接口,用戶可一鍵選擇需要抓包的網卡。抓包支持混雜模式和嚴格模式切換,滿足不同場景需求。
關鍵代碼片段:
// 獲取所有網絡接口
func Get_if_list() []IfaceInfo {devices, err := pcap.FindAllDevs()if err != nil {log.Fatal(err)}// ...省略部分代碼...for _, i := range interface_list {byName, err := net.InterfaceByName(i.Name)address, err := byName.Addrs()ifaceInfoList = append(ifaceInfoList, IfaceInfo{NickName: byName.Name, IPv4: address[1].String()})}return ifaceInfoList
}
2. 實時數據包捕獲與展示
抓包過程中,所有捕獲到的數據包會實時顯示在主界面列表中,包含序號、時間、源/目的地址、協議、長度、摘要等信息。支持點擊查看詳細內容和分層信息。
關鍵代碼片段:
func GetPkg(ctx context.Context, device_str string) {handle, err = pcap.OpenLive(device_str, snapshot_len, Promiscuous, timeout)packetSource := gopacket.NewPacketSource(handle, handle.LinkType())for packet := range packetSource.Packets() {p := anlysePacket(packet)AllPkgs = append(AllPkgs, p)AllPkgInfos = append(AllPkgInfos, packet)// ...省略部分代碼...}
}
3. 數據包詳細內容與分層解析
點擊任意數據包,可查看其原始字節內容(16 進制/ASCII)、協議分層(鏈路層、網絡層、傳輸層、應用層)等詳細信息,便于協議分析和調試。
關鍵代碼片段:
func NewPkgInfoData(packet gopacket.Packet) {PkgMetaData = PkgBytes2StringSlice(packet.Data())PkgCharData = PkgBytes2AsciiSlice(packet.Data())PkgInfoWidget.Refresh()PkgCharWidget.Refresh()
}
func NewLayersData(FrameNo int, packet gopacket.Packet) map[string][]string {// 解析各層協議if packet.LinkLayer() != nil {// ...}if packet.NetworkLayer() != nil {// ...}if packet.TransportLayer() != nil {// ...}if packet.ApplicationLayer() != nil {// ...}return LayersData
}
4. 數據包過濾與排序
支持按源/目的 IP、端口、長度等多維度過濾和排序,幫助用戶快速定位目標流量。
菜單功能示例:
var tools_key = []string{"文件(F)", "過濾(E)", "排序(V)", "切換(W)", "模式(M)", "發送(S)", "捕獲(C)"}
5. pcap 文件保存與導入
抓包結果可一鍵保存為 pcap 文件,便于后續分析或與他人共享。也支持導入本地 pcap 文件進行離線分析。
關鍵代碼片段:
func SaveAsPcap(path string, pkgs []gopacket.Packet) (string, error) {f, err := os.Create(path)w := pcapgo.NewWriter(f)for _, packet := range pkgs {w.WritePacket(packet.Metadata().CaptureInfo, packet.Data())}return path, nil
}
6. 自定義數據包發送
內置數據包發送功能,支持自定義源/目的 IP、端口、MAC、Payload 等,適合協議測試和網絡實驗。
關鍵代碼片段:
func SendPkg(pkg SendPkgInfo) (int, error) {handle, err = pcap.OpenLive(device, snapshot_len, promiscuous, timeout)ethernetLayer := &layers.Ethernet{...}ipLayer := &layers.IPv4{...}tcpLayer := &layers.TCP{...}buffer = gopacket.NewSerializeBuffer()gopacket.SerializeLayers(buffer, options, ethernetLayer, ipLayer, tcpLayer, gopacket.Payload(rawBytes))handle.WritePacketData(buffer.Bytes())return 0, nil
}
7. 實時流量速率監控
主界面實時顯示當前網卡上下行速率,便于流量監控和異常檢測。
關鍵代碼片段:
func monitor(ctx context.Context) {for {FlowsStr.Set(fmt.Sprintf("\rDown:%.2fkb/s \t Up:%.2fkb/s", float32(downStreamDataSize)/1024, float32(upStreamDataSize)/1024))downStreamDataSize = 0upStreamDataSize = 0time.Sleep(1 * time.Second)}
}
五、界面展示
界面采用 Fyne 框架,風格簡潔現代,主要分為:
- 頂部菜單欄:文件、過濾、排序、模式切換、發送、捕獲等功能入口
- 主體區域:數據包列表、分層信息、詳細內容、流量速率等模塊分區
- 支持窗口自適應、分辨率縮放
六、使用體驗
- 跨平臺:Windows、Linux 下均可流暢運行,界面一致。
- 易用性:無需復雜配置,開箱即用,適合新手和日常分析。
- 可擴展:代碼結構清晰,便于二次開發和功能拓展。
- 性能:基于 Go 并發,抓包效率高,界面響應流暢。
七、總結與展望
本項目作為一款輕量級抓包工具,兼顧了易用性與實用性,適合網絡學習、協議分析、實驗教學等多種場景。后續計劃:
- 增加更多協議解析與可視化支持
- 豐富過濾與統計功能
- 支持插件機制,便于社區擴展
- 優化界面交互體驗
項目地址:
https://github.com/evepupil/ip_package
歡迎大家試用、反饋和參與改進!
部分核心代碼已在文中穿插展示,完整代碼請參考項目倉庫。
如有疑問或建議,歡迎留言交流!