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