github.com/20yyq/packet@v0.1.4-0.20231013092308-386a004a3baa/arp.go (about) 1 // @@ 2 // @ Author : Eacher 3 // @ Date : 2023-07-01 15:19:37 4 // @ LastEditTime : 2023-09-04 09:40:23 5 // @ LastEditors : Eacher 6 // @ --------------------------------------------------------------------------------< 7 // @ Description : 8 // @ --------------------------------------------------------------------------------< 9 // @ FilePath : /20yyq/packet/arp.go 10 // @@ 11 package packet 12 13 import ( 14 "unsafe" 15 "encoding/binary" 16 ) 17 18 /* 19 Also define the following values (to be discussed later): 20 ares_hrd$Ethernet (= 1), 21 ares_op$REQUEST (= 1, high byte transmitted first) 22 ares_op$REPLY (= 2). 23 */ 24 const ( 25 ARP_ETHERNETTYPE= 0x01 26 ARP_REQUEST = 0x01 27 ARP_REPLY = 0x02 28 29 SizeofArpPacket = 0x1c 30 ) 31 32 /* 33 Ethernet transmission layer (not necessarily accessible to the user): 34 // 14.byte EthernetPacket 35 2.byte 16.bit: (ar$hrd) Hardware address space (e.g., Ethernet, Packet Radio Net.) 36 2.byte 16.bit: (ar$pro) Protocol address space. For Ethernet hardware, this is from the set of type fields ether_typ$<protocol>. 37 1.byte 8.bit: (ar$hln) byte length of each hardware address 38 1.byte 8.bit: (ar$pln) byte length of each protocol address 39 2.byte 16.bit: (ar$op) opcode (ares_op$REQUEST | ares_op$REPLY) 40 nbytes: (ar$sha) Hardware address of sender of this packet, n from the ar$hln field. 41 mbytes: (ar$spa) Protocol address of sender of this packet, m from the ar$pln field. 42 nbytes: (ar$tha) Hardware address of target of this packet (if known). 43 mbytes: (ar$tpa) Protocol address of target. 44 45 */ 46 type ArpPacket struct { 47 HardwareType uint16 48 ProtocolType uint16 49 HardwareLen uint8 50 IPLen uint8 51 Operation uint16 52 SendHardware HardwareAddr 53 SendIP IPv4 54 TargetHardware HardwareAddr 55 TargetIP IPv4 56 } 57 58 func NewArpPacket(b [SizeofArpPacket]byte) (arp ArpPacket) { 59 arp = *(*ArpPacket)(unsafe.Pointer(&b[0])) 60 arp.HardwareType = binary.BigEndian.Uint16(b[0:2]) 61 arp.ProtocolType = binary.BigEndian.Uint16(b[2:4]) 62 arp.Operation = binary.BigEndian.Uint16(b[6:8]) 63 return 64 } 65 66 func (arp ArpPacket) WireFormat() []byte { 67 var b [SizeofArpPacket]byte 68 binary.BigEndian.PutUint16(b[:2], arp.HardwareType) 69 binary.BigEndian.PutUint16(b[2:4], arp.ProtocolType) 70 b[4], b[5] = arp.HardwareLen, arp.IPLen 71 binary.BigEndian.PutUint16(b[6:8], arp.Operation) 72 *(*HardwareAddr)(b[8:14]) = arp.SendHardware 73 *(*IPv4)(b[14:18]) = arp.SendIP 74 *(*HardwareAddr)(b[18:24]) = arp.TargetHardware 75 *(*IPv4)(b[24:28]) = arp.TargetIP 76 return b[:] 77 } 78 79 func (arp ArpPacket) String() string { 80 str := "OP: request" 81 if 1 != arp.Operation { 82 str = "OP: replay" 83 } 84 str += " Src-MAC: " + arp.SendHardware.String() + " Src-IP: " + arp.SendIP.String() 85 str += " Dst-MAC: " + arp.TargetHardware.String() + " Dst-IP: " + arp.TargetIP.String() 86 return str 87 }