github.com/sagernet/netlink@v0.0.0-20240612041022-b9a21c07ac6a/xfrm_state.go (about) 1 package netlink 2 3 import ( 4 "fmt" 5 "net" 6 "time" 7 ) 8 9 // XfrmStateAlgo represents the algorithm to use for the ipsec encryption. 10 type XfrmStateAlgo struct { 11 Name string 12 Key []byte 13 TruncateLen int // Auth only 14 ICVLen int // AEAD only 15 } 16 17 func (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. 29 type EncapType uint8 30 31 const ( 32 XFRM_ENCAP_ESPINUDP_NONIKE EncapType = iota + 1 33 XFRM_ENCAP_ESPINUDP 34 ) 35 36 func (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. 47 type XfrmStateEncap struct { 48 Type EncapType 49 SrcPort int 50 DstPort int 51 OriginalAddress net.IP 52 } 53 54 func (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. 60 type 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. 74 type 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 // XfrmReplayState represents the sequence number states for 85 // "legacy" anti-replay mode. 86 type XfrmReplayState struct { 87 OSeq uint32 88 Seq uint32 89 BitMap uint32 90 } 91 92 func (r XfrmReplayState) String() string { 93 return fmt.Sprintf("{OSeq: 0x%x, Seq: 0x%x, BitMap: 0x%x}", 94 r.OSeq, r.Seq, r.BitMap) 95 } 96 97 // XfrmState represents the state of an ipsec policy. It optionally 98 // contains an XfrmStateAlgo for encryption and one for authentication. 99 type XfrmState struct { 100 Dst net.IP 101 Src net.IP 102 Proto Proto 103 Mode Mode 104 Spi int 105 Reqid int 106 ReplayWindow int 107 Limits XfrmStateLimits 108 Statistics XfrmStateStats 109 Mark *XfrmMark 110 OutputMark *XfrmMark 111 Ifid int 112 Auth *XfrmStateAlgo 113 Crypt *XfrmStateAlgo 114 Aead *XfrmStateAlgo 115 Encap *XfrmStateEncap 116 ESN bool 117 DontEncapDSCP bool 118 OSeqMayWrap bool 119 Replay *XfrmReplayState 120 } 121 122 func (sa XfrmState) String() string { 123 return fmt.Sprintf("Dst: %v, Src: %v, Proto: %s, Mode: %s, SPI: 0x%x, ReqID: 0x%x, ReplayWindow: %d, Mark: %v, OutputMark: %v, Ifid: %d, Auth: %v, Crypt: %v, Aead: %v, Encap: %v, ESN: %t, DontEncapDSCP: %t, OSeqMayWrap: %t, Replay: %v", 124 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, sa.DontEncapDSCP, sa.OSeqMayWrap, sa.Replay) 125 } 126 func (sa XfrmState) Print(stats bool) string { 127 if !stats { 128 return sa.String() 129 } 130 at := time.Unix(int64(sa.Statistics.AddTime), 0).Format(time.UnixDate) 131 ut := "-" 132 if sa.Statistics.UseTime > 0 { 133 ut = time.Unix(int64(sa.Statistics.UseTime), 0).Format(time.UnixDate) 134 } 135 return fmt.Sprintf("%s, ByteSoft: %s, ByteHard: %s, PacketSoft: %s, PacketHard: %s, TimeSoft: %d, TimeHard: %d, TimeUseSoft: %d, TimeUseHard: %d, Bytes: %d, Packets: %d, "+ 136 "AddTime: %s, UseTime: %s, ReplayWindow: %d, Replay: %d, Failed: %d", 137 sa.String(), printLimit(sa.Limits.ByteSoft), printLimit(sa.Limits.ByteHard), printLimit(sa.Limits.PacketSoft), printLimit(sa.Limits.PacketHard), 138 sa.Limits.TimeSoft, sa.Limits.TimeHard, sa.Limits.TimeUseSoft, sa.Limits.TimeUseHard, sa.Statistics.Bytes, sa.Statistics.Packets, at, ut, 139 sa.Statistics.ReplayWindow, sa.Statistics.Replay, sa.Statistics.Failed) 140 } 141 142 func printLimit(lmt uint64) string { 143 if lmt == ^uint64(0) { 144 return "(INF)" 145 } 146 return fmt.Sprintf("%d", lmt) 147 }