使用gopacket解析协议层中的相关数据方式

 更新时间:2025年07月08日 09:20:10   作者:jj吉吉国王  
文章介绍使用Wireshark抓取ping数据包并保存为pcap格式,通过Go语言gopacket解析,提取IP版本号、指定标识的数据包长度及应用层ICMP字符串内容,展示TCP/IP协议族解析的简便方法

通过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会非常的简单,首先要知道需要解析的数据在哪一层上,如果在应用层上就使用相关应用协议进行解析,或者自定义解析其他协议。

查看源代码可看到内置了很多支持的协议格式

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:

相关文章

  • Go语言学习之操作MYSQL实现CRUD

    Go语言学习之操作MYSQL实现CRUD

    Go官方提供了database包,database包下有sql/driver。该包用来定义操作数据库的接口,这保证了无论使用哪种数据库,操作方式都是相同的。本文就来和大家聊聊Go语言如何操作MYSQL实现CRUD,希望对大家有所帮助
    2023-02-02
  • go-spew调试利器详解

    go-spew调试利器详解

    这篇文章主要介绍了调试利器 go-spew,go-spew 可以以一种非常友好的方式输出完整的数据结构信息,go-spew 支持一些自定义配置,可以通过 spew.Config 修改,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • Golang语言如何避免空指针引发的panic详解

    Golang语言如何避免空指针引发的panic详解

    简单地说go语言的指针类型和C/C++的指针类型用法是一样的,除了出去安全性的考虑,go语言增加了一些限制,这篇文章主要给大家介绍了关于Golang语言如何避免空指针引发panic的相关资料,需要的朋友可以参考下
    2022-01-01
  • go RWMutex的实现示例

    go RWMutex的实现示例

    本文主要来介绍读写锁的一种Go语言的实现方式RWMutex,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Go1.21新增内置函数(built-in functions)详解

    Go1.21新增内置函数(built-in functions)详解

    Go 1.21新增的内置函数分别是 min、max 和 clear,这篇文章主要带大家一起了解一下这几个函数的用途和使用示例,感兴趣的小伙伴可以学习一下
    2023-08-08
  • Go读取yaml文件到struct类的实现方法

    Go读取yaml文件到struct类的实现方法

    本文主要介绍了Go读取yaml文件到struct类,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • 使用Go语言实现发送HTTP请求并给GET添加参数

    使用Go语言实现发送HTTP请求并给GET添加参数

    在开发Web应用程序时,我们经常需要向服务器发送HTTP请求,本文将介绍一下使用Go语言发送HTTP请求,并给GET请求添加参数的方法,感兴趣的小伙伴可以了解一下
    2023-07-07
  • Golang WebView跨平台的桌面应用库的使用

    Golang WebView跨平台的桌面应用库的使用

    Golang WebView是一个强大的桌面应用库,本文介绍了Golang WebView的特点和使用方法,并列举示例详细的介绍了其在实际项目中的应用,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Windows下Goland的环境搭建过程详解

    Windows下Goland的环境搭建过程详解

    这篇文章主要介绍了Windows下Goland的环境搭建过程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • Go语言数据结构之二叉树必会知识点总结

    Go语言数据结构之二叉树必会知识点总结

    如果你是一个开发人员,或多或少对树型结构都有一定的认识。二叉树作为树的一种,是一种重要的数据结构,也是面试官经常考的东西。本文为大家总结了一些二叉树必会知识点,需要的可以参考一下
    2022-08-08

最新评论