// Copyright 2016 The Netstack Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package header import "gvisor.googlesource.com/gvisor/pkg/tcpip" const ( // ARPProtocolNumber is the ARP network protocol number. ARPProtocolNumber tcpip.NetworkProtocolNumber = 0x0806 // ARPSize is the size of an IPv4-over-Ethernet ARP packet. ARPSize = 2 + 2 + 1 + 1 + 2 + 2*6 + 2*4 ) // ARPOp is an ARP opcode. type ARPOp uint16 // Typical ARP opcodes defined in RFC 826. const ( ARPRequest ARPOp = 1 ARPReply ARPOp = 2 ) // ARP is an ARP packet stored in a byte array as described in RFC 826. type ARP []byte func (a ARP) hardwareAddressSpace() uint16 { return uint16(a[0])<<8 | uint16(a[1]) } func (a ARP) protocolAddressSpace() uint16 { return uint16(a[2])<<8 | uint16(a[3]) } func (a ARP) hardwareAddressSize() int { return int(a[4]) } func (a ARP) protocolAddressSize() int { return int(a[5]) } // Op is the ARP opcode. func (a ARP) Op() ARPOp { return ARPOp(a[6])<<8 | ARPOp(a[7]) } // SetOp sets the ARP opcode. func (a ARP) SetOp(op ARPOp) { a[6] = uint8(op >> 8) a[7] = uint8(op) } // SetIPv4OverEthernet configures the ARP packet for IPv4-over-Ethernet. func (a ARP) SetIPv4OverEthernet() { a[0], a[1] = 0, 1 // htypeEthernet a[2], a[3] = 0x08, 0x00 // IPv4ProtocolNumber a[4] = 6 // macSize a[5] = uint8(IPv4AddressSize) } // HardwareAddressSender is the link address of the sender. // It is a view on to the ARP packet so it can be used to set the value. func (a ARP) HardwareAddressSender() []byte { const s = 8 return a[s : s+6] } // ProtocolAddressSender is the protocol address of the sender. // It is a view on to the ARP packet so it can be used to set the value. func (a ARP) ProtocolAddressSender() []byte { const s = 8 + 6 return a[s : s+4] } // HardwareAddressTarget is the link address of the target. // It is a view on to the ARP packet so it can be used to set the value. func (a ARP) HardwareAddressTarget() []byte { const s = 8 + 6 + 4 return a[s : s+6] } // ProtocolAddressTarget is the protocol address of the target. // It is a view on to the ARP packet so it can be used to set the value. func (a ARP) ProtocolAddressTarget() []byte { const s = 8 + 6 + 4 + 6 return a[s : s+4] } // IsValid reports whether this is an ARP packet for IPv4 over Ethernet. func (a ARP) IsValid() bool { if len(a) < ARPSize { return false } const htypeEthernet = 1 const macSize = 6 return a.hardwareAddressSpace() == htypeEthernet && a.protocolAddressSpace() == uint16(IPv4ProtocolNumber) && a.hardwareAddressSize() == macSize && a.protocolAddressSize() == IPv4AddressSize }