]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/Common/pfkey_dump.c
ipsec-292.40.4.tar.gz
[apple/ipsec.git] / ipsec-tools / Common / pfkey_dump.c
1 /* $KAME: pfkey_dump.c,v 1.45 2003/09/08 10:14:56 itojun Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
39 #ifdef HAVE_NETINET6_IPSEC
40 # include <netinet6/ipsec.h>
41 #else
42 # include <netinet/ipsec.h>
43 #endif
44
45 #include <net/pfkeyv2.h>
46
47 #include <netinet/in.h>
48 #include <arpa/inet.h>
49
50 #include <stdlib.h>
51 #include <unistd.h>
52 #include <stdio.h>
53 #include <string.h>
54 #include <time.h>
55 #include <netdb.h>
56
57 #include "ipsec_strerror.h"
58 #include "libpfkey.h"
59
60 /* cope with old kame headers - ugly */
61 #ifndef SADB_X_AALG_MD5
62 #define SADB_X_AALG_MD5 SADB_AALG_MD5
63 #endif
64 #ifndef SADB_X_AALG_SHA
65 #define SADB_X_AALG_SHA SADB_AALG_SHA
66 #endif
67 #ifndef SADB_X_AALG_NULL
68 #define SADB_X_AALG_NULL SADB_AALG_NULL
69 #endif
70
71 #ifndef SADB_X_EALG_BLOWFISHCBC
72 #define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC
73 #endif
74 #ifndef SADB_X_EALG_CAST128CBC
75 #define SADB_X_EALG_CAST128CBC SADB_EALG_CAST128CBC
76 #endif
77 #ifndef SADB_X_EALG_RC5CBC
78 #ifdef SADB_EALG_RC5CBC
79 #define SADB_X_EALG_RC5CBC SADB_EALG_RC5CBC
80 #endif
81 #endif
82
83 #define GETMSGSTR(str, num) \
84 do { \
85 /*CONSTCOND*/ \
86 if (sizeof((str)[0]) == 0 \
87 || num >= sizeof(str)/sizeof((str)[0])) \
88 printf("%u ", (num)); \
89 else if (strlen((str)[(num)]) == 0) \
90 printf("%u ", (num)); \
91 else \
92 printf("%s ", (str)[(num)]); \
93 } while (/*CONSTCOND*/0)
94
95 #define GETMSGV2S(v2s, num) \
96 do { \
97 struct val2str *p; \
98 for (p = (v2s); p && p->str; p++) { \
99 if (p->val == (num)) \
100 break; \
101 } \
102 if (p && p->str) \
103 printf("%s ", p->str); \
104 else \
105 printf("%u ", (num)); \
106 } while (/*CONSTCOND*/0)
107
108 static char *str_ipaddr (struct sockaddr *);
109 static char *str_ipport (struct sockaddr *);
110 static char *str_prefport (u_int, u_int, u_int, u_int);
111 static void str_upperspec (u_int, u_int, u_int);
112 static char *str_time (time_t);
113 static void str_lifetime_byte (struct sadb_lifetime *, char *);
114 static void pfkey_sadump1 (struct sadb_msg *, int);
115 static void pfkey_spdump1 (struct sadb_msg *, int);
116
117 struct val2str {
118 int val;
119 const char *str;
120 };
121
122 /*
123 * Must to be re-written about following strings.
124 */
125 static char *str_satype[] = {
126 "unspec",
127 "unknown",
128 "ah",
129 "esp",
130 "unknown",
131 "rsvp",
132 "ospfv2",
133 "ripv2",
134 "mip",
135 "ipcomp",
136 "policy",
137 "tcp",
138 };
139
140 static char *str_mode[] = {
141 "any",
142 "transport",
143 "tunnel",
144 };
145
146 static char *str_state[] = {
147 "larval",
148 "mature",
149 "dying",
150 "dead",
151 };
152
153 static struct val2str str_alg_auth[] = {
154 { SADB_AALG_NONE, "none", },
155 { SADB_AALG_MD5HMAC, "hmac-md5", },
156 { SADB_AALG_SHA1HMAC, "hmac-sha1", },
157 { SADB_X_AALG_MD5, "md5", },
158 { SADB_X_AALG_SHA, "sha", },
159 { SADB_X_AALG_NULL, "null", },
160 #ifdef SADB_X_AALG_TCP_MD5
161 { SADB_X_AALG_TCP_MD5, "tcp-md5", },
162 #endif
163 #ifdef SADB_X_AALG_SHA2_256
164 { SADB_X_AALG_SHA2_256, "hmac-sha256", },
165 #endif
166 #ifdef SADB_X_AALG_SHA2_384
167 { SADB_X_AALG_SHA2_384, "hmac-sha384", },
168 #endif
169 #ifdef SADB_X_AALG_SHA2_512
170 { SADB_X_AALG_SHA2_512, "hmac-sha512", },
171 #endif
172 #ifdef SADB_X_AALG_RIPEMD160HMAC
173 { SADB_X_AALG_RIPEMD160HMAC, "hmac-ripemd160", },
174 #endif
175 #ifdef SADB_X_AALG_AES_XCBC_MAC
176 { SADB_X_AALG_AES_XCBC_MAC, "aes-xcbc-mac", },
177 #endif
178 { -1, NULL, },
179 };
180
181 static struct val2str str_alg_enc[] = {
182 { SADB_EALG_NONE, "none", },
183 { SADB_EALG_DESCBC, "des-cbc", },
184 { SADB_EALG_3DESCBC, "3des-cbc", },
185 { SADB_EALG_NULL, "null", },
186 #ifdef SADB_X_EALG_RC5CBC
187 { SADB_X_EALG_RC5CBC, "rc5-cbc", },
188 #endif
189 { SADB_X_EALG_CAST128CBC, "cast128-cbc", },
190 { SADB_X_EALG_BLOWFISHCBC, "blowfish-cbc", },
191 #ifdef SADB_X_EALG_AESCBC
192 { SADB_X_EALG_AESCBC, "aes-cbc", },
193 #endif
194 #ifdef SADB_X_EALG_TWOFISHCBC
195 { SADB_X_EALG_TWOFISHCBC, "twofish-cbc", },
196 #endif
197 #ifdef SADB_X_EALG_AESCTR
198 { SADB_X_EALG_AESCTR, "aes-ctr", },
199 #endif
200 { -1, NULL, },
201 };
202
203 static struct val2str str_alg_comp[] = {
204 { SADB_X_CALG_NONE, "none", },
205 { SADB_X_CALG_OUI, "oui", },
206 { SADB_X_CALG_DEFLATE, "deflate", },
207 { SADB_X_CALG_LZS, "lzs", },
208 { -1, NULL, },
209 };
210
211 /*
212 * dump SADB_MSG formated. For debugging, you should use kdebug_sadb().
213 */
214
215 void
216 pfkey_sadump(m)
217 struct sadb_msg *m;
218 {
219 pfkey_sadump1(m, 0);
220 }
221
222 void
223 pfkey_sadump_withports(m)
224 struct sadb_msg *m;
225 {
226 pfkey_sadump1(m, 1);
227 }
228
229 void
230 pfkey_sadump1(m, withports)
231 struct sadb_msg *m;
232 int withports;
233 {
234 caddr_t mhp[SADB_EXT_MAX + 1];
235 struct sadb_sa *m_sa;
236 struct sadb_x_sa2 *m_sa2;
237 struct sadb_lifetime *m_lftc, *m_lfth, *m_lfts;
238 struct sadb_address *m_saddr, *m_daddr;
239 #ifdef notdef
240 struct sadb_address *m_paddr;
241 #endif
242 struct sadb_key *m_auth, *m_enc;
243 #ifdef notdef
244 struct sadb_ident *m_sid, *m_did;
245 struct sadb_sens *m_sens;
246 #endif
247 #ifdef SADB_X_EXT_NAT_T_TYPE
248 struct sadb_x_nat_t_type *natt_type;
249 struct sadb_x_nat_t_port *natt_sport, *natt_dport;
250 struct sadb_address *natt_oa;
251
252 int use_natt = 0;
253 #endif
254 struct sadb_x_ipsecif *m_ipif = NULL;
255 struct sockaddr *sa;
256
257 /* check pfkey message. */
258 if (pfkey_align(m, mhp)) {
259 printf("%s\n", ipsec_strerror());
260 return;
261 }
262 if (pfkey_check(mhp)) {
263 printf("%s\n", ipsec_strerror());
264 return;
265 }
266
267 m_sa = (void *)mhp[SADB_EXT_SA];
268 m_sa2 = (void *)mhp[SADB_X_EXT_SA2];
269 m_lftc = (void *)mhp[SADB_EXT_LIFETIME_CURRENT];
270 m_lfth = (void *)mhp[SADB_EXT_LIFETIME_HARD];
271 m_lfts = (void *)mhp[SADB_EXT_LIFETIME_SOFT];
272 m_saddr = (void *)mhp[SADB_EXT_ADDRESS_SRC];
273 m_daddr = (void *)mhp[SADB_EXT_ADDRESS_DST];
274 #ifdef notdef
275 m_paddr = (void *)mhp[SADB_EXT_ADDRESS_PROXY];
276 #endif
277 m_auth = (void *)mhp[SADB_EXT_KEY_AUTH];
278 m_enc = (void *)mhp[SADB_EXT_KEY_ENCRYPT];
279 #ifdef notdef
280 m_sid = (void *)mhp[SADB_EXT_IDENTITY_SRC];
281 m_did = (void *)mhp[SADB_EXT_IDENTITY_DST];
282 m_sens = (void *)mhp[SADB_EXT_SENSITIVITY];
283 #endif
284 #ifdef SADB_X_EXT_NAT_T_TYPE
285 natt_type = (void *)mhp[SADB_X_EXT_NAT_T_TYPE];
286 natt_sport = (void *)mhp[SADB_X_EXT_NAT_T_SPORT];
287 natt_dport = (void *)mhp[SADB_X_EXT_NAT_T_DPORT];
288 natt_oa = (void *)mhp[SADB_X_EXT_NAT_T_OA];
289
290 if (natt_type && natt_type->sadb_x_nat_t_type_type)
291 use_natt = 1;
292 #endif
293 m_ipif = (void *)mhp[SADB_X_EXT_IPSECIF];
294 /* source address */
295 if (m_saddr == NULL) {
296 printf("no ADDRESS_SRC extension.\n");
297 return;
298 }
299 sa = (void *)(m_saddr + 1);
300 if (withports)
301 printf("%s[%s]", str_ipaddr(sa), str_ipport(sa));
302 else
303 printf("%s", str_ipaddr(sa));
304 #ifdef SADB_X_EXT_NAT_T_TYPE
305 if (use_natt && natt_sport)
306 printf("[%u]", ntohs(natt_sport->sadb_x_nat_t_port_port));
307 #endif
308 printf(" ");
309
310 /* destination address */
311 if (m_daddr == NULL) {
312 printf(" no ADDRESS_DST extension.\n");
313 return;
314 }
315 sa = (void *)(m_daddr + 1);
316 if (withports)
317 printf("%s[%s]", str_ipaddr(sa), str_ipport(sa));
318 else
319 printf("%s", str_ipaddr(sa));
320 #ifdef SADB_X_EXT_NAT_T_TYPE
321 if (use_natt && natt_dport)
322 printf("[%u]", ntohs(natt_dport->sadb_x_nat_t_port_port));
323 #endif
324 printf(" ");
325
326 /* SA type */
327 if (m_sa == NULL) {
328 printf("no SA extension.\n");
329 return;
330 }
331 if (m_sa2 == NULL) {
332 printf("no SA2 extension.\n");
333 return;
334 }
335 printf("\n\t");
336
337 #ifdef SADB_X_EXT_NAT_T_TYPE
338 if (use_natt && m->sadb_msg_satype == SADB_SATYPE_ESP)
339 printf("esp-udp ");
340 else if (use_natt)
341 printf("natt+");
342
343 if (!use_natt || m->sadb_msg_satype != SADB_SATYPE_ESP)
344 #endif
345 GETMSGSTR(str_satype, m->sadb_msg_satype);
346
347 printf("mode=");
348 GETMSGSTR(str_mode, m_sa2->sadb_x_sa2_mode);
349
350 printf("spi=%u(0x%08x) reqid=%u(0x%08x)\n",
351 (u_int32_t)ntohl(m_sa->sadb_sa_spi),
352 (u_int32_t)ntohl(m_sa->sadb_sa_spi),
353 (u_int32_t)m_sa2->sadb_x_sa2_reqid,
354 (u_int32_t)m_sa2->sadb_x_sa2_reqid);
355
356 #ifdef SADB_X_EXT_NAT_T_TYPE
357 /* other NAT-T information */
358 if (use_natt && natt_oa)
359 printf("\tNAT OA=%s\n",
360 str_ipaddr((void *)(natt_oa + 1)));
361 #endif
362
363 /* encryption key */
364 if (m->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) {
365 printf("\tC: ");
366 GETMSGV2S(str_alg_comp, m_sa->sadb_sa_encrypt);
367 } else if (m->sadb_msg_satype == SADB_SATYPE_ESP) {
368 if (m_enc != NULL) {
369 printf("\tE: ");
370 GETMSGV2S(str_alg_enc, m_sa->sadb_sa_encrypt);
371 ipsec_hexdump((caddr_t)(void *)m_enc + sizeof(*m_enc),
372 m_enc->sadb_key_bits / 8);
373 printf("\n");
374 }
375 }
376
377 /* authentication key */
378 if (m_auth != NULL) {
379 printf("\tA: ");
380 GETMSGV2S(str_alg_auth, m_sa->sadb_sa_auth);
381 ipsec_hexdump((caddr_t)(void *)m_auth + sizeof(*m_auth),
382 m_auth->sadb_key_bits / 8);
383 printf("\n");
384 }
385
386 /* replay windoe size & flags */
387 printf("\tseq=0x%08x replay=%u flags=0x%08x ",
388 m_sa2->sadb_x_sa2_sequence,
389 m_sa->sadb_sa_replay,
390 m_sa->sadb_sa_flags);
391
392 #ifdef SADB_X_EXT_SA2_DELETE_ON_DETACH
393 printf("flags2=0x%08x ",
394 m_sa2->sadb_x_sa2_flags);
395 #endif
396
397 /* state */
398 printf("state=");
399 GETMSGSTR(str_state, m_sa->sadb_sa_state);
400 printf("\n");
401
402 if (m_ipif) {
403 printf("\t");
404 if (m_ipif->sadb_x_ipsecif_internal_if[0])
405 printf("internal_if: %s ", m_ipif->sadb_x_ipsecif_internal_if);
406 if (m_ipif->sadb_x_ipsecif_outgoing_if[0])
407 printf("outgoing_if: %s ", m_ipif->sadb_x_ipsecif_outgoing_if);
408 if (m_ipif->sadb_x_ipsecif_ipsec_if[0])
409 printf("ipsec_if: %s ", m_ipif->sadb_x_ipsecif_ipsec_if);
410 printf("disabled: %d\n", m_ipif->sadb_x_ipsecif_init_disabled);
411 }
412
413 /* lifetime */
414 if (m_lftc != NULL) {
415 time_t tmp_time = time(0);
416
417 printf("\tcreated: %s",
418 str_time((long)m_lftc->sadb_lifetime_addtime));
419 printf("\tcurrent: %s\n", str_time(tmp_time));
420 printf("\tdiff: %lu(s)",
421 (u_long)(m_lftc->sadb_lifetime_addtime == 0 ?
422 0 : (tmp_time - m_lftc->sadb_lifetime_addtime)));
423
424 printf("\thard: %lu(s)",
425 (u_long)(m_lfth == NULL ?
426 0 : m_lfth->sadb_lifetime_addtime));
427 printf("\tsoft: %lu(s)\n",
428 (u_long)(m_lfts == NULL ?
429 0 : m_lfts->sadb_lifetime_addtime));
430
431 printf("\tlast: %s",
432 str_time((long)m_lftc->sadb_lifetime_usetime));
433 printf("\thard: %lu(s)",
434 (u_long)(m_lfth == NULL ?
435 0 : m_lfth->sadb_lifetime_usetime));
436 printf("\tsoft: %lu(s)\n",
437 (u_long)(m_lfts == NULL ?
438 0 : m_lfts->sadb_lifetime_usetime));
439
440 str_lifetime_byte(m_lftc, "current");
441 str_lifetime_byte(m_lfth, "hard");
442 str_lifetime_byte(m_lfts, "soft");
443 printf("\n");
444
445 printf("\tallocated: %lu",
446 (unsigned long)m_lftc->sadb_lifetime_allocations);
447 printf("\thard: %lu",
448 (u_long)(m_lfth == NULL ?
449 0 : m_lfth->sadb_lifetime_allocations));
450 printf("\tsoft: %lu\n",
451 (u_long)(m_lfts == NULL ?
452 0 : m_lfts->sadb_lifetime_allocations));
453 }
454
455 printf("\tsadb_seq=%lu pid=%lu ",
456 (u_long)m->sadb_msg_seq,
457 (u_long)m->sadb_msg_pid);
458
459 /* XXX DEBUG */
460 printf("refcnt=%u\n", m->sadb_msg_reserved);
461
462 return;
463 }
464
465 void
466 pfkey_spdump(m)
467 struct sadb_msg *m;
468 {
469 pfkey_spdump1(m, 0);
470 }
471
472 void
473 pfkey_spdump_withports(m)
474 struct sadb_msg *m;
475 {
476 pfkey_spdump1(m, 1);
477 }
478
479 static void
480 pfkey_dump_single_address (struct sadb_address *addr)
481 {
482 u_int16_t port = 0;
483 char pbuf[NI_MAXSERV];
484 struct sockaddr *sa;
485 sa = (void *)(addr + 1);
486 switch (sa->sa_family) {
487 case AF_INET:
488 case AF_INET6:
489 if (getnameinfo(sa, (socklen_t)sysdep_sa_len((struct sockaddr *)sa), NULL,
490 0, pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0)
491 port = 0; /*XXX*/
492 else
493 port = atoi(pbuf);
494 printf("%s%s", str_ipaddr(sa),
495 str_prefport((u_int)sa->sa_family,
496 (u_int)addr->sadb_address_prefixlen,
497 (u_int)port,
498 (u_int)addr->sadb_address_proto));
499 break;
500 default:
501 printf("unknown-af");
502 break;
503 }
504
505 }
506
507 static void
508 pfkey_spdump1(m, withports)
509 struct sadb_msg *m;
510 int withports;
511 {
512 char pbuf[NI_MAXSERV];
513 caddr_t mhp[SADB_EXT_MAX + 1];
514 struct sadb_address *m_saddr, *m_daddr;
515 struct sadb_address *m_saddr_s, *m_saddr_e, *m_daddr_s, *m_daddr_e;
516 #ifdef SADB_X_EXT_TAG
517 struct sadb_x_tag *m_tag;
518 #endif
519 struct sadb_x_policy *m_xpl;
520 struct sadb_lifetime *m_lftc = NULL, *m_lfth = NULL;
521 struct sadb_x_ipsecif *m_ipif = NULL;
522 struct sockaddr *sa;
523 u_int16_t sport = 0, dport = 0;
524
525 /* check pfkey message. */
526 if (pfkey_align(m, mhp)) {
527 printf("%s\n", ipsec_strerror());
528 return;
529 }
530 if (pfkey_check(mhp)) {
531 printf("%s\n", ipsec_strerror());
532 return;
533 }
534
535 m_saddr = (void *)mhp[SADB_EXT_ADDRESS_SRC];
536 m_daddr = (void *)mhp[SADB_EXT_ADDRESS_DST];
537 m_saddr_s = (void *)mhp[SADB_X_EXT_ADDR_RANGE_SRC_START];
538 m_saddr_e = (void *)mhp[SADB_X_EXT_ADDR_RANGE_SRC_END];
539 m_daddr_s = (void *)mhp[SADB_X_EXT_ADDR_RANGE_DST_START];
540 m_daddr_e = (void *)mhp[SADB_X_EXT_ADDR_RANGE_DST_END];
541 #ifdef SADB_X_EXT_TAG
542 m_tag = (void *)mhp[SADB_X_EXT_TAG];
543 #endif
544 m_xpl = (void *)mhp[SADB_X_EXT_POLICY];
545 m_lftc = (void *)mhp[SADB_EXT_LIFETIME_CURRENT];
546 m_lfth = (void *)mhp[SADB_EXT_LIFETIME_HARD];
547 m_ipif = (void *)mhp[SADB_X_EXT_IPSECIF];
548
549 if ((m_saddr || (m_saddr_s && m_saddr_e)) && (m_daddr || (m_daddr_s && m_daddr_e))) {
550 /* source address */
551 if (m_saddr_s && m_saddr_e) {
552 pfkey_dump_single_address(m_saddr_s);
553 printf("-");
554 pfkey_dump_single_address(m_saddr_e);
555 printf(" ");
556 } else if (m_saddr) {
557 sa = (void *)(m_saddr + 1);
558 switch (sa->sa_family) {
559 case AF_INET:
560 case AF_INET6:
561 if (getnameinfo(sa, (socklen_t)sysdep_sa_len((struct sockaddr *)sa), NULL,
562 0, pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0)
563 sport = 0; /*XXX*/
564 else
565 sport = atoi(pbuf);
566 printf("%s%s ", str_ipaddr(sa),
567 str_prefport((u_int)sa->sa_family,
568 (u_int)m_saddr->sadb_address_prefixlen,
569 (u_int)sport,
570 (u_int)m_saddr->sadb_address_proto));
571 break;
572 default:
573 printf("unknown-af ");
574 break;
575 }
576 }
577
578 /* destination address */
579 if (m_daddr_s && m_daddr_e) {
580 pfkey_dump_single_address(m_daddr_s);
581 printf("-");
582 pfkey_dump_single_address(m_daddr_e);
583 printf(" ");
584 } else if (m_daddr) {
585 sa = (void *)(m_daddr + 1);
586 switch (sa->sa_family) {
587 case AF_INET:
588 case AF_INET6:
589 if (getnameinfo(sa, (socklen_t)sysdep_sa_len((struct sockaddr *)sa), NULL,
590 0, pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0)
591 dport = 0; /*XXX*/
592 else
593 dport = atoi(pbuf);
594 printf("%s%s ", str_ipaddr(sa),
595 str_prefport((u_int)sa->sa_family,
596 (u_int)m_daddr->sadb_address_prefixlen,
597 (u_int)dport,
598 (u_int)m_daddr->sadb_address_proto));
599 break;
600 default:
601 printf("unknown-af ");
602 break;
603 }
604 }
605
606 /* upper layer protocol */
607 if (m_saddr && m_daddr) {
608 if (m_saddr->sadb_address_proto !=
609 m_daddr->sadb_address_proto) {
610 printf("upper layer protocol mismatched.\n");
611 return;
612 }
613 str_upperspec((u_int)m_saddr->sadb_address_proto, (u_int)sport,
614 (u_int)dport);
615 }
616 }
617 #ifdef SADB_X_EXT_TAG
618 else if (m_tag)
619 printf("tagged \"%s\" ", m_tag->sadb_x_tag_name);
620 #endif
621 else
622 printf("(no selector, probably per-socket policy) ");
623
624 /* policy */
625 {
626 char *d_xpl;
627
628 if (m_xpl == NULL) {
629 printf("no X_POLICY extension.\n");
630 return;
631 }
632 if (withports)
633 d_xpl = ipsec_dump_policy_withports(m_xpl, "\n\t");
634 else
635 d_xpl = ipsec_dump_policy((ipsec_policy_t)m_xpl, "\n\t");
636
637 if (!d_xpl)
638 printf("\n\tPolicy:[%s]\n", ipsec_strerror());
639 else {
640 /* dump SPD */
641 printf("\n\t%s\n", d_xpl);
642 free(d_xpl);
643 }
644 }
645
646 /* lifetime */
647 if (m_lftc) {
648 printf("\tcreated: %s ",
649 str_time((long)m_lftc->sadb_lifetime_addtime));
650 printf("lastused: %s\n",
651 str_time((long)m_lftc->sadb_lifetime_usetime));
652 }
653 if (m_lfth) {
654 printf("\tlifetime: %lu(s) ",
655 (u_long)m_lfth->sadb_lifetime_addtime);
656 printf("validtime: %lu(s)\n",
657 (u_long)m_lfth->sadb_lifetime_usetime);
658 }
659
660 if (m_ipif) {
661 printf("\t");
662 if (m_ipif->sadb_x_ipsecif_internal_if[0])
663 printf("internal_if: %s ", m_ipif->sadb_x_ipsecif_internal_if);
664 if (m_ipif->sadb_x_ipsecif_outgoing_if[0])
665 printf("outgoing_if: %s ", m_ipif->sadb_x_ipsecif_outgoing_if);
666 if (m_ipif->sadb_x_ipsecif_ipsec_if[0])
667 printf("ipsec_if: %s ", m_ipif->sadb_x_ipsecif_ipsec_if);
668 printf("disabled: %d\n", m_ipif->sadb_x_ipsecif_init_disabled);
669 }
670
671 printf("\tspid=%ld seq=%ld pid=%ld\n",
672 (u_long)m_xpl->sadb_x_policy_id,
673 (u_long)m->sadb_msg_seq,
674 (u_long)m->sadb_msg_pid);
675
676 /* XXX TEST */
677 printf("\trefcnt=%u\n", m->sadb_msg_reserved);
678
679 return;
680 }
681
682 /*
683 * set "ipaddress" to buffer.
684 */
685 static char *
686 str_ipaddr(sa)
687 struct sockaddr *sa;
688 {
689 static char buf[NI_MAXHOST];
690 const int niflag = NI_NUMERICHOST;
691
692 if (sa == NULL)
693 return "";
694
695 if (getnameinfo(sa, (socklen_t)sysdep_sa_len(sa), buf, sizeof(buf),
696 NULL, 0, niflag) == 0)
697 return buf;
698 return NULL;
699 }
700
701 /*
702 * set "port" to buffer.
703 */
704 static char *
705 str_ipport(sa)
706 struct sockaddr *sa;
707 {
708 static char buf[NI_MAXHOST];
709 const int niflag = NI_NUMERICSERV;
710
711 if (sa == NULL)
712 return "";
713
714 if (getnameinfo(sa, (socklen_t)sysdep_sa_len(sa), NULL, 0,
715 buf, sizeof(buf), niflag) == 0)
716 return buf;
717 return NULL;
718 }
719
720
721 /*
722 * set "/prefix[port number]" to buffer.
723 */
724 static char *
725 str_prefport(family, pref, port, ulp)
726 u_int family, pref, port, ulp;
727 {
728 static char buf[128];
729 char prefbuf[128];
730 char portbuf[128];
731 int plen;
732
733 switch (family) {
734 case AF_INET:
735 plen = sizeof(struct in_addr) << 3;
736 break;
737 case AF_INET6:
738 plen = sizeof(struct in6_addr) << 3;
739 break;
740 default:
741 return "?";
742 }
743
744 if (pref == plen)
745 prefbuf[0] = '\0';
746 else
747 snprintf(prefbuf, sizeof(prefbuf), "/%u", pref);
748
749 if (ulp == IPPROTO_ICMPV6)
750 memset(portbuf, 0, sizeof(portbuf));
751 else {
752 if (port == IPSEC_PORT_ANY)
753 snprintf(portbuf, sizeof(portbuf), "[%s]", "any");
754 else
755 snprintf(portbuf, sizeof(portbuf), "[%u]", port);
756 }
757
758 snprintf(buf, sizeof(buf), "%s%s", prefbuf, portbuf);
759
760 return buf;
761 }
762
763 static void
764 str_upperspec(ulp, p1, p2)
765 u_int ulp, p1, p2;
766 {
767 if (ulp == IPSEC_ULPROTO_ANY)
768 printf("any");
769 else if (ulp == IPPROTO_ICMPV6) {
770 printf("icmp6");
771 if (!(p1 == IPSEC_PORT_ANY && p2 == IPSEC_PORT_ANY))
772 printf(" %u,%u", p1, p2);
773 } else {
774 struct protoent *ent;
775
776 switch (ulp) {
777 case IPPROTO_IPV4:
778 printf("ip4");
779 break;
780 default:
781 ent = getprotobynumber((int)ulp);
782 if (ent)
783 printf("%s", ent->p_name);
784 else
785 printf("%u", ulp);
786
787 endprotoent();
788 break;
789 }
790 }
791 }
792
793 /*
794 * set "Mon Day Time Year" to buffer
795 */
796 static char *
797 str_time(t)
798 time_t t;
799 {
800 static char buf[128];
801
802 if (t == 0) {
803 int i = 0;
804 for (;i < 20;) buf[i++] = ' ';
805 } else {
806 char *t0;
807 t0 = ctime(&t);
808 memcpy(buf, t0 + 4, 20);
809 }
810
811 buf[20] = '\0';
812
813 return(buf);
814 }
815
816 static void
817 str_lifetime_byte(x, str)
818 struct sadb_lifetime *x;
819 char *str;
820 {
821 double y;
822 char *unit;
823 int w;
824
825 if (x == NULL) {
826 printf("\t%s: 0(bytes)", str);
827 return;
828 }
829
830 #if 0
831 if ((x->sadb_lifetime_bytes) / 1024 / 1024) {
832 y = (x->sadb_lifetime_bytes) * 1.0 / 1024 / 1024;
833 unit = "M";
834 w = 1;
835 } else if ((x->sadb_lifetime_bytes) / 1024) {
836 y = (x->sadb_lifetime_bytes) * 1.0 / 1024;
837 unit = "K";
838 w = 1;
839 } else {
840 y = (x->sadb_lifetime_bytes) * 1.0;
841 unit = "";
842 w = 0;
843 }
844 #else
845 y = (x->sadb_lifetime_bytes) * 1.0;
846 unit = "";
847 w = 0;
848 #endif
849 printf("\t%s: %.*f(%sbytes)", str, w, y, unit);
850 }