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