xref: /openbsd-src/sbin/ipsecctl/pfkdump.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: pfkdump.c,v 1.42 2015/12/09 21:41:50 naddy Exp $	*/
2 
3 /*
4  * Copyright (c) 2003 Markus Friedl.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include <sys/socket.h>
28 #include <sys/time.h>
29 #include <sys/sysctl.h>
30 #include <net/pfkeyv2.h>
31 #include <netinet/ip_ipsp.h>
32 #include <netdb.h>
33 #include <string.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <err.h>
38 #include <errno.h>
39 
40 #include "ipsecctl.h"
41 #include "pfkey.h"
42 
43 static void	print_proto(struct sadb_ext *, struct sadb_msg *);
44 static void	print_flow(struct sadb_ext *, struct sadb_msg *);
45 static void	print_supp(struct sadb_ext *, struct sadb_msg *);
46 static void	print_prop(struct sadb_ext *, struct sadb_msg *);
47 static void	print_sens(struct sadb_ext *, struct sadb_msg *);
48 static void	print_spir(struct sadb_ext *, struct sadb_msg *);
49 static void	print_policy(struct sadb_ext *, struct sadb_msg *);
50 static void	print_sa(struct sadb_ext *, struct sadb_msg *);
51 static void	print_addr(struct sadb_ext *, struct sadb_msg *);
52 static void	print_key(struct sadb_ext *, struct sadb_msg *);
53 static void	print_life(struct sadb_ext *, struct sadb_msg *);
54 static void	print_ident(struct sadb_ext *, struct sadb_msg *);
55 static void	print_udpenc(struct sadb_ext *, struct sadb_msg *);
56 static void	print_tag(struct sadb_ext *, struct sadb_msg *);
57 static void	print_tap(struct sadb_ext *, struct sadb_msg *);
58 
59 static struct idname *lookup(struct idname *, u_int32_t);
60 static char    *lookup_name(struct idname *, u_int32_t);
61 static void	print_ext(struct sadb_ext *, struct sadb_msg *);
62 
63 void		pfkey_print_raw(u_int8_t *, ssize_t);
64 static char	*print_flags(uint32_t);
65 
66 struct sadb_ext *extensions[SADB_EXT_MAX + 1];
67 
68 struct idname {
69 	u_int32_t id;
70 	char *name;
71 	void (*func)(struct sadb_ext *, struct sadb_msg *);
72 };
73 
74 struct idname ext_types[] = {
75 	{ SADB_EXT_RESERVED,		"reserved",		NULL },
76 	{ SADB_EXT_SA,			"sa",			print_sa },
77 	{ SADB_EXT_LIFETIME_CURRENT,	"lifetime_cur",		print_life },
78 	{ SADB_EXT_LIFETIME_HARD,	"lifetime_hard",	print_life },
79 	{ SADB_EXT_LIFETIME_SOFT,	"lifetime_soft",	print_life },
80 	{ SADB_EXT_ADDRESS_SRC,		"address_src",		print_addr },
81 	{ SADB_EXT_ADDRESS_DST,		"address_dst",		print_addr },
82 	{ SADB_EXT_ADDRESS_PROXY,	"address_proxy",	print_addr },
83 	{ SADB_EXT_KEY_AUTH,		"key_auth",		print_key },
84 	{ SADB_EXT_KEY_ENCRYPT,		"key_encrypt",		print_key },
85 	{ SADB_EXT_IDENTITY_SRC,	"identity_src",		print_ident },
86 	{ SADB_EXT_IDENTITY_DST,	"identity_dst",		print_ident },
87 	{ SADB_EXT_SENSITIVITY,		"sensitivity",		print_sens },
88 	{ SADB_EXT_PROPOSAL,		"proposal",		print_prop },
89 	{ SADB_EXT_SUPPORTED_AUTH,	"supported_auth",	print_supp },
90 	{ SADB_EXT_SUPPORTED_ENCRYPT,	"supported_encrypt",	print_supp },
91 	{ SADB_EXT_SPIRANGE,		"spirange",		print_spir },
92 	{ SADB_X_EXT_SRC_MASK,		"src_mask",		print_addr },
93 	{ SADB_X_EXT_DST_MASK,		"dst_mask",		print_addr },
94 	{ SADB_X_EXT_PROTOCOL,		"protocol",		print_proto },
95 	{ SADB_X_EXT_FLOW_TYPE,		"flow_type",		print_flow },
96 	{ SADB_X_EXT_SRC_FLOW,		"src_flow",		print_addr },
97 	{ SADB_X_EXT_DST_FLOW,		"dst_flow",		print_addr },
98 	{ SADB_X_EXT_SA2,		"sa2",			print_sa },
99 	{ SADB_X_EXT_DST2,		"dst2",			print_addr },
100 	{ SADB_X_EXT_POLICY,		"policy",		print_policy },
101 	{ SADB_X_EXT_SUPPORTED_COMP,	"supported_comp",	print_supp },
102 	{ SADB_X_EXT_UDPENCAP,		"udpencap",		print_udpenc },
103 	{ SADB_X_EXT_LIFETIME_LASTUSE,	"lifetime_lastuse",	print_life },
104 	{ SADB_X_EXT_TAG,		"tag",			print_tag },
105 	{ SADB_X_EXT_TAP,		"tap",			print_tap },
106 	{ 0,				NULL,			NULL }
107 };
108 
109 struct idname msg_types[] = {
110 	{ SADB_ACQUIRE,			"sadb_acquire",		NULL },
111 	{ SADB_ADD,			"sadb_add",		NULL },
112 	{ SADB_DELETE,			"sadb_delete",		NULL },
113 	{ SADB_DUMP,			"sadb_dump",		NULL },
114 	{ SADB_EXPIRE,			"sadb_expire",		NULL },
115 	{ SADB_FLUSH,			"sadb_flush",		NULL },
116 	{ SADB_GET,			"sadb_get",		NULL },
117 	{ SADB_GETSPI,			"sadb_getspi",		NULL },
118 	{ SADB_REGISTER,		"sadb_register",	NULL },
119 	{ SADB_UPDATE,			"sadb_update",		NULL },
120 	{ SADB_X_ADDFLOW,		"sadb_addflow",		NULL },
121 	{ SADB_X_ASKPOLICY,		"sadb_askpolicy",	NULL },
122 	{ SADB_X_DELFLOW,		"sadb_delflow",		NULL },
123 	{ SADB_X_GRPSPIS,		"sadb_grpspis",		NULL },
124 	{ SADB_X_PROMISC,		"sadb_promisc",		NULL },
125 	{ 0,				NULL,			NULL },
126 };
127 
128 struct idname sa_types[] = {
129 	{ SADB_SATYPE_UNSPEC,		"unspec",		NULL },
130 	{ SADB_SATYPE_AH,		"ah",			NULL },
131 	{ SADB_SATYPE_ESP,		"esp",			NULL },
132 	{ SADB_SATYPE_RSVP,		"rsvp",			NULL },
133 	{ SADB_SATYPE_OSPFV2,		"ospfv2",		NULL },
134 	{ SADB_SATYPE_RIPV2,		"ripv2",		NULL },
135 	{ SADB_SATYPE_MIP,		"mip",			NULL },
136 	{ SADB_X_SATYPE_IPIP,		"ipip",			NULL },
137 	{ SADB_X_SATYPE_TCPSIGNATURE,	"tcpmd5",		NULL },
138 	{ SADB_X_SATYPE_IPCOMP,		"ipcomp",		NULL },
139 	{ 0,				NULL,			NULL }
140 };
141 
142 struct idname auth_types[] = {
143 	{ SADB_AALG_NONE,		"none",			NULL },
144 	{ SADB_AALG_MD5HMAC,		"hmac-md5",		NULL },
145 	{ SADB_X_AALG_RIPEMD160HMAC,	"hmac-ripemd160",	NULL },
146 	{ SADB_AALG_SHA1HMAC,		"hmac-sha1",		NULL },
147 	{ SADB_X_AALG_SHA2_256,		"hmac-sha2-256",	NULL },
148 	{ SADB_X_AALG_SHA2_384,		"hmac-sha2-384",	NULL },
149 	{ SADB_X_AALG_SHA2_512,		"hmac-sha2-512",	NULL },
150 	{ SADB_X_AALG_AES128GMAC,	"gmac-aes-128",		NULL },
151 	{ SADB_X_AALG_AES192GMAC,	"gmac-aes-192",		NULL },
152 	{ SADB_X_AALG_AES256GMAC,	"gmac-aes-256",		NULL },
153 	{ SADB_X_AALG_CHACHA20POLY1305,	"chacha20-poly1305",	NULL },
154 	{ 0,				NULL,			NULL }
155 };
156 
157 struct idname enc_types[] = {
158 	{ SADB_EALG_NONE,		"none",			NULL },
159 	{ SADB_EALG_3DESCBC,		"3des-cbc",		NULL },
160 	{ SADB_X_EALG_AES,		"aes",			NULL },
161 	{ SADB_X_EALG_AESCTR,		"aesctr",		NULL },
162 	{ SADB_X_EALG_AESGCM16,		"aes-gcm",		NULL },
163 	{ SADB_X_EALG_AESGMAC,		"aes-gmac",		NULL },
164 	{ SADB_X_EALG_BLF,		"blowfish",		NULL },
165 	{ SADB_X_EALG_CAST,		"cast128",		NULL },
166 	{ SADB_EALG_NULL,		"null",			NULL },
167 	{ SADB_X_EALG_CHACHA20POLY1305,	"chacha20-poly1305",	NULL },
168 	{ 0,				NULL,			NULL }
169 };
170 
171 struct idname comp_types[] = {
172 	{ SADB_X_CALG_NONE,		"none",			NULL },
173 	{ SADB_X_CALG_OUI,		"oui",			NULL },
174 	{ SADB_X_CALG_DEFLATE,		"deflate",		NULL },
175 	{ SADB_X_CALG_LZS,		"lzs",			NULL },
176 	{ 0,				NULL,			NULL }
177 };
178 
179 struct idname flag_types[] = {
180 	{ SADB_SAFLAGS_PFS,		"pfs",			NULL },
181 	{ SADB_X_SAFLAGS_TUNNEL,	"tunnel",		NULL },
182 	{ SADB_X_SAFLAGS_CHAINDEL,	"chaindel",		NULL },
183 	{ SADB_X_SAFLAGS_UDPENCAP,	"udpencap",		NULL },
184 	{ SADB_X_SAFLAGS_ESN,		"esn",			NULL },
185 	{ 0,				NULL,			NULL }
186 };
187 
188 struct idname identity_types[] = {
189 	{ SADB_IDENTTYPE_RESERVED,	"reserved",		NULL },
190 	{ SADB_IDENTTYPE_PREFIX,	"prefix",		NULL },
191 	{ SADB_IDENTTYPE_FQDN,		"fqdn",			NULL },
192 	{ SADB_IDENTTYPE_USERFQDN,	"ufqdn",		NULL },
193 	{ 0,				NULL,			NULL }
194 };
195 
196 struct idname flow_types[] = {
197 	{ SADB_X_FLOW_TYPE_USE,		"use",			NULL },
198 	{ SADB_X_FLOW_TYPE_ACQUIRE,	"acquire",		NULL },
199 	{ SADB_X_FLOW_TYPE_REQUIRE,	"require",		NULL },
200 	{ SADB_X_FLOW_TYPE_BYPASS,	"bypass",		NULL },
201 	{ SADB_X_FLOW_TYPE_DENY,	"deny",			NULL },
202 	{ SADB_X_FLOW_TYPE_DONTACQ,	"dontacq",		NULL },
203 	{ 0,				NULL,			NULL }
204 };
205 
206 struct idname states[] = {
207 	{ SADB_SASTATE_LARVAL,		"larval",		NULL },
208 	{ SADB_SASTATE_MATURE,		"mature",		NULL },
209 	{ SADB_SASTATE_DYING,		"dying",		NULL },
210 	{ SADB_SASTATE_DEAD,		"dead",			NULL },
211 	{ 0,				NULL,			NULL }
212 };
213 
214 static struct idname *
215 lookup(struct idname *tab, u_int32_t id)
216 {
217 	struct idname *entry;
218 
219 	for (entry = tab; entry->name; entry++)
220 		if (entry->id == id)
221 			return (entry);
222 	return (NULL);
223 }
224 
225 static char *
226 lookup_name(struct idname *tab, u_int32_t id)
227 {
228 	struct idname *entry;
229 
230 	entry = lookup(tab, id);
231 	return (entry ? entry->name : "unknown");
232 }
233 
234 static void
235 print_ext(struct sadb_ext *ext, struct sadb_msg *msg)
236 {
237 	struct idname *entry;
238 
239 	if ((entry = lookup(ext_types, ext->sadb_ext_type)) == NULL) {
240 		printf("unknown ext: type %u len %u\n",
241 		    ext->sadb_ext_type, ext->sadb_ext_len);
242 		return;
243 	}
244 	printf("\t%s: ", entry->name);
245 	if (entry->func != NULL)
246 		(*entry->func)(ext, msg);
247 	else
248 		printf("type %u len %u",
249 		    ext->sadb_ext_type, ext->sadb_ext_len);
250 	printf("\n");
251 }
252 
253 static char *
254 print_flags(uint32_t flags)
255 {
256 	static char fstr[80];
257 	struct idname *entry;
258 	size_t len;
259 	int i, comma = 0;
260 
261 	len = snprintf(fstr, sizeof(fstr), "%#x<", flags);
262 	for (i = 0; i < 32; i++) {
263 		if ((flags & (1 << i)) == 0 ||
264 		    (entry = lookup(flag_types, 1 << i)) == NULL)
265 			continue;
266 		len += snprintf(fstr + len, sizeof(fstr) - len - 1,
267 		    comma ? ",%s" : "%s", entry->name);
268 		comma = 1;
269 	}
270 	strlcat(fstr, ">", sizeof(fstr));
271 
272 	return (fstr);
273 }
274 
275 static void
276 print_sa(struct sadb_ext *ext, struct sadb_msg *msg)
277 {
278 	struct sadb_sa *sa = (struct sadb_sa *)ext;
279 
280 	if (msg->sadb_msg_satype == SADB_X_SATYPE_IPCOMP)
281 		printf("cpi 0x%8.8x comp %s\n",
282 		    ntohl(sa->sadb_sa_spi),
283 		    lookup_name(comp_types, sa->sadb_sa_encrypt));
284 	else
285 		printf("spi 0x%8.8x auth %s enc %s\n",
286 		    ntohl(sa->sadb_sa_spi),
287 		    lookup_name(auth_types, sa->sadb_sa_auth),
288 		    lookup_name(enc_types, sa->sadb_sa_encrypt));
289 	printf("\t\tstate %s replay %u flags %s",
290 	    lookup_name(states, sa->sadb_sa_state),
291 	    sa->sadb_sa_replay, print_flags(sa->sadb_sa_flags));
292 }
293 
294 /* ARGSUSED1 */
295 static void
296 print_addr(struct sadb_ext *ext, struct sadb_msg *msg)
297 {
298 	struct sadb_address *addr = (struct sadb_address *)ext;
299 	struct sockaddr *sa;
300 	struct sockaddr_in *sin4;
301 	struct sockaddr_in6 *sin6;
302 	char hbuf[NI_MAXHOST];
303 
304 	sa = (struct sockaddr *)(addr + 1);
305 	if (sa->sa_family == 0)
306 		printf("<any>");
307 	else if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0,
308 	    NI_NUMERICHOST))
309 		printf("<could not get numeric hostname>");
310 	else
311 		printf("%s", hbuf);
312 	switch (sa->sa_family) {
313 	case AF_INET:
314 		sin4 = (struct sockaddr_in *)sa;
315 		if (sin4->sin_port)
316 			printf(" port %u", ntohs(sin4->sin_port));
317 		break;
318 	case AF_INET6:
319 		sin6 = (struct sockaddr_in6 *)sa;
320 		if (sin6->sin6_port)
321 			printf(" port %u", ntohs(sin6->sin6_port));
322 		break;
323 	}
324 }
325 
326 /* ARGSUSED1 */
327 static void
328 print_key(struct sadb_ext *ext, struct sadb_msg *msg)
329 {
330 	struct sadb_key *key = (struct sadb_key *)ext;
331 	u_int8_t *data;
332 	int i;
333 
334 	printf("bits %u: ", key->sadb_key_bits);
335 	data = (u_int8_t *)(key + 1);
336 	for (i = 0; i < key->sadb_key_bits / 8; i++) {
337 		printf("%2.2x", data[i]);
338 		data[i] = 0x00;		/* clear sensitive data */
339 	}
340 }
341 
342 /* ARGSUSED1 */
343 static void
344 print_life(struct sadb_ext *ext, struct sadb_msg *msg)
345 {
346 	struct sadb_lifetime *life = (struct sadb_lifetime *)ext;
347 
348 	printf("alloc %u bytes %llu add %llu first %llu",
349 	    life->sadb_lifetime_allocations,
350 	    life->sadb_lifetime_bytes,
351 	    life->sadb_lifetime_addtime,
352 	    life->sadb_lifetime_usetime);
353 }
354 
355 static void
356 print_proto(struct sadb_ext *ext, struct sadb_msg *msg)
357 {
358 	struct sadb_protocol *proto = (struct sadb_protocol *)ext;
359 
360 	/* overloaded */
361 	if (msg->sadb_msg_type == SADB_X_GRPSPIS)
362 		printf("satype %s flags %x",
363 		    lookup_name(sa_types, proto->sadb_protocol_proto),
364 		    proto->sadb_protocol_flags);
365 	else
366 		printf("proto %u flags %x",
367 		    proto->sadb_protocol_proto, proto->sadb_protocol_flags);
368 }
369 
370 /* ARGSUSED1 */
371 static void
372 print_flow(struct sadb_ext *ext, struct sadb_msg *msg)
373 {
374 	struct sadb_protocol *proto = (struct sadb_protocol *)ext;
375 	char *dir = "unknown";
376 
377 	switch (proto->sadb_protocol_direction) {
378 	case IPSP_DIRECTION_IN:
379 		dir = "in";
380 		break;
381 	case IPSP_DIRECTION_OUT:
382 		dir = "out";
383 		break;
384 	}
385 	printf("type %s direction %s",
386 	    lookup_name(flow_types, proto->sadb_protocol_proto), dir);
387 }
388 
389 static void
390 print_tag(struct sadb_ext *ext, struct sadb_msg *msg)
391 {
392 	struct sadb_x_tag *stag = (struct sadb_x_tag *)ext;
393 	char *p;
394 
395 	p = (char *)(stag + 1);
396 	printf("%s", p);
397 }
398 
399 static void
400 print_tap(struct sadb_ext *ext, struct sadb_msg *msg)
401 {
402 	struct sadb_x_tap *stap = (struct sadb_x_tap *)ext;
403 
404 	printf("enc%u", stap->sadb_x_tap_unit);
405 }
406 
407 static char *
408 alg_by_ext(u_int8_t ext_type, u_int8_t id)
409 {
410 	switch (ext_type) {
411 	case SADB_EXT_SUPPORTED_ENCRYPT:
412 		return lookup_name(enc_types, id);
413 	case SADB_EXT_SUPPORTED_AUTH:
414 		return lookup_name(auth_types, id);
415 	case SADB_X_EXT_SUPPORTED_COMP:
416 		return lookup_name(comp_types, id);
417 	default:
418 		return "unknown";
419 	}
420 }
421 
422 static void
423 print_alg(struct sadb_alg *alg, u_int8_t ext_type)
424 {
425 	printf("\t\t%s iv %u min %u max %u",
426 	    alg_by_ext(ext_type, alg->sadb_alg_id), alg->sadb_alg_ivlen,
427 	    alg->sadb_alg_minbits, alg->sadb_alg_maxbits);
428 }
429 
430 /* ARGSUSED1 */
431 static void
432 print_supp(struct sadb_ext *ext, struct sadb_msg *msg)
433 {
434 	struct sadb_supported *supported = (struct sadb_supported *)ext;
435 	struct sadb_alg *alg;
436 
437 	printf("\n");
438 	for (alg = (struct sadb_alg *)(supported + 1);
439 	    (size_t)((u_int8_t *)alg - (u_int8_t *)ext) <
440 	    ext->sadb_ext_len * PFKEYV2_CHUNK;
441 	    alg++) {
442 		struct sadb_alg *next = alg + 1;
443 		print_alg(alg, ext->sadb_ext_type);
444 		if ((size_t)((u_int8_t *)next - (u_int8_t *)ext) <
445 		    ext->sadb_ext_len * PFKEYV2_CHUNK)
446 			printf("\n");
447 	}
448 }
449 
450 /* ARGSUSED1 */
451 static void
452 print_comb(struct sadb_comb *comb, struct sadb_msg *msg)
453 {
454 	printf("\t\tauth %s min %u max %u\n"
455 	    "\t\tenc %s min %u max %u\n"
456 	    "\t\taddtime hard %llu soft %llu\n"
457 	    "\t\tusetime hard %llu soft %llu",
458 	    lookup_name(auth_types, comb->sadb_comb_auth),
459 	    comb->sadb_comb_auth_minbits,
460 	    comb->sadb_comb_auth_maxbits,
461 	    lookup_name(enc_types, comb->sadb_comb_encrypt),
462 	    comb->sadb_comb_encrypt_minbits,
463 	    comb->sadb_comb_encrypt_maxbits,
464 	    comb->sadb_comb_soft_addtime,
465 	    comb->sadb_comb_hard_addtime,
466 	    comb->sadb_comb_soft_usetime,
467 	    comb->sadb_comb_hard_usetime);
468 #if 0
469 	    comb->sadb_comb_flags,
470 	    comb->sadb_comb_reserved,
471 	    comb->sadb_comb_soft_allocations,
472 	    comb->sadb_comb_hard_allocations,
473 	    comb->sadb_comb_soft_bytes,
474 	    comb->sadb_comb_hard_bytes,
475 #endif
476 }
477 
478 /* ARGSUSED1 */
479 static void
480 print_prop(struct sadb_ext *ext, struct sadb_msg *msg)
481 {
482 	struct sadb_prop *prop = (struct sadb_prop *)ext;
483 	struct sadb_comb *comb;
484 
485 	printf("replay %u\n", prop->sadb_prop_replay);
486 	for (comb = (struct sadb_comb *)(prop + 1);
487 	    (size_t)((u_int8_t *)comb - (u_int8_t *)ext) <
488 	    ext->sadb_ext_len * PFKEYV2_CHUNK;
489 	    comb++)
490 		print_comb(comb, msg);
491 }
492 
493 /* ARGSUSED1 */
494 static void
495 print_sens(struct sadb_ext *ext, struct sadb_msg *msg)
496 {
497 	struct sadb_sens *sens = (struct sadb_sens *)ext;
498 
499 	printf("dpd %u sens_level %u integ_level %u",
500 	    sens->sadb_sens_dpd,
501 	    sens->sadb_sens_sens_level,
502 	    sens->sadb_sens_integ_level);
503 }
504 
505 /* ARGSUSED1 */
506 static void
507 print_spir(struct sadb_ext *ext, struct sadb_msg *msg)
508 {
509 	struct sadb_spirange *spirange = (struct sadb_spirange *)ext;
510 
511 	printf("min 0x%8.8x max 0x%8.8x",
512 	    spirange->sadb_spirange_min, spirange->sadb_spirange_max);
513 }
514 
515 /* ARGSUSED1 */
516 static void
517 print_ident(struct sadb_ext *ext, struct sadb_msg *msg)
518 {
519 	struct sadb_ident *ident = (struct sadb_ident *)ext;
520 
521 	printf("type %s id %llu: %s",
522 	    lookup_name(identity_types, ident->sadb_ident_type),
523 	    ident->sadb_ident_id, (char *)(ident + 1));
524 }
525 
526 /* ARGSUSED1 */
527 static void
528 print_policy(struct sadb_ext *ext, struct sadb_msg *msg)
529 {
530 	struct sadb_x_policy *x_policy = (struct sadb_x_policy *)ext;
531 
532 	printf("seq %u", x_policy->sadb_x_policy_seq);
533 }
534 
535 /* ARGSUSED1 */
536 static void
537 print_udpenc(struct sadb_ext *ext, struct sadb_msg *msg)
538 {
539 	struct sadb_x_udpencap *x_udpencap = (struct sadb_x_udpencap *)ext;
540 
541 	printf("udpencap port %u", ntohs(x_udpencap->sadb_x_udpencap_port));
542 }
543 
544 static void
545 setup_extensions(struct sadb_msg *msg)
546 {
547 	struct sadb_ext *ext;
548 
549 	bzero(extensions, sizeof(extensions));
550 	if (msg->sadb_msg_len == 0)
551 		return;
552 	for (ext = (struct sadb_ext *)(msg + 1);
553 	    (size_t)((u_int8_t *)ext - (u_int8_t *)msg) <
554 	    msg->sadb_msg_len * PFKEYV2_CHUNK && ext->sadb_ext_len > 0;
555 	    ext = (struct sadb_ext *)((u_int8_t *)ext +
556 	    ext->sadb_ext_len * PFKEYV2_CHUNK))
557 		extensions[ext->sadb_ext_type] = ext;
558 }
559 
560 static void
561 parse_addr(struct sadb_ext *ext, struct ipsec_addr_wrap *ipa)
562 {
563 	struct sadb_address *addr = (struct sadb_address *)ext;
564 	struct sockaddr *sa;
565 
566 	if (addr == NULL)
567 		return;
568 	sa = (struct sockaddr *)(addr + 1);
569 	switch (sa->sa_family) {
570 	case AF_INET:
571 		ipa->address.v4 = ((struct sockaddr_in *)sa)->sin_addr;
572 		set_ipmask(ipa, 32);
573 		break;
574 	case AF_INET6:
575 		ipa->address.v6 = ((struct sockaddr_in6 *)sa)->sin6_addr;
576 		set_ipmask(ipa, 128);
577 		break;
578 	}
579 	ipa->af = sa->sa_family;
580 	ipa->next = NULL;
581 	ipa->tail = ipa;
582 }
583 
584 static void
585 parse_key(struct sadb_ext *ext, struct ipsec_key *ikey)
586 {
587 	struct sadb_key *key = (struct sadb_key *)ext;
588 	u_int8_t *data;
589 
590 	if (key == NULL)
591 		return;
592 	data = (u_int8_t *)(key + 1);
593 	ikey->data = data;
594 	ikey->len = key->sadb_key_bits / 8;
595 }
596 
597 u_int32_t
598 pfkey_get_spi(struct sadb_msg *msg)
599 {
600 	struct sadb_sa *sa;
601 
602 	setup_extensions(msg);
603 	sa = (struct sadb_sa *)extensions[SADB_EXT_SA];
604 	return (ntohl(sa->sadb_sa_spi));
605 }
606 
607 /* opposite of pfkey_sa() */
608 void
609 pfkey_print_sa(struct sadb_msg *msg, int opts)
610 {
611 	int i;
612 	struct ipsec_rule r;
613 	struct ipsec_key enckey, authkey;
614 	struct ipsec_transforms xfs;
615 	struct ipsec_addr_wrap src, dst;
616 	struct sadb_sa *sa;
617 
618 	setup_extensions(msg);
619 	sa = (struct sadb_sa *)extensions[SADB_EXT_SA];
620 	bzero(&r, sizeof r);
621 	r.type |= RULE_SA;
622 	r.tmode = (msg->sadb_msg_satype != SADB_X_SATYPE_TCPSIGNATURE) &&
623 	    (sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL) ?
624 	    IPSEC_TUNNEL : IPSEC_TRANSPORT;
625 	r.spi = ntohl(sa->sadb_sa_spi);
626 
627 	switch (msg->sadb_msg_satype) {
628 	case SADB_SATYPE_AH:
629 		r.satype = IPSEC_AH;
630 		break;
631 	case SADB_SATYPE_ESP:
632 		r.satype = IPSEC_ESP;
633 		break;
634 	case SADB_X_SATYPE_IPCOMP:
635 		r.satype = IPSEC_IPCOMP;
636 		break;
637 	case SADB_X_SATYPE_TCPSIGNATURE:
638 		r.satype = IPSEC_TCPMD5;
639 		break;
640 	case SADB_X_SATYPE_IPIP:
641 		r.satype = IPSEC_IPIP;
642 		break;
643 	default:
644 		return;
645 	}
646 	bzero(&dst, sizeof dst);
647 	bzero(&src, sizeof src);
648 	parse_addr(extensions[SADB_EXT_ADDRESS_SRC], &src);
649 	parse_addr(extensions[SADB_EXT_ADDRESS_DST], &dst);
650 	r.src = &src;
651 	r.dst = &dst;
652 	if (r.satype == IPSEC_IPCOMP) {
653 		if (sa->sadb_sa_encrypt) {
654 			bzero(&xfs, sizeof xfs);
655 			r.xfs = &xfs;
656 			switch (sa->sadb_sa_encrypt) {
657 			case SADB_X_CALG_DEFLATE:
658 				xfs.compxf = &compxfs[COMPXF_DEFLATE];
659 				break;
660 			case SADB_X_CALG_LZS:
661 				xfs.compxf = &compxfs[COMPXF_LZS];
662 				break;
663 			}
664 		}
665 	} else if (r.satype == IPSEC_TCPMD5) {
666 		bzero(&authkey, sizeof authkey);
667 		parse_key(extensions[SADB_EXT_KEY_AUTH], &authkey);
668 		r.authkey = &authkey;
669 	} else if (sa->sadb_sa_encrypt || sa->sadb_sa_auth) {
670 		bzero(&xfs, sizeof xfs);
671 		r.xfs = &xfs;
672 		if (sa->sadb_sa_encrypt) {
673 			bzero(&enckey, sizeof enckey);
674 			parse_key(extensions[SADB_EXT_KEY_ENCRYPT], &enckey);
675 			r.enckey = &enckey;
676 
677 			switch (sa->sadb_sa_encrypt) {
678 			case SADB_EALG_3DESCBC:
679 				xfs.encxf = &encxfs[ENCXF_3DES_CBC];
680 				break;
681 			case SADB_X_EALG_AES:
682 				switch (r.enckey->len) {
683 				case 192/8:
684 					xfs.encxf = &encxfs[ENCXF_AES_192];
685 					break;
686 				case 256/8:
687 					xfs.encxf = &encxfs[ENCXF_AES_256];
688 					break;
689 				default:
690 					xfs.encxf = &encxfs[ENCXF_AES];
691 					break;
692 				}
693 				break;
694 			case SADB_X_EALG_AESCTR:
695 				switch (r.enckey->len) {
696 				case 28:
697 					xfs.encxf = &encxfs[ENCXF_AES_192_CTR];
698 					break;
699 				case 36:
700 					xfs.encxf = &encxfs[ENCXF_AES_256_CTR];
701 					break;
702 				default:
703 					xfs.encxf = &encxfs[ENCXF_AESCTR];
704 					break;
705 				}
706 				break;
707 			case SADB_X_EALG_AESGCM16:
708 				switch (r.enckey->len) {
709 				case 28:
710 					xfs.encxf = &encxfs[ENCXF_AES_192_GCM];
711 					break;
712 				case 36:
713 					xfs.encxf = &encxfs[ENCXF_AES_256_GCM];
714 					break;
715 				default:
716 					xfs.encxf = &encxfs[ENCXF_AES_128_GCM];
717 					break;
718 				}
719 				break;
720 			case SADB_X_EALG_AESGMAC:
721 				switch (r.enckey->len) {
722 				case 28:
723 					xfs.encxf = &encxfs[ENCXF_AES_192_GMAC];
724 					break;
725 				case 36:
726 					xfs.encxf = &encxfs[ENCXF_AES_256_GMAC];
727 					break;
728 				default:
729 					xfs.encxf = &encxfs[ENCXF_AES_128_GMAC];
730 					break;
731 				}
732 				break;
733 			case SADB_X_EALG_BLF:
734 				xfs.encxf = &encxfs[ENCXF_BLOWFISH];
735 				break;
736 			case SADB_X_EALG_CAST:
737 				xfs.encxf = &encxfs[ENCXF_CAST128];
738 				break;
739 			case SADB_X_EALG_CHACHA20POLY1305:
740 				xfs.encxf = &encxfs[ENCXF_CHACHA20_POLY1305];
741 				break;
742 			case SADB_EALG_NULL:
743 				xfs.encxf = &encxfs[ENCXF_NULL];
744 				break;
745 			}
746 		}
747 		if (sa->sadb_sa_auth) {
748 			bzero(&authkey, sizeof authkey);
749 			parse_key(extensions[SADB_EXT_KEY_AUTH], &authkey);
750 			r.authkey = &authkey;
751 
752 			switch (sa->sadb_sa_auth) {
753 			case SADB_AALG_MD5HMAC:
754 				xfs.authxf = &authxfs[AUTHXF_HMAC_MD5];
755 				break;
756 			case SADB_X_AALG_RIPEMD160HMAC:
757 				xfs.authxf = &authxfs[AUTHXF_HMAC_RIPEMD160];
758 				break;
759 			case SADB_AALG_SHA1HMAC:
760 				xfs.authxf = &authxfs[AUTHXF_HMAC_SHA1];
761 				break;
762 			case SADB_X_AALG_SHA2_256:
763 				xfs.authxf = &authxfs[AUTHXF_HMAC_SHA2_256];
764 				break;
765 			case SADB_X_AALG_SHA2_384:
766 				xfs.authxf = &authxfs[AUTHXF_HMAC_SHA2_384];
767 				break;
768 			case SADB_X_AALG_SHA2_512:
769 				xfs.authxf = &authxfs[AUTHXF_HMAC_SHA2_512];
770 				break;
771 			}
772 		}
773 	}
774 	if (!(opts & IPSECCTL_OPT_SHOWKEY)) {
775 		bzero(&enckey, sizeof enckey);
776 		bzero(&authkey, sizeof authkey);
777 		extensions[SADB_EXT_KEY_AUTH] = NULL;
778 		extensions[SADB_EXT_KEY_ENCRYPT] = NULL;
779 	}
780 	ipsecctl_print_rule(&r, opts);
781 
782 	if (opts & IPSECCTL_OPT_VERBOSE) {
783 		for (i = 0; i <= SADB_EXT_MAX; i++)
784 			if (extensions[i])
785 				print_ext(extensions[i], msg);
786 	}
787 	fflush(stdout);
788 }
789 
790 /* ARGSUSED1 */
791 void
792 pfkey_monitor_sa(struct sadb_msg *msg, int opts)
793 {
794 	int		 i;
795 
796 	setup_extensions(msg);
797 
798 	printf("%s: satype %s vers %u len %u seq %u pid %u\n",
799 	    lookup_name(msg_types, msg->sadb_msg_type),
800 	    lookup_name(sa_types, msg->sadb_msg_satype),
801 	    msg->sadb_msg_version, msg->sadb_msg_len,
802 	    msg->sadb_msg_seq,
803 	    msg->sadb_msg_pid);
804 	if (msg->sadb_msg_errno)
805 		printf("\terrno %u: %s\n", msg->sadb_msg_errno,
806 		    strerror(msg->sadb_msg_errno));
807 	for (i = 0; i <= SADB_EXT_MAX; i++)
808 		if (extensions[i])
809 			print_ext(extensions[i], msg);
810 	fflush(stdout);
811 }
812 
813 void
814 pfkey_print_raw(u_int8_t *data, ssize_t len)
815 {
816 	int i;
817 	const u_int8_t *sp = (const u_int8_t *)data;
818 
819 	printf("RAW PFKEYV2 MESSAGE:\n");
820 	for (i = 0; i < len; i++) {
821 		if ((i % 8 == 0) && (i != 0))
822 			printf("\n");
823 		printf("%02x ", *sp);
824 		sp++;
825 	}
826 	printf("\n");
827 }
828