]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libipsec/pfkey_dump.c
Add UPDATING entries and bump version.
[FreeBSD/FreeBSD.git] / lib / libipsec / pfkey_dump.c
1 /*      $KAME: pfkey_dump.c,v 1.45 2003/09/08 10:14:56 itojun Exp $     */
2
3 /*-
4  * SPDX-License-Identifier: BSD-3-Clause
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 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <sys/socket.h>
40 #include <net/if.h>
41 #include <net/pfkeyv2.h>
42 #include <netipsec/ipsec.h>
43 #include <netipsec/key_var.h>
44 #include <netipsec/key_debug.h>
45
46 #include <netinet/in.h>
47 #include <arpa/inet.h>
48
49 #include <stdlib.h>
50 #include <unistd.h>
51 #include <stdio.h>
52 #include <string.h>
53 #include <time.h>
54 #include <netdb.h>
55
56 #include "ipsec_strerror.h"
57 #include "libpfkey.h"
58
59 /* cope with old kame headers - ugly */
60 #ifndef SADB_X_AALG_MD5
61 #define SADB_X_AALG_MD5         SADB_AALG_MD5   
62 #endif
63 #ifndef SADB_X_AALG_SHA
64 #define SADB_X_AALG_SHA         SADB_AALG_SHA
65 #endif
66 #ifndef SADB_X_AALG_NULL
67 #define SADB_X_AALG_NULL        SADB_AALG_NULL
68 #endif
69
70 #ifndef SADB_X_EALG_BLOWFISHCBC
71 #define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC
72 #endif
73 #ifndef SADB_X_EALG_CAST128CBC
74 #define SADB_X_EALG_CAST128CBC  SADB_EALG_CAST128CBC
75 #endif
76 #ifndef SADB_X_EALG_RC5CBC
77 #ifdef SADB_EALG_RC5CBC
78 #define SADB_X_EALG_RC5CBC      SADB_EALG_RC5CBC
79 #endif
80 #endif
81
82 #define GETMSGSTR(str, num) \
83 do { \
84         if (sizeof((str)[0]) == 0 \
85          || num >= sizeof(str)/sizeof((str)[0])) \
86                 printf("%u ", (num)); \
87         else if (strlen((str)[(num)]) == 0) \
88                 printf("%u ", (num)); \
89         else \
90                 printf("%s ", (str)[(num)]); \
91 } while (0)
92
93 #define GETMSGV2S(v2s, num) \
94 do { \
95         struct val2str *p;  \
96         for (p = (v2s); p && p->str; p++) { \
97                 if (p->val == (num)) \
98                         break; \
99         } \
100         if (p && p->str) \
101                 printf("%s ", p->str); \
102         else \
103                 printf("%u ", (num)); \
104 } while (0)
105
106 static char *str_ipaddr(struct sockaddr *);
107 static char *str_prefport(u_int, u_int, u_int, u_int);
108 static void str_upperspec(u_int, u_int, u_int);
109 static char *str_time(time_t);
110 static void str_lifetime_byte(struct sadb_lifetime *, char *);
111
112 struct val2str {
113         int val;
114         const char *str;
115 };
116
117 /*
118  * Must to be re-written about following strings.
119  */
120 static char *str_satype[] = {
121         "unspec",
122         "unknown",
123         "ah",
124         "esp",
125         "unknown",
126         "rsvp",
127         "ospfv2",
128         "ripv2",
129         "mip",
130         "ipcomp",
131         "policy",
132         "tcp"
133 };
134
135 static char *str_mode[] = {
136         "any",
137         "transport",
138         "tunnel",
139 };
140
141 static char *str_state[] = {
142         "larval",
143         "mature",
144         "dying",
145         "dead",
146 };
147
148 static struct val2str str_alg_auth[] = {
149         { SADB_AALG_NONE, "none", },
150         { SADB_AALG_MD5HMAC, "hmac-md5", },
151         { SADB_AALG_SHA1HMAC, "hmac-sha1", },
152         { SADB_X_AALG_MD5, "md5", },
153         { SADB_X_AALG_SHA, "sha", },
154         { SADB_X_AALG_NULL, "null", },
155         { SADB_X_AALG_TCP_MD5, "tcp-md5", },
156 #ifdef SADB_X_AALG_SHA2_256
157         { SADB_X_AALG_SHA2_256, "hmac-sha2-256", },
158 #endif
159 #ifdef SADB_X_AALG_SHA2_384
160         { SADB_X_AALG_SHA2_384, "hmac-sha2-384", },
161 #endif
162 #ifdef SADB_X_AALG_SHA2_512
163         { SADB_X_AALG_SHA2_512, "hmac-sha2-512", },
164 #endif
165 #ifdef SADB_X_AALG_RIPEMD160HMAC
166         { SADB_X_AALG_RIPEMD160HMAC, "hmac-ripemd160", },
167 #endif
168 #ifdef SADB_X_AALG_AES_XCBC_MAC
169         { SADB_X_AALG_AES_XCBC_MAC, "aes-xcbc-mac", },
170 #endif
171         { -1, NULL, },
172 };
173
174 static struct val2str str_alg_enc[] = {
175         { SADB_EALG_NONE, "none", },
176         { SADB_EALG_DESCBC, "des-cbc", },
177         { SADB_EALG_3DESCBC, "3des-cbc", },
178         { SADB_EALG_NULL, "null", },
179 #ifdef SADB_X_EALG_RC5CBC
180         { SADB_X_EALG_RC5CBC, "rc5-cbc", },
181 #endif
182         { SADB_X_EALG_CAST128CBC, "cast128-cbc", },
183         { SADB_X_EALG_BLOWFISHCBC, "blowfish-cbc", },
184 #ifdef SADB_X_EALG_RIJNDAELCBC
185         { SADB_X_EALG_RIJNDAELCBC, "rijndael-cbc", },
186 #endif
187 #ifdef SADB_X_EALG_TWOFISHCBC
188         { SADB_X_EALG_TWOFISHCBC, "twofish-cbc", },
189 #endif
190 #ifdef SADB_X_EALG_AESCTR
191         { SADB_X_EALG_AESCTR, "aes-ctr", },
192 #endif
193 #ifdef SADB_X_EALG_AESGCM16
194         { SADB_X_EALG_AESGCM16, "aes-gcm-16", },
195 #endif
196 #ifdef SADB_X_EALG_CAMELLIACBC
197         { SADB_X_EALG_CAMELLIACBC, "camellia-cbc", },
198 #endif
199         { -1, NULL, },
200 };
201
202 static struct val2str str_alg_comp[] = {
203         { SADB_X_CALG_NONE, "none", },
204         { SADB_X_CALG_OUI, "oui", },
205         { SADB_X_CALG_DEFLATE, "deflate", },
206         { SADB_X_CALG_LZS, "lzs", },
207         { -1, NULL, },
208 };
209
210 static struct val2str str_sp_scope[] = {
211         { IPSEC_POLICYSCOPE_GLOBAL, "global" },
212         { IPSEC_POLICYSCOPE_IFNET, "ifnet" },
213         { IPSEC_POLICYSCOPE_PCB, "pcb"},
214         { -1, NULL },
215 };
216
217 /*
218  * dump SADB_MSG formated.  For debugging, you should use kdebug_sadb().
219  */
220 void
221 pfkey_sadump(m)
222         struct sadb_msg *m;
223 {
224         caddr_t mhp[SADB_EXT_MAX + 1];
225         struct sadb_sa *m_sa;
226         struct sadb_x_sa2 *m_sa2;
227         struct sadb_lifetime *m_lftc, *m_lfth, *m_lfts;
228         struct sadb_address *m_saddr, *m_daddr, *m_paddr;
229         struct sadb_key *m_auth, *m_enc;
230         struct sadb_ident *m_sid, *m_did;
231         struct sadb_sens *m_sens;
232         struct sadb_x_sa_replay *m_sa_replay;
233         struct sadb_x_nat_t_type *natt_type;
234         struct sadb_x_nat_t_port *natt_sport, *natt_dport;
235         struct sadb_address *natt_oai, *natt_oar;
236
237         /* check pfkey message. */
238         if (pfkey_align(m, mhp)) {
239                 printf("%s\n", ipsec_strerror());
240                 return;
241         }
242         if (pfkey_check(mhp)) {
243                 printf("%s\n", ipsec_strerror());
244                 return;
245         }
246
247         m_sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
248         m_sa2 = (struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2];
249         m_lftc = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_CURRENT];
250         m_lfth = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD];
251         m_lfts = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_SOFT];
252         m_saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
253         m_daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
254         m_paddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_PROXY];
255         m_auth = (struct sadb_key *)mhp[SADB_EXT_KEY_AUTH];
256         m_enc = (struct sadb_key *)mhp[SADB_EXT_KEY_ENCRYPT];
257         m_sid = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_SRC];
258         m_did = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_DST];
259         m_sens = (struct sadb_sens *)mhp[SADB_EXT_SENSITIVITY];
260         m_sa_replay = (struct sadb_x_sa_replay *)mhp[SADB_X_EXT_SA_REPLAY];
261         natt_type = (struct sadb_x_nat_t_type *)mhp[SADB_X_EXT_NAT_T_TYPE];
262         natt_sport = (struct sadb_x_nat_t_port *)mhp[SADB_X_EXT_NAT_T_SPORT];
263         natt_dport = (struct sadb_x_nat_t_port *)mhp[SADB_X_EXT_NAT_T_DPORT];
264         natt_oai = (struct sadb_address *)mhp[SADB_X_EXT_NAT_T_OAI];
265         natt_oar = (struct sadb_address *)mhp[SADB_X_EXT_NAT_T_OAR];
266
267
268         /* source address */
269         if (m_saddr == NULL) {
270                 printf("no ADDRESS_SRC extension.\n");
271                 return;
272         }
273         printf("%s", str_ipaddr((struct sockaddr *)(m_saddr + 1)));
274         if (natt_type != NULL && natt_sport != NULL)
275                 printf("[%u]", ntohs(natt_sport->sadb_x_nat_t_port_port));
276
277         /* destination address */
278         if (m_daddr == NULL) {
279                 printf("\nno ADDRESS_DST extension.\n");
280                 return;
281         }
282         printf(" %s", str_ipaddr((struct sockaddr *)(m_daddr + 1)));
283         if (natt_type != NULL && natt_dport != NULL)
284                 printf("[%u]", ntohs(natt_dport->sadb_x_nat_t_port_port));
285
286         /* SA type */
287         if (m_sa == NULL) {
288                 printf("\nno SA extension.\n");
289                 return;
290         }
291         if (m_sa2 == NULL) {
292                 printf("\nno SA2 extension.\n");
293                 return;
294         }
295         printf("\n\t");
296
297         if (m->sadb_msg_satype == SADB_SATYPE_ESP && natt_type != NULL)
298                 printf("esp-udp ");
299         else
300                 GETMSGSTR(str_satype, m->sadb_msg_satype);
301
302         printf("mode=");
303         GETMSGSTR(str_mode, m_sa2->sadb_x_sa2_mode);
304
305         printf("spi=%u(0x%08x) reqid=%u(0x%08x)\n",
306                 (u_int32_t)ntohl(m_sa->sadb_sa_spi),
307                 (u_int32_t)ntohl(m_sa->sadb_sa_spi),
308                 (u_int32_t)m_sa2->sadb_x_sa2_reqid,
309                 (u_int32_t)m_sa2->sadb_x_sa2_reqid);
310
311         /* other NAT-T information */
312         if (natt_type != NULL && (natt_oai != NULL || natt_oar != NULL)) {
313                 printf("\tNAT:");
314                 if (natt_oai != NULL)
315                         printf(" OAI=%s",
316                             str_ipaddr((struct sockaddr *)(natt_oai + 1)));
317                 if (natt_oar != NULL)
318                         printf(" OAR=%s",
319                             str_ipaddr((struct sockaddr *)(natt_oar + 1)));
320                 printf("\n");
321         }
322
323         /* encryption key */
324         if (m->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) {
325                 printf("\tC: ");
326                 GETMSGV2S(str_alg_comp, m_sa->sadb_sa_encrypt);
327         } else if (m->sadb_msg_satype == SADB_SATYPE_ESP) {
328                 if (m_enc != NULL) {
329                         printf("\tE: ");
330                         GETMSGV2S(str_alg_enc, m_sa->sadb_sa_encrypt);
331                         ipsec_hexdump((caddr_t)m_enc + sizeof(*m_enc),
332                                       m_enc->sadb_key_bits / 8);
333                         printf("\n");
334                 }
335         }
336
337         /* authentication key */
338         if (m_auth != NULL) {
339                 printf("\tA: ");
340                 GETMSGV2S(str_alg_auth, m_sa->sadb_sa_auth);
341                 ipsec_hexdump((caddr_t)m_auth + sizeof(*m_auth),
342                               m_auth->sadb_key_bits / 8);
343                 printf("\n");
344         }
345
346         /* replay windoe size & flags */
347         printf("\tseq=0x%08x replay=%u flags=0x%08x ",
348                 m_sa2->sadb_x_sa2_sequence,
349                 m_sa_replay ? (m_sa_replay->sadb_x_sa_replay_replay >> 3) :
350                         m_sa->sadb_sa_replay,
351                 m_sa->sadb_sa_flags);
352
353         /* state */
354         printf("state=");
355         GETMSGSTR(str_state, m_sa->sadb_sa_state);
356         printf("\n");
357
358         /* lifetime */
359         if (m_lftc != NULL) {
360                 time_t tmp_time = time(0);
361
362                 printf("\tcreated: %s",
363                         str_time(m_lftc->sadb_lifetime_addtime));
364                 printf("\tcurrent: %s\n", str_time(tmp_time));
365                 printf("\tdiff: %lu(s)",
366                         (u_long)(m_lftc->sadb_lifetime_addtime == 0 ?
367                         0 : (tmp_time - m_lftc->sadb_lifetime_addtime)));
368
369                 printf("\thard: %lu(s)",
370                         (u_long)(m_lfth == NULL ?
371                         0 : m_lfth->sadb_lifetime_addtime));
372                 printf("\tsoft: %lu(s)\n",
373                         (u_long)(m_lfts == NULL ?
374                         0 : m_lfts->sadb_lifetime_addtime));
375
376                 printf("\tlast: %s",
377                         str_time(m_lftc->sadb_lifetime_usetime));
378                 printf("\thard: %lu(s)",
379                         (u_long)(m_lfth == NULL ?
380                         0 : m_lfth->sadb_lifetime_usetime));
381                 printf("\tsoft: %lu(s)\n",
382                         (u_long)(m_lfts == NULL ?
383                         0 : m_lfts->sadb_lifetime_usetime));
384
385                 str_lifetime_byte(m_lftc, "current");
386                 str_lifetime_byte(m_lfth, "hard");
387                 str_lifetime_byte(m_lfts, "soft");
388                 printf("\n");
389
390                 printf("\tallocated: %lu",
391                         (unsigned long)m_lftc->sadb_lifetime_allocations);
392                 printf("\thard: %lu",
393                         (u_long)(m_lfth == NULL ?
394                         0 : m_lfth->sadb_lifetime_allocations));
395                 printf("\tsoft: %lu\n",
396                         (u_long)(m_lfts == NULL ?
397                         0 : m_lfts->sadb_lifetime_allocations));
398         }
399
400         printf("\tsadb_seq=%lu pid=%lu ",
401                 (u_long)m->sadb_msg_seq,
402                 (u_long)m->sadb_msg_pid);
403
404         /* XXX DEBUG */
405         printf("refcnt=%u\n", m->sadb_msg_reserved);
406
407         return;
408 }
409
410 void
411 pfkey_spdump(struct sadb_msg *m)
412 {
413         char pbuf[NI_MAXSERV];
414         caddr_t mhp[SADB_EXT_MAX + 1];
415         struct sadb_address *m_saddr, *m_daddr;
416         struct sadb_x_policy *m_xpl;
417         struct sadb_lifetime *m_lftc = NULL, *m_lfth = NULL;
418         struct sockaddr *sa;
419         u_int16_t sport = 0, dport = 0;
420
421         /* check pfkey message. */
422         if (pfkey_align(m, mhp)) {
423                 printf("%s\n", ipsec_strerror());
424                 return;
425         }
426         if (pfkey_check(mhp)) {
427                 printf("%s\n", ipsec_strerror());
428                 return;
429         }
430
431         m_saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
432         m_daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
433         m_xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
434         m_lftc = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_CURRENT];
435         m_lfth = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD];
436
437         if (m_saddr && m_daddr) {
438                 /* source address */
439                 sa = (struct sockaddr *)(m_saddr + 1);
440                 switch (sa->sa_family) {
441                 case AF_INET:
442                 case AF_INET6:
443                         if (getnameinfo(sa, sa->sa_len, NULL, 0,
444                             pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0)
445                                 sport = 0;      /*XXX*/
446                         else
447                                 sport = atoi(pbuf);
448                         printf("%s%s ", str_ipaddr(sa),
449                                 str_prefport(sa->sa_family,
450                                     m_saddr->sadb_address_prefixlen, sport,
451                                     m_saddr->sadb_address_proto));
452                         break;
453                 default:
454                         printf("unknown-af ");
455                         break;
456                 }
457
458                 /* destination address */
459                 sa = (struct sockaddr *)(m_daddr + 1);
460                 switch (sa->sa_family) {
461                 case AF_INET:
462                 case AF_INET6:
463                         if (getnameinfo(sa, sa->sa_len, NULL, 0,
464                             pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0)
465                                 dport = 0;      /*XXX*/
466                         else
467                                 dport = atoi(pbuf);
468                         printf("%s%s ", str_ipaddr(sa),
469                                 str_prefport(sa->sa_family,
470                                     m_daddr->sadb_address_prefixlen, dport,
471                                     m_saddr->sadb_address_proto));
472                         break;
473                 default:
474                         printf("unknown-af ");
475                         break;
476                 }
477
478                 /* upper layer protocol */
479                 if (m_saddr->sadb_address_proto !=
480                     m_daddr->sadb_address_proto) {
481                         printf("upper layer protocol mismatched.\n");
482                         return;
483                 }
484                 str_upperspec(m_saddr->sadb_address_proto, sport, dport);
485         }
486         else
487                 printf("(no selector, probably per-socket policy) ");
488
489         /* policy */
490     {
491         char *d_xpl;
492
493         if (m_xpl == NULL) {
494                 printf("no X_POLICY extension.\n");
495                 return;
496         }
497         d_xpl = ipsec_dump_policy((char *)m_xpl, "\n\t");
498
499         /* dump SPD */
500         printf("\n\t%s\n", d_xpl);
501         free(d_xpl);
502     }
503
504         /* lifetime */
505         if (m_lftc) {
506                 printf("\tcreated: %s  ",
507                         str_time(m_lftc->sadb_lifetime_addtime));
508                 printf("lastused: %s\n",
509                         str_time(m_lftc->sadb_lifetime_usetime));
510         }
511         if (m_lfth) {
512                 printf("\tlifetime: %lu(s) ",
513                         (u_long)m_lfth->sadb_lifetime_addtime);
514                 printf("validtime: %lu(s)\n",
515                         (u_long)m_lfth->sadb_lifetime_usetime);
516         }
517
518
519         printf("\tspid=%ld seq=%ld pid=%ld scope=",
520                 (u_long)m_xpl->sadb_x_policy_id,
521                 (u_long)m->sadb_msg_seq,
522                 (u_long)m->sadb_msg_pid);
523         GETMSGV2S(str_sp_scope, m_xpl->sadb_x_policy_scope);
524         if (m_xpl->sadb_x_policy_scope == IPSEC_POLICYSCOPE_IFNET &&
525             if_indextoname(m_xpl->sadb_x_policy_ifindex, pbuf) != NULL)
526                 printf("ifname=%s", pbuf);
527         printf("\n");
528
529         /* XXX TEST */
530         printf("\trefcnt=%u\n", m->sadb_msg_reserved);
531
532         return;
533 }
534
535 /*
536  * set "ipaddress" to buffer.
537  */
538 static char *
539 str_ipaddr(sa)
540         struct sockaddr *sa;
541 {
542         static char buf[NI_MAXHOST];
543         const int niflag = NI_NUMERICHOST;
544
545         if (sa == NULL)
546                 return "";
547
548         if (getnameinfo(sa, sa->sa_len, buf, sizeof(buf), NULL, 0, niflag) == 0)
549                 return buf;
550         return NULL;
551 }
552
553 /*
554  * set "/prefix[port number]" to buffer.
555  */
556 static char *
557 str_prefport(family, pref, port, ulp)
558         u_int family, pref, port, ulp;
559 {
560         static char buf[128];
561         char prefbuf[128];
562         char portbuf[128];
563         int plen;
564
565         switch (family) {
566         case AF_INET:
567                 plen = sizeof(struct in_addr) << 3;
568                 break;
569         case AF_INET6:
570                 plen = sizeof(struct in6_addr) << 3;
571                 break;
572         default:
573                 return "?";
574         }
575
576         if (pref == plen)
577                 prefbuf[0] = '\0';
578         else
579                 snprintf(prefbuf, sizeof(prefbuf), "/%u", pref);
580
581         if (ulp == IPPROTO_ICMPV6)
582                 memset(portbuf, 0, sizeof(portbuf));
583         else {
584                 if (port == IPSEC_PORT_ANY)
585                         snprintf(portbuf, sizeof(portbuf), "[%s]", "any");
586                 else
587                         snprintf(portbuf, sizeof(portbuf), "[%u]", port);
588         }
589
590         snprintf(buf, sizeof(buf), "%s%s", prefbuf, portbuf);
591
592         return buf;
593 }
594
595 static void
596 str_upperspec(ulp, p1, p2)
597         u_int ulp, p1, p2;
598 {
599         if (ulp == IPSEC_ULPROTO_ANY)
600                 printf("any");
601         else if (ulp == IPPROTO_ICMPV6) {
602                 printf("icmp6");
603                 if (!(p1 == IPSEC_PORT_ANY && p2 == IPSEC_PORT_ANY))
604                         printf(" %u,%u", p1, p2);
605         } else {
606                 struct protoent *ent;
607
608                 switch (ulp) {
609                 case IPPROTO_IPV4:
610                         printf("ip4");
611                         break;
612                 default:
613                         ent = getprotobynumber(ulp);
614                         if (ent)
615                                 printf("%s", ent->p_name);
616                         else
617                                 printf("%u", ulp);
618
619                         endprotoent();
620                         break;
621                 }
622         }
623 }
624
625 /*
626  * set "Mon Day Time Year" to buffer
627  */
628 static char *
629 str_time(t)
630         time_t t;
631 {
632         static char buf[128];
633
634         if (t == 0) {
635                 int i = 0;
636                 for (;i < 20;) buf[i++] = ' ';
637         } else {
638                 char *t0;
639                 t0 = ctime(&t);
640                 memcpy(buf, t0 + 4, 20);
641         }
642
643         buf[20] = '\0';
644
645         return(buf);
646 }
647
648 static void
649 str_lifetime_byte(x, str)
650         struct sadb_lifetime *x;
651         char *str;
652 {
653         double y;
654         char *unit;
655         int w;
656
657         if (x == NULL) {
658                 printf("\t%s: 0(bytes)", str);
659                 return;
660         }
661
662 #if 0
663         if ((x->sadb_lifetime_bytes) / 1024 / 1024) {
664                 y = (x->sadb_lifetime_bytes) * 1.0 / 1024 / 1024;
665                 unit = "M";
666                 w = 1;
667         } else if ((x->sadb_lifetime_bytes) / 1024) {
668                 y = (x->sadb_lifetime_bytes) * 1.0 / 1024;
669                 unit = "K";
670                 w = 1;
671         } else {
672                 y = (x->sadb_lifetime_bytes) * 1.0;
673                 unit = "";
674                 w = 0;
675         }
676 #else
677         y = (x->sadb_lifetime_bytes) * 1.0;
678         unit = "";
679         w = 0;
680 #endif
681         printf("\t%s: %.*f(%sbytes)", str, w, y, unit);
682 }