package parser import ( "encoding/binary" "fmt" "net" ) // ARP ref: https://zh.wikipedia.org/zh-cn/%E5%9C%B0%E5%9D%80%E8%A7%A3%E6%9E%90%E5%8D%8F%E8%AE%AE#%E6%8A%A5%E6%96%87%E6%A0%BC%E5%BC%8F type ARP struct { BaseLayer HardwareType uint16 // 硬件类型 ProtoType uint16 // 协议类型 HwAddressSize uint8 // 硬件地址长度 ProtoAddrSize uint8 // 协议地址长度 Opcode uint16 // 操作码 SrcHwAddress net.HardwareAddr // 源硬件地址 SrcProtoAddress net.IP // 源协议地址 DstHwAddress net.HardwareAddr // 目标硬件地址 DstProtoAddress net.IP // 目标协议地址 } func (A *ARP) LayerType() int { return LayerTypeARP } // DecodeARP ref: https://zh.wikipedia.org/zh-cn/%E5%9C%B0%E5%9D%80%E8%A7%A3%E6%9E%90%E5%8D%8F%E8%AE%AE#%E6%8A%A5%E6%96%87%E6%A0%BC%E5%BC%8F func DecodeARP(data []byte) (*ARP, error) { // 至少要有8bytes if len(data) < 8 { return nil, fmt.Errorf("[arp] 数据包太短: %d bytes", len(data)) } arp := ARP{} arp.HardwareType = binary.BigEndian.Uint16(data[0:2]) arp.ProtoType = binary.BigEndian.Uint16(data[2:4]) arp.HwAddressSize = data[4] arp.ProtoAddrSize = data[5] arp.Opcode = binary.BigEndian.Uint16(data[6:8]) arpLen := 8 + 2*arp.HwAddressSize + 2*arp.ProtoAddrSize if len(data) < int(arpLen) { return nil, fmt.Errorf("[arp] 实际长度小于声明长度:实际:%d,声明:%d", len(data), arpLen) } var offset uint8 = 8 arp.SrcHwAddress = data[offset : offset+arp.HwAddressSize] offset += arp.HwAddressSize arp.SrcProtoAddress = data[offset : offset+arp.ProtoAddrSize] offset += arp.ProtoAddrSize arp.DstHwAddress = data[offset : offset+arp.HwAddressSize] offset += arp.HwAddressSize arp.DstProtoAddress = data[offset : offset+arp.ProtoAddrSize] arp.Header = data[:arpLen] arp.Payload = data[arpLen:] return &arp, nil }