xref: /openbsd-src/sbin/ipsecctl/pfkdump.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /*	$OpenBSD: pfkdump.c,v 1.25 2008/08/19 10:37:12 markus 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 #include <sys/param.h>
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_auth(struct sadb_ext *, struct sadb_msg *);
56 static void	print_cred(struct sadb_ext *, struct sadb_msg *);
57 static void	print_udpenc(struct sadb_ext *, struct sadb_msg *);
58 static void	print_tag(struct sadb_ext *, struct sadb_msg *);
59 
60 static struct idname *lookup(struct idname [], u_int8_t);
61 static char    *lookup_name(struct idname [], u_int8_t);
62 static void	print_ext(struct sadb_ext *, struct sadb_msg *);
63 
64 void		pfkey_print_raw(u_int8_t *, ssize_t);
65 
66 struct sadb_ext *extensions[SADB_EXT_MAX + 1];
67 
68 struct idname {
69 	u_int8_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_LOCAL_AUTH,	"local_auth",		print_auth },
102 	{ SADB_X_EXT_SUPPORTED_COMP,	"supported_comp",	print_supp },
103 	{ SADB_X_EXT_REMOTE_AUTH,	"remote_auth",		print_auth },
104 	{ SADB_X_EXT_LOCAL_CREDENTIALS,	"local_cred",		print_cred },
105 	{ SADB_X_EXT_REMOTE_CREDENTIALS,"remote_cred",		print_cred },
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 	{ 0,				NULL,			NULL }
110 };
111 
112 struct idname msg_types[] = {
113 	{ SADB_ACQUIRE,			"sadb_acquire",		NULL },
114 	{ SADB_ADD,			"sadb_add",		NULL },
115 	{ SADB_DELETE,			"sadb_delete",		NULL },
116 	{ SADB_DUMP,			"sadb_dump",		NULL },
117 	{ SADB_EXPIRE,			"sadb_expire",		NULL },
118 	{ SADB_FLUSH,			"sadb_flush",		NULL },
119 	{ SADB_GET,			"sadb_get",		NULL },
120 	{ SADB_GETSPI,			"sadb_getspi",		NULL },
121 	{ SADB_REGISTER,		"sadb_register",	NULL },
122 	{ SADB_UPDATE,			"sadb_update",		NULL },
123 	{ SADB_X_ADDFLOW,		"sadb_addflow",		NULL },
124 	{ SADB_X_ASKPOLICY,		"sadb_askpolicy",	NULL },
125 	{ SADB_X_DELFLOW,		"sadb_delflow",		NULL },
126 	{ SADB_X_GRPSPIS,		"sadb_grpspis",		NULL },
127 	{ SADB_X_PROMISC,		"sadb_promisc",		NULL },
128 	{ 0,				NULL,			NULL },
129 };
130 
131 struct idname sa_types[] = {
132 	{ SADB_SATYPE_UNSPEC,		"unspec",		NULL },
133 	{ SADB_SATYPE_AH,		"ah",			NULL },
134 	{ SADB_SATYPE_ESP,		"esp",			NULL },
135 	{ SADB_SATYPE_RSVP,		"rsvp",			NULL },
136 	{ SADB_SATYPE_OSPFV2,		"ospfv2",		NULL },
137 	{ SADB_SATYPE_RIPV2,		"ripv2",		NULL },
138 	{ SADB_SATYPE_MIP,		"mip",			NULL },
139 	{ SADB_X_SATYPE_IPIP,		"ipip",			NULL },
140 	{ SADB_X_SATYPE_TCPSIGNATURE,	"tcpmd5",		NULL },
141 	{ SADB_X_SATYPE_IPCOMP,		"ipcomp",		NULL },
142 	{ 0,				NULL,			NULL }
143 };
144 
145 struct idname auth_types[] = {
146 	{ SADB_AALG_NONE,		"none",			NULL },
147 	{ SADB_X_AALG_DES,		"des",			NULL },
148 	{ SADB_AALG_MD5HMAC,		"hmac-md5",		NULL },
149 	{ SADB_X_AALG_RIPEMD160HMAC,	"hmac-ripemd160",	NULL },
150 	{ SADB_AALG_SHA1HMAC,		"hmac-sha1",		NULL },
151 	{ SADB_X_AALG_SHA2_256,		"hmac-sha2-256",	NULL },
152 	{ SADB_X_AALG_SHA2_384,		"hmac-sha2-384",	NULL },
153 	{ SADB_X_AALG_SHA2_512,		"hmac-sha2-512",	NULL },
154 	{ SADB_X_AALG_MD5,		"md5",			NULL },
155 	{ SADB_X_AALG_SHA1,		"sha1",			NULL },
156 	{ 0,				NULL,			NULL }
157 };
158 
159 struct idname cred_types[] = {
160 	{ SADB_X_CREDTYPE_X509,		"x509-asn1",		NULL },
161 	{ SADB_X_CREDTYPE_KEYNOTE,	"keynote",		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_EALG_DESCBC,		"des-cbc",		NULL },
169 	{ SADB_X_EALG_3IDEA,		"idea3",		NULL },
170 	{ SADB_X_EALG_AES,		"aes",			NULL },
171 	{ SADB_X_EALG_AESCTR,		"aesctr",		NULL },
172 	{ SADB_X_EALG_BLF,		"blowfish",		NULL },
173 	{ SADB_X_EALG_CAST,		"cast128",		NULL },
174 	{ SADB_X_EALG_DES_IV32,		"des-iv32",		NULL },
175 	{ SADB_X_EALG_DES_IV64,		"des-iv64",		NULL },
176 	{ SADB_X_EALG_IDEA,		"idea",			NULL },
177 	{ SADB_EALG_NULL,		"null",			NULL },
178 	{ SADB_X_EALG_RC4,		"rc4",			NULL },
179 	{ SADB_X_EALG_RC5,		"rc5",			NULL },
180 	{ SADB_X_EALG_SKIPJACK,		"skipjack",		NULL },
181 	{ 0,				NULL,			NULL }
182 };
183 
184 struct idname comp_types[] = {
185 	{ SADB_X_CALG_NONE,		"none",			NULL },
186 	{ SADB_X_CALG_OUI,		"oui",			NULL },
187 	{ SADB_X_CALG_DEFLATE,		"deflate",		NULL },
188 	{ SADB_X_CALG_LZS,		"lzs",			NULL },
189 	{ 0,				NULL,			NULL }
190 };
191 
192 struct idname xauth_types[] = {
193 	{ SADB_X_AUTHTYPE_NONE,		"none",			NULL },
194 	{ SADB_X_AUTHTYPE_PASSPHRASE,	"passphrase",		NULL },
195 	{ SADB_X_AUTHTYPE_RSA,		"rsa",			NULL },
196 	{ 0,				NULL,			NULL }
197 };
198 
199 struct idname identity_types[] = {
200 	{ SADB_IDENTTYPE_RESERVED,	"reserved",		NULL },
201 	{ SADB_IDENTTYPE_PREFIX,	"prefix",		NULL },
202 	{ SADB_IDENTTYPE_FQDN,		"fqdn",			NULL },
203 	{ SADB_IDENTTYPE_USERFQDN,	"ufqdn",		NULL },
204 	{ SADB_X_IDENTTYPE_CONNECTION,	"x_connection",		NULL },
205 	{ 0,				NULL,			NULL }
206 };
207 
208 struct idname flow_types[] = {
209 	{ SADB_X_FLOW_TYPE_USE,		"use",			NULL },
210 	{ SADB_X_FLOW_TYPE_ACQUIRE,	"acquire",		NULL },
211 	{ SADB_X_FLOW_TYPE_REQUIRE,	"require",		NULL },
212 	{ SADB_X_FLOW_TYPE_BYPASS,	"bypass",		NULL },
213 	{ SADB_X_FLOW_TYPE_DENY,	"deny",			NULL },
214 	{ SADB_X_FLOW_TYPE_DONTACQ,	"dontacq",		NULL },
215 	{ 0,				NULL,			NULL }
216 };
217 
218 struct idname states[] = {
219 	{ SADB_SASTATE_LARVAL,		"larval",		NULL },
220 	{ SADB_SASTATE_MATURE,		"mature",		NULL },
221 	{ SADB_SASTATE_DYING,		"dying",		NULL },
222 	{ SADB_SASTATE_DEAD,		"dead",			NULL },
223 	{ 0,				NULL,			NULL }
224 };
225 
226 static struct idname *
227 lookup(struct idname tab[], u_int8_t id)
228 {
229 	struct idname *entry;
230 
231 	for (entry = tab; entry->name; entry++)
232 		if (entry->id == id)
233 			return (entry);
234 	return (NULL);
235 }
236 
237 static char *
238 lookup_name(struct idname tab[], u_int8_t id)
239 {
240 	struct idname *entry;
241 
242 	entry = lookup(tab, id);
243 	return (entry ? entry->name : "unknown");
244 }
245 
246 static void
247 print_ext(struct sadb_ext *ext, struct sadb_msg *msg)
248 {
249 	struct idname *entry;
250 
251 	if ((entry = lookup(ext_types, ext->sadb_ext_type)) == NULL) {
252 		printf("unknown ext: type %u len %u\n",
253 		    ext->sadb_ext_type, ext->sadb_ext_len);
254 		return;
255 	}
256 	printf("\t%s: ", entry->name);
257 	if (entry->func != NULL)
258 		(*entry->func)(ext, msg);
259 	else
260 		printf("type %u len %u",
261 		    ext->sadb_ext_type, ext->sadb_ext_len);
262 	printf("\n");
263 }
264 
265 static void
266 print_sa(struct sadb_ext *ext, struct sadb_msg *msg)
267 {
268 	struct sadb_sa *sa = (struct sadb_sa *)ext;
269 
270 	if (msg->sadb_msg_satype == SADB_X_SATYPE_IPCOMP)
271 		printf("cpi 0x%8.8x comp %s\n",
272 		    ntohl(sa->sadb_sa_spi),
273 		    lookup_name(comp_types, sa->sadb_sa_encrypt));
274 	else
275 		printf("spi 0x%8.8x auth %s enc %s\n",
276 		    ntohl(sa->sadb_sa_spi),
277 		    lookup_name(auth_types, sa->sadb_sa_auth),
278 		    lookup_name(enc_types, sa->sadb_sa_encrypt));
279 	printf("\t\tstate %s replay %u flags %u",
280 	    lookup_name(states, sa->sadb_sa_state),
281 	    sa->sadb_sa_replay, sa->sadb_sa_flags);
282 }
283 
284 /* ARGSUSED1 */
285 static void
286 print_addr(struct sadb_ext *ext, struct sadb_msg *msg)
287 {
288 	struct sadb_address *addr = (struct sadb_address *)ext;
289 	struct sockaddr *sa;
290 	struct sockaddr_in *sin4;
291 	struct sockaddr_in6 *sin6;
292 	char hbuf[NI_MAXHOST];
293 
294 	sa = (struct sockaddr *)(addr + 1);
295 	if (sa->sa_family == 0)
296 		printf("<any>");
297 	else if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0,
298 	    NI_NUMERICHOST))
299 		printf("<could not get numeric hostname>");
300 	else
301 		printf("%s", hbuf);
302 	switch (sa->sa_family) {
303 	case AF_INET:
304 		sin4 = (struct sockaddr_in *)sa;
305 		if (sin4->sin_port)
306 			printf(" port %u", ntohs(sin4->sin_port));
307 		break;
308 	case AF_INET6:
309 		sin6 = (struct sockaddr_in6 *)sa;
310 		if (sin6->sin6_port)
311 			printf(" port %u", ntohs(sin6->sin6_port));
312 		break;
313 	}
314 }
315 
316 /* ARGSUSED1 */
317 static void
318 print_key(struct sadb_ext *ext, struct sadb_msg *msg)
319 {
320 	struct sadb_key *key = (struct sadb_key *)ext;
321 	u_int8_t *data;
322 	int i;
323 
324 	printf("bits %u: ", key->sadb_key_bits);
325 	data = (u_int8_t *)(key + 1);
326 	for (i = 0; i < key->sadb_key_bits / 8; i++) {
327 		printf("%2.2x", data[i]);
328 		data[i] = 0x00;		/* clear sensitive data */
329 	}
330 }
331 
332 /* ARGSUSED1 */
333 static void
334 print_life(struct sadb_ext *ext, struct sadb_msg *msg)
335 {
336 	struct sadb_lifetime *life = (struct sadb_lifetime *)ext;
337 
338 	printf("alloc %u bytes %llu add %llu first %llu",
339 	    life->sadb_lifetime_allocations,
340 	    life->sadb_lifetime_bytes,
341 	    life->sadb_lifetime_addtime,
342 	    life->sadb_lifetime_usetime);
343 }
344 
345 static void
346 print_proto(struct sadb_ext *ext, struct sadb_msg *msg)
347 {
348 	struct sadb_protocol *proto = (struct sadb_protocol *)ext;
349 
350 	/* overloaded */
351 	if (msg->sadb_msg_type == SADB_X_GRPSPIS)
352 		printf("satype %s flags %u",
353 		    lookup_name(sa_types, proto->sadb_protocol_proto),
354 		    proto->sadb_protocol_flags);
355 	else
356 		printf("proto %u flags %u",
357 		    proto->sadb_protocol_proto, proto->sadb_protocol_flags);
358 }
359 
360 /* ARGSUSED1 */
361 static void
362 print_flow(struct sadb_ext *ext, struct sadb_msg *msg)
363 {
364 	struct sadb_protocol *proto = (struct sadb_protocol *)ext;
365 	char *dir = "unknown";
366 
367 	switch (proto->sadb_protocol_direction) {
368 	case IPSP_DIRECTION_IN:
369 		dir = "in";
370 		break;
371 	case IPSP_DIRECTION_OUT:
372 		dir = "out";
373 		break;
374 	}
375 	printf("type %s direction %s",
376 	    lookup_name(flow_types, proto->sadb_protocol_proto), dir);
377 }
378 
379 static void
380 print_tag(struct sadb_ext *ext, struct sadb_msg *msg)
381 {
382 	struct sadb_x_tag *stag = (struct sadb_x_tag *)ext;
383 	char *p;
384 
385 	p = (char *)(stag + 1);
386 	printf("%s", p);
387 }
388 
389 static char *
390 alg_by_ext(u_int8_t ext_type, u_int8_t id)
391 {
392 	switch (ext_type) {
393 	case SADB_EXT_SUPPORTED_ENCRYPT:
394 		return lookup_name(enc_types, id);
395 	case SADB_EXT_SUPPORTED_AUTH:
396 		return lookup_name(auth_types, id);
397 	case SADB_X_EXT_SUPPORTED_COMP:
398 		return lookup_name(comp_types, id);
399 	default:
400 		return "unknown";
401 	}
402 }
403 
404 static void
405 print_alg(struct sadb_alg *alg, u_int8_t ext_type)
406 {
407 	printf("\t\t%s iv %u min %u max %u",
408 	    alg_by_ext(ext_type, alg->sadb_alg_id), alg->sadb_alg_ivlen,
409 	    alg->sadb_alg_minbits, alg->sadb_alg_maxbits);
410 }
411 
412 /* ARGSUSED1 */
413 static void
414 print_supp(struct sadb_ext *ext, struct sadb_msg *msg)
415 {
416 	struct sadb_supported *supported = (struct sadb_supported *)ext;
417 	struct sadb_alg *alg;
418 
419 	printf("\n");
420 	for (alg = (struct sadb_alg *)(supported + 1);
421 	    (size_t)((u_int8_t *)alg - (u_int8_t *)ext) <
422 	    ext->sadb_ext_len * PFKEYV2_CHUNK;
423 	    alg++) {
424 		struct sadb_alg *next = alg + 1;
425 		print_alg(alg, ext->sadb_ext_type);
426 		if ((size_t)((u_int8_t *)next - (u_int8_t *)ext) <
427 		    ext->sadb_ext_len * PFKEYV2_CHUNK)
428 			printf("\n");
429 	}
430 }
431 
432 /* ARGSUSED1 */
433 static void
434 print_comb(struct sadb_comb *comb, struct sadb_msg *msg)
435 {
436 	printf("\t\tauth %s min %u max %u\n"
437 	    "\t\tenc %s min %u max %u\n"
438 	    "\t\taddtime hard %llu soft %llu\n"
439 	    "\t\tusetime hard %llu soft %llu",
440 	    lookup_name(auth_types, comb->sadb_comb_auth),
441 	    comb->sadb_comb_auth_minbits,
442 	    comb->sadb_comb_auth_maxbits,
443 	    lookup_name(enc_types, comb->sadb_comb_encrypt),
444 	    comb->sadb_comb_encrypt_minbits,
445 	    comb->sadb_comb_encrypt_maxbits,
446 	    comb->sadb_comb_soft_addtime,
447 	    comb->sadb_comb_hard_addtime,
448 	    comb->sadb_comb_soft_usetime,
449 	    comb->sadb_comb_hard_usetime);
450 #if 0
451 	    comb->sadb_comb_flags,
452 	    comb->sadb_comb_reserved,
453 	    comb->sadb_comb_soft_allocations,
454 	    comb->sadb_comb_hard_allocations,
455 	    comb->sadb_comb_soft_bytes,
456 	    comb->sadb_comb_hard_bytes,
457 #endif
458 }
459 
460 /* ARGSUSED1 */
461 static void
462 print_prop(struct sadb_ext *ext, struct sadb_msg *msg)
463 {
464 	struct sadb_prop *prop = (struct sadb_prop *)ext;
465 	struct sadb_comb *comb;
466 
467 	printf("replay %u\n", prop->sadb_prop_replay);
468 	for (comb = (struct sadb_comb *)(prop + 1);
469 	    (size_t)((u_int8_t *)comb - (u_int8_t *)ext) <
470 	    ext->sadb_ext_len * PFKEYV2_CHUNK;
471 	    comb++)
472 		print_comb(comb, msg);
473 }
474 
475 /* ARGSUSED1 */
476 static void
477 print_sens(struct sadb_ext *ext, struct sadb_msg *msg)
478 {
479 	struct sadb_sens *sens = (struct sadb_sens *)ext;
480 
481 	printf("dpd %u sens_level %u integ_level %u",
482 	    sens->sadb_sens_dpd,
483 	    sens->sadb_sens_sens_level,
484 	    sens->sadb_sens_integ_level);
485 }
486 
487 /* ARGSUSED1 */
488 static void
489 print_spir(struct sadb_ext *ext, struct sadb_msg *msg)
490 {
491 	struct sadb_spirange *spirange = (struct sadb_spirange *)ext;
492 
493 	printf("min 0x%8.8x max 0x%8.8x",
494 	    spirange->sadb_spirange_min, spirange->sadb_spirange_max);
495 }
496 
497 /* ARGSUSED1 */
498 static void
499 print_ident(struct sadb_ext *ext, struct sadb_msg *msg)
500 {
501 	struct sadb_ident *ident = (struct sadb_ident *)ext;
502 
503 	printf("type %s id %llu: %s",
504 	    lookup_name(identity_types, ident->sadb_ident_type),
505 	    ident->sadb_ident_id, (char *)(ident + 1));
506 }
507 
508 /* ARGSUSED1 */
509 static void
510 print_auth(struct sadb_ext *ext, struct sadb_msg *msg)
511 {
512 	struct sadb_x_cred *x_cred = (struct sadb_x_cred *)ext;
513 
514 	printf("type %s",
515 	    lookup_name(xauth_types, x_cred->sadb_x_cred_type));
516 }
517 
518 /* ARGSUSED1 */
519 static void
520 print_cred(struct sadb_ext *ext, struct sadb_msg *msg)
521 {
522 	struct sadb_x_cred *x_cred = (struct sadb_x_cred *)ext;
523 	printf("type %s",
524 	    lookup_name(cred_types, x_cred->sadb_x_cred_type));
525 }
526 
527 /* ARGSUSED1 */
528 static void
529 print_policy(struct sadb_ext *ext, struct sadb_msg *msg)
530 {
531 	struct sadb_x_policy *x_policy = (struct sadb_x_policy *)ext;
532 
533 	printf("seq %u", x_policy->sadb_x_policy_seq);
534 }
535 
536 /* ARGSUSED1 */
537 static void
538 print_udpenc(struct sadb_ext *ext, struct sadb_msg *msg)
539 {
540 	struct sadb_x_udpencap *x_udpencap = (struct sadb_x_udpencap *)ext;
541 
542 	printf("udpencap port %u", ntohs(x_udpencap->sadb_x_udpencap_port));
543 }
544 
545 static void
546 setup_extensions(struct sadb_msg *msg)
547 {
548 	struct sadb_ext *ext;
549 
550 	bzero(extensions, sizeof(extensions));
551 	if (msg->sadb_msg_len == 0)
552 		return;
553 	for (ext = (struct sadb_ext *)(msg + 1);
554 	    (size_t)((u_int8_t *)ext - (u_int8_t *)msg) <
555 	    msg->sadb_msg_len * PFKEYV2_CHUNK && ext->sadb_ext_len > 0;
556 	    ext = (struct sadb_ext *)((u_int8_t *)ext +
557 	    ext->sadb_ext_len * PFKEYV2_CHUNK))
558 		extensions[ext->sadb_ext_type] = ext;
559 }
560 
561 static void
562 parse_addr(struct sadb_ext *ext, struct ipsec_addr_wrap *ipa)
563 {
564 	struct sadb_address *addr = (struct sadb_address *)ext;
565 	struct sockaddr *sa;
566 
567 	if (addr == NULL)
568 		return;
569 	sa = (struct sockaddr *)(addr + 1);
570 	switch (sa->sa_family) {
571 	case AF_INET:
572 		ipa->address.v4 = ((struct sockaddr_in *)sa)->sin_addr;
573 		set_ipmask(ipa, 32);
574 		break;
575 	case AF_INET6:
576 		ipa->address.v6 = ((struct sockaddr_in6 *)sa)->sin6_addr;
577 		set_ipmask(ipa, 128);
578 		break;
579 	}
580 	ipa->af = sa->sa_family;
581 	ipa->next = NULL;
582 	ipa->tail = ipa;
583 }
584 
585 static void
586 parse_key(struct sadb_ext *ext, struct ipsec_key *ikey)
587 {
588 	struct sadb_key *key = (struct sadb_key *)ext;
589 	u_int8_t *data;
590 
591 	if (key == NULL)
592 		return;
593 	data = (u_int8_t *)(key + 1);
594 	ikey->data = data;
595 	ikey->len = key->sadb_key_bits / 8;
596 }
597 
598 u_int32_t
599 pfkey_get_spi(struct sadb_msg *msg)
600 {
601 	struct sadb_sa *sa;
602 
603 	setup_extensions(msg);
604 	sa = (struct sadb_sa *)extensions[SADB_EXT_SA];
605 	return (ntohl(sa->sadb_sa_spi));
606 }
607 
608 /* opposite of pfkey_sa() */
609 void
610 pfkey_print_sa(struct sadb_msg *msg, int opts)
611 {
612 	int i;
613 	struct ipsec_rule r;
614 	struct ipsec_key enckey, authkey;
615 	struct ipsec_transforms xfs;
616 	struct ipsec_addr_wrap src, dst;
617 	struct sadb_sa *sa;
618 
619 	setup_extensions(msg);
620 	sa = (struct sadb_sa *)extensions[SADB_EXT_SA];
621 	bzero(&r, sizeof r);
622 	r.type |= RULE_SA;
623 	r.tmode = (msg->sadb_msg_satype != SADB_X_SATYPE_TCPSIGNATURE) &&
624 	    (sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL) ?
625 	    IPSEC_TUNNEL : IPSEC_TRANSPORT;
626 	r.spi = ntohl(sa->sadb_sa_spi);
627 
628 	switch (msg->sadb_msg_satype) {
629 	case SADB_SATYPE_AH:
630 		r.satype = IPSEC_AH;
631 		break;
632 	case SADB_SATYPE_ESP:
633 		r.satype = IPSEC_ESP;
634 		break;
635 	case SADB_X_SATYPE_IPCOMP:
636 		r.satype = IPSEC_IPCOMP;
637 		break;
638 	case SADB_X_SATYPE_TCPSIGNATURE:
639 		r.satype = IPSEC_TCPMD5;
640 		break;
641 	case SADB_X_SATYPE_IPIP:
642 		r.satype = IPSEC_IPIP;
643 		break;
644 	default:
645 		return;
646 	}
647 	bzero(&dst, sizeof dst);
648 	bzero(&src, sizeof src);
649 	parse_addr(extensions[SADB_EXT_ADDRESS_SRC], &src);
650 	parse_addr(extensions[SADB_EXT_ADDRESS_DST], &dst);
651 	r.src = &src;
652 	r.dst = &dst;
653 	if (r.satype == IPSEC_IPCOMP) {
654 		if (sa->sadb_sa_encrypt) {
655 			bzero(&xfs, sizeof xfs);
656 			r.xfs = &xfs;
657 			switch (sa->sadb_sa_encrypt) {
658 			case SADB_X_CALG_DEFLATE:
659 				xfs.encxf = &compxfs[COMPXF_DEFLATE];
660 				break;
661 			case SADB_X_CALG_LZS:
662 				xfs.encxf = &compxfs[COMPXF_LZS];
663 				break;
664 			}
665 		}
666 	} else if (r.satype == IPSEC_TCPMD5) {
667 		bzero(&authkey, sizeof authkey);
668 		parse_key(extensions[SADB_EXT_KEY_AUTH], &authkey);
669 		r.authkey = &authkey;
670 	} else if (sa->sadb_sa_encrypt || sa->sadb_sa_auth) {
671 		bzero(&xfs, sizeof xfs);
672 		r.xfs = &xfs;
673 		if (sa->sadb_sa_encrypt) {
674 			bzero(&enckey, sizeof enckey);
675 			parse_key(extensions[SADB_EXT_KEY_ENCRYPT], &enckey);
676 			r.enckey = &enckey;
677 
678 			switch (sa->sadb_sa_encrypt) {
679 			case SADB_EALG_3DESCBC:
680 				xfs.encxf = &encxfs[ENCXF_3DES_CBC];
681 				break;
682 			case SADB_EALG_DESCBC:
683 				xfs.encxf = &encxfs[ENCXF_DES_CBC];
684 				break;
685 			case SADB_X_EALG_AES:
686 				switch (r.enckey->len) {
687 				case 192/8:
688 					xfs.encxf = &encxfs[ENCXF_AES_192];
689 					break;
690 				case 256/8:
691 					xfs.encxf = &encxfs[ENCXF_AES_256];
692 					break;
693 				default:
694 					xfs.encxf = &encxfs[ENCXF_AES];
695 					break;
696 				}
697 				break;
698 			case SADB_X_EALG_AESCTR:
699 				xfs.encxf = &encxfs[ENCXF_AESCTR];
700 				break;
701 			case SADB_X_EALG_BLF:
702 				xfs.encxf = &encxfs[ENCXF_BLOWFISH];
703 				break;
704 			case SADB_X_EALG_CAST:
705 				xfs.encxf = &encxfs[ENCXF_CAST128];
706 				break;
707 			case SADB_EALG_NULL:
708 				xfs.encxf = &encxfs[ENCXF_NULL];
709 				break;
710 			case SADB_X_EALG_SKIPJACK:
711 				xfs.encxf = &encxfs[ENCXF_SKIPJACK];
712 				break;
713 			}
714 		}
715 		if (sa->sadb_sa_auth) {
716 			bzero(&authkey, sizeof authkey);
717 			parse_key(extensions[SADB_EXT_KEY_AUTH], &authkey);
718 			r.authkey = &authkey;
719 
720 			switch (sa->sadb_sa_auth) {
721 			case SADB_AALG_MD5HMAC:
722 				xfs.authxf = &authxfs[AUTHXF_HMAC_MD5];
723 				break;
724 			case SADB_X_AALG_RIPEMD160HMAC:
725 				xfs.authxf = &authxfs[AUTHXF_HMAC_RIPEMD160];
726 				break;
727 			case SADB_AALG_SHA1HMAC:
728 				xfs.authxf = &authxfs[AUTHXF_HMAC_SHA1];
729 				break;
730 			case SADB_X_AALG_SHA2_256:
731 				xfs.authxf = &authxfs[AUTHXF_HMAC_SHA2_256];
732 				break;
733 			case SADB_X_AALG_SHA2_384:
734 				xfs.authxf = &authxfs[AUTHXF_HMAC_SHA2_384];
735 				break;
736 			case SADB_X_AALG_SHA2_512:
737 				xfs.authxf = &authxfs[AUTHXF_HMAC_SHA2_512];
738 				break;
739 			}
740 		}
741 	}
742 	if (!(opts & IPSECCTL_OPT_SHOWKEY)) {
743 		bzero(&enckey, sizeof enckey);
744 		bzero(&authkey, sizeof authkey);
745 		extensions[SADB_EXT_KEY_AUTH] = NULL;
746 		extensions[SADB_EXT_KEY_ENCRYPT] = NULL;
747 	}
748 	ipsecctl_print_rule(&r, opts);
749 
750 	if (opts & IPSECCTL_OPT_VERBOSE) {
751 		for (i = 0; i <= SADB_EXT_MAX; i++)
752 			if (extensions[i])
753 				print_ext(extensions[i], msg);
754 	}
755 	fflush(stdout);
756 }
757 
758 /* ARGSUSED1 */
759 void
760 pfkey_monitor_sa(struct sadb_msg *msg, int opts)
761 {
762 	int		 i;
763 
764 	setup_extensions(msg);
765 
766 	printf("%s: satype %s vers %u len %u seq %u pid %u\n",
767 	    lookup_name(msg_types, msg->sadb_msg_type),
768 	    lookup_name(sa_types, msg->sadb_msg_satype),
769 	    msg->sadb_msg_version, msg->sadb_msg_len,
770 	    msg->sadb_msg_seq,
771 	    msg->sadb_msg_pid);
772 	if (msg->sadb_msg_errno)
773 		printf("\terrno %u: %s\n", msg->sadb_msg_errno,
774 		    strerror(msg->sadb_msg_errno));
775 	for (i = 0; i <= SADB_EXT_MAX; i++)
776 		if (extensions[i])
777 			print_ext(extensions[i], msg);
778 	fflush(stdout);
779 }
780 
781 void
782 pfkey_print_raw(u_int8_t *data, ssize_t len)
783 {
784 	int i;
785 	const u_int8_t *sp = (const u_int8_t *)data;
786 
787 	printf("RAW PFKEYV2 MESSAGE:\n");
788 	for (i = 0; i < len; i++) {
789 		if ((i % 8 == 0) && (i != 0))
790 			printf("\n");
791 		printf("%02x ", *sp);
792 		sp++;
793 	}
794 	printf("\n");
795 }
796