@@ -9,18 +9,33 @@ import (
99
1010const headerSizeARP = 28
1111
12+ type Operation uint16
13+
14+ const (
15+ OperationRequest Operation = 1
16+ OperationReply Operation = 2
17+ )
18+
19+ type ARPOperation struct {
20+ Val Operation
21+ Desc string
22+ }
23+
24+ func (ao * ARPOperation ) String () string {
25+ return fmt .Sprintf ("%s (%d)" , ao .Desc , ao .Val )
26+ }
27+
1228// The Address Resolution Protocol (ARP) is a communication protocol
1329// used for discovering the link layer address, such as a MAC address,
1430// associated with a given internet layer address, typically an IPv4 address.
1531// Defined in RFC 826.
1632type ARPPacket struct {
17- HardwareType uint16 // Network link protocol type.
18- ProtocolType uint16 // Internetwork protocol for which the ARP request is intended.
19- ProtocolTypeDesc string // Internetwork protocol description.
20- Hlen uint8 // Length (in octets) of a hardware address.
21- Plen uint8 // Length (in octets) of internetwork addresses.
22- Op uint16 // Specifies the operation that the sender is performing.
23- OpDesc string // Operation description.
33+ HardwareType uint16 // Network link protocol type.
34+ ProtocolType uint16 // Internetwork protocol for which the ARP request is intended.
35+ ProtocolTypeDesc string // Internetwork protocol description.
36+ Hlen uint8 // Length (in octets) of a hardware address.
37+ Plen uint8 // Length (in octets) of internetwork addresses.
38+ Op * ARPOperation // Specifies the operation that the sender is performing.
2439 // Media address of the sender. In an ARP request this field is used to indicate
2540 // the address of the host sending the request. In an ARP reply this field is used
2641 // to indicate the address of the host that the request was looking for.
@@ -32,13 +47,40 @@ type ARPPacket struct {
3247 TargetIP netip.Addr // Internetwork address of the intended receiver.
3348}
3449
50+ func New (
51+ op Operation ,
52+ senderMAC net.HardwareAddr ,
53+ senderIP netip.Addr ,
54+ targetMAC net.HardwareAddr ,
55+ targetIP netip.Addr ,
56+ ) (* ARPPacket , error ) {
57+ if len (senderMAC ) < 6 || len (targetMAC ) < 6 || len (senderMAC ) != len (targetMAC ) {
58+ return nil , fmt .Errorf ("malformed hardware address" )
59+ }
60+ if ! senderIP .IsValid () || ! senderIP .Is4 () || ! targetIP .IsValid () || ! targetIP .Is4 () {
61+ return nil , fmt .Errorf ("malformed protocol address" )
62+ }
63+ return & ARPPacket {
64+ HardwareType : 1 ,
65+ ProtocolType : 0x0800 ,
66+ ProtocolTypeDesc : "IPv4" ,
67+ Hlen : uint8 (len (senderMAC )),
68+ Plen : 4 ,
69+ Op : & ARPOperation {Val : op , Desc : opdesc (op )},
70+ SenderMAC : senderMAC ,
71+ SenderIP : senderIP ,
72+ TargetMAC : targetMAC ,
73+ TargetIP : targetIP ,
74+ }, nil
75+ }
76+
3577func (ap * ARPPacket ) String () string {
3678 return fmt .Sprintf (`%s
3779- Hardware Type: %d
3880- Protocol Type: %s (%#04x)
3981- HLen: %d
40- - PLen: %d
41- - Operation: %s (%d)
82+ - PLen: %d
83+ - Operation: %s
4284- Sender MAC Address: %s
4385- Sender IP Address: %s
4486- Target MAC Address: %s
@@ -50,7 +92,6 @@ func (ap *ARPPacket) String() string {
5092 ap .ProtocolType ,
5193 ap .Hlen ,
5294 ap .Plen ,
53- ap .OpDesc ,
5495 ap .Op ,
5596 ap .SenderMAC ,
5697 ap .SenderIP ,
@@ -61,29 +102,57 @@ func (ap *ARPPacket) String() string {
61102
62103func (ap * ARPPacket ) Summary () string {
63104 var message string
64- switch ap .OpDesc {
65- case "request" :
66- message = fmt .Sprintf ("ARP Packet: (%s) Who has %s? Tell %s" , ap .OpDesc , ap .TargetIP , ap .SenderIP )
67- case "reply" :
68- message = fmt .Sprintf ("ARP Packet: (%s) %s at %s" , ap .OpDesc , ap .SenderIP , ap .SenderMAC )
105+ switch ap .Op . Val {
106+ case OperationRequest :
107+ message = fmt .Sprintf ("ARP Packet: (%s) Who has %s? Tell %s" , ap .Op . Desc , ap .TargetIP , ap .SenderIP )
108+ case OperationReply :
109+ message = fmt .Sprintf ("ARP Packet: (%s) %s at %s" , ap .Op . Desc , ap .SenderIP , ap .SenderMAC )
69110 default :
70- message = fmt .Sprintf ("ARP Packet: (%s)" , ap .OpDesc )
111+ message = fmt .Sprintf ("ARP Packet: (%s)" , ap .Op . Desc )
71112 }
72113 return message
73114}
74115
75- // Parse parses the given ARP packet data into the ARPPacket struct.
76- func (ap * ARPPacket ) Parse (data []byte ) error {
116+ // MarshalBinary implements encoding.BinaryMarshaler interface
117+ func (ap * ARPPacket ) MarshalBinary () ([]byte , error ) {
118+ buf := make ([]byte , 2 + 2 + 1 + 1 + 2 + (ap .Plen * 2 )+ (ap .Hlen * 2 ))
119+ binary .BigEndian .PutUint16 (buf [0 :2 ], ap .HardwareType )
120+ binary .BigEndian .PutUint16 (buf [2 :4 ], ap .ProtocolType )
121+ buf [4 ] = ap .Hlen
122+ buf [5 ] = ap .Plen
123+ binary .BigEndian .PutUint16 (buf [6 :8 ], uint16 (ap .Op .Val ))
124+ hoffset := 8 + ap .Hlen
125+ poffset := hoffset + ap .Plen
126+ copy (buf [8 :hoffset ], ap .SenderMAC )
127+ copy (buf [hoffset :poffset ], ap .SenderIP .AsSlice ())
128+ copy (buf [poffset :poffset + ap .Hlen ], ap .TargetMAC )
129+ copy (buf [poffset + ap .Hlen :poffset + ap .Hlen + ap .Plen ], ap .TargetIP .AsSlice ())
130+ return buf , nil
131+ }
132+
133+ func (ap * ARPPacket ) ToBytes () ([]byte , error ) {
134+ return ap .MarshalBinary ()
135+ }
136+
137+ // UnmarshalBinary implements encoding.BinaryUnmarshaler interface
138+ func (ap * ARPPacket ) UnmarshalBinary (data []byte ) error {
77139 if len (data ) < headerSizeARP {
78140 return fmt .Errorf ("minimum header size for ARP is %d bytes, got %d bytes" , headerSizeARP , len (data ))
79141 }
80142 ap .HardwareType = binary .BigEndian .Uint16 (data [0 :2 ])
81143 ap .ProtocolType = binary .BigEndian .Uint16 (data [2 :4 ])
82144 ap .ProtocolTypeDesc = ptypedesc (ap .ProtocolType )
145+ if ap .ProtocolTypeDesc == "Unknown" {
146+ return fmt .Errorf ("unknown protocol type" )
147+ }
83148 ap .Hlen = data [4 ]
84149 ap .Plen = data [5 ]
85- ap .Op = binary .BigEndian .Uint16 (data [6 :8 ])
86- ap .OpDesc = opdesc (ap .Op )
150+ op := Operation (binary .BigEndian .Uint16 (data [6 :8 ]))
151+ opdesc := opdesc (op )
152+ if opdesc == "Unknown" {
153+ return fmt .Errorf ("unknown operation" )
154+ }
155+ ap .Op = & ARPOperation {Val : op , Desc : opdesc }
87156 hoffset := 8 + ap .Hlen
88157 ap .SenderMAC = net .HardwareAddr (data [8 :hoffset ])
89158 poffset := hoffset + ap .Plen
@@ -100,6 +169,11 @@ func (ap *ARPPacket) Parse(data []byte) error {
100169 return nil
101170}
102171
172+ // Parse parses the given ARP packet data into the ARPPacket struct.
173+ func (ap * ARPPacket ) Parse (data []byte ) error {
174+ return ap .UnmarshalBinary (data )
175+ }
176+
103177func (ap * ARPPacket ) NextLayer () (layer string , payload []byte ) { return }
104178
105179func ptypedesc (pt uint16 ) string {
@@ -115,12 +189,12 @@ func ptypedesc(pt uint16) string {
115189 return proto
116190}
117191
118- func opdesc (op uint16 ) string {
192+ func opdesc (op Operation ) string {
119193 var opdesc string
120194 switch op {
121- case 1 :
195+ case OperationRequest :
122196 opdesc = "request"
123- case 2 :
197+ case OperationReply :
124198 opdesc = "reply"
125199 default :
126200 opdesc = "Unknown"
0 commit comments