-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathipv6.go
92 lines (67 loc) · 1.71 KB
/
ipv6.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
package proto
import (
"net"
)
// IPv6Packet represents an IPv6 packet.
type IPv6Packet struct {
Version uint8 `json:"version"`
TrafficClass uint8 `json:"trafficClass"`
FlowLabel uint32 `json:"flowLabel"`
Length uint16 `json:"length"`
NextHeader uint8 `json:"nextHeader"`
HopLimit uint8 `json:"hopLimit"`
Source net.IP `json:"source"`
Destination net.IP `json:"destination"`
Payload []byte `json:"payload"`
}
const minIPv6PacketSize = 1 + 1 + 4 + 2 + 1 + 1 + 16 + 16
// DecodeIPv6 decodes an IPv6 packet.
func DecodeIPv6(b []byte) (IPv6Packet, error) {
packet := IPv6Packet{}
if len(b) < minIPv6PacketSize {
return packet, ErrorNotEnoughBytes
}
i := 0
packet.Version = b[i] >> 4
packet.TrafficClass = uint8(b[i]&0xf)<<4 | uint8(b[i+1]>>4)
i++
packet.FlowLabel = uint32(b[i]&0xf)<<16 | uint32(b[i+1])<<8 | uint32(b[i+2])
i += 3
packet.Length = uint16(b[i])<<8 | uint16(b[i+1])
i += 2
packet.NextHeader = uint8(b[i])
i++
packet.HopLimit = uint8(b[i])
i++
packet.Source = net.IP(b[i : i+16])
i += 16
packet.Destination = net.IP(b[i : i+16])
i += 16
packet.Payload = b[i:]
return packet, nil
}
// Bytes returns an encoded IPv6 packet.
func (p IPv6Packet) Bytes() []byte {
i := 0
b := make([]byte, 40+len(p.Payload))
b[i] = p.Version<<4 | byte(p.TrafficClass>>4)
b[i+1] = p.TrafficClass<<4 | byte(p.FlowLabel>>16)
i += 2
b[i] = byte(p.FlowLabel >> 8)
b[i+1] = byte(p.FlowLabel)
i += 2
b[i] = byte(p.Length >> 8)
b[i+1] = byte(p.Length)
i += 2
b[i] = p.NextHeader
i++
b[i] = p.HopLimit
i++
copy(b[i:], p.Source)
i += len(p.Source)
copy(b[i:], p.Destination)
i += len(p.Destination)
copy(b[i:], p.Payload)
i += len(p.Payload)
return b[:i]
}