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