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