1package netlink
2
3import (
4	"fmt"
5	"net"
6	"time"
7)
8
9// XfrmStateAlgo represents the algorithm to use for the ipsec encryption.
10type XfrmStateAlgo struct {
11	Name        string
12	Key         []byte
13	TruncateLen int // Auth only
14	ICVLen      int // AEAD only
15}
16
17func (a XfrmStateAlgo) String() string {
18	base := fmt.Sprintf("{Name: %s, Key: 0x%x", a.Name, a.Key)
19	if a.TruncateLen != 0 {
20		base = fmt.Sprintf("%s, Truncate length: %d", base, a.TruncateLen)
21	}
22	if a.ICVLen != 0 {
23		base = fmt.Sprintf("%s, ICV length: %d", base, a.ICVLen)
24	}
25	return fmt.Sprintf("%s}", base)
26}
27
28// EncapType is an enum representing the optional packet encapsulation.
29type EncapType uint8
30
31const (
32	XFRM_ENCAP_ESPINUDP_NONIKE EncapType = iota + 1
33	XFRM_ENCAP_ESPINUDP
34)
35
36func (e EncapType) String() string {
37	switch e {
38	case XFRM_ENCAP_ESPINUDP_NONIKE:
39		return "espinudp-non-ike"
40	case XFRM_ENCAP_ESPINUDP:
41		return "espinudp"
42	}
43	return "unknown"
44}
45
46// XfrmStateEncap represents the encapsulation to use for the ipsec encryption.
47type XfrmStateEncap struct {
48	Type            EncapType
49	SrcPort         int
50	DstPort         int
51	OriginalAddress net.IP
52}
53
54func (e XfrmStateEncap) String() string {
55	return fmt.Sprintf("{Type: %s, Srcport: %d, DstPort: %d, OriginalAddress: %v}",
56		e.Type, e.SrcPort, e.DstPort, e.OriginalAddress)
57}
58
59// XfrmStateLimits represents the configured limits for the state.
60type XfrmStateLimits struct {
61	ByteSoft    uint64
62	ByteHard    uint64
63	PacketSoft  uint64
64	PacketHard  uint64
65	TimeSoft    uint64
66	TimeHard    uint64
67	TimeUseSoft uint64
68	TimeUseHard uint64
69}
70
71// XfrmStateStats represents the current number of bytes/packets
72// processed by this State, the State's installation and first use
73// time and the replay window counters.
74type XfrmStateStats struct {
75	ReplayWindow uint32
76	Replay       uint32
77	Failed       uint32
78	Bytes        uint64
79	Packets      uint64
80	AddTime      uint64
81	UseTime      uint64
82}
83
84// XfrmState represents the state of an ipsec policy. It optionally
85// contains an XfrmStateAlgo for encryption and one for authentication.
86type XfrmState struct {
87	Dst          net.IP
88	Src          net.IP
89	Proto        Proto
90	Mode         Mode
91	Spi          int
92	Reqid        int
93	ReplayWindow int
94	Limits       XfrmStateLimits
95	Statistics   XfrmStateStats
96	Mark         *XfrmMark
97	OutputMark   int
98	Ifid         int
99	Auth         *XfrmStateAlgo
100	Crypt        *XfrmStateAlgo
101	Aead         *XfrmStateAlgo
102	Encap        *XfrmStateEncap
103	ESN          bool
104}
105
106func (sa XfrmState) String() string {
107	return fmt.Sprintf("Dst: %v, Src: %v, Proto: %s, Mode: %s, SPI: 0x%x, ReqID: 0x%x, ReplayWindow: %d, Mark: %v, OutputMark: %d, Ifid: %d, Auth: %v, Crypt: %v, Aead: %v, Encap: %v, ESN: %t",
108		sa.Dst, sa.Src, sa.Proto, sa.Mode, sa.Spi, sa.Reqid, sa.ReplayWindow, sa.Mark, sa.OutputMark, sa.Ifid, sa.Auth, sa.Crypt, sa.Aead, sa.Encap, sa.ESN)
109}
110func (sa XfrmState) Print(stats bool) string {
111	if !stats {
112		return sa.String()
113	}
114	at := time.Unix(int64(sa.Statistics.AddTime), 0).Format(time.UnixDate)
115	ut := "-"
116	if sa.Statistics.UseTime > 0 {
117		ut = time.Unix(int64(sa.Statistics.UseTime), 0).Format(time.UnixDate)
118	}
119	return fmt.Sprintf("%s, ByteSoft: %s, ByteHard: %s, PacketSoft: %s, PacketHard: %s, TimeSoft: %d, TimeHard: %d, TimeUseSoft: %d, TimeUseHard: %d, Bytes: %d, Packets: %d, "+
120		"AddTime: %s, UseTime: %s, ReplayWindow: %d, Replay: %d, Failed: %d",
121		sa.String(), printLimit(sa.Limits.ByteSoft), printLimit(sa.Limits.ByteHard), printLimit(sa.Limits.PacketSoft), printLimit(sa.Limits.PacketHard),
122		sa.Limits.TimeSoft, sa.Limits.TimeHard, sa.Limits.TimeUseSoft, sa.Limits.TimeUseHard, sa.Statistics.Bytes, sa.Statistics.Packets, at, ut,
123		sa.Statistics.ReplayWindow, sa.Statistics.Replay, sa.Statistics.Failed)
124}
125
126func printLimit(lmt uint64) string {
127	if lmt == ^uint64(0) {
128		return "(INF)"
129	}
130	return fmt.Sprintf("%d", lmt)
131}
132