使用gopacket解析协议层中的相关数据方式
目录
- 通过wirshark可视化相关应用层
- 打印所有数据包中协议版本号(4、6)
- 获取指定数据包的长度
- 总结
通过wirshark可视化相关应用层
使用gopacket来进行解析,或获取指定结构内容。
首先使用wirshark抓取ping x.x.x.x 命令数据包
保存数据包为pcap格式。
在使用wirshark打开pcap数据包。
尝试使用go语言的gopacket来读取指定数据包的字段数据。
可看到,数据包一共为103个。先用go读取文件,统计有多少个数据包。
package main import ( "fmt" "github.com/google/goppythonacket" "github.com/google/gopacket/pcap" ) func main() { handle, _ := pcap.OpenOffline("ping.pcap") defer handle.Close() packetSource := gopacket.NewpacketSource( handle, handle.LinkType(), ) num := 0 for packet := range packetSource.Packets() { num += 1 fmt.Println(num) fmt.Println(packet) } }
运行代码
打印所有数据包中协议版本号(4、6)
目前的协议版本号是4,因此IP有时也称作IPv4。该值存放在IP层中,所以利用程序解析IP层中的数据。
package main import ( "fmt" "github.com/google/gopacket/layers" "github.com/google/g编程客栈opacket" "github.com/google/gopacket/pcap" ) func main() { handle, _ := pcap.OpenOffline("ping.pcap") defer handle.Close() packetSource := gopacket.NewPacketSource( handle, handle.LinkType(), ) for packet := range packetSource.Packets() { ipLayer := packet.Layer(layers.LayerTypeIPv4) //解析IP层 if ipLayer != nil 编程客栈{ ip, _ := ipLayer.(*layers.IPv4) fmt.Println("Version:", ip.Version) } } }
获取指定数据包的长度
要获取指定数据包就需要找到数据包的唯一标识:
标识字段唯一地标识主机发送的每一份数据报。通常每发送一份报文它的值就会加1。
获取唯一标识1917的总长度:
package main import ( "fmt" "github.com/google/gopacket/layers" "github.com/google/gopacket" "github.com/google/gopacket/pcap" ) func main() { handle, _ := pcap.Op编程客栈enOffline("ping.pcap") defer handle.Close() packetSource := gopacket.NewPacketSource( handle, handle.LinkType(), ) for packet := range packetSource.Packets() { ipLayer := packet.Layer(layers.LayerTypeIPv4) //解析IP层 if ipLayer != nil { ip, _ := ipLayer.(*layers.IPv4) //fmt.Println("Version:", ip.Version) if ip.Id == 1917 { fmt.Println("ID:", ip.Id) fmt.Println("Length:", ip.Length) } } } }
查看源代码,IP层可使用以下相关字段
fmt.Println("ID:", ip.Id) fmt.Println("Length:", ip.Length) fmt.Println("源IP:", ip.SrcIP) fmt.Println("目的IP:", ip.DstIP)
1917数据包向目的地址发送了一段字符串abcdef…尝试使用程序获取这段字符串
从wirshark中可看到,想要获取的这段字符串在应用层上,可看到该协议为ICMP协议。
gopacket内置的有ICMP包的解析方式,不需要我们在自定义。
package main import ( "fmt" "github.com/google/gopacket/layers" "github.com/google/gopacket" "github.com/google/gopacket/pcap" ) func main() { handle, _ := pcap.OpenOffline("ping.pcap") defer handle.Close() packetSource := gopacket.NewPacketSource( handle, handle.LinkType(), ) for packet := range packetSource.Packets() { ipLayer := packet.Layer(layers.LayerTypeIPv4) if ipLayer != nil { ip, _ := ipLayer.(*layers.IPv4) if ip.Id == 1917 { icmpLayer := packet.Layer(layers.LayerTypeICMPv4) //解析应用层ICMP数据包 if icmpLayer != nil { fmt.Println(string(icmpLayer.LayerPayload())) } } } } }
成功获取数据内容。
熟悉TCP/IP协议族使用gopacket会非常的简单,首先要知道需要解析的数据在哪一层上,如果在应用层上就使用相关应用协议进行解析,或者自定义解析其他协议。
查看源代码可看到内置了很多支持的协议格式
总结
以上为http://www.devze.com个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。
精彩评论