1package nl
2
3import (
4	"unsafe"
5)
6
7const (
8	SizeofXfrmUsersaId       = 0x18
9	SizeofXfrmStats          = 0x0c
10	SizeofXfrmUsersaInfo     = 0xe0
11	SizeofXfrmUserSpiInfo    = 0xe8
12	SizeofXfrmAlgo           = 0x44
13	SizeofXfrmAlgoAuth       = 0x48
14	SizeofXfrmAlgoAEAD       = 0x48
15	SizeofXfrmEncapTmpl      = 0x18
16	SizeofXfrmUsersaFlush    = 0x8
17	SizeofXfrmReplayStateEsn = 0x18
18)
19
20const (
21	XFRM_STATE_NOECN      = 1
22	XFRM_STATE_DECAP_DSCP = 2
23	XFRM_STATE_NOPMTUDISC = 4
24	XFRM_STATE_WILDRECV   = 8
25	XFRM_STATE_ICMP       = 16
26	XFRM_STATE_AF_UNSPEC  = 32
27	XFRM_STATE_ALIGN4     = 64
28	XFRM_STATE_ESN        = 128
29)
30
31// struct xfrm_usersa_id {
32//   xfrm_address_t      daddr;
33//   __be32        spi;
34//   __u16       family;
35//   __u8        proto;
36// };
37
38type XfrmUsersaId struct {
39	Daddr  XfrmAddress
40	Spi    uint32 // big endian
41	Family uint16
42	Proto  uint8
43	Pad    byte
44}
45
46func (msg *XfrmUsersaId) Len() int {
47	return SizeofXfrmUsersaId
48}
49
50func DeserializeXfrmUsersaId(b []byte) *XfrmUsersaId {
51	return (*XfrmUsersaId)(unsafe.Pointer(&b[0:SizeofXfrmUsersaId][0]))
52}
53
54func (msg *XfrmUsersaId) Serialize() []byte {
55	return (*(*[SizeofXfrmUsersaId]byte)(unsafe.Pointer(msg)))[:]
56}
57
58// struct xfrm_stats {
59//   __u32 replay_window;
60//   __u32 replay;
61//   __u32 integrity_failed;
62// };
63
64type XfrmStats struct {
65	ReplayWindow    uint32
66	Replay          uint32
67	IntegrityFailed uint32
68}
69
70func (msg *XfrmStats) Len() int {
71	return SizeofXfrmStats
72}
73
74func DeserializeXfrmStats(b []byte) *XfrmStats {
75	return (*XfrmStats)(unsafe.Pointer(&b[0:SizeofXfrmStats][0]))
76}
77
78func (msg *XfrmStats) Serialize() []byte {
79	return (*(*[SizeofXfrmStats]byte)(unsafe.Pointer(msg)))[:]
80}
81
82// struct xfrm_usersa_info {
83//   struct xfrm_selector    sel;
84//   struct xfrm_id      id;
85//   xfrm_address_t      saddr;
86//   struct xfrm_lifetime_cfg  lft;
87//   struct xfrm_lifetime_cur  curlft;
88//   struct xfrm_stats   stats;
89//   __u32       seq;
90//   __u32       reqid;
91//   __u16       family;
92//   __u8        mode;   /* XFRM_MODE_xxx */
93//   __u8        replay_window;
94//   __u8        flags;
95// #define XFRM_STATE_NOECN  1
96// #define XFRM_STATE_DECAP_DSCP 2
97// #define XFRM_STATE_NOPMTUDISC 4
98// #define XFRM_STATE_WILDRECV 8
99// #define XFRM_STATE_ICMP   16
100// #define XFRM_STATE_AF_UNSPEC  32
101// #define XFRM_STATE_ALIGN4 64
102// #define XFRM_STATE_ESN    128
103// };
104//
105// #define XFRM_SA_XFLAG_DONT_ENCAP_DSCP 1
106//
107
108type XfrmUsersaInfo struct {
109	Sel          XfrmSelector
110	Id           XfrmId
111	Saddr        XfrmAddress
112	Lft          XfrmLifetimeCfg
113	Curlft       XfrmLifetimeCur
114	Stats        XfrmStats
115	Seq          uint32
116	Reqid        uint32
117	Family       uint16
118	Mode         uint8
119	ReplayWindow uint8
120	Flags        uint8
121	Pad          [7]byte
122}
123
124func (msg *XfrmUsersaInfo) Len() int {
125	return SizeofXfrmUsersaInfo
126}
127
128func DeserializeXfrmUsersaInfo(b []byte) *XfrmUsersaInfo {
129	return (*XfrmUsersaInfo)(unsafe.Pointer(&b[0:SizeofXfrmUsersaInfo][0]))
130}
131
132func (msg *XfrmUsersaInfo) Serialize() []byte {
133	return (*(*[SizeofXfrmUsersaInfo]byte)(unsafe.Pointer(msg)))[:]
134}
135
136// struct xfrm_userspi_info {
137// 	struct xfrm_usersa_info		info;
138// 	__u32				min;
139// 	__u32				max;
140// };
141
142type XfrmUserSpiInfo struct {
143	XfrmUsersaInfo XfrmUsersaInfo
144	Min            uint32
145	Max            uint32
146}
147
148func (msg *XfrmUserSpiInfo) Len() int {
149	return SizeofXfrmUserSpiInfo
150}
151
152func DeserializeXfrmUserSpiInfo(b []byte) *XfrmUserSpiInfo {
153	return (*XfrmUserSpiInfo)(unsafe.Pointer(&b[0:SizeofXfrmUserSpiInfo][0]))
154}
155
156func (msg *XfrmUserSpiInfo) Serialize() []byte {
157	return (*(*[SizeofXfrmUserSpiInfo]byte)(unsafe.Pointer(msg)))[:]
158}
159
160// struct xfrm_algo {
161//   char    alg_name[64];
162//   unsigned int  alg_key_len;    /* in bits */
163//   char    alg_key[0];
164// };
165
166type XfrmAlgo struct {
167	AlgName   [64]byte
168	AlgKeyLen uint32
169	AlgKey    []byte
170}
171
172func (msg *XfrmAlgo) Len() int {
173	return SizeofXfrmAlgo + int(msg.AlgKeyLen/8)
174}
175
176func DeserializeXfrmAlgo(b []byte) *XfrmAlgo {
177	ret := XfrmAlgo{}
178	copy(ret.AlgName[:], b[0:64])
179	ret.AlgKeyLen = *(*uint32)(unsafe.Pointer(&b[64]))
180	ret.AlgKey = b[68:ret.Len()]
181	return &ret
182}
183
184func (msg *XfrmAlgo) Serialize() []byte {
185	b := make([]byte, msg.Len())
186	copy(b[0:64], msg.AlgName[:])
187	copy(b[64:68], (*(*[4]byte)(unsafe.Pointer(&msg.AlgKeyLen)))[:])
188	copy(b[68:msg.Len()], msg.AlgKey[:])
189	return b
190}
191
192// struct xfrm_algo_auth {
193//   char    alg_name[64];
194//   unsigned int  alg_key_len;    /* in bits */
195//   unsigned int  alg_trunc_len;  /* in bits */
196//   char    alg_key[0];
197// };
198
199type XfrmAlgoAuth struct {
200	AlgName     [64]byte
201	AlgKeyLen   uint32
202	AlgTruncLen uint32
203	AlgKey      []byte
204}
205
206func (msg *XfrmAlgoAuth) Len() int {
207	return SizeofXfrmAlgoAuth + int(msg.AlgKeyLen/8)
208}
209
210func DeserializeXfrmAlgoAuth(b []byte) *XfrmAlgoAuth {
211	ret := XfrmAlgoAuth{}
212	copy(ret.AlgName[:], b[0:64])
213	ret.AlgKeyLen = *(*uint32)(unsafe.Pointer(&b[64]))
214	ret.AlgTruncLen = *(*uint32)(unsafe.Pointer(&b[68]))
215	ret.AlgKey = b[72:ret.Len()]
216	return &ret
217}
218
219func (msg *XfrmAlgoAuth) Serialize() []byte {
220	b := make([]byte, msg.Len())
221	copy(b[0:64], msg.AlgName[:])
222	copy(b[64:68], (*(*[4]byte)(unsafe.Pointer(&msg.AlgKeyLen)))[:])
223	copy(b[68:72], (*(*[4]byte)(unsafe.Pointer(&msg.AlgTruncLen)))[:])
224	copy(b[72:msg.Len()], msg.AlgKey[:])
225	return b
226}
227
228// struct xfrm_algo_aead {
229//   char    alg_name[64];
230//   unsigned int  alg_key_len;  /* in bits */
231//   unsigned int  alg_icv_len;  /* in bits */
232//   char    alg_key[0];
233// }
234
235type XfrmAlgoAEAD struct {
236	AlgName   [64]byte
237	AlgKeyLen uint32
238	AlgICVLen uint32
239	AlgKey    []byte
240}
241
242func (msg *XfrmAlgoAEAD) Len() int {
243	return SizeofXfrmAlgoAEAD + int(msg.AlgKeyLen/8)
244}
245
246func DeserializeXfrmAlgoAEAD(b []byte) *XfrmAlgoAEAD {
247	ret := XfrmAlgoAEAD{}
248	copy(ret.AlgName[:], b[0:64])
249	ret.AlgKeyLen = *(*uint32)(unsafe.Pointer(&b[64]))
250	ret.AlgICVLen = *(*uint32)(unsafe.Pointer(&b[68]))
251	ret.AlgKey = b[72:ret.Len()]
252	return &ret
253}
254
255func (msg *XfrmAlgoAEAD) Serialize() []byte {
256	b := make([]byte, msg.Len())
257	copy(b[0:64], msg.AlgName[:])
258	copy(b[64:68], (*(*[4]byte)(unsafe.Pointer(&msg.AlgKeyLen)))[:])
259	copy(b[68:72], (*(*[4]byte)(unsafe.Pointer(&msg.AlgICVLen)))[:])
260	copy(b[72:msg.Len()], msg.AlgKey[:])
261	return b
262}
263
264// struct xfrm_encap_tmpl {
265//   __u16   encap_type;
266//   __be16    encap_sport;
267//   __be16    encap_dport;
268//   xfrm_address_t  encap_oa;
269// };
270
271type XfrmEncapTmpl struct {
272	EncapType  uint16
273	EncapSport uint16 // big endian
274	EncapDport uint16 // big endian
275	Pad        [2]byte
276	EncapOa    XfrmAddress
277}
278
279func (msg *XfrmEncapTmpl) Len() int {
280	return SizeofXfrmEncapTmpl
281}
282
283func DeserializeXfrmEncapTmpl(b []byte) *XfrmEncapTmpl {
284	return (*XfrmEncapTmpl)(unsafe.Pointer(&b[0:SizeofXfrmEncapTmpl][0]))
285}
286
287func (msg *XfrmEncapTmpl) Serialize() []byte {
288	return (*(*[SizeofXfrmEncapTmpl]byte)(unsafe.Pointer(msg)))[:]
289}
290
291// struct xfrm_usersa_flush {
292//    __u8 proto;
293// };
294
295type XfrmUsersaFlush struct {
296	Proto uint8
297}
298
299func (msg *XfrmUsersaFlush) Len() int {
300	return SizeofXfrmUsersaFlush
301}
302
303func DeserializeXfrmUsersaFlush(b []byte) *XfrmUsersaFlush {
304	return (*XfrmUsersaFlush)(unsafe.Pointer(&b[0:SizeofXfrmUsersaFlush][0]))
305}
306
307func (msg *XfrmUsersaFlush) Serialize() []byte {
308	return (*(*[SizeofXfrmUsersaFlush]byte)(unsafe.Pointer(msg)))[:]
309}
310
311// struct xfrm_replay_state_esn {
312//     unsigned int    bmp_len;
313//     __u32           oseq;
314//     __u32           seq;
315//     __u32           oseq_hi;
316//     __u32           seq_hi;
317//     __u32           replay_window;
318//     __u32           bmp[0];
319// };
320
321type XfrmReplayStateEsn struct {
322	BmpLen       uint32
323	OSeq         uint32
324	Seq          uint32
325	OSeqHi       uint32
326	SeqHi        uint32
327	ReplayWindow uint32
328	Bmp          []uint32
329}
330
331func (msg *XfrmReplayStateEsn) Serialize() []byte {
332	// We deliberately do not pass Bmp, as it gets set by the kernel.
333	return (*(*[SizeofXfrmReplayStateEsn]byte)(unsafe.Pointer(msg)))[:]
334}
335