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