forked from ctulek/stun
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mapped_address.go
88 lines (80 loc) · 1.54 KB
/
mapped_address.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
package stun
import (
"errors"
"fmt"
"net"
)
type MappedAddress struct {
Family byte
Port uint16
IP net.IP
}
func (m *MappedAddress) Type() uint16 {
return ATTR_TYPE_MAPPED_ADDRESS
}
func (m *MappedAddress) Length() uint16 {
if m.Family == 0x01 {
return 8
} else {
return 20
}
}
func (m *MappedAddress) Pack(b []byte) error {
b = b[4:]
if m.Family == 0x01 {
if len(b) < 8 {
return errors.New("Buffer too short for IPv4")
}
b[0] = 0
b[1] = 0x01 // Family
putUint16(b[2:4], m.Port)
i := copy(b[4:8], m.IP.To4())
if i != 4 {
return errors.New("Copy failed")
}
return nil
} else if m.Family == 0x02 {
if len(b) < 20 {
return errors.New("Buffer too short for IPv6")
}
b[1] = 0x02 // Family
putUint16(b[2:4], m.Port)
i := copy(b[4:20], m.IP)
if i != 16 {
return errors.New("Copy failed")
}
return nil
}
return errors.New("Undefined Family")
}
func (m *MappedAddress) UnPack(b []byte) error {
b = b[4:]
if len(b) < 8 {
return errors.New("Buffer too short")
}
m.Family = b[1]
if m.Family == 0x02 && len(b) < 20 {
return errors.New("Buffer is too short for IPv6")
}
m.Port = toUint16(b[2:4])
if m.Family == 0x01 {
m.IP = net.IPv4(b[4], b[5], b[6], b[7])
} else {
m.IP = make(net.IP, 16)
i := copy(m.IP, b[4:20])
if i != 16 {
return errors.New("Copy failed")
}
}
return nil
}
func (m *MappedAddress) String() string {
var family string
switch m.Family {
case 1:
family = "IPv4"
case 2:
family = "IPv6"
}
return fmt.Sprintf("Mapped Address: %s %s:%d", family, m.IP, m.Port)
}