github.com/contiv/libOpenflow@v0.0.0-20210609050114-d967b14cc688/protocol/arp.go (about) 1 package protocol 2 3 import ( 4 "encoding/binary" 5 "errors" 6 "net" 7 ) 8 9 const ( 10 Type_Request = 1 11 Type_Reply = 2 12 ) 13 14 type ARP struct { 15 HWType uint16 16 ProtoType uint16 17 HWLength uint8 18 ProtoLength uint8 19 Operation uint16 20 HWSrc net.HardwareAddr 21 IPSrc net.IP 22 HWDst net.HardwareAddr 23 IPDst net.IP 24 } 25 26 func NewARP(opt int) (*ARP, error) { 27 if opt != Type_Request && opt != Type_Reply { 28 return nil, errors.New("Invalid ARP Operation.") 29 } 30 a := new(ARP) 31 a.HWType = 1 32 a.ProtoType = 0x800 33 a.HWLength = 6 34 a.ProtoLength = 4 35 a.Operation = uint16(opt) 36 a.HWSrc = net.HardwareAddr(make([]byte, 6)) 37 a.IPSrc = net.IP(make([]byte, 4)) 38 a.HWDst = net.HardwareAddr(make([]byte, 6)) 39 a.IPDst = net.IP(make([]byte, 4)) 40 return a, nil 41 } 42 43 func (a *ARP) Len() (n uint16) { 44 n = 8 45 n += uint16(a.HWLength*2 + a.ProtoLength*2) 46 return 47 } 48 49 func (a *ARP) MarshalBinary() (data []byte, err error) { 50 data = make([]byte, int(a.Len())) 51 binary.BigEndian.PutUint16(data[:2], a.HWType) 52 binary.BigEndian.PutUint16(data[2:4], a.ProtoType) 53 data[4] = a.HWLength 54 data[5] = a.ProtoLength 55 binary.BigEndian.PutUint16(data[6:8], a.Operation) 56 57 n := 8 58 59 copy(data[n:n+int(a.HWLength)], a.HWSrc) 60 n += int(a.HWLength) 61 copy(data[n:n+int(a.ProtoLength)], a.IPSrc.To4()) 62 n += int(a.ProtoLength) 63 copy(data[n:n+int(a.HWLength)], a.HWDst) 64 n += int(a.HWLength) 65 copy(data[n:n+int(a.ProtoLength)], a.IPDst.To4()) 66 return data, nil 67 } 68 69 func (a *ARP) UnmarshalBinary(data []byte) error { 70 if len(data) < 8 { 71 return errors.New("The []byte is too short to unmarshal a full ARP message.") 72 } 73 a.HWType = binary.BigEndian.Uint16(data[:2]) 74 a.ProtoType = binary.BigEndian.Uint16(data[2:4]) 75 a.HWLength = data[4] 76 a.ProtoLength = data[5] 77 a.Operation = binary.BigEndian.Uint16(data[6:8]) 78 79 n := 8 80 if len(data[n:]) < (int(a.HWLength)*2 + int(a.ProtoLength)*2) { 81 return errors.New("The []byte is too short to unmarshal a full ARP message.") 82 } 83 a.HWSrc = data[n : n+int(a.HWLength)] 84 n += int(a.HWLength) 85 a.IPSrc = data[n : n+int(a.ProtoLength)] 86 n += int(a.ProtoLength) 87 a.HWDst = data[n : n+int(a.HWLength)] 88 n += int(a.HWLength) 89 a.IPDst = data[n : n+int(a.ProtoLength)] 90 return nil 91 }