Golang案例开发之gopacket监听网卡抓包(2)

文章目录


前言

本节实战,监听指定网卡,进行网络抓包,根据分层,解析不同分层包的内容。


二、实践 监听网卡抓包

1.代码

代码如下(示例):

go 复制代码
package main

import (
	"fmt"
	"log"
	"strings"
	"time"

	"github.com/google/gopacket"
	"github.com/google/gopacket/layers"
	"github.com/google/gopacket/pcap"
)

// 监听 ens33 网卡上的  目标端口 5100的 TCP包

func main() {

	handler, err := pcap.OpenLive("ens33", 1024, false, time.Second*5)
	if err != nil {
		log.Fatal(err)
	}
	defer handler.Close()

	var filter string = "tcp port 5100"
	handler.SetBPFFilter(filter)
	source := gopacket.NewPacketSource(handler, handler.LinkType())
	for packet := range source.Packets() {
		// fmt.Printf("%v", packet.String())
		printPacketInfo(packet)
	}
}

// 根据网络层级,输出信息
func printPacketInfo(packet gopacket.Packet) {

	ethernetLayer := packet.Layer(layers.LayerTypeEthernet)
	if ethernetLayer != nil {
		fmt.Println("Ethernet layer detected.")
		ethernetPacket, _ := ethernetLayer.(*layers.Ethernet)
		fmt.Println("Source MAC: ", ethernetPacket.SrcMAC)
		fmt.Println("Destination MAC: ", ethernetPacket.DstMAC)
		// Ethernet type is typically IPv4 but could be ARP or other
		fmt.Println("Ethernet type: ", ethernetPacket.EthernetType)
		fmt.Println()
	}

	ipLayer := packet.Layer(layers.LayerTypeIPv4)
	if ipLayer != nil {
		fmt.Println("IPv4 Layer detected")
		if ip, ok := ipLayer.(*layers.IPv4); ok {
			fmt.Printf("From %s to %s \n", ip.SrcIP, ip.DstIP)
			fmt.Println("Protocol", ip.Protocol)
		}
	}

	tcpLayer := packet.Layer(layers.LayerTypeTCP)
	if tcpLayer != nil {
		fmt.Println("TCP layer detected.")
		tcp, _ := tcpLayer.(*layers.TCP)
		// TCP layer variables:
		// SrcPort, DstPort, Seq, Ack, DataOffset, Window, Checksum, Urgent
		// Bool flags: FIN, SYN, RST, PSH, ACK, URG, ECE, CWR, NS
		fmt.Printf("From port %d to %d\n", tcp.SrcPort, tcp.DstPort)
		fmt.Println("Sequence number: ", tcp.Seq)
		fmt.Println()
	}

	// Iterate over all layers, printing out each layer type
	fmt.Println("All packet layers:")
	for _, layer := range packet.Layers() {
		fmt.Println("- ", layer.LayerType())
	}
	// When iterating through packet.Layers() above,
	// if it lists Payload layer then that is the same as
	// this applicationLayer. applicationLayer contains the payload
	applicationLayer := packet.ApplicationLayer()
	if applicationLayer != nil {
		fmt.Println("Application layer/Payload found.")
		fmt.Printf("%s\n", applicationLayer.Payload())
		// Search for a string inside the payload
		if strings.Contains(string(applicationLayer.Payload()), "HTTP") {
			fmt.Println("HTTP found!")
		}
	}
	// Check for errors
	if err := packet.ErrorLayer(); err != nil {
		fmt.Println("Error decoding some part of the packet:", err)
	}

}

2.知识点

OpenLive方法

go 复制代码
func OpenLive(device string, snaplen int32, promisc bool, timeout time.Duration) (handle *Handle, _ error)

参数说明:

  • device:要打开的网络接口名称,例如"eth0"、"en0"等。
  • snaplen:要捕获的数据包最大长度,通常设置为65535以便捕获完整的数据包。
  • promiscuous:是否启用混杂模式,即接收所有经过网络接口的数据包,默认为false。
  • timeout:超时时间,表示在没有新数据包到达时等待多久,默认为无限等待。

返回值:handle *Handle error

SetBPFFilter

支持通过handle.SetBPFFilter 方式这是过滤器。

filter的规则和tcpdump的用法类似。

断言

在Go语言中,断言(assertion)是一种重要的机制,它用于判定某个条件是否为真,并在条件不满足时触发相应的操作。

断言的语法格式如下:

bash 复制代码
value, ok := x.(T)

上文中的几处都用到了断言

bash 复制代码
ethernetPacket, _ := ethernetLayer.(*layers.Ethernet)
ip, ok := ipLayer.(*layers.IPv4)
tcp, _ := tcpLayer.(*layers.TCP)

总结

本节内容,对gopacket抓包有了一个初步的认识,后期我们需要优化工具。

相关推荐
学长毕设15 分钟前
基于SpringBoot的高校后勤报修管理系统-附源码
java·spring boot·后端
特立独行的猫A24 分钟前
cj-tauri vs Rust/Tauri 同款播放器实测:编译 21 秒 vs 11 分钟,磁盘 12 MB vs 1.2 GB
java·后端·python
鸿蒙开发爱好者38 分钟前
下班后做的小工具和小游戏,我把它们整理成了 WyanHub
网络·人工智能·职场和发展·个人开发
乐橙开放平台1 小时前
海康和大华摄像头能统一管理吗?可以通过 GB28181 或视频融合平台接入
网络·后端·物联网·音视频
Felven2 小时前
C. Brr Brrr Patapim
c语言·开发语言
张小姐的猫3 小时前
【基于 WebSocket 的多用户网页五子棋】—— 项目结构设计与实用工具类模块
网络·websocket·网络协议
路溪非溪3 小时前
python标准库使用总结
开发语言·python
QXWZ_IA3 小时前
测绘单位采购RTK:设备价格、账号年费、售后,用时间轴分权重
网络·人工智能·安全
一条Go4 小时前
OnCall 时段路由:跨午夜、左闭右开与「Local 不是时区」
后端·架构·github
Moment4 小时前
不会后期的我,发现了一个开源胶片神器😍😍😍
前端·后端·开源