-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmac.go
70 lines (62 loc) · 1.52 KB
/
mac.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
package goutil
import (
"encoding/binary"
"fmt"
"gopkg.in/mgo.v2/bson"
"math"
"net"
)
// Wraps around net.HardwareAddr with JSON marshal/unmarshal support.
type MAC net.HardwareAddr
func (t *MAC) UnmarshalJSON(b []byte) error {
if !IsJSONString(b) {
return fmt.Errorf("Malformed JSON string: %s", string(b))
}
s := string(b[1 : len(b)-1])
mac, err := net.ParseMAC(s)
if err != nil {
goto Error
}
*t = MAC(mac)
return nil
Error:
return fmt.Errorf("Malformed MAC: %s", s)
}
func (t MAC) MarshalJSON() (b []byte, err error) {
return []byte(`"` + net.HardwareAddr(t).String() + `"`), nil
}
func (t *MAC) String() string {
return net.HardwareAddr(*t).String()
}
var bsonBinaryKind byte = 0x05
// Save as binary
func (t MAC) GetBSON() (interface{}, error) {
mac := []byte(t)
l := len(mac)
if l > math.MaxInt32 {
return nil, fmt.Errorf("Length overflow int32: %d", l)
}
data := make([]byte, 4, 4+1+l)
binary.LittleEndian.PutUint32(data, uint32(l))
data = append(data, byte(0x00))
data = append(data, mac...)
return bson.Raw{
Kind: bsonBinaryKind,
Data: data,
}, nil
}
func (t *MAC) SetBSON(raw bson.Raw) error {
if raw.Kind != bsonBinaryKind {
return fmt.Errorf("Kind 0x%x, expect 0x05", raw.Kind)
}
totalLen := uint64(len(raw.Data))
if totalLen < 6 {
return fmt.Errorf("Data too short: %d, at least 6", totalLen)
}
l := binary.LittleEndian.Uint32(raw.Data[0:4])
if totalLen != uint64(4+1+l) {
return fmt.Errorf("Incorrect length %d, expect %d", totalLen, 4+1+l)
}
*t = MAC(raw.Data[5:])
return nil
}