2024年Go最新gopacket源码分析_gopacket中tcpassembly源码解读(1),2024年最新数据库开发面试自我介绍

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

概览

NewPacketSource

NewPacketSource 其参数需要两个接口 PacketDataSource 和 Decoder,PacketDataSource 为数据包,一般我们使用 handle,Decoder 为解码器,一般我们都使用 hanler.LinkType 来传递

func NewPacketSource(source PacketDataSource, decoder Decoder) \*PacketSource {
	return &PacketSource{
		source:  source,
		decoder: decoder,
	}
}

handle.LinkType

handle.LinkType()是源的链路层类型,一般是 LinkType 对应枚举 LinkTypeEthernet

func (p \*Handle) LinkType() layers.LinkType {
	return p.pcapDatalink()
}
func (p \*Handle) pcapDatalink() layers.LinkType {
	ret, \_, \_ := syscall.Syscall(pcapDatalinkPtr, 1, uintptr(p.cptr), 0, 0)
	return layers.LinkType(ret)
}


LinkType

type LinkType uint8
func (a LinkType) Decode(data []byte, p gopacket.PacketBuilder) error {
	return LinkTypeMetadata[a].DecodeWith.Decode(data, p)
}

那么 LinkTypeMetadata 数据是从那里呢?我们可以借助 IDE 的全局查找功能进行查找

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WESNx1yE-1659280486701)(assets/image-20220729111733-0mflbru.png)]

查找后我们可以在 layers.enums.go 大约 368 行看到 LinkTypeEthernet 的注册信息

LinkTypeMetadata[LinkTypeEthernet] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEthernet), Name: "Ethernet"}


然后反推其调用链为 init->initActualTypeData

func init() {
	initUnknownTypesForLinkType()
	initUnknownTypesForEthernetType()
	initUnknownTypesForPPPType()
	initUnknownTypesForIPProtocol()
	initUnknownTypesForSCTPChunkType()
	initUnknownTypesForPPPoECode()
	initUnknownTypesForFDDIFrameControl()
	initUnknownTypesForEAPOLType()
	initUnknownTypesForProtocolFamily()
	initUnknownTypesForDot11Type()
	initUnknownTypesForUSBTransportType()
	initActualTypeData()
}

func initActualTypeData() {
	...
	LinkTypeMetadata[LinkTypeEthernet] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEthernet), Name: "Ethernet"}
	...
}

decodeEthernet
func decodeEthernet(data []byte, p gopacket.PacketBuilder) error {
	eth := &Ethernet{}
	err := eth.DecodeFromBytes(data, p)
	if err != nil {
		return err
	}
	p.AddLayer(eth)
	p.SetLinkLayer(eth)
	return p.NextDecoder(eth.EthernetType)
}

然后我们可以看到 ether 的解析过程

func (eth \*Ethernet) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
	if len(data) < 14 {
		return errors.New("Ethernet packet too small")
	}
	eth.DstMAC = net.HardwareAddr(data[0:6])
	eth.SrcMAC = net.HardwareAddr(data[6:12])
	eth.EthernetType = EthernetType(binary.BigEndian.Uint16(data[12:14]))
	eth.BaseLayer = BaseLayer{data[:14], data[14:]}
	eth.Length = 0
	if eth.EthernetType < 0x0600 {
		eth.Length = uint16(eth.EthernetType)
		eth.EthernetType = EthernetTypeLLC
		if cmp := len(eth.Payload) - int(eth.Length); cmp < 0 {
			df.SetTruncated()
		} else if cmp > 0 {
			// Strip off bytes at the end, since we have too many bytes
			eth.Payload = eth.Payload[:len(eth.Payload)-cmp]
		}
		// fmt.Println(eth)
	}
	return nil
}

NextPacket

func (p \*PacketSource) NextPacket() (Packet, error) {
	data, ci, err := p.source.ReadPacketData()
	if err != nil {
		return nil, err
	}
	packet := NewPacket(data, p.decoder, p.DecodeOptions)
	m := packet.Metadata()
	m.CaptureInfo = ci
	m.Truncated = m.Truncated || ci.CaptureLength < ci.Length
	return packet, nil
}

NewPacket

func NewPacket(data []byte, firstLayerDecoder Decoder, options DecodeOptions) Packet {
	if !options.NoCopy {
		dataCopy := make([]byte, len(data))
		copy(dataCopy, data)
		data = dataCopy
	}
	if options.Lazy {
		p := &lazyPacket{
			packet: packet{data: data, decodeOptions: options},
			next:   firstLayerDecoder,


![img](https://img-blog.csdnimg.cn/img_convert/9f0acc27666f22606f91e0c4d7259651.png)
![img](https://img-blog.csdnimg.cn/img_convert/f575c04207fe589dea09235add561046.png)
![img](https://img-blog.csdnimg.cn/img_convert/130a09bdee72105ef194f2ad280d9e68.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618658159)**

习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618658159)**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值