1 // Copyright 2012 Google, Inc. All rights reserved.
2 // Copyright 2009-2011 Andreas Krennmair. All rights reserved.
4 // Use of this source code is governed by a BSD-style license
5 // that can be found in the LICENSE file in the root of the source
14 "github.com/google/gopacket"
17 // Potential values for ARP.Operation.
23 // ARP is a ARP packet header.
31 SourceHwAddress []byte
32 SourceProtAddress []byte
37 // LayerType returns LayerTypeARP
38 func (arp *ARP) LayerType() gopacket.LayerType { return LayerTypeARP }
40 // DecodeFromBytes decodes the given bytes into this layer.
41 func (arp *ARP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
42 arp.AddrType = LinkType(binary.BigEndian.Uint16(data[0:2]))
43 arp.Protocol = EthernetType(binary.BigEndian.Uint16(data[2:4]))
44 arp.HwAddressSize = data[4]
45 arp.ProtAddressSize = data[5]
46 arp.Operation = binary.BigEndian.Uint16(data[6:8])
47 arp.SourceHwAddress = data[8 : 8+arp.HwAddressSize]
48 arp.SourceProtAddress = data[8+arp.HwAddressSize : 8+arp.HwAddressSize+arp.ProtAddressSize]
49 arp.DstHwAddress = data[8+arp.HwAddressSize+arp.ProtAddressSize : 8+2*arp.HwAddressSize+arp.ProtAddressSize]
50 arp.DstProtAddress = data[8+2*arp.HwAddressSize+arp.ProtAddressSize : 8+2*arp.HwAddressSize+2*arp.ProtAddressSize]
52 arpLength := 8 + 2*arp.HwAddressSize + 2*arp.ProtAddressSize
53 arp.Contents = data[:arpLength]
54 arp.Payload = data[arpLength:]
58 // SerializeTo writes the serialized form of this layer into the
59 // SerializationBuffer, implementing gopacket.SerializableLayer.
60 // See the docs for gopacket.SerializableLayer for more info.
61 func (arp *ARP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
62 size := 8 + len(arp.SourceHwAddress) + len(arp.SourceProtAddress) + len(arp.DstHwAddress) + len(arp.DstProtAddress)
63 bytes, err := b.PrependBytes(size)
68 if len(arp.SourceHwAddress) != len(arp.DstHwAddress) {
69 return errors.New("mismatched hardware address sizes")
71 arp.HwAddressSize = uint8(len(arp.SourceHwAddress))
72 if len(arp.SourceProtAddress) != len(arp.DstProtAddress) {
73 return errors.New("mismatched prot address sizes")
75 arp.ProtAddressSize = uint8(len(arp.SourceProtAddress))
77 binary.BigEndian.PutUint16(bytes, uint16(arp.AddrType))
78 binary.BigEndian.PutUint16(bytes[2:], uint16(arp.Protocol))
79 bytes[4] = arp.HwAddressSize
80 bytes[5] = arp.ProtAddressSize
81 binary.BigEndian.PutUint16(bytes[6:], arp.Operation)
83 for _, addr := range [][]byte{
85 arp.SourceProtAddress,
89 copy(bytes[start:], addr)
95 // CanDecode returns the set of layer types that this DecodingLayer can decode.
96 func (arp *ARP) CanDecode() gopacket.LayerClass {
100 // NextLayerType returns the layer type contained by this DecodingLayer.
101 func (arp *ARP) NextLayerType() gopacket.LayerType {
102 return gopacket.LayerTypePayload
105 func decodeARP(data []byte, p gopacket.PacketBuilder) error {
108 return decodingLayerDecoder(arp, data, p)