306 lines
7.3 KiB
Go
306 lines
7.3 KiB
Go
package nl
|
|
|
|
import (
|
|
"bytes"
|
|
"net"
|
|
"unsafe"
|
|
)
|
|
|
|
// Infinity for packet and byte counts
|
|
const (
|
|
XFRM_INF = ^uint64(0)
|
|
)
|
|
|
|
type XfrmMsgType uint8
|
|
|
|
type XfrmMsg interface {
|
|
Type() XfrmMsgType
|
|
}
|
|
|
|
// Message Types
|
|
const (
|
|
XFRM_MSG_BASE XfrmMsgType = 0x10
|
|
XFRM_MSG_NEWSA = 0x10
|
|
XFRM_MSG_DELSA = 0x11
|
|
XFRM_MSG_GETSA = 0x12
|
|
XFRM_MSG_NEWPOLICY = 0x13
|
|
XFRM_MSG_DELPOLICY = 0x14
|
|
XFRM_MSG_GETPOLICY = 0x15
|
|
XFRM_MSG_ALLOCSPI = 0x16
|
|
XFRM_MSG_ACQUIRE = 0x17
|
|
XFRM_MSG_EXPIRE = 0x18
|
|
XFRM_MSG_UPDPOLICY = 0x19
|
|
XFRM_MSG_UPDSA = 0x1a
|
|
XFRM_MSG_POLEXPIRE = 0x1b
|
|
XFRM_MSG_FLUSHSA = 0x1c
|
|
XFRM_MSG_FLUSHPOLICY = 0x1d
|
|
XFRM_MSG_NEWAE = 0x1e
|
|
XFRM_MSG_GETAE = 0x1f
|
|
XFRM_MSG_REPORT = 0x20
|
|
XFRM_MSG_MIGRATE = 0x21
|
|
XFRM_MSG_NEWSADINFO = 0x22
|
|
XFRM_MSG_GETSADINFO = 0x23
|
|
XFRM_MSG_NEWSPDINFO = 0x24
|
|
XFRM_MSG_GETSPDINFO = 0x25
|
|
XFRM_MSG_MAPPING = 0x26
|
|
XFRM_MSG_MAX = 0x26
|
|
XFRM_NR_MSGTYPES = 0x17
|
|
)
|
|
|
|
// Attribute types
|
|
const (
|
|
/* Netlink message attributes. */
|
|
XFRMA_UNSPEC = iota
|
|
XFRMA_ALG_AUTH /* struct xfrm_algo */
|
|
XFRMA_ALG_CRYPT /* struct xfrm_algo */
|
|
XFRMA_ALG_COMP /* struct xfrm_algo */
|
|
XFRMA_ENCAP /* struct xfrm_algo + struct xfrm_encap_tmpl */
|
|
XFRMA_TMPL /* 1 or more struct xfrm_user_tmpl */
|
|
XFRMA_SA /* struct xfrm_usersa_info */
|
|
XFRMA_POLICY /* struct xfrm_userpolicy_info */
|
|
XFRMA_SEC_CTX /* struct xfrm_sec_ctx */
|
|
XFRMA_LTIME_VAL
|
|
XFRMA_REPLAY_VAL
|
|
XFRMA_REPLAY_THRESH
|
|
XFRMA_ETIMER_THRESH
|
|
XFRMA_SRCADDR /* xfrm_address_t */
|
|
XFRMA_COADDR /* xfrm_address_t */
|
|
XFRMA_LASTUSED /* unsigned long */
|
|
XFRMA_POLICY_TYPE /* struct xfrm_userpolicy_type */
|
|
XFRMA_MIGRATE
|
|
XFRMA_ALG_AEAD /* struct xfrm_algo_aead */
|
|
XFRMA_KMADDRESS /* struct xfrm_user_kmaddress */
|
|
XFRMA_ALG_AUTH_TRUNC /* struct xfrm_algo_auth */
|
|
XFRMA_MARK /* struct xfrm_mark */
|
|
XFRMA_TFCPAD /* __u32 */
|
|
XFRMA_REPLAY_ESN_VAL /* struct xfrm_replay_esn */
|
|
XFRMA_SA_EXTRA_FLAGS /* __u32 */
|
|
XFRMA_PROTO /* __u8 */
|
|
XFRMA_ADDRESS_FILTER /* struct xfrm_address_filter */
|
|
XFRMA_PAD
|
|
XFRMA_OFFLOAD_DEV /* struct xfrm_state_offload */
|
|
XFRMA_SET_MARK /* __u32 */
|
|
XFRMA_SET_MARK_MASK /* __u32 */
|
|
XFRMA_IF_ID /* __u32 */
|
|
|
|
XFRMA_MAX = iota - 1
|
|
)
|
|
|
|
const XFRMA_OUTPUT_MARK = XFRMA_SET_MARK
|
|
|
|
const (
|
|
SizeofXfrmAddress = 0x10
|
|
SizeofXfrmSelector = 0x38
|
|
SizeofXfrmLifetimeCfg = 0x40
|
|
SizeofXfrmLifetimeCur = 0x20
|
|
SizeofXfrmId = 0x18
|
|
SizeofXfrmMark = 0x08
|
|
)
|
|
|
|
// Netlink groups
|
|
const (
|
|
XFRMNLGRP_NONE = 0x0
|
|
XFRMNLGRP_ACQUIRE = 0x1
|
|
XFRMNLGRP_EXPIRE = 0x2
|
|
XFRMNLGRP_SA = 0x3
|
|
XFRMNLGRP_POLICY = 0x4
|
|
XFRMNLGRP_AEVENTS = 0x5
|
|
XFRMNLGRP_REPORT = 0x6
|
|
XFRMNLGRP_MIGRATE = 0x7
|
|
XFRMNLGRP_MAPPING = 0x8
|
|
__XFRMNLGRP_MAX = 0x9
|
|
)
|
|
|
|
// typedef union {
|
|
// __be32 a4;
|
|
// __be32 a6[4];
|
|
// } xfrm_address_t;
|
|
|
|
type XfrmAddress [SizeofXfrmAddress]byte
|
|
|
|
func (x *XfrmAddress) ToIP() net.IP {
|
|
var empty = [12]byte{}
|
|
ip := make(net.IP, net.IPv6len)
|
|
if bytes.Equal(x[4:16], empty[:]) {
|
|
ip[10] = 0xff
|
|
ip[11] = 0xff
|
|
copy(ip[12:16], x[0:4])
|
|
} else {
|
|
copy(ip[:], x[:])
|
|
}
|
|
return ip
|
|
}
|
|
|
|
func (x *XfrmAddress) ToIPNet(prefixlen uint8) *net.IPNet {
|
|
ip := x.ToIP()
|
|
if GetIPFamily(ip) == FAMILY_V4 {
|
|
return &net.IPNet{IP: ip, Mask: net.CIDRMask(int(prefixlen), 32)}
|
|
}
|
|
return &net.IPNet{IP: ip, Mask: net.CIDRMask(int(prefixlen), 128)}
|
|
}
|
|
|
|
func (x *XfrmAddress) FromIP(ip net.IP) {
|
|
var empty = [16]byte{}
|
|
if len(ip) < net.IPv4len {
|
|
copy(x[4:16], empty[:])
|
|
} else if GetIPFamily(ip) == FAMILY_V4 {
|
|
copy(x[0:4], ip.To4()[0:4])
|
|
copy(x[4:16], empty[:12])
|
|
} else {
|
|
copy(x[0:16], ip.To16()[0:16])
|
|
}
|
|
}
|
|
|
|
func DeserializeXfrmAddress(b []byte) *XfrmAddress {
|
|
return (*XfrmAddress)(unsafe.Pointer(&b[0:SizeofXfrmAddress][0]))
|
|
}
|
|
|
|
func (x *XfrmAddress) Serialize() []byte {
|
|
return (*(*[SizeofXfrmAddress]byte)(unsafe.Pointer(x)))[:]
|
|
}
|
|
|
|
// struct xfrm_selector {
|
|
// xfrm_address_t daddr;
|
|
// xfrm_address_t saddr;
|
|
// __be16 dport;
|
|
// __be16 dport_mask;
|
|
// __be16 sport;
|
|
// __be16 sport_mask;
|
|
// __u16 family;
|
|
// __u8 prefixlen_d;
|
|
// __u8 prefixlen_s;
|
|
// __u8 proto;
|
|
// int ifindex;
|
|
// __kernel_uid32_t user;
|
|
// };
|
|
|
|
type XfrmSelector struct {
|
|
Daddr XfrmAddress
|
|
Saddr XfrmAddress
|
|
Dport uint16 // big endian
|
|
DportMask uint16 // big endian
|
|
Sport uint16 // big endian
|
|
SportMask uint16 // big endian
|
|
Family uint16
|
|
PrefixlenD uint8
|
|
PrefixlenS uint8
|
|
Proto uint8
|
|
Pad [3]byte
|
|
Ifindex int32
|
|
User uint32
|
|
}
|
|
|
|
func (msg *XfrmSelector) Len() int {
|
|
return SizeofXfrmSelector
|
|
}
|
|
|
|
func DeserializeXfrmSelector(b []byte) *XfrmSelector {
|
|
return (*XfrmSelector)(unsafe.Pointer(&b[0:SizeofXfrmSelector][0]))
|
|
}
|
|
|
|
func (msg *XfrmSelector) Serialize() []byte {
|
|
return (*(*[SizeofXfrmSelector]byte)(unsafe.Pointer(msg)))[:]
|
|
}
|
|
|
|
// struct xfrm_lifetime_cfg {
|
|
// __u64 soft_byte_limit;
|
|
// __u64 hard_byte_limit;
|
|
// __u64 soft_packet_limit;
|
|
// __u64 hard_packet_limit;
|
|
// __u64 soft_add_expires_seconds;
|
|
// __u64 hard_add_expires_seconds;
|
|
// __u64 soft_use_expires_seconds;
|
|
// __u64 hard_use_expires_seconds;
|
|
// };
|
|
//
|
|
|
|
type XfrmLifetimeCfg struct {
|
|
SoftByteLimit uint64
|
|
HardByteLimit uint64
|
|
SoftPacketLimit uint64
|
|
HardPacketLimit uint64
|
|
SoftAddExpiresSeconds uint64
|
|
HardAddExpiresSeconds uint64
|
|
SoftUseExpiresSeconds uint64
|
|
HardUseExpiresSeconds uint64
|
|
}
|
|
|
|
func (msg *XfrmLifetimeCfg) Len() int {
|
|
return SizeofXfrmLifetimeCfg
|
|
}
|
|
|
|
func DeserializeXfrmLifetimeCfg(b []byte) *XfrmLifetimeCfg {
|
|
return (*XfrmLifetimeCfg)(unsafe.Pointer(&b[0:SizeofXfrmLifetimeCfg][0]))
|
|
}
|
|
|
|
func (msg *XfrmLifetimeCfg) Serialize() []byte {
|
|
return (*(*[SizeofXfrmLifetimeCfg]byte)(unsafe.Pointer(msg)))[:]
|
|
}
|
|
|
|
// struct xfrm_lifetime_cur {
|
|
// __u64 bytes;
|
|
// __u64 packets;
|
|
// __u64 add_time;
|
|
// __u64 use_time;
|
|
// };
|
|
|
|
type XfrmLifetimeCur struct {
|
|
Bytes uint64
|
|
Packets uint64
|
|
AddTime uint64
|
|
UseTime uint64
|
|
}
|
|
|
|
func (msg *XfrmLifetimeCur) Len() int {
|
|
return SizeofXfrmLifetimeCur
|
|
}
|
|
|
|
func DeserializeXfrmLifetimeCur(b []byte) *XfrmLifetimeCur {
|
|
return (*XfrmLifetimeCur)(unsafe.Pointer(&b[0:SizeofXfrmLifetimeCur][0]))
|
|
}
|
|
|
|
func (msg *XfrmLifetimeCur) Serialize() []byte {
|
|
return (*(*[SizeofXfrmLifetimeCur]byte)(unsafe.Pointer(msg)))[:]
|
|
}
|
|
|
|
// struct xfrm_id {
|
|
// xfrm_address_t daddr;
|
|
// __be32 spi;
|
|
// __u8 proto;
|
|
// };
|
|
|
|
type XfrmId struct {
|
|
Daddr XfrmAddress
|
|
Spi uint32 // big endian
|
|
Proto uint8
|
|
Pad [3]byte
|
|
}
|
|
|
|
func (msg *XfrmId) Len() int {
|
|
return SizeofXfrmId
|
|
}
|
|
|
|
func DeserializeXfrmId(b []byte) *XfrmId {
|
|
return (*XfrmId)(unsafe.Pointer(&b[0:SizeofXfrmId][0]))
|
|
}
|
|
|
|
func (msg *XfrmId) Serialize() []byte {
|
|
return (*(*[SizeofXfrmId]byte)(unsafe.Pointer(msg)))[:]
|
|
}
|
|
|
|
type XfrmMark struct {
|
|
Value uint32
|
|
Mask uint32
|
|
}
|
|
|
|
func (msg *XfrmMark) Len() int {
|
|
return SizeofXfrmMark
|
|
}
|
|
|
|
func DeserializeXfrmMark(b []byte) *XfrmMark {
|
|
return (*XfrmMark)(unsafe.Pointer(&b[0:SizeofXfrmMark][0]))
|
|
}
|
|
|
|
func (msg *XfrmMark) Serialize() []byte {
|
|
return (*(*[SizeofXfrmMark]byte)(unsafe.Pointer(msg)))[:]
|
|
}
|