gopacket使用总结

获取网卡信息

devices, err := pcap.FindAllDevs()

打开监听

//这里的第一个参数一定是要你现在正在工作的网卡,因为获取网卡信息会获取到很多,具体现在你用的哪个还得替换
//这个handle就可以用来监听网卡进行抓包
handle, err := pcap.OpenLive(devices[0].Name, 65535, true, pcap.BlockForever)

抓包并进行解析

//方式一
eth := &layers.Ethernet{}
ip4 := &layers.IPv4{}
tcp := &layers.TCP{}
//具体解析格式,就是你的数据包每一层都有啥
parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, eth, ip4, tcp)
//抓包,这里的data返回的就是纯二进制数据,就是从你网卡上获取的数据,还没有进行解包
data, _, err := handle.ReadPacketData()
decoded := []gopacket.LayerType{}
//开始解析数据包,解析完成的包在上面的eth、ip4、tcp里面存储,比如你想知道tcp的源端口,你可以直接tcp.SrcPort,具体如何取数据自己查看吧
if err := parser.DecodeLayers(data, &decoded); err != nil {
	continue
}



//方式2
var (
	ethLayer layers.Ethernet
	ipLayer  layers.IPv4
	udpLayer layers.UDP
)

    packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
	//packetSource.Packets()开始抓包
	for packet := range packetSource.Packets() {

		foundLayerTypes := []gopacket.LayerType{}

		//解析格式
		parserOpen := gopacket.NewDecodingLayerParser(
				layers.LayerTypeEthernet,
				&ethLayer,
				&ipLayer,
				&udpLayer,
		)
		//开始解析
		_ = parserOpen.DecodeLayers(packet.Data(), &foundLayerTypes)
		for _, layerType := range foundLayerTypes {
			if layerType == layers.LayerTypeUDP && rawPort == int(udpLayer.DstPort){
				fmt.Println("open")
			}
		}
	}

发包过程

//先写出包结构
eth := layers.Ethernet{
	SrcMAC:       xxxx,
	DstMAC:       xxxx,
	EthernetType: layers.EthernetTypeIPv4,
}
ip4 := layers.IPv4{
	SrcIP:    xxxx,
	DstIP:    xxxx,
	Version:  4,
	TTL:      255,
	Protocol: layers.IPProtocolUDP,
}
udp := layers.UDP{
	SrcPort:   layers.UDPPort(rawPort),
	DstPort:   0,
	Checksum:  0,
}
//这个一定要加上,不管是基于tcp的还是udp的
udp.SetNetworkLayerForChecksum(&ip4)

//有的时候应用层协议gopacket并不是全都有,所以gopacket支持自定义数据包,但是假如说要用到的应用层包
//比较多的时候还是比较麻烦 会写很多的代码,同时gopacket可以发送原始二进制数据,这种使用起来就比较方便
//了,不需要你进行自定义新的数据包,只需要你把原始数据放在这里就行了,比如:
rawBytes := []byte{
		0x16,0xfe,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x36,
		0x01,0x00,0x00,0x2a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2a,
		0xfe,0xfd,
		0x00,0x00,0x00,0x00,0x7c,0x77,0x40,0x1e,0x8a,0xc8,0x22,0xa0,0xa0,0x18,0xff,0x93,
		0x08,0xca,0xac,0x0a,0x64,0x2f,0xc9,0x22,0x64,0xbc,0x08,0xa8,0x16,0x89,0x19,0x3f,
		0x00,0x00,
		0x00,0x02,0x00,0x2f,
		0x01,0x00,
	}
//参数ComputeChecksums,如果为true的话会自动帮你计算检验和
serializeOptions := gopacket.SerializeOptions{
			FixLengths:       true,
			ComputeChecksums: true,//是否在序列化阶段要重新计算检验和
		}
		
buf := gopacket.NewSerializeBuffer()
if err := gopacket.SerializeLayers(buf, serializeOptions , &eth, &ip4, &udp,gopacket.Payload(rawBytes)); err != nil {
	return err
}
//发送数据
handle.WritePacketData(buf.Bytes())

参考文章

  1. gopacket 使用手册 学习笔记 中文文档

https://blog.csdn.net/weixin_49393427/article/details/112362561

2.golang使用gopacket包进行数据包捕获,注入和分析

https://blog.csdn.net/ptmozhu/article/details/72652310

你可能感兴趣的:(网络,tcp/ip,udp,安全)