1 1.24 msaitoh /* $NetBSD: fast_ipsec.c,v 1.24 2022/09/01 10:10:20 msaitoh Exp $ */ 2 1.24 msaitoh /* $FreeBSD: src/tools/tools/crypto/ipsecstats.c,v 1.1.4.1 2003/06/03 00:13:13 sam Exp $ */ 3 1.1 jonathan 4 1.1 jonathan /*- 5 1.1 jonathan * Copyright (c) 2003, 2004 Jonathan Stone 6 1.1 jonathan * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting 7 1.1 jonathan * All rights reserved. 8 1.1 jonathan * 9 1.1 jonathan * Redistribution and use in source and binary forms, with or without 10 1.1 jonathan * modification, are permitted provided that the following conditions 11 1.1 jonathan * are met: 12 1.1 jonathan * 1. Redistributions of source code must retain the above copyright 13 1.1 jonathan * notice, this list of conditions and the following disclaimer. 14 1.1 jonathan * 2. Redistributions in binary form must reproduce the above copyright 15 1.1 jonathan * notice, this list of conditions and the following disclaimer in the 16 1.1 jonathan * documentation and/or other materials provided with the distribution. 17 1.1 jonathan * 18 1.1 jonathan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 1.1 jonathan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 1.1 jonathan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 1.1 jonathan * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 1.1 jonathan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 1.1 jonathan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 1.1 jonathan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 1.1 jonathan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 1.1 jonathan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 1.1 jonathan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 1.1 jonathan * SUCH DAMAGE. 29 1.1 jonathan * 30 1.1 jonathan * $FreeBSD: src/tools/tools/crypto/ipsecstats.c,v 1.1.4.1 2003/06/03 00:13:13 sam Exp $ 31 1.1 jonathan */ 32 1.1 jonathan 33 1.1 jonathan #include <sys/cdefs.h> 34 1.1 jonathan #ifndef lint 35 1.1 jonathan #ifdef __NetBSD__ 36 1.24 msaitoh __RCSID("$NetBSD: fast_ipsec.c,v 1.24 2022/09/01 10:10:20 msaitoh Exp $"); 37 1.1 jonathan #endif 38 1.1 jonathan #endif /* not lint*/ 39 1.1 jonathan 40 1.1 jonathan /* Kernel headers required, but not included, by netstat.h */ 41 1.1 jonathan #include <sys/types.h> 42 1.1 jonathan #include <sys/socket.h> 43 1.1 jonathan 44 1.1 jonathan /* Kernel headers for sysctl(3). */ 45 1.1 jonathan #include <sys/param.h> 46 1.1 jonathan #include <sys/sysctl.h> 47 1.1 jonathan 48 1.1 jonathan /* Kernel headers for FAST_IPSEC statistics */ 49 1.1 jonathan #include <net/pfkeyv2.h> 50 1.1 jonathan #include <netipsec/esp_var.h> 51 1.1 jonathan #include <netipsec/ah_var.h> 52 1.1 jonathan #include <netipsec/ipip_var.h> 53 1.1 jonathan #include <netipsec/ipcomp_var.h> 54 1.1 jonathan #include <netipsec/ipsec_var.h> 55 1.1 jonathan 56 1.2 petrov #include <machine/int_fmtio.h> 57 1.2 petrov 58 1.7 rpaulo #include <kvm.h> 59 1.1 jonathan #include <err.h> 60 1.6 atatat #include <errno.h> 61 1.1 jonathan #include <stdio.h> 62 1.1 jonathan #include <string.h> 63 1.1 jonathan 64 1.1 jonathan #include "netstat.h" 65 1.23 kamil #include "prog_ops.h" 66 1.1 jonathan 67 1.1 jonathan /* 68 1.1 jonathan * Table-driven mapping from SADB algorithm codes to string names. 69 1.1 jonathan */ 70 1.1 jonathan struct alg { 71 1.1 jonathan int a; 72 1.1 jonathan const char *name; 73 1.1 jonathan }; 74 1.1 jonathan 75 1.21 christos static const char *ahalgs[] = { AH_ALG_STR }; 76 1.21 christos static const char *espalgs[] = { ESP_ALG_STR }; 77 1.21 christos static const char *ipcompalgs[] = { IPCOMP_ALG_STR }; 78 1.21 christos 79 1.21 christos static const char * 80 1.21 christos algname(size_t a, const char *algs[], size_t nalgs) 81 1.1 jonathan { 82 1.1 jonathan static char buf[80]; 83 1.1 jonathan 84 1.21 christos if (a < nalgs) 85 1.21 christos return algs[a]; 86 1.21 christos snprintf(buf, sizeof(buf), "alg#%zu", a); 87 1.1 jonathan return buf; 88 1.1 jonathan } 89 1.1 jonathan 90 1.1 jonathan /* 91 1.1 jonathan * Print the fast_ipsec statistics. 92 1.24 msaitoh * Since NetBSD's netstat(1) seems not to find us for "netstat -s", 93 1.1 jonathan * but does(?) find KAME, be prepared to be called explicitly from 94 1.1 jonathan * netstat's main program for "netstat -s"; but silently do nothing 95 1.1 jonathan * if that happens when we are running on KAME IPsec. 96 1.1 jonathan */ 97 1.1 jonathan void 98 1.12 lukem fast_ipsec_stats(u_long off, const char *name) 99 1.1 jonathan { 100 1.10 thorpej uint64_t ipsecstats[IPSEC_NSTATS]; 101 1.10 thorpej uint64_t ahstats[AH_NSTATS]; 102 1.10 thorpej uint64_t espstats[ESP_NSTATS]; 103 1.10 thorpej uint64_t ipcs[IPCOMP_NSTATS]; 104 1.10 thorpej uint64_t ipips[IPIP_NSTATS]; 105 1.2 petrov int status; 106 1.21 christos size_t slen, i; 107 1.1 jonathan 108 1.11 thorpej if (! use_sysctl) { 109 1.11 thorpej warnx("IPsec stats not available via KVM."); 110 1.11 thorpej return; 111 1.11 thorpej } 112 1.11 thorpej 113 1.10 thorpej memset(ipsecstats, 0, sizeof(ipsecstats)); 114 1.10 thorpej memset(ahstats, 0, sizeof(ahstats)); 115 1.10 thorpej memset(espstats, 0, sizeof(espstats)); 116 1.10 thorpej memset(ipcs, 0, sizeof(ipcs)); 117 1.10 thorpej memset(ipips, 0, sizeof(ipips)); 118 1.1 jonathan 119 1.1 jonathan slen = sizeof(ipsecstats); 120 1.24 msaitoh status = prog_sysctlbyname("net.inet.ipsec.ipsecstats", 121 1.24 msaitoh ipsecstats, &slen, NULL, 0); 122 1.20 christos if (status < 0) { 123 1.20 christos if (errno == ENOENT) 124 1.20 christos return; 125 1.20 christos if (errno != ENOMEM) 126 1.20 christos err(1, "net.inet.ipsec.ipsecstats"); 127 1.20 christos } 128 1.1 jonathan 129 1.1 jonathan slen = sizeof (ahstats); 130 1.24 msaitoh status = prog_sysctlbyname("net.inet.ah.ah_stats", 131 1.24 msaitoh ahstats, &slen, NULL, 0); 132 1.6 atatat if (status < 0 && errno != ENOMEM) 133 1.6 atatat err(1, "net.inet.ah.ah_stats"); 134 1.6 atatat 135 1.1 jonathan slen = sizeof (espstats); 136 1.24 msaitoh status = prog_sysctlbyname("net.inet.esp.esp_stats", 137 1.24 msaitoh espstats, &slen, NULL, 0); 138 1.6 atatat if (status < 0 && errno != ENOMEM) 139 1.6 atatat err(1, "net.inet.esp.esp_stats"); 140 1.6 atatat 141 1.6 atatat slen = sizeof(ipcs); 142 1.24 msaitoh status = prog_sysctlbyname("net.inet.ipcomp.ipcomp_stats", 143 1.24 msaitoh ipcs, &slen, NULL, 0); 144 1.6 atatat if (status < 0 && errno != ENOMEM) 145 1.6 atatat err(1, "net.inet.ipcomp.ipcomp_stats"); 146 1.6 atatat 147 1.6 atatat slen = sizeof(ipips); 148 1.24 msaitoh status = prog_sysctlbyname("net.inet.ipip.ipip_stats", 149 1.24 msaitoh ipips, &slen, NULL, 0); 150 1.6 atatat if (status < 0 && errno != ENOMEM) 151 1.6 atatat err(1, "net.inet.ipip.ipip_stats"); 152 1.1 jonathan 153 1.22 ozaki printf("%s:\n", name); 154 1.1 jonathan 155 1.24 msaitoh #define STAT(x, fmt) \ 156 1.24 msaitoh if (ipsecstats[x] || sflag <= 1) \ 157 1.24 msaitoh printf("\t%"PRIu64" " fmt "\n", ipsecstats[x]) 158 1.24 msaitoh 159 1.10 thorpej if (ipsecstats[IPSEC_STAT_IN_POLVIO]+ipsecstats[IPSEC_STAT_OUT_POLVIO]) 160 1.24 msaitoh printf("\t%"PRIu64" policy violations: %"PRIu64" input %" 161 1.24 msaitoh PRIu64" output\n", 162 1.24 msaitoh ipsecstats[IPSEC_STAT_IN_POLVIO] + ipsecstats[IPSEC_STAT_OUT_POLVIO], 163 1.24 msaitoh ipsecstats[IPSEC_STAT_IN_POLVIO], ipsecstats[IPSEC_STAT_OUT_POLVIO]); 164 1.24 msaitoh STAT(IPSEC_STAT_OUT_NOSA, "no SA found (output)"); 165 1.24 msaitoh STAT(IPSEC_STAT_OUT_NOMEM, "no memory available (output)"); 166 1.24 msaitoh STAT(IPSEC_STAT_OUT_NOROUTE, "no route available (output)"); 167 1.24 msaitoh STAT(IPSEC_STAT_OUT_INVAL, "generic errors (output)"); 168 1.24 msaitoh STAT(IPSEC_STAT_OUT_BUNDLESA, "bundled SA processed (output)"); 169 1.24 msaitoh STAT(IPSEC_STAT_SPDCACHELOOKUP, "SPD cache lookups"); 170 1.24 msaitoh STAT(IPSEC_STAT_SPDCACHEMISS, "SPD cache misses"); 171 1.1 jonathan #undef STAT 172 1.24 msaitoh 173 1.22 ozaki printf("\tah:\n"); 174 1.24 msaitoh #define AHSTAT(x, fmt) \ 175 1.24 msaitoh if (ahstats[x] || sflag <= 1) \ 176 1.24 msaitoh printf("\t\t%"PRIu64" ah " fmt "\n", ahstats[x]) 177 1.24 msaitoh 178 1.24 msaitoh AHSTAT(AH_STAT_INPUT, "input packets processed"); 179 1.24 msaitoh AHSTAT(AH_STAT_OUTPUT, "output packets processed"); 180 1.24 msaitoh AHSTAT(AH_STAT_HDROPS, "headers too short"); 181 1.24 msaitoh AHSTAT(AH_STAT_NOPF, "headers for unsupported address family"); 182 1.24 msaitoh AHSTAT(AH_STAT_NOTDB, "packets with no SA"); 183 1.24 msaitoh AHSTAT(AH_STAT_BADKCR, 184 1.24 msaitoh "packets dropped by crypto returning NULL mbuf"); 185 1.24 msaitoh AHSTAT(AH_STAT_BADAUTH, "packets with bad authentication"); 186 1.24 msaitoh AHSTAT(AH_STAT_NOXFORM, "packets with no xform"); 187 1.24 msaitoh AHSTAT(AH_STAT_QFULL, "packets dropped due to queue full"); 188 1.24 msaitoh AHSTAT(AH_STAT_WRAP, "packets dropped for replay counter wrap"); 189 1.24 msaitoh AHSTAT(AH_STAT_REPLAY, "packets dropped for possible replay"); 190 1.24 msaitoh AHSTAT(AH_STAT_BADAUTHL, 191 1.24 msaitoh "packets dropped for bad authenticator length"); 192 1.24 msaitoh AHSTAT(AH_STAT_INVALID, "packets with an invalid SA"); 193 1.24 msaitoh AHSTAT(AH_STAT_TOOBIG, "packets too big"); 194 1.24 msaitoh AHSTAT(AH_STAT_PDROPS, "packets blocked due to policy"); 195 1.24 msaitoh AHSTAT(AH_STAT_CRYPTO, "failed crypto requests"); 196 1.24 msaitoh AHSTAT(AH_STAT_TUNNEL, "tunnel sanity check failures"); 197 1.1 jonathan 198 1.1 jonathan printf("\tah histogram:\n"); 199 1.1 jonathan for (i = 0; i < AH_ALG_MAX; i++) 200 1.10 thorpej if (ahstats[AH_STAT_HIST + i]) 201 1.24 msaitoh printf("\t\tah packets with %s: %"PRIu64"\n", 202 1.24 msaitoh algname(i, ahalgs, __arraycount(ahalgs)), 203 1.24 msaitoh ahstats[AH_STAT_HIST + i]); 204 1.24 msaitoh AHSTAT(AH_STAT_IBYTES, "bytes received"); 205 1.24 msaitoh AHSTAT(AH_STAT_OBYTES, "bytes transmitted"); 206 1.1 jonathan #undef AHSTAT 207 1.1 jonathan 208 1.22 ozaki printf("\tesp:\n"); 209 1.24 msaitoh #define ESPSTAT(x, fmt) \ 210 1.24 msaitoh if (espstats[x] || sflag <= 1) \ 211 1.24 msaitoh printf("\t\t%"PRIu64" esp " fmt "\n", espstats[x]) 212 1.24 msaitoh 213 1.24 msaitoh ESPSTAT(ESP_STAT_INPUT, "input packets processed"); 214 1.24 msaitoh ESPSTAT(ESP_STAT_OUTPUT, "output packets processed"); 215 1.24 msaitoh ESPSTAT(ESP_STAT_HDROPS, "headers too short"); 216 1.24 msaitoh ESPSTAT(ESP_STAT_NOPF, "headers for unsupported address family"); 217 1.24 msaitoh ESPSTAT(ESP_STAT_NOTDB, "packets with no SA"); 218 1.24 msaitoh ESPSTAT(ESP_STAT_BADKCR, 219 1.24 msaitoh "packets dropped by crypto returning NULL mbuf"); 220 1.24 msaitoh ESPSTAT(ESP_STAT_QFULL, "packets dropped due to queue full"); 221 1.24 msaitoh ESPSTAT(ESP_STAT_NOXFORM, "packets with no xform"); 222 1.24 msaitoh ESPSTAT(ESP_STAT_BADILEN, "packets with bad ilen"); 223 1.24 msaitoh ESPSTAT(ESP_STAT_BADENC, "packets with bad encryption"); 224 1.24 msaitoh ESPSTAT(ESP_STAT_BADAUTH, "packets with bad authentication"); 225 1.24 msaitoh ESPSTAT(ESP_STAT_WRAP, "packets dropped for replay counter wrap"); 226 1.24 msaitoh ESPSTAT(ESP_STAT_REPLAY, "packets dropped for possible replay"); 227 1.24 msaitoh ESPSTAT(ESP_STAT_INVALID, "packets with an invalid SA"); 228 1.24 msaitoh ESPSTAT(ESP_STAT_TOOBIG, "packets too big"); 229 1.24 msaitoh ESPSTAT(ESP_STAT_PDROPS, "packets blocked due to policy"); 230 1.24 msaitoh ESPSTAT(ESP_STAT_CRYPTO, "failed crypto requests"); 231 1.24 msaitoh ESPSTAT(ESP_STAT_TUNNEL, "tunnel sanity check failures"); 232 1.1 jonathan printf("\tesp histogram:\n"); 233 1.1 jonathan for (i = 0; i < ESP_ALG_MAX; i++) 234 1.10 thorpej if (espstats[ESP_STAT_HIST + i]) 235 1.24 msaitoh printf("\t\tesp packets with %s: %"PRIu64"\n", 236 1.24 msaitoh algname(i, espalgs, __arraycount(espalgs)), 237 1.24 msaitoh espstats[ESP_STAT_HIST + i]); 238 1.24 msaitoh ESPSTAT(ESP_STAT_IBYTES, "bytes received"); 239 1.24 msaitoh ESPSTAT(ESP_STAT_OBYTES, "bytes transmitted"); 240 1.1 jonathan #undef ESPSTAT 241 1.22 ozaki printf("\tipip:\n"); 242 1.1 jonathan 243 1.24 msaitoh #define IPIPSTAT(x, fmt) \ 244 1.24 msaitoh if (ipips[x] || sflag <= 1) \ 245 1.24 msaitoh printf("\t\t%"PRIu64" ipip " fmt "\n", ipips[x]) 246 1.24 msaitoh 247 1.24 msaitoh IPIPSTAT(IPIP_STAT_IPACKETS, "total input packets"); 248 1.24 msaitoh IPIPSTAT(IPIP_STAT_OPACKETS, "total output packets"); 249 1.24 msaitoh IPIPSTAT(IPIP_STAT_HDROPS, "packets too short for header length"); 250 1.24 msaitoh IPIPSTAT(IPIP_STAT_QFULL, "packets dropped due to queue full"); 251 1.24 msaitoh IPIPSTAT(IPIP_STAT_PDROPS, "packets blocked due to policy"); 252 1.24 msaitoh IPIPSTAT(IPIP_STAT_SPOOF, "IP spoofing attempts"); 253 1.24 msaitoh IPIPSTAT(IPIP_STAT_FAMILY, "protocol family mismatched"); 254 1.24 msaitoh IPIPSTAT(IPIP_STAT_UNSPEC, "missing tunnel-endpoint address"); 255 1.24 msaitoh IPIPSTAT(IPIP_STAT_IBYTES, "input bytes received"); 256 1.24 msaitoh IPIPSTAT(IPIP_STAT_OBYTES, "output bytes processed"); 257 1.1 jonathan #undef IPIPSTAT 258 1.1 jonathan 259 1.22 ozaki printf("\tipcomp:\n"); 260 1.24 msaitoh #define IPCOMP(x, fmt) \ 261 1.24 msaitoh if (ipcs[x] || sflag <= 1) \ 262 1.24 msaitoh printf("\t\t%"PRIu64" ipcomp " fmt "\n", ipcs[x]) 263 1.24 msaitoh 264 1.24 msaitoh IPCOMP(IPCOMP_STAT_HDROPS, "packets too short for header length"); 265 1.24 msaitoh IPCOMP(IPCOMP_STAT_NOPF, "protocol family not supported"); 266 1.24 msaitoh IPCOMP(IPCOMP_STAT_NOTDB, "packets with no SA"); 267 1.24 msaitoh IPCOMP(IPCOMP_STAT_BADKCR, 268 1.24 msaitoh "packets dropped by crypto returning NULL mbuf"); 269 1.24 msaitoh IPCOMP(IPCOMP_STAT_QFULL, "queue full"); 270 1.24 msaitoh IPCOMP(IPCOMP_STAT_NOXFORM, "no support for transform"); 271 1.24 msaitoh IPCOMP(IPCOMP_STAT_WRAP, "packets dropped for replay counter wrap"); 272 1.24 msaitoh IPCOMP(IPCOMP_STAT_INPUT, "input IPcomp packets"); 273 1.24 msaitoh IPCOMP(IPCOMP_STAT_OUTPUT, "output IPcomp packets"); 274 1.24 msaitoh IPCOMP(IPCOMP_STAT_INVALID, "packets with an invalid SA"); 275 1.24 msaitoh IPCOMP(IPCOMP_STAT_TOOBIG, "packets decompressed as too big"); 276 1.24 msaitoh IPCOMP(IPCOMP_STAT_MINLEN, "packets too short to be compressed"); 277 1.24 msaitoh IPCOMP(IPCOMP_STAT_USELESS,"packet for which compression was useless"); 278 1.24 msaitoh IPCOMP(IPCOMP_STAT_PDROPS, "packets blocked due to policy"); 279 1.24 msaitoh IPCOMP(IPCOMP_STAT_CRYPTO, "failed crypto requests"); 280 1.1 jonathan 281 1.22 ozaki printf("\tipcomp histogram:\n"); 282 1.1 jonathan for (i = 0; i < IPCOMP_ALG_MAX; i++) 283 1.10 thorpej if (ipcs[IPCOMP_STAT_HIST + i]) 284 1.24 msaitoh printf("\t\tIPcomp packets with %s: %"PRIu64"\n", 285 1.24 msaitoh algname(i, ipcompalgs, __arraycount(ipcompalgs)), 286 1.24 msaitoh ipcs[IPCOMP_STAT_HIST + i]); 287 1.24 msaitoh IPCOMP(IPCOMP_STAT_IBYTES, "input bytes"); 288 1.24 msaitoh IPCOMP(IPCOMP_STAT_OBYTES, "output bytes"); 289 1.1 jonathan #undef IPCOMP 290 1.1 jonathan } 291