]>
git.saurik.com Git - apple/network_cmds.git/blob - netstat.tproj/ipsec.c
   2  * Copyright (c) 2008-2012 Apple Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. The rights granted to you under the License 
  10  * may not be used to create, or enable the creation or redistribution of, 
  11  * unlawful or unlicensed copies of an Apple operating system, or to 
  12  * circumvent, violate, or enable the circumvention or violation of, any 
  13  * terms of an Apple operating system software license agreement. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  18  * The Original Code and all software distributed under the License are 
  19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  23  * Please see the License for the specific language governing rights and 
  24  * limitations under the License. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  28 /*      $FreeBSD: src/usr.bin/netstat/ipsec.c,v 1.1.2.3 2001/08/10 09:07:09 ru Exp $    */ 
  29 /*      $NetBSD: inet.c,v 1.35.2.1 1999/04/29 14:57:08 perry Exp $      */ 
  30 /*      $KAME: ipsec.c,v 1.25 2001/03/12 09:04:39 itojun Exp $  */ 
  33  * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 
  34  * All rights reserved. 
  36  * Redistribution and use in source and binary forms, with or without 
  37  * modification, are permitted provided that the following conditions 
  39  * 1. Redistributions of source code must retain the above copyright 
  40  *    notice, this list of conditions and the following disclaimer. 
  41  * 2. Redistributions in binary form must reproduce the above copyright 
  42  *    notice, this list of conditions and the following disclaimer in the 
  43  *    documentation and/or other materials provided with the distribution. 
  44  * 3. Neither the name of the project nor the names of its contributors 
  45  *    may be used to endorse or promote products derived from this software 
  46  *    without specific prior written permission. 
  48  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 
  49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 
  52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  62  * Copyright (c) 1983, 1988, 1993 
  63  *      The Regents of the University of California.  All rights reserved. 
  65  * Redistribution and use in source and binary forms, with or without 
  66  * modification, are permitted provided that the following conditions 
  68  * 1. Redistributions of source code must retain the above copyright 
  69  *    notice, this list of conditions and the following disclaimer. 
  70  * 2. Redistributions in binary form must reproduce the above copyright 
  71  *    notice, this list of conditions and the following disclaimer in the 
  72  *    documentation and/or other materials provided with the distribution. 
  73  * 3. All advertising materials mentioning features or use of this software 
  74  *    must display the following acknowledgement: 
  75  *      This product includes software developed by the University of 
  76  *      California, Berkeley and its contributors. 
  77  * 4. Neither the name of the University nor the names of its contributors 
  78  *    may be used to endorse or promote products derived from this software 
  79  *    without specific prior written permission. 
  81  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 
  82  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  83  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  84  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 
  85  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  86  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  87  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  88  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  89  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  90  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  94 #include <sys/param.h> 
  95 #include <sys/queue.h> 
  96 #include <sys/socket.h> 
  97 #include <sys/sysctl.h> 
  99 #include <netinet/in.h> 
 102 #include <netinet6/ipsec.h> 
 103 #include <netkey/keysock.h> 
 111 #if defined(__APPLE__) && !defined(__unused) 
 115  * portability issues: 
 116  * - bsdi[34] uses PLURAL(), not plural(). 
 117  * - freebsd2 can't print "unsigned long long" properly. 
 120  * XXX see PORTABILITY for the twist 
 123 #define CAST    unsigned long long 
 131 static struct val2str ipsec_ahnames
[] = { 
 132         { SADB_AALG_NONE
, "none", }, 
 133         { SADB_AALG_MD5HMAC
, "hmac-md5", }, 
 134         { SADB_AALG_SHA1HMAC
, "hmac-sha1", }, 
 135         { SADB_X_AALG_MD5
, "md5", }, 
 136         { SADB_X_AALG_SHA
, "sha", }, 
 137         { SADB_X_AALG_NULL
, "null", }, 
 138 #ifdef SADB_X_AALG_SHA2_256 
 139         { SADB_X_AALG_SHA2_256
, "hmac-sha2-256", }, 
 141 #ifdef SADB_X_AALG_SHA2_384 
 142         { SADB_X_AALG_SHA2_384
, "hmac-sha2-384", }, 
 144 #ifdef SADB_X_AALG_SHA2_512 
 145         { SADB_X_AALG_SHA2_512
, "hmac-sha2-512", }, 
 150 static struct val2str ipsec_espnames
[] = { 
 151         { SADB_EALG_NONE
, "none", }, 
 152         { SADB_EALG_DESCBC
, "des-cbc", }, 
 153         { SADB_EALG_3DESCBC
, "3des-cbc", }, 
 154         { SADB_EALG_NULL
, "null", }, 
 155 #ifdef SADB_X_EALG_RC5CBC 
 156         { SADB_X_EALG_RC5CBC
, "rc5-cbc", }, 
 158         { SADB_X_EALG_CAST128CBC
, "cast128-cbc", }, 
 159         { SADB_X_EALG_BLOWFISHCBC
, "blowfish-cbc", }, 
 160 #ifdef SADB_X_EALG_RIJNDAELCBC 
 161         { SADB_X_EALG_RIJNDAELCBC
, "rijndael-cbc", }, 
 166 static struct val2str ipsec_compnames
[] = { 
 167         { SADB_X_CALG_NONE
, "none", }, 
 168         { SADB_X_CALG_OUI
, "oui", }, 
 169         { SADB_X_CALG_DEFLATE
, "deflate", }, 
 170         { SADB_X_CALG_LZS
, "lzs", }, 
 174 static const char *pfkey_msgtypenames
[] = { 
 175         "reserved", "getspi", "update", "add", "delete", 
 176         "get", "acquire", "register", "expire", "flush", 
 177         "dump", "x_promisc", "x_pchange", "x_spdupdate", "x_spdadd", 
 178         "x_spddelete", "x_spdget", "x_spdacquire", "x_spddump", "x_spdflush", 
 179         "x_spdsetidx", "x_spdexpire", "x_spddelete2" 
 182 static struct ipsecstat pipsecstat
; 
 183 static struct ipsecstat ipsecstat
; 
 185 static void print_ipsecstats (void); 
 186 static const char *pfkey_msgtype_names (int); 
 187 static void ipsec_hist (const u_quad_t 
*, const u_quad_t 
*, size_t, 
 188     const struct val2str 
*, const char *); 
 191  * Dump IPSEC statistics structure. 
 194 ipsec_hist(const u_quad_t 
*hist
, 
 195            const u_quad_t 
*phist
, 
 197            const struct val2str 
*name
, 
 202         const struct val2str 
*p
; 
 205         for (proto 
= 0; proto 
< histmax
; proto
++) { 
 206                 if ((hist
[proto
] - phist
[proto
]) <= 0) 
 209                         printf("\t%s histogram:\n", title
); 
 212                 for (p 
= name
; p 
&& p
->str
; p
++) { 
 213                         if (p
->val 
== (int)proto
) 
 217                         printf("\t\t%s: " LLU 
"\n", p
->str
, 
 218                             (CAST
)hist
[proto
] - (CAST
)phist
[proto
]); 
 220                         printf("\t\t#%ld: " LLU 
"\n", (long)proto
, 
 221                             (CAST
)hist
[proto
] - (CAST
)phist
[proto
]); 
 227 print_ipsecstats(void) 
 229 #define IPSECDIFF(f) (ipsecstat.f - pipsecstat.f) 
 230 #define p(f, m) if (IPSECDIFF(f) || sflag <= 1) \ 
 231     printf(m, (CAST)IPSECDIFF(f), plural(IPSECDIFF(f))) 
 232 #define hist(f, n, t) \ 
 233     ipsec_hist(ipsecstat.f, pipsecstat.f, \ 
 234         sizeof(ipsecstat.f)/sizeof(ipsecstat.f[0]), (n), (t)); 
 236     if (interval 
&& vflag 
> 0) 
 239         p(in_success
, "\t" LLU 
" inbound packet%s processed successfully\n"); 
 240         p(in_polvio
, "\t" LLU 
" inbound packet%s violated process security " 
 242         p(in_nosa
, "\t" LLU 
" inbound packet%s with no SA available\n"); 
 243         p(in_inval
, "\t" LLU 
" invalid inbound packet%s\n"); 
 244         p(in_nomem
, "\t" LLU 
" inbound packet%s failed due to insufficient memory\n"); 
 245         p(in_badspi
, "\t" LLU 
" inbound packet%s failed getting SPI\n"); 
 246         p(in_ahreplay
, "\t" LLU 
" inbound packet%s failed on AH replay check\n"); 
 247         p(in_espreplay
, "\t" LLU 
" inbound packet%s failed on ESP replay check\n"); 
 248         p(in_ahauthsucc
, "\t" LLU 
" inbound packet%s considered authentic\n"); 
 249         p(in_ahauthfail
, "\t" LLU 
" inbound packet%s failed on authentication\n"); 
 250         hist(in_ahhist
, ipsec_ahnames
, "AH input"); 
 251         hist(in_esphist
, ipsec_espnames
, "ESP input"); 
 252         hist(in_comphist
, ipsec_compnames
, "IPComp input"); 
 254         p(out_success
, "\t" LLU 
" outbound packet%s processed successfully\n"); 
 255         p(out_polvio
, "\t" LLU 
" outbound packet%s violated process security " 
 257         p(out_nosa
, "\t" LLU 
" outbound packet%s with no SA available\n"); 
 258         p(out_inval
, "\t" LLU 
" invalid outbound packet%s\n"); 
 259         p(out_nomem
, "\t" LLU 
" outbound packet%s failed due to insufficient memory\n"); 
 260         p(out_noroute
, "\t" LLU 
" outbound packet%s with no route\n"); 
 261         hist(out_ahhist
, ipsec_ahnames
, "AH output"); 
 262         hist(out_esphist
, ipsec_espnames
, "ESP output"); 
 263         hist(out_comphist
, ipsec_compnames
, "IPComp output"); 
 270 ipsec_stats(uint32_t off __unused
, char *name
, int af __unused
) 
 274         len 
= sizeof(struct ipsecstat
); 
 275         if (strcmp(name
, "ipsec") == 0) { 
 276                 if (sysctlbyname("net.inet.ipsec.stats", &ipsecstat
, &len
, 0, 0) == -1) 
 278         } else if (strcmp(name
, "ipsec6") == 0) { 
 279                 if (sysctlbyname("net.inet6.ipsec6.stats", &ipsecstat
, &len
, 0, 0) == -1) 
 283         printf ("%s:\n", name
); 
 288                 bcopy(&ipsecstat
, &pipsecstat
, len
); 
 292 pfkey_msgtype_names(int x
) 
 295             sizeof(pfkey_msgtypenames
)/sizeof(pfkey_msgtypenames
[0]); 
 298         if (x 
< max 
&& pfkey_msgtypenames
[x
]) 
 299                 return pfkey_msgtypenames
[x
]; 
 300         snprintf(buf
, sizeof(buf
), "#%d", x
); 
 305 pfkey_stats(uint32_t off __unused
, char *name
, int af __unused
) 
 307         static struct pfkeystat ppfkeystat
; 
 308         struct pfkeystat pfkeystat
; 
 309         unsigned first
, type
; 
 312         len 
= sizeof(struct pfkeystat
); 
 313         if (sysctlbyname("net.key.pfkeystat", &pfkeystat
, &len
, 0, 0) == -1) 
 315     if (interval 
&& vflag 
> 0) 
 317         printf ("%s:\n", name
); 
 319 #define PFKEYDIFF(f) (pfkeystat.f - ppfkeystat.f) 
 320 #define p(f, m) if (PFKEYDIFF(f) || sflag <= 1) \ 
 321     printf(m, (CAST)PFKEYDIFF(f), plural(PFKEYDIFF(f))) 
 323         /* kernel -> userland */ 
 324         p(out_total
, "\t" LLU 
" request%s sent to userland\n"); 
 325         p(out_bytes
, "\t" LLU 
" byte%s sent to userland\n"); 
 326         for (first 
= 1, type 
= 0; 
 327              type 
< sizeof(pfkeystat
.out_msgtype
)/sizeof(pfkeystat
.out_msgtype
[0]); 
 329                 if (PFKEYDIFF(out_msgtype
[type
]) <= 0) 
 332                         printf("\thistogram by message type:\n"); 
 335                 printf("\t\t%s: " LLU 
"\n", pfkey_msgtype_names(type
), 
 336                         (CAST
)PFKEYDIFF(out_msgtype
[type
])); 
 338         p(out_invlen
, "\t" LLU 
" message%s with invalid length field\n"); 
 339         p(out_invver
, "\t" LLU 
" message%s with invalid version field\n"); 
 340         p(out_invmsgtype
, "\t" LLU 
" message%s with invalid message type field\n"); 
 341         p(out_tooshort
, "\t" LLU 
" message%s too short\n"); 
 342         p(out_nomem
, "\t" LLU 
" message%s with memory allocation failure\n"); 
 343         p(out_dupext
, "\t" LLU 
" message%s with duplicate extension\n"); 
 344         p(out_invexttype
, "\t" LLU 
" message%s with invalid extension type\n"); 
 345         p(out_invsatype
, "\t" LLU 
" message%s with invalid sa type\n"); 
 346         p(out_invaddr
, "\t" LLU 
" message%s with invalid address extension\n"); 
 348         /* userland -> kernel */ 
 349         p(in_total
, "\t" LLU 
" request%s sent from userland\n"); 
 350         p(in_bytes
, "\t" LLU 
" byte%s sent from userland\n"); 
 351         for (first 
= 1, type 
= 0; 
 352              type 
< sizeof(pfkeystat
.in_msgtype
)/sizeof(pfkeystat
.in_msgtype
[0]); 
 354                 if (PFKEYDIFF(in_msgtype
[type
]) <= 0) 
 357                         printf("\thistogram by message type:\n"); 
 360                 printf("\t\t%s: " LLU 
"\n", pfkey_msgtype_names(type
), 
 361                         (CAST
)PFKEYDIFF(in_msgtype
[type
])); 
 363         p(in_msgtarget
[KEY_SENDUP_ONE
], 
 364             "\t" LLU 
" message%s toward single socket\n"); 
 365         p(in_msgtarget
[KEY_SENDUP_ALL
], 
 366             "\t" LLU 
" message%s toward all sockets\n"); 
 367         p(in_msgtarget
[KEY_SENDUP_REGISTERED
], 
 368             "\t" LLU 
" message%s toward registered sockets\n"); 
 369         p(in_nomem
, "\t" LLU 
" message%s with memory allocation failure\n"); 
 372                 bcopy(&pfkeystat
, &ppfkeystat
, len
);