1 /* $KAME: ipsec.c,v 1.33 2003/07/25 09:54:32 itojun Exp $ */ 2 3 /*- 4 * Copyright (c) 2005 NTT Multimedia Communications Laboratories, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 /*- 29 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 30 * All rights reserved. 31 * 32 * Redistribution and use in source and binary forms, with or without 33 * modification, are permitted provided that the following conditions 34 * are met: 35 * 1. Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * 2. Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in the 39 * documentation and/or other materials provided with the distribution. 40 * 3. Neither the name of the project nor the names of its contributors 41 * may be used to endorse or promote products derived from this software 42 * without specific prior written permission. 43 * 44 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 47 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 54 * SUCH DAMAGE. 55 */ 56 /*- 57 * Copyright (c) 1983, 1988, 1993 58 * The Regents of the University of California. All rights reserved. 59 * 60 * Redistribution and use in source and binary forms, with or without 61 * modification, are permitted provided that the following conditions 62 * are met: 63 * 1. Redistributions of source code must retain the above copyright 64 * notice, this list of conditions and the following disclaimer. 65 * 2. Redistributions in binary form must reproduce the above copyright 66 * notice, this list of conditions and the following disclaimer in the 67 * documentation and/or other materials provided with the distribution. 68 * 4. Neither the name of the University nor the names of its contributors 69 * may be used to endorse or promote products derived from this software 70 * without specific prior written permission. 71 * 72 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 73 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 74 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 75 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 76 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 77 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 78 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 79 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 80 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 81 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 82 * SUCH DAMAGE. 83 */ 84 85 #if 0 86 #ifndef lint 87 static char sccsid[] = "@(#)inet.c 8.5 (Berkeley) 5/24/95"; 88 #endif /* not lint */ 89 #endif 90 91 #include <sys/cdefs.h> 92 __FBSDID("$FreeBSD$"); 93 94 #include <sys/param.h> 95 #include <sys/queue.h> 96 #include <sys/socket.h> 97 #include <sys/socketvar.h> 98 99 #include <netinet/in.h> 100 101 #ifdef IPSEC 102 #include <netipsec/ipsec.h> 103 #include <netipsec/ah_var.h> 104 #include <netipsec/esp_var.h> 105 #include <netipsec/ipcomp_var.h> 106 #endif 107 108 #include <stdint.h> 109 #include <stdio.h> 110 #include <string.h> 111 #include <unistd.h> 112 #include "netstat.h" 113 114 #ifdef IPSEC 115 struct val2str { 116 int val; 117 const char *str; 118 }; 119 120 static struct val2str ipsec_ahnames[] = { 121 { SADB_AALG_NONE, "none", }, 122 { SADB_AALG_MD5HMAC, "hmac-md5", }, 123 { SADB_AALG_SHA1HMAC, "hmac-sha1", }, 124 { SADB_X_AALG_MD5, "md5", }, 125 { SADB_X_AALG_SHA, "sha", }, 126 { SADB_X_AALG_NULL, "null", }, 127 #ifdef SADB_X_AALG_SHA2_256 128 { SADB_X_AALG_SHA2_256, "hmac-sha2-256", }, 129 #endif 130 #ifdef SADB_X_AALG_SHA2_384 131 { SADB_X_AALG_SHA2_384, "hmac-sha2-384", }, 132 #endif 133 #ifdef SADB_X_AALG_SHA2_512 134 { SADB_X_AALG_SHA2_512, "hmac-sha2-512", }, 135 #endif 136 #ifdef SADB_X_AALG_RIPEMD160HMAC 137 { SADB_X_AALG_RIPEMD160HMAC, "hmac-ripemd160", }, 138 #endif 139 #ifdef SADB_X_AALG_AES_XCBC_MAC 140 { SADB_X_AALG_AES_XCBC_MAC, "aes-xcbc-mac", }, 141 #endif 142 { -1, NULL }, 143 }; 144 145 static struct val2str ipsec_espnames[] = { 146 { SADB_EALG_NONE, "none", }, 147 { SADB_EALG_DESCBC, "des-cbc", }, 148 { SADB_EALG_3DESCBC, "3des-cbc", }, 149 { SADB_EALG_NULL, "null", }, 150 { SADB_X_EALG_CAST128CBC, "cast128-cbc", }, 151 { SADB_X_EALG_BLOWFISHCBC, "blowfish-cbc", }, 152 #ifdef SADB_X_EALG_RIJNDAELCBC 153 { SADB_X_EALG_RIJNDAELCBC, "rijndael-cbc", }, 154 #endif 155 #ifdef SADB_X_EALG_AESCTR 156 { SADB_X_EALG_AESCTR, "aes-ctr", }, 157 #endif 158 { -1, NULL }, 159 }; 160 161 static struct val2str ipsec_compnames[] = { 162 { SADB_X_CALG_NONE, "none", }, 163 { SADB_X_CALG_OUI, "oui", }, 164 { SADB_X_CALG_DEFLATE, "deflate", }, 165 { SADB_X_CALG_LZS, "lzs", }, 166 { -1, NULL }, 167 }; 168 169 static void print_ipsecstats(const struct ipsecstat *ipsecstat); 170 171 static void 172 print_ipsecstats(const struct ipsecstat *ipsecstat) 173 { 174 #define p(f, m) if (ipsecstat->f || sflag <= 1) \ 175 printf(m, (uintmax_t)ipsecstat->f, plural(ipsecstat->f)) 176 p(ips_in_polvio, "\t%ju inbound packet%s violated process " 177 "security policy\n"); 178 p(ips_in_nomem, "\t%ju inbound packet%s failed due to " 179 "insufficient memory\n"); 180 p(ips_in_inval, "\t%ju invalid inbound packet%s\n"); 181 p(ips_out_polvio, "\t%ju outbound packet%s violated process " 182 "security policy\n"); 183 p(ips_out_nosa, "\t%ju outbound packet%s with no SA available\n"); 184 p(ips_out_nomem, "\t%ju outbound packet%s failed due to " 185 "insufficient memory\n"); 186 p(ips_out_noroute, "\t%ju outbound packet%s with no route " 187 "available\n"); 188 p(ips_out_inval, "\t%ju invalid outbound packet%s\n"); 189 p(ips_out_bundlesa, "\t%ju outbound packet%s with bundled SAs\n"); 190 p(ips_mbcoalesced, "\t%ju mbuf%s coalesced during clone\n"); 191 p(ips_clcoalesced, "\t%ju cluster%s coalesced during clone\n"); 192 p(ips_clcopied, "\t%ju cluster%s copied during clone\n"); 193 p(ips_mbinserted, "\t%ju mbuf%s inserted during makespace\n"); 194 #undef p 195 } 196 197 void 198 ipsec_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 199 { 200 struct ipsecstat ipsecstat; 201 202 if (off == 0) 203 return; 204 printf ("%s:\n", name); 205 kread_counters(off, (char *)&ipsecstat, sizeof(ipsecstat)); 206 207 print_ipsecstats(&ipsecstat); 208 } 209 210 211 static void ipsec_hist_new(const uint64_t *hist, size_t histmax, 212 const struct val2str *name, const char *title); 213 static void print_ahstats(const struct ahstat *ahstat); 214 static void print_espstats(const struct espstat *espstat); 215 static void print_ipcompstats(const struct ipcompstat *ipcompstat); 216 217 /* 218 * Dump IPSEC statistics structure. 219 */ 220 static void 221 ipsec_hist_new(const uint64_t *hist, size_t histmax, 222 const struct val2str *name, const char *title) 223 { 224 int first; 225 size_t proto; 226 const struct val2str *p; 227 228 first = 1; 229 for (proto = 0; proto < histmax; proto++) { 230 if (hist[proto] <= 0) 231 continue; 232 if (first) { 233 printf("\t%s histogram:\n", title); 234 first = 0; 235 } 236 for (p = name; p && p->str; p++) { 237 if (p->val == (int)proto) 238 break; 239 } 240 if (p && p->str) { 241 printf("\t\t%s: %ju\n", p->str, 242 (uintmax_t)hist[proto]); 243 } else { 244 printf("\t\t#%lu: %ju\n", (unsigned long)proto, 245 (uintmax_t)hist[proto]); 246 } 247 } 248 } 249 250 static void 251 print_ahstats(const struct ahstat *ahstat) 252 { 253 #define p(f, m) if (ahstat->f || sflag <= 1) \ 254 printf("\t%ju" m, (uintmax_t)ahstat->f, plural(ahstat->f)) 255 #define hist(f, n, t) \ 256 ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t)); 257 258 p(ahs_hdrops, " packet%s shorter than header shows\n"); 259 p(ahs_nopf, " packet%s dropped; protocol family not supported\n"); 260 p(ahs_notdb, " packet%s dropped; no TDB\n"); 261 p(ahs_badkcr, " packet%s dropped; bad KCR\n"); 262 p(ahs_qfull, " packet%s dropped; queue full\n"); 263 p(ahs_noxform, " packet%s dropped; no transform\n"); 264 p(ahs_wrap, " replay counter wrap%s\n"); 265 p(ahs_badauth, " packet%s dropped; bad authentication detected\n"); 266 p(ahs_badauthl, " packet%s dropped; bad authentication length\n"); 267 p(ahs_replay, " possible replay packet%s detected\n"); 268 p(ahs_input, " packet%s in\n"); 269 p(ahs_output, " packet%s out\n"); 270 p(ahs_invalid, " packet%s dropped; invalid TDB\n"); 271 p(ahs_ibytes, " byte%s in\n"); 272 p(ahs_obytes, " byte%s out\n"); 273 p(ahs_toobig, " packet%s dropped; larger than IP_MAXPACKET\n"); 274 p(ahs_pdrops, " packet%s blocked due to policy\n"); 275 p(ahs_crypto, " crypto processing failure%s\n"); 276 p(ahs_tunnel, " tunnel sanity check failure%s\n"); 277 hist(ahstat->ahs_hist, ipsec_ahnames, "AH output"); 278 279 #undef p 280 #undef hist 281 } 282 283 void 284 ah_stats(u_long off, const char *name, int family __unused, int proto __unused) 285 { 286 struct ahstat ahstat; 287 288 if (off == 0) 289 return; 290 printf ("%s:\n", name); 291 kread_counters(off, (char *)&ahstat, sizeof(ahstat)); 292 293 print_ahstats(&ahstat); 294 } 295 296 static void 297 print_espstats(const struct espstat *espstat) 298 { 299 #define p(f, m) if (espstat->f || sflag <= 1) \ 300 printf("\t%ju" m, (uintmax_t)espstat->f, plural(espstat->f)) 301 #define hist(f, n, t) \ 302 ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t)); 303 304 p(esps_hdrops, " packet%s shorter than header shows\n"); 305 p(esps_nopf, " packet%s dropped; protocol family not supported\n"); 306 p(esps_notdb, " packet%s dropped; no TDB\n"); 307 p(esps_badkcr, " packet%s dropped; bad KCR\n"); 308 p(esps_qfull, " packet%s dropped; queue full\n"); 309 p(esps_noxform, " packet%s dropped; no transform\n"); 310 p(esps_badilen, " packet%s dropped; bad ilen\n"); 311 p(esps_wrap, " replay counter wrap%s\n"); 312 p(esps_badenc, " packet%s dropped; bad encryption detected\n"); 313 p(esps_badauth, " packet%s dropped; bad authentication detected\n"); 314 p(esps_replay, " possible replay packet%s detected\n"); 315 p(esps_input, " packet%s in\n"); 316 p(esps_output, " packet%s out\n"); 317 p(esps_invalid, " packet%s dropped; invalid TDB\n"); 318 p(esps_ibytes, " byte%s in\n"); 319 p(esps_obytes, " byte%s out\n"); 320 p(esps_toobig, " packet%s dropped; larger than IP_MAXPACKET\n"); 321 p(esps_pdrops, " packet%s blocked due to policy\n"); 322 p(esps_crypto, " crypto processing failure%s\n"); 323 p(esps_tunnel, " tunnel sanity check failure%s\n"); 324 hist(espstat->esps_hist, ipsec_espnames, "ESP output"); 325 326 #undef p 327 #undef hist 328 } 329 330 void 331 esp_stats(u_long off, const char *name, int family __unused, int proto __unused) 332 { 333 struct espstat espstat; 334 335 if (off == 0) 336 return; 337 printf ("%s:\n", name); 338 kread_counters(off, (char *)&espstat, sizeof(espstat)); 339 340 print_espstats(&espstat); 341 } 342 343 static void 344 print_ipcompstats(const struct ipcompstat *ipcompstat) 345 { 346 #define p(f, m) if (ipcompstat->f || sflag <= 1) \ 347 printf("\t%ju" m, (uintmax_t)ipcompstat->f, plural(ipcompstat->f)) 348 #define hist(f, n, t) \ 349 ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t)); 350 351 p(ipcomps_hdrops, " packet%s shorter than header shows\n"); 352 p(ipcomps_nopf, " packet%s dropped; protocol family not supported\n"); 353 p(ipcomps_notdb, " packet%s dropped; no TDB\n"); 354 p(ipcomps_badkcr, " packet%s dropped; bad KCR\n"); 355 p(ipcomps_qfull, " packet%s dropped; queue full\n"); 356 p(ipcomps_noxform, " packet%s dropped; no transform\n"); 357 p(ipcomps_wrap, " replay counter wrap%s\n"); 358 p(ipcomps_input, " packet%s in\n"); 359 p(ipcomps_output, " packet%s out\n"); 360 p(ipcomps_invalid, " packet%s dropped; invalid TDB\n"); 361 p(ipcomps_ibytes, " byte%s in\n"); 362 p(ipcomps_obytes, " byte%s out\n"); 363 p(ipcomps_toobig, " packet%s dropped; larger than IP_MAXPACKET\n"); 364 p(ipcomps_pdrops, " packet%s blocked due to policy\n"); 365 p(ipcomps_crypto, " crypto processing failure%s\n"); 366 hist(ipcompstat->ipcomps_hist, ipsec_compnames, "COMP output"); 367 p(ipcomps_threshold, " packet%s sent uncompressed; size < compr. algo. threshold\n"); 368 p(ipcomps_uncompr, " packet%s sent uncompressed; compression was useless\n"); 369 370 #undef p 371 #undef hist 372 } 373 374 void 375 ipcomp_stats(u_long off, const char *name, int family __unused, 376 int proto __unused) 377 { 378 struct ipcompstat ipcompstat; 379 380 if (off == 0) 381 return; 382 printf ("%s:\n", name); 383 kread_counters(off, (char *)&ipcompstat, sizeof(ipcompstat)); 384 385 print_ipcompstats(&ipcompstat); 386 } 387 388 #endif /*IPSEC*/ 389