Home | History | Annotate | Line # | Download | only in netipsec
      1 /*	$NetBSD: key_debug.c,v 1.25 2022/10/11 09:51:47 knakahara Exp $	*/
      2 /*	$FreeBSD: key_debug.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $	*/
      3 /*	$KAME: key_debug.c,v 1.26 2001/06/27 10:46:50 sakane Exp $	*/
      4 
      5 /*
      6  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
      7  * All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. Neither the name of the project nor the names of its contributors
     18  *    may be used to endorse or promote products derived from this software
     19  *    without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
     22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
     25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  * SUCH DAMAGE.
     32  */
     33 
     34 #ifdef _KERNEL
     35 #include <sys/cdefs.h>
     36 __KERNEL_RCSID(0, "$NetBSD: key_debug.c,v 1.25 2022/10/11 09:51:47 knakahara Exp $");
     37 #endif
     38 
     39 #if defined(_KERNEL_OPT)
     40 #include "opt_inet.h"
     41 #endif
     42 
     43 #include <sys/types.h>
     44 #include <sys/param.h>
     45 #ifdef _KERNEL
     46 #include <sys/systm.h>
     47 #include <sys/mbuf.h>
     48 #include <sys/queue.h>
     49 #endif
     50 #include <sys/socket.h>
     51 
     52 #include <net/route.h>
     53 
     54 #include <netipsec/key.h>
     55 #include <netipsec/key_var.h>
     56 #include <netipsec/key_debug.h>
     57 
     58 #include <netinet/in.h>
     59 #include <netipsec/ipsec.h>
     60 
     61 #ifndef _KERNEL
     62 #include <ctype.h>
     63 #include <stdio.h>
     64 #include <stdlib.h>
     65 #include <err.h>
     66 #endif /* !_KERNEL */
     67 
     68 static void kdebug_sadb_prop(const struct sadb_ext *);
     69 static void kdebug_sadb_identity(const struct sadb_ext *);
     70 static void kdebug_sadb_supported(const struct sadb_ext *);
     71 static void kdebug_sadb_lifetime(const struct sadb_ext *);
     72 static void kdebug_sadb_sa(const struct sadb_ext *);
     73 static void kdebug_sadb_address(const struct sadb_ext *);
     74 static void kdebug_sadb_key(const struct sadb_ext *);
     75 static void kdebug_sadb_x_sa2(const struct sadb_ext *);
     76 static void kdebug_sadb_x_policy(const struct sadb_ext *);
     77 
     78 static void kdebug__secpolicyindex(const struct secpolicyindex *);
     79 
     80 static void kdebug_hexdump(const char *, const void *, size_t);
     81 static void kdebug_sockaddr(const struct sockaddr *);
     82 static void kdebug_secasindex(const struct secasindex *);
     83 static void kdebug_mbufhdr(const struct mbuf *);
     84 
     85 #ifdef _KERNEL
     86 #if 0
     87 static void kdebug_secasv(const struct secasvar *);
     88 static void kdebug_secreplay(const struct secreplay *);
     89 #endif
     90 #endif
     91 
     92 #ifndef _KERNEL
     93 #define panic(fmt, ...)	err(EXIT_FAILURE, fmt, __VA_ARGS__)
     94 #endif
     95 
     96 /* NOTE: host byte order */
     97 /* %%%: about struct sadb_msg */
     98 void
     99 kdebug_sadb(const struct sadb_msg *base)
    100 {
    101 	const struct sadb_ext *ext;
    102 	int tlen, extlen;
    103 
    104 	/* sanity check */
    105 	if (base == NULL)
    106 		panic("%s: NULL pointer was passed", __func__);
    107 
    108 	printf("sadb { version=%u type=%u errno=%u satype=%u",
    109 	    base->sadb_msg_version, base->sadb_msg_type,
    110 	    base->sadb_msg_errno, base->sadb_msg_satype);
    111 	printf(" len=%u reserved=%u seq=%u pid=%u",
    112 	    base->sadb_msg_len, base->sadb_msg_reserved,
    113 	    base->sadb_msg_seq, base->sadb_msg_pid);
    114 
    115 	tlen = PFKEY_UNUNIT64(base->sadb_msg_len) - sizeof(struct sadb_msg);
    116 	ext = (const void *)(base + 1);
    117 
    118 	while (tlen > 0) {
    119 		if (ext->sadb_ext_len == 0 || ext->sadb_ext_len > tlen) {
    120 			panic("%s: invalid ext_len=%d tlen=%d was passed",
    121 			    __func__, ext->sadb_ext_len, tlen);
    122 		}
    123 
    124 		printf(" sadb_ext { len=%u type=%u }",
    125 		    PFKEY_UNUNIT64(ext->sadb_ext_len), ext->sadb_ext_type);
    126 
    127 
    128 		switch (ext->sadb_ext_type) {
    129 		case SADB_EXT_SA:
    130 			kdebug_sadb_sa(ext);
    131 			break;
    132 		case SADB_EXT_LIFETIME_CURRENT:
    133 		case SADB_EXT_LIFETIME_HARD:
    134 		case SADB_EXT_LIFETIME_SOFT:
    135 			kdebug_sadb_lifetime(ext);
    136 			break;
    137 		case SADB_EXT_ADDRESS_SRC:
    138 		case SADB_EXT_ADDRESS_DST:
    139 		case SADB_EXT_ADDRESS_PROXY:
    140 			kdebug_sadb_address(ext);
    141 			break;
    142 		case SADB_EXT_KEY_AUTH:
    143 		case SADB_EXT_KEY_ENCRYPT:
    144 			kdebug_sadb_key(ext);
    145 			break;
    146 		case SADB_EXT_IDENTITY_SRC:
    147 		case SADB_EXT_IDENTITY_DST:
    148 			kdebug_sadb_identity(ext);
    149 			break;
    150 		case SADB_EXT_SENSITIVITY:
    151 			break;
    152 		case SADB_EXT_PROPOSAL:
    153 			kdebug_sadb_prop(ext);
    154 			break;
    155 		case SADB_EXT_SUPPORTED_AUTH:
    156 		case SADB_EXT_SUPPORTED_ENCRYPT:
    157 			kdebug_sadb_supported(ext);
    158 			break;
    159 		case SADB_EXT_SPIRANGE:
    160 		case SADB_X_EXT_KMPRIVATE:
    161 			break;
    162 		case SADB_X_EXT_POLICY:
    163 			kdebug_sadb_x_policy(ext);
    164 			break;
    165 		case SADB_X_EXT_SA2:
    166 			kdebug_sadb_x_sa2(ext);
    167 			break;
    168 		default:
    169 			panic("%s: invalid ext_type %u was passed",
    170 			    __func__, ext->sadb_ext_type);
    171 		}
    172 
    173 		extlen = PFKEY_UNUNIT64(ext->sadb_ext_len);
    174 		tlen -= extlen;
    175 		ext = (const void *)((const char *)ext + extlen);
    176 	}
    177 	printf("\n");
    178 }
    179 
    180 static void
    181 kdebug_sadb_prop(const struct sadb_ext *ext)
    182 {
    183 	const struct sadb_prop *prop = (const struct sadb_prop *)ext;
    184 	const struct sadb_comb *comb;
    185 	int len;
    186 
    187 	/* sanity check */
    188 	if (ext == NULL)
    189 		panic("%s: NULL pointer was passed", __func__);
    190 
    191 	len = (PFKEY_UNUNIT64(prop->sadb_prop_len) - sizeof(*prop))
    192 		/ sizeof(*comb);
    193 	comb = (const void *)(prop + 1);
    194 	printf(" sadb_prop { replay=%u", prop->sadb_prop_replay);
    195 
    196 	while (len--) {
    197 		printf(" sadb_comb { auth=%u encrypt=%u"
    198 		    "flags=%#04x reserved=%#08x ",
    199 		    comb->sadb_comb_auth, comb->sadb_comb_encrypt,
    200 		    comb->sadb_comb_flags, comb->sadb_comb_reserved);
    201 
    202 		printf(" auth_minbits=%u auth_maxbits=%u"
    203 		    "encrypt_minbits=%u encrypt_maxbits=%u",
    204 		    comb->sadb_comb_auth_minbits,
    205 		    comb->sadb_comb_auth_maxbits,
    206 		    comb->sadb_comb_encrypt_minbits,
    207 		    comb->sadb_comb_encrypt_maxbits);
    208 
    209 		printf(" soft_alloc=%u hard_alloc=%u"
    210 		    "soft_bytes=%lu hard_bytes=%lu",
    211 		    comb->sadb_comb_soft_allocations,
    212 		    comb->sadb_comb_hard_allocations,
    213 		    (unsigned long)comb->sadb_comb_soft_bytes,
    214 		    (unsigned long)comb->sadb_comb_hard_bytes);
    215 
    216 		printf(" soft_alloc=%lu hard_alloc=%lu"
    217 		    "soft_bytes=%lu hard_bytes=%lu }",
    218 		    (unsigned long)comb->sadb_comb_soft_addtime,
    219 		    (unsigned long)comb->sadb_comb_hard_addtime,
    220 		    (unsigned long)comb->sadb_comb_soft_usetime,
    221 		    (unsigned long)comb->sadb_comb_hard_usetime);
    222 		comb++;
    223 	}
    224 	printf(" }");
    225 
    226 	return;
    227 }
    228 
    229 static void
    230 kdebug_sadb_identity(const struct sadb_ext *ext)
    231 {
    232 	const struct sadb_ident *id = (const struct sadb_ident *)ext;
    233 	int len;
    234 
    235 	/* sanity check */
    236 	if (ext == NULL)
    237 		panic("%s: NULL pointer was passed", __func__);
    238 
    239 	len = PFKEY_UNUNIT64(id->sadb_ident_len) - sizeof(*id);
    240 	printf(" sadb_ident_%s {",
    241 	    id->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC ? "src" : "dst");
    242 	switch (id->sadb_ident_type) {
    243 	default:
    244 		printf(" type=%d id=%lu",
    245 		    id->sadb_ident_type, (u_long)id->sadb_ident_id);
    246 		if (len) {
    247 			kdebug_hexdump("data", id + 1, len);
    248 		}
    249 		break;
    250 	}
    251 
    252 	printf(" }");
    253 }
    254 
    255 static void
    256 kdebug_sadb_supported(const struct sadb_ext *ext)
    257 {
    258 	const struct sadb_supported *sup = (const struct sadb_supported *)ext;
    259 	const struct sadb_alg *alg;
    260 	int len;
    261 
    262 	/* sanity check */
    263 	if (ext == NULL)
    264 		panic("%s: NULL pointer was passed", __func__);
    265 
    266 	len = (PFKEY_UNUNIT64(sup->sadb_supported_len) - sizeof(*sup))
    267 		/ sizeof(*alg);
    268 	alg = (const void *)(sup + 1);
    269 	printf(" sadb_sup {");
    270 	while (len--) {
    271 		printf(" { id=%d ivlen=%d min=%d max=%d }",
    272 		    alg->sadb_alg_id, alg->sadb_alg_ivlen,
    273 		    alg->sadb_alg_minbits, alg->sadb_alg_maxbits);
    274 		alg++;
    275 	}
    276 	printf(" }");
    277 }
    278 
    279 static void
    280 kdebug_sadb_lifetime(const struct sadb_ext *ext)
    281 {
    282 	const struct sadb_lifetime *lft = (const struct sadb_lifetime *)ext;
    283 
    284 	/* sanity check */
    285 	if (ext == NULL)
    286 		panic("%s: NULL pointer was passed", __func__);
    287 
    288 	printf(" sadb_lifetime { alloc=%u, bytes=%u",
    289 	    lft->sadb_lifetime_allocations,
    290 	    (u_int32_t)lft->sadb_lifetime_bytes);
    291 	printf(" addtime=%u, usetime=%u }",
    292 	    (u_int32_t)lft->sadb_lifetime_addtime,
    293 	    (u_int32_t)lft->sadb_lifetime_usetime);
    294 }
    295 
    296 static void
    297 kdebug_sadb_sa(const struct sadb_ext *ext)
    298 {
    299 	const struct sadb_sa *sa = (const struct sadb_sa *)ext;
    300 
    301 	/* sanity check */
    302 	if (ext == NULL)
    303 		panic("%s: NULL pointer was passed", __func__);
    304 
    305 	printf(" sadb_sa { spi=%u replay=%u state=%u",
    306 	    (u_int32_t)ntohl(sa->sadb_sa_spi), sa->sadb_sa_replay,
    307 	    sa->sadb_sa_state);
    308 	printf(" auth=%u encrypt=%u flags=%#08x }",
    309 	    sa->sadb_sa_auth, sa->sadb_sa_encrypt, sa->sadb_sa_flags);
    310 }
    311 
    312 static void
    313 kdebug_sadb_address(const struct sadb_ext *ext)
    314 {
    315 	const struct sadb_address *addr = (const struct sadb_address *)ext;
    316 
    317 	/* sanity check */
    318 	if (ext == NULL)
    319 		panic("%s: NULL pointer was passed", __func__);
    320 
    321 	printf(" sadb_address { proto=%u prefixlen=%u reserved=%#02x%02x }",
    322 	    addr->sadb_address_proto, addr->sadb_address_prefixlen,
    323 	    ((const u_char *)&addr->sadb_address_reserved)[0],
    324 	    ((const u_char *)&addr->sadb_address_reserved)[1]);
    325 
    326 	kdebug_sockaddr((const struct sockaddr *)
    327 	    ((const char *)ext + sizeof(*addr)));
    328 }
    329 
    330 static void
    331 kdebug_sadb_key(const struct sadb_ext *ext)
    332 {
    333 	const struct sadb_key *key = (const struct sadb_key *)ext;
    334 
    335 	/* sanity check */
    336 	if (ext == NULL)
    337 		panic("%s: NULL pointer was passed", __func__);
    338 
    339 	/* sanity check 2 */
    340 	if ((key->sadb_key_bits >> 3) >
    341 	    (PFKEY_UNUNIT64(key->sadb_key_len) - sizeof(struct sadb_key))) {
    342 		panic("%s: key length mismatch, bit:%d len:%ld ", __func__,
    343 		    key->sadb_key_bits >> 3,
    344 		    (long)PFKEY_UNUNIT64(key->sadb_key_len)
    345 		    - sizeof(struct sadb_key));
    346 	}
    347 
    348 	printf(" sadb_key { bits=%u reserved=%u",
    349 	    key->sadb_key_bits, key->sadb_key_reserved);
    350 	kdebug_hexdump("key", key + 1, key->sadb_key_bits >> 3);
    351 	printf(" }");
    352 }
    353 
    354 static void
    355 kdebug_sadb_x_sa2(const struct sadb_ext *ext)
    356 {
    357 	const struct sadb_x_sa2 *sa2 = (const struct sadb_x_sa2 *)ext;
    358 
    359 	/* sanity check */
    360 	if (ext == NULL)
    361 		panic("%s: NULL pointer was passed", __func__);
    362 
    363 	printf(" sadb_x_sa2 { mode=%u reqid=%u",
    364 	    sa2->sadb_x_sa2_mode, sa2->sadb_x_sa2_reqid);
    365 	printf(" reserved1=%u reserved2=%u sequence=%u }",
    366 	    sa2->sadb_x_sa2_reserved1, sa2->sadb_x_sa2_reserved2,
    367 	    sa2->sadb_x_sa2_sequence);
    368 }
    369 
    370 static void
    371 kdebug_sadb_x_policy(const struct sadb_ext *ext)
    372 {
    373 	const struct sadb_x_policy *xpl = (const struct sadb_x_policy *)ext;
    374 	const struct sockaddr *addr;
    375 
    376 	/* sanity check */
    377 	if (ext == NULL)
    378 		panic("%s: NULL pointer was passed", __func__);
    379 
    380 	printf(" sadb_x_policy { type=%u dir=%u flags=0x%02x id=%x }",
    381 		xpl->sadb_x_policy_type, xpl->sadb_x_policy_dir,
    382 		xpl->sadb_x_policy_flags, xpl->sadb_x_policy_id);
    383 
    384 	if (xpl->sadb_x_policy_type == IPSEC_POLICY_IPSEC) {
    385 		int tlen;
    386 		const struct sadb_x_ipsecrequest *xisr;
    387 
    388 		tlen = PFKEY_UNUNIT64(xpl->sadb_x_policy_len) - sizeof(*xpl);
    389 		xisr = (const struct sadb_x_ipsecrequest *)(xpl + 1);
    390 
    391 		while (tlen > 0) {
    392 			printf(" { len=%u proto=%u mode=%u level=%u reqid=%u",
    393 			    xisr->sadb_x_ipsecrequest_len,
    394 			    xisr->sadb_x_ipsecrequest_proto,
    395 			    xisr->sadb_x_ipsecrequest_mode,
    396 			    xisr->sadb_x_ipsecrequest_level,
    397 			    xisr->sadb_x_ipsecrequest_reqid);
    398 
    399 			if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
    400 				addr = (const void *)(xisr + 1);
    401 				kdebug_sockaddr(addr);
    402 				addr = (const void *)((const char *)addr
    403 				    + addr->sa_len);
    404 				kdebug_sockaddr(addr);
    405 			}
    406 
    407 			printf(" }");
    408 
    409 			/* prevent infinite loop */
    410 			if (xisr->sadb_x_ipsecrequest_len <= 0) {
    411 				panic("%s: wrong policy struct", __func__);
    412 			}
    413 			/* prevent overflow */
    414 			if (xisr->sadb_x_ipsecrequest_len > tlen) {
    415 				panic("%s: invalid ipsec policy length",
    416 				    __func__);
    417 			}
    418 
    419 			tlen -= xisr->sadb_x_ipsecrequest_len;
    420 
    421 			xisr = (const struct sadb_x_ipsecrequest *)
    422 			    ((const char *)xisr
    423 			    + xisr->sadb_x_ipsecrequest_len);
    424 		}
    425 
    426 		if (tlen != 0)
    427 			panic("%s: wrong policy struct", __func__);
    428 	}
    429 }
    430 
    431 #ifdef _KERNEL
    432 
    433 void
    434 kdebug_sadb_xpolicy(const char *msg, const struct sadb_ext *ext)
    435 {
    436 	printf("%s:", msg);
    437 	kdebug_sadb_x_policy(ext);
    438 	printf("\n");
    439 }
    440 
    441 /* %%%: about SPD and SAD */
    442 void
    443 kdebug_secpolicy(const struct secpolicy *sp)
    444 {
    445 	/* sanity check */
    446 	if (sp == NULL)
    447 		panic("%s: NULL pointer was passed", __func__);
    448 
    449 	printf(" secpolicy { refcnt=%u state=%u policy=%u",
    450 	    key_sp_refcnt(sp), sp->state, sp->policy);
    451 
    452 	kdebug__secpolicyindex(&sp->spidx);
    453 
    454 	printf(" type=");
    455 	switch (sp->policy) {
    456 	case IPSEC_POLICY_DISCARD:
    457 		printf("discard");
    458 		break;
    459 	case IPSEC_POLICY_NONE:
    460 		printf("none");
    461 		break;
    462 	case IPSEC_POLICY_IPSEC:
    463 	    {
    464 		printf("ipsec {");
    465 		struct ipsecrequest *isr;
    466 		for (isr = sp->req; isr != NULL; isr = isr->next) {
    467 			printf(" level=%u", isr->level);
    468 			kdebug_secasindex(&isr->saidx);
    469 		}
    470 		printf(" }");
    471 	    }
    472 		break;
    473 	case IPSEC_POLICY_BYPASS:
    474 		printf("bypass");
    475 		break;
    476 	case IPSEC_POLICY_ENTRUST:
    477 		printf("entrust");
    478 		break;
    479 	default:
    480 		panic("%s: Invalid policy found. %d", __func__, sp->policy);
    481 	}
    482 	printf(" }\n");
    483 }
    484 
    485 void
    486 kdebug_secpolicyindex(const char *msg, const struct secpolicyindex *spidx)
    487 {
    488 	printf("%s:", msg);
    489 	kdebug__secpolicyindex(spidx);
    490 	printf("\n");
    491 }
    492 
    493 
    494 static void
    495 kdebug__secpolicyindex(const struct secpolicyindex *spidx)
    496 {
    497 	/* sanity check */
    498 	if (spidx == NULL)
    499 		panic("%s: NULL pointer was passed", __func__);
    500 
    501 	printf(" secpolicy { dir=%u prefs=%u prefd=%u ul_proto=%u",
    502 		spidx->dir, spidx->prefs, spidx->prefd, spidx->ul_proto);
    503 
    504 	kdebug_hexdump("src", &spidx->src, spidx->src.sa.sa_len);
    505 	kdebug_hexdump("dst", &spidx->dst, spidx->dst.sa.sa_len);
    506 	printf(" }");
    507 }
    508 
    509 static void
    510 kdebug_secasindex(const struct secasindex *saidx)
    511 {
    512 	/* sanity check */
    513 	if (saidx == NULL)
    514 		panic("%s: NULL pointer was passed", __func__);
    515 
    516 	printf(" secasindex { mode=%u proto=%u",
    517 	    saidx->mode, saidx->proto);
    518 	kdebug_hexdump("src", &saidx->src, saidx->src.sa.sa_len);
    519 	kdebug_hexdump("dst", &saidx->dst, saidx->dst.sa.sa_len);
    520 	printf(" }");
    521 }
    522 
    523 #if 0
    524 static void
    525 kdebug_secasv(const struct secasvar *sav)
    526 {
    527 	/* sanity check */
    528 	if (sav == NULL)
    529 		panic("%s: NULL pointer was passed", __func__);
    530 
    531 	printf(" secasv {", );
    532 	kdebug_secasindex(&sav->sah->saidx);
    533 
    534 	printf(" refcnt=%u state=%u auth=%u enc=%u",
    535 	    key_sa_refcnt(sav), sav->state, sav->alg_auth, sav->alg_enc);
    536 	printf(" spi=%u flags=%u",
    537 	    (u_int32_t)ntohl(sav->spi), sav->flags);
    538 
    539 	if (sav->key_auth != NULL)
    540 		kdebug_sadb_key((struct sadb_ext *)sav->key_auth);
    541 	if (sav->key_enc != NULL)
    542 		kdebug_sadb_key((struct sadb_ext *)sav->key_enc);
    543 
    544 	if (sav->replay != NULL)
    545 		kdebug_secreplay(sav->replay);
    546 	if (sav->lft_c != NULL)
    547 		kdebug_sadb_lifetime((struct sadb_ext *)sav->lft_c);
    548 	if (sav->lft_h != NULL)
    549 		kdebug_sadb_lifetime((struct sadb_ext *)sav->lft_h);
    550 	if (sav->lft_s != NULL)
    551 		kdebug_sadb_lifetime((struct sadb_ext *)sav->lft_s);
    552 
    553 	/* XXX: misc[123] ? */
    554 }
    555 
    556 static void
    557 kdebug_secreplay(const struct secreplay *rpl)
    558 {
    559 	int len, l;
    560 
    561 	/* sanity check */
    562 	if (rpl == NULL)
    563 		panic("%s: NULL pointer was passed", __func__);
    564 
    565 	printf(" secreplay { count=%u wsize=%u seq=%u lastseq=%u",
    566 	    rpl->count, rpl->wsize, rpl->seq, rpl->lastseq);
    567 
    568 	if (rpl->bitmap == NULL) {
    569 		printf(" }");
    570 		return;
    571 	}
    572 
    573 	printf(" bitmap {");
    574 
    575 	for (len = 0; len < rpl->wsize; len++) {
    576 		for (l = 7; l >= 0; l--)
    577 			printf(" %u", (((rpl->bitmap)[len] >> l) & 1) ? 1 : 0);
    578 	}
    579 	printf(" } }");
    580 }
    581 #endif
    582 
    583 static void
    584 kdebug_mbufhdr(const struct mbuf *m)
    585 {
    586 	/* sanity check */
    587 	if (m == NULL)
    588 		return;
    589 
    590 	printf(" mbuf(%p) { m_next:%p m_nextpkt:%p m_data:%p "
    591 	       "m_len:%d m_type:%#02x m_flags:%#02x }",
    592 		m, m->m_next, m->m_nextpkt, m->m_data,
    593 		m->m_len, m->m_type, m->m_flags);
    594 
    595 	if (m->m_flags & M_PKTHDR) {
    596 		printf(" m_pkthdr { len:%d rcvif:%p }",
    597 		    m->m_pkthdr.len, m_get_rcvif_NOMPSAFE(m));
    598 	}
    599 
    600 	if (m->m_flags & M_EXT) {
    601 		printf(" m_ext { ext_buf:%p ext_free:%p "
    602 		   "ext_size:%zu ext_refcnt:%u }",
    603 		    m->m_ext.ext_buf, m->m_ext.ext_free,
    604 		    m->m_ext.ext_size, m->m_ext.ext_refcnt);
    605 	}
    606 }
    607 
    608 void
    609 kdebug_mbuf(const char *msg, const struct mbuf *m0)
    610 {
    611 	const struct mbuf *m = m0;
    612 	int i, j;
    613 
    614 	printf("%s:", msg);
    615 	for (j = 0; m; m = m->m_next) {
    616 		kdebug_mbufhdr(m);
    617 		printf(" m_data:");
    618 		for (i = 0; i < m->m_len; i++) {
    619 			if (i % 4 == 0)
    620 				printf(" ");
    621 			printf("%02x", mtod(m, u_char *)[i]);
    622 			j++;
    623 		}
    624 	}
    625 	printf("\n");
    626 }
    627 #endif /* _KERNEL */
    628 
    629 static void
    630 kdebug_sockaddr(const struct sockaddr *addr)
    631 {
    632 	const struct sockaddr_in *sin4;
    633 #ifdef INET6
    634 	const struct sockaddr_in6 *sin6;
    635 #endif
    636 
    637 	/* sanity check */
    638 	if (addr == NULL)
    639 		panic("%s: NULL pointer was passed", __func__);
    640 
    641 	/* NOTE: We deal with port number as host byte order. */
    642 	printf(" sockaddr { len=%u family=%u",
    643 	    addr->sa_len, addr->sa_family);
    644 
    645 	switch (addr->sa_family) {
    646 	case AF_INET:
    647 		sin4 = (const struct sockaddr_in *)addr;
    648 		printf(" port=%u", ntohs(sin4->sin_port));
    649 		kdebug_hexdump("addr", &sin4->sin_addr, sizeof(sin4->sin_addr));
    650 		break;
    651 #ifdef INET6
    652 	case AF_INET6:
    653 		sin6 = (const struct sockaddr_in6 *)addr;
    654 		printf(" port=%u", ntohs(sin6->sin6_port));
    655 		printf(" flowinfo=%#08x, scope_id=%#08x",
    656 		    sin6->sin6_flowinfo, sin6->sin6_scope_id);
    657 		kdebug_hexdump("addr", &sin6->sin6_addr, sizeof(sin6->sin6_addr));
    658 		break;
    659 #endif
    660 	}
    661 
    662 	printf(" }");
    663 }
    664 
    665 static void
    666 kdebug_hexdump(const char *tag, const void *v, size_t len)
    667 {
    668 	size_t i;
    669 	const unsigned char *buf = v;
    670 
    671 	if (len)
    672 		printf(" %s=", tag);
    673 
    674 	for (i = 0; i < len; i++) {
    675 		if (i && i % 4 == 0) printf(" ");
    676 		printf("%02x", buf[i]);
    677 	}
    678 }
    679