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