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  }