forked from florianl/go-conntrack
-
Notifications
You must be signed in to change notification settings - Fork 0
/
attributeExpect.go
154 lines (142 loc) · 3.25 KB
/
attributeExpect.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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package conntrack
import (
"encoding/binary"
"log"
"github.com/mdlayher/netlink"
)
const (
ctaExpUnspec = iota
ctaExpMaster
ctaExpTuple
ctaExpMask
ctaExpTimeout
ctaExpID
ctaExpHelpName
ctaExpZone
ctaExpFlags
ctaExpClass
ctaExpNat
ctaExpFn
)
const (
ctaExpNatUnspec = iota
ctaExpNatDir
ctaExpNatTuple
)
func extractNatInfo(v *NatInfo, logger *log.Logger, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data)
if err != nil {
return err
}
ad.ByteOrder = nativeEndian
for ad.Next() {
switch ad.Type() {
case ctaExpNatDir:
ad.ByteOrder = binary.BigEndian
tmp := ad.Uint32()
v.Dir = &tmp
ad.ByteOrder = nativeEndian
case ctaExpNatTuple:
tuple := &IPTuple{}
if err := extractIPTuple(tuple, logger, ad.Bytes()); err != nil {
return err
}
v.Tuple = tuple
default:
logger.Printf("extractNatInfo(): %d | %d\t %v", ad.Type(), ad.Type()&0xFF, ad.Bytes())
}
}
return ad.Err()
}
func marshalNatInfo(logger *log.Logger, v *NatInfo) ([]byte, error) {
ae := netlink.NewAttributeEncoder()
if v.Dir != nil {
ae.ByteOrder = binary.BigEndian
ae.Uint32(ctaExpNatDir, *v.Dir)
ae.ByteOrder = nativeEndian
}
if v.Tuple != nil {
data, err := marshalIPTuple(logger, v.Tuple)
if err != nil {
return []byte{}, err
}
ae.Bytes(ctaExpNatTuple|nlafNested, data)
}
return ae.Encode()
}
func extractAttributeExpect(c *Con, logger *log.Logger, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data)
if err != nil {
return err
}
c.Exp = &Exp{}
for ad.Next() {
switch ad.Type() {
case ctaExpMaster:
tuple := &IPTuple{}
if err := extractIPTuple(tuple, logger, ad.Bytes()); err != nil {
return err
}
c.Origin = tuple
case ctaExpTuple:
tuple := &IPTuple{}
if err := extractIPTuple(tuple, logger, ad.Bytes()); err != nil {
return err
}
c.Exp.Tuple = tuple
case ctaExpMask:
tuple := &IPTuple{}
if err := extractIPTuple(tuple, logger, ad.Bytes()); err != nil {
return err
}
c.Exp.Mask = tuple
case ctaExpTimeout:
ad.ByteOrder = binary.BigEndian
tmp := ad.Uint32()
c.Exp.Timeout = &tmp
ad.ByteOrder = nativeEndian
case ctaExpID:
ad.ByteOrder = binary.BigEndian
tmp := ad.Uint32()
c.Exp.ID = &tmp
ad.ByteOrder = nativeEndian
case ctaExpHelpName:
tmp := ad.String()
c.Exp.HelperName = &tmp
case ctaExpZone:
ad.ByteOrder = binary.BigEndian
zone := ad.Uint16()
c.Exp.Zone = &zone
ad.ByteOrder = nativeEndian
case ctaExpFlags:
ad.ByteOrder = binary.BigEndian
tmp := ad.Uint32()
c.Exp.Flags = &tmp
ad.ByteOrder = nativeEndian
case ctaExpClass:
ad.ByteOrder = binary.BigEndian
tmp := ad.Uint32()
c.Exp.Class = &tmp
ad.ByteOrder = nativeEndian
case ctaExpNat:
tmp := &NatInfo{}
if err := extractNatInfo(tmp, logger, ad.Bytes()); err != nil {
return err
}
c.Exp.Nat = tmp
case ctaExpFn:
tmp := ad.String()
c.Exp.Fn = &tmp
default:
logger.Printf("extractAttributeExpect() - Unknown attribute: %d %d %v\n", ad.Type()&0xFF, ad.Type(), ad.Bytes())
}
}
return ad.Err()
}
func extractExpectAttributes(logger *log.Logger, c *Con, msg []byte) error {
offset := checkHeader(msg[:2])
if err := extractAttributeExpect(c, logger, msg[offset:]); err != nil {
return err
}
return nil
}