使用gopacket解析協議層中的相關數據

通過wirshark可視化相關應用層使用gopacket來進行解析,或獲取指定結構內容。

首先使用wirshark抓取ping x.x.x.x 命令數據包
在這裏插入圖片描述
保存數據包爲pcap格式。

在使用wirshark打開pcap數據包。

在這裏插入圖片描述
嘗試使用go語言的gopacket來讀取指定數據包的字段數據。
可看到,數據包一共爲103個。先用go讀取文件,統計有多少個數據包。

package main
import (
	"fmt"
	"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(),
	)
	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/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) //解析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.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)
			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會非常的簡單,首先要知道需要解析的數據在哪一層上,如果在應用層上就使用相關應用協議進行解析,或者自定義解析其他協議。

查看源代碼可看到內置了很多支持的協議格式
在這裏插入圖片描述

本文相關參考:
https://blog.lab99.org/post/golang-2017-09-23-video-packet-capture-analysis-with-go.html
http://www.52im.net/topic-tcpipvol1.html?mobile=no

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章