gopacket
是一个在 Go 语言中用于网络包解析和分析的库。它允许你捕获网络流量,解析网络层(如 IP、TCP、UDP 等)和应用层协议(如 HTTP、DNS 等)的数据包。在 gopacket
中,Packet
类型代表了一个完整的网络数据包,而 Layer
类型则代表了这个数据包中的一个单独的层(如 IP 层、TCP 层等)。
ICMPv4结构体解析:
type ICMPv4 struct {
BaseLayer //含有PayLoad和Contents变量
TypeCode ICMPv4TypeCode
Checksum uint16
Id uint16
Seq uint16
}
package main
import (
"fmt"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
)
func main() {
//handle, err := pcap.OpenLive("any", 1600, true, pcap.BlockForever) //监听本地any网卡
handle, _ := pcap.OpenOffline("icmp_onvif_111_207.pcap") //打开pcap文件
defer handle.Close()
packetSource := gopacket.NewPacketSource(
handle,
handle.LinkType(),
)
handle.SetBPFFilter("icmp or tcp") //设置过滤条件,只解析icmp或者tcp包
for packet := range packetSource.Packets() {
layer := packet.Layer(layers.LayerTypeICMPv4) //获取数据包的ICMP层
if layer != nil {
icmplayer := layer.(*layers.ICMPv4) //将layer转换成ICMPv4类型
if icmplayer.TypeCode.Type() == layers.ICMPv4TypeEchoReply { //判断是否是ICMP ECHO REPLY 类型的报文
fmt.Println("-----------------layer------------------")
fmt.Println("-----LayerType", layer.LayerType())
fmt.Printf("-----LayerContents ")
ByteArrTo16(layer.LayerContents())
fmt.Printf("-----LayerPayload ")
ByteArrTo16(layer.LayerPayload()) //输出数据包的携带的data部分
fmt.Println("-----------------icmplayer------------------")
fmt.Printf("-----BaseLayer.Contents ")
ByteArrTo16(icmplayer.BaseLayer.Contents)
fmt.Printf("-----BaseLayer.Payload ")
ByteArrTo16(icmplayer.BaseLayer.Payload)
fmt.Println("-----TypeCode", icmplayer.TypeCode)
fmt.Println("-----Checksum", icmplayer.Checksum)
fmt.Println("-----Id", icmplayer.Id)
fmt.Println("-----Seq", icmplayer.Seq)
}
}
}
}
//以十六进制输出字节数组
func ByteArrTo16(arr []byte) {
for _, a := range arr {
fmt.Printf("%x ", a)
}
fmt.Println()
}
其中layers.ICMPv4中的各个变量都同wireshark打开的pcap文件中一一对应: