# 嗅探和播放网络数据包的辅助函数 **Repository Path**: sillyman/pcaphelper ## Basic Information - **Project Name**: 嗅探和播放网络数据包的辅助函数 - **Description**: gopacket 的再包装,用于 ip 设备的自动化测试。 - **Primary Language**: Go - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 1 - **Created**: 2020-09-14 - **Last Updated**: 2022-07-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 嗅探和播放网络数据包的辅助函数 ## 介绍 `github.com/google/gopacket` 的再包装,所以需要系统要安装 libpacap-dev,以 Deepin 为例: ``` sudo apt install libpcap-dev libpcap0.8-dev ``` ## 安装教程 `go get gitee.com/sillyman/pcaphelper` ## Example ### 播放 pcap 文件 ```go package main import ( "log" "net" "gitee.com/sillyman/pcaphelper" ) func main() { pktPlayer, err := pcaphelper.New("enp3s0") if err != nil { log.Fatalln(err) } defer pktPlayer.Close() if err := pktPlayer.PlayPCAPFileWithHook("test.pcap", "dst host 10.0.0.228 and tcp", 0, pcaphelper.MakeTrHookThatMutateEthIP4(nil, net.HardwareAddr{0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, nil, net.IPv4(10, 0, 0, 1)), ); err != nil { log.Fatalln(err) } } ``` ### 播放自定义的网络数据包 以下播放了一个带双VLAN的UDP包 ```go package main import ( "log" "net" "time" "gitee.com/sillyman/pcaphelper" "gitee.com/sillyman/pcaphelper/pktbuilder" ) func main() { pktPlayer, err := pcaphelper.New("enp3s0") if err != nil { log.Fatalln(err) } defer pktPlayer.Close() _ = pktPlayer.WritePacketData( pktbuilder.BuildingEtherPkt(net.HardwareAddr{0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, net.HardwareAddr{0x0, 0x0, 0x0, 0x0, 0x0, 0x2}, pktbuilder.GenLayerThatDot1Q(3, 3000, pktbuilder.GenLayerThatDot1Q(1, 41, pktbuilder.GenLayerThatIP4(net.IPv4(10, 0, 0, 1), net.IPv4(10, 0, 0, 2), pktbuilder.GenLayerThatUDP(40000, 40000, nil), ), ), ), ), ) } ``` ### 捕获网络数据包并保存到文件 ```go package main import ( "log" "time" "github.com/google/gopacket/pcap" "gitee.com/sillyman/pcaphelper" ) func main() { pktSniffer, err := pcaphelper.New("enp3s0") if err != nil { log.Fatalln(err) } defer pktSniffer.Close() if err = pktSniffer.MustSetDireAndBPF(pcap.DirectionInOut, "").SniffingOnDurationToFile(10*time.Second, "test.pcap"); err != nil { log.Fatalln(err) } } ``` ### 捕获 ARP 并打印其信息 ```go package main import ( "fmt" "log" "net" "time" "github.com/google/gopacket" "github.com/google/gopacket/layers" "github.com/google/gopacket/pcap" "gitee.com/sillyman/pcaphelper" "gitee.com/sillyman/pcaphelper/bpfgenerator" ) func main() { pktSniffer, err := pcaphelper.New("wlp5s0") if err != nil { log.Fatalln(err) } defer pktSniffer.Close() matchOUI := bpfgenerator.GenRuleForMatchMacOUI("src|dst", [3]byte{0x30, 0x5a, 0x3a}) pktSniffer.MustSetDireAndBPF(pcap.DirectionInOut, matchOUI).SniffingOnDuration(100*time.Second, func(pkt gopacket.Packet) bool { if arpLayer := pkt.Layer(layers.LayerTypeARP); arpLayer != nil { arpHeader := arpLayer.(*layers.ARP) switch arpHeader.Operation { case layers.ARPRequest: fmt.Printf("%s --> %s | %s --> %s\n", net.HardwareAddr(arpHeader.SourceHwAddress), net.HardwareAddr(arpHeader.DstHwAddress), net.IP(arpHeader.SourceProtAddress), net.IP(arpHeader.DstProtAddress)) case layers.ARPReply: fmt.Printf("%s <-- %s | %s <-- %s\n", net.HardwareAddr(arpHeader.DstHwAddress), net.HardwareAddr(arpHeader.SourceHwAddress), net.IP(arpHeader.DstProtAddress), net.IP(arpHeader.SourceProtAddress)) } } return true }) } ```