source: rtems-libbsd/ipsec-tools/src/setkey/setkey.c @ ff36f5e

5-freebsd-12
Last change on this file since ff36f5e was ff36f5e, checked in by Christian Mauderer <christian.mauderer@…>, on May 30, 2018 at 12:27:35 PM

Import ipsec-tools 0.8.2.

Import unchanged ipsec-tools sources in the release version 0.8.2. The
homepage of ipsec-tools is http://ipsec-tools.sourceforge.net/. The
sources can be obtained from there.

  • Property mode set to 100644
File size: 21.2 KB
Line 
1/*      $NetBSD: setkey.c,v 1.14 2009/08/06 04:44:43 tteras Exp $       */
2
3/*      $KAME: setkey.c,v 1.36 2003/09/24 23:52:51 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 <sys/time.h>
42#include <sys/stat.h>
43#include <sys/sysctl.h>
44#include <err.h>
45#include <netinet/in.h>
46#include <net/pfkeyv2.h>
47#include PATH_IPSEC_H
48
49#include <stdio.h>
50#include <stdlib.h>
51#include <limits.h>
52#include <string.h>
53#include <ctype.h>
54#include <unistd.h>
55#include <errno.h>
56#include <netdb.h>
57#include <fcntl.h>
58#include <dirent.h>
59#include <time.h>
60
61#ifdef HAVE_READLINE
62#include <readline/readline.h>
63#include <readline/history.h>
64#endif
65
66#include "config.h"
67#include "libpfkey.h"
68#include "package_version.h"
69#define extern /* so that variables in extern.h are not extern... */
70#include "extern.h"
71
72#define strlcpy(d,s,l) (strncpy(d,s,l), (d)[(l)-1] = '\0')
73
74void usage __P((int));
75int main __P((int, char **));
76int get_supported __P((void));
77void sendkeyshort __P((u_int));
78void promisc __P((void));
79int postproc __P((struct sadb_msg *, int));
80int verifypriority __P((struct sadb_msg *m));
81int fileproc __P((const char *));
82const char *numstr __P((int));
83void shortdump_hdr __P((void));
84void shortdump __P((struct sadb_msg *));
85static void printdate __P((void));
86static int32_t gmt2local __P((time_t));
87void stdin_loop __P((void));
88
89#define MODE_SCRIPT     1
90#define MODE_CMDDUMP    2
91#define MODE_CMDFLUSH   3
92#define MODE_PROMISC    4
93#define MODE_STDIN      5
94
95int so;
96
97int f_forever = 0;
98int f_all = 0;
99int f_verbose = 0;
100int f_mode = 0;
101int f_cmddump = 0;
102int f_policy = 0;
103int f_hexdump = 0;
104int f_tflag = 0;
105int f_notreally = 0;
106int f_withports = 0;
107#ifdef HAVE_POLICY_FWD
108int f_rfcmode = 1;
109#define RK_OPTS "rk"
110#else
111int f_rkwarn = 0;
112#define RK_OPTS ""
113static void rkwarn(void);
114static void
115rkwarn(void)
116{
117        if (!f_rkwarn) {
118                f_rkwarn = 1;
119                printf("warning: -r and -k options are not supported in this environment\n");
120        }
121}
122
123#endif
124static time_t thiszone;
125
126void
127usage(int only_version)
128{
129        printf("setkey @(#) %s (%s)\n", TOP_PACKAGE_STRING, TOP_PACKAGE_URL); 
130        if (! only_version) {
131                printf("usage: setkey [-v" RK_OPTS "] file ...\n");
132                printf("       setkey [-nv" RK_OPTS "] -c\n");
133                printf("       setkey [-nv" RK_OPTS "] -f filename\n");
134                printf("       setkey [-Palpv" RK_OPTS "] -D\n");
135                printf("       setkey [-Pv] -F\n");
136                printf("       setkey [-H] -x\n");
137                printf("       setkey [-V] [-h]\n");
138        }
139        exit(1);
140}
141
142int
143main(argc, argv)
144        int argc;
145        char **argv;
146{
147        FILE *fp = stdin;
148        int c;
149
150        if (argc == 1) {
151                usage(0);
152                /* NOTREACHED */
153        }
154
155        thiszone = gmt2local(0);
156
157        while ((c = getopt(argc, argv, "acdf:HlnvxDFPphVrk?")) != -1) {
158                switch (c) {
159                case 'c':
160                        f_mode = MODE_STDIN;
161#ifdef HAVE_READLINE
162                        /* disable filename completion */
163                        rl_bind_key('\t', rl_insert);
164#endif
165                        break;
166                case 'f':
167                        f_mode = MODE_SCRIPT;
168                        if ((fp = fopen(optarg, "r")) == NULL) {
169                                err(1, "fopen");
170                                /*NOTREACHED*/
171                        }
172                        break;
173                case 'D':
174                        f_mode = MODE_CMDDUMP;
175                        break;
176                case 'F':
177                        f_mode = MODE_CMDFLUSH;
178                        break;
179                case 'a':
180                        f_all = 1;
181                        break;
182                case 'l':
183                        f_forever = 1;
184                        break;
185                case 'n':
186                        f_notreally = 1;
187                        break;
188#ifdef __NetBSD__
189                case 'h':
190#endif
191                case 'H':
192                        f_hexdump = 1;
193                        break;
194                case 'x':
195                        f_mode = MODE_PROMISC;
196                        f_tflag++;
197                        break;
198                case 'P':
199                        f_policy = 1;
200                        break;
201                case 'p':
202                        f_withports = 1;
203                        break;
204                case 'v':
205                        f_verbose = 1;
206                        break;
207                case 'r':
208#ifdef HAVE_POLICY_FWD
209                        f_rfcmode = 1;
210#else
211                        rkwarn();
212#endif
213                        break;
214                case 'k':
215#ifdef HAVE_POLICY_FWD
216                        f_rfcmode = 0;
217#else
218                        rkwarn();
219#endif
220                        break;
221                case 'V':
222                        usage(1);
223                        break;
224                        /*NOTREACHED*/
225#ifndef __NetBSD__
226                case 'h':
227#endif
228                case '?':
229                default:
230                        usage(0);
231                        /*NOTREACHED*/
232                }
233        }
234
235        argc -= optind;
236        argv += optind;
237
238        if (argc > 0) {
239                while (argc--)
240                        if (fileproc(*argv++) < 0) {
241                                err(1, "%s", argv[-1]);
242                                /*NOTREACHED*/
243                        }
244                exit(0);
245        }
246
247        so = pfkey_open();
248        if (so < 0) {
249                perror("pfkey_open");
250                exit(1);
251        }
252
253        switch (f_mode) {
254        case MODE_CMDDUMP:
255                sendkeyshort(f_policy ? SADB_X_SPDDUMP : SADB_DUMP);
256                break;
257        case MODE_CMDFLUSH:
258                sendkeyshort(f_policy ? SADB_X_SPDFLUSH: SADB_FLUSH);
259                break;
260        case MODE_SCRIPT:
261                if (get_supported() < 0) {
262                        errx(1, "%s", ipsec_strerror());
263                        /*NOTREACHED*/
264                }
265                if (parse(&fp))
266                        exit (1);
267                break;
268        case MODE_STDIN:
269                if (get_supported() < 0) {
270                        errx(1, "%s", ipsec_strerror());
271                        /*NOTREACHED*/
272                }
273                stdin_loop();
274                break;
275        case MODE_PROMISC:
276                promisc();
277                /*NOTREACHED*/
278        default:
279                usage(0);
280                /*NOTREACHED*/
281        }
282
283        exit(0);
284}
285
286int
287get_supported()
288{
289
290        if (pfkey_send_register(so, SADB_SATYPE_UNSPEC) < 0)
291                return -1;
292
293        if (pfkey_recv_register(so) < 0)
294                return -1;
295
296        return (0);
297}
298
299void
300stdin_loop()
301{
302        char line[1024], *semicolon, *comment;
303        size_t linelen = 0;
304       
305        memset (line, 0, sizeof(line));
306
307        parse_init();
308        while (1) {
309#ifdef HAVE_READLINE
310                char *rbuf;
311                rbuf = readline ("");
312                if (! rbuf)
313                        break;
314#else
315                char rbuf[1024];
316                rbuf[0] = '\0';
317                if (fgets(rbuf, sizeof(rbuf), stdin) == NULL)
318                        break;
319                if (rbuf[strlen(rbuf)-1] == '\n')
320                        rbuf[strlen(rbuf)-1] = '\0';
321#endif
322                comment = strchr(rbuf, '#');
323                if (comment)
324                        *comment = '\0';
325
326                if (!rbuf[0])
327                        continue;
328
329                linelen += snprintf (&line[linelen], sizeof(line) - linelen,
330                                     "%s%s", linelen > 0 ? " " : "", rbuf);
331
332                semicolon = strchr(line, ';');
333                while (semicolon) {
334                        char saved_char = *++semicolon;
335                        *semicolon = '\0';
336#ifdef HAVE_READLINE
337                        add_history (line);
338#endif
339
340#ifdef HAVE_PFKEY_POLICY_PRIORITY
341                        last_msg_type = -1;  /* invalid message type */
342#endif
343
344                        parse_string (line);
345                        if (exit_now)
346                                return;
347                        if (saved_char) {
348                                *semicolon = saved_char;
349                                linelen = strlen (semicolon);
350                                memmove (line, semicolon, linelen + 1);
351                                semicolon = strchr(line, ';');
352                        }
353                        else {
354                                semicolon = NULL;
355                                linelen = 0;
356                        }
357                }
358        }
359}
360
361void
362sendkeyshort(type)
363        u_int type;
364{
365        struct sadb_msg msg;
366
367        msg.sadb_msg_version = PF_KEY_V2;
368        msg.sadb_msg_type = type;
369        msg.sadb_msg_errno = 0;
370        msg.sadb_msg_satype = SADB_SATYPE_UNSPEC;
371        msg.sadb_msg_len = PFKEY_UNIT64(sizeof(msg));
372        msg.sadb_msg_reserved = 0;
373        msg.sadb_msg_seq = 0;
374        msg.sadb_msg_pid = getpid();
375
376        sendkeymsg((char *)&msg, sizeof(msg));
377
378        return;
379}
380
381void
382promisc()
383{
384        struct sadb_msg msg;
385        u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */
386        ssize_t l;
387
388        msg.sadb_msg_version = PF_KEY_V2;
389        msg.sadb_msg_type = SADB_X_PROMISC;
390        msg.sadb_msg_errno = 0;
391        msg.sadb_msg_satype = 1;
392        msg.sadb_msg_len = PFKEY_UNIT64(sizeof(msg));
393        msg.sadb_msg_reserved = 0;
394        msg.sadb_msg_seq = 0;
395        msg.sadb_msg_pid = getpid();
396
397        if ((l = send(so, &msg, sizeof(msg), 0)) < 0) {
398                err(1, "send");
399                /*NOTREACHED*/
400        }
401
402        while (1) {
403                struct sadb_msg *base;
404
405                if ((l = recv(so, rbuf, sizeof(*base), MSG_PEEK)) < 0) {
406                        err(1, "recv");
407                        /*NOTREACHED*/
408                }
409
410                if (l != sizeof(*base))
411                        continue;
412
413                base = (struct sadb_msg *)rbuf;
414                if ((l = recv(so, rbuf, PFKEY_UNUNIT64(base->sadb_msg_len),
415                                0)) < 0) {
416                        err(1, "recv");
417                        /*NOTREACHED*/
418                }
419                printdate();
420                if (f_hexdump) {
421                        int i;
422                        for (i = 0; i < l; i++) {
423                                if (i % 16 == 0)
424                                        printf("%08x: ", i);
425                                printf("%02x ", rbuf[i] & 0xff);
426                                if (i % 16 == 15)
427                                        printf("\n");
428                        }
429                        if (l % 16)
430                                printf("\n");
431                }
432                /* adjust base pointer for promisc mode */
433                if (base->sadb_msg_type == SADB_X_PROMISC) {
434                        if ((ssize_t)sizeof(*base) < l)
435                                base++;
436                        else
437                                base = NULL;
438                }
439                if (base) {
440                        kdebug_sadb(base);
441                        printf("\n");
442                        fflush(stdout);
443                }
444        }
445}
446
447/* Generate 'spi' array with SPIs matching 'satype', 'srcs', and 'dsts'
448 * Return value is dynamically generated array of SPIs, also number of
449 * SPIs through num_spi pointer.
450 * On any error, set *num_spi to 0 and return NULL.
451 */
452u_int32_t *
453sendkeymsg_spigrep(satype, srcs, dsts, num_spi)
454        unsigned int satype;
455        struct addrinfo *srcs;
456        struct addrinfo *dsts;
457        int *num_spi;
458{
459        struct sadb_msg msg, *m;
460        char *buf;
461        size_t len;
462        ssize_t l;
463        u_char rbuf[1024 * 32];
464        caddr_t mhp[SADB_EXT_MAX + 1];
465        struct sadb_address *saddr;
466        struct sockaddr *s;
467        struct addrinfo *a;
468        struct sadb_sa *sa;
469        u_int32_t *spi = NULL;
470        int max_spi = 0, fail = 0;
471
472        *num_spi = 0;
473
474        if (f_notreally) {
475                return NULL;
476        }
477
478    {
479        struct timeval tv;
480        tv.tv_sec = 1;
481        tv.tv_usec = 0;
482        if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
483                perror("setsockopt");
484                return NULL;
485        }
486    }
487
488        msg.sadb_msg_version = PF_KEY_V2;
489        msg.sadb_msg_type = SADB_DUMP;
490        msg.sadb_msg_errno = 0;
491        msg.sadb_msg_satype = satype;
492        msg.sadb_msg_len = PFKEY_UNIT64(sizeof(msg));
493        msg.sadb_msg_reserved = 0;
494        msg.sadb_msg_seq = 0;
495        msg.sadb_msg_pid = getpid();
496        buf = (char *)&msg;
497        len = sizeof(msg);
498
499        if (f_verbose) {
500                kdebug_sadb(&msg);
501                printf("\n");
502        }
503        if (f_hexdump) {
504                int i;
505                for (i = 0; i < len; i++) {
506                        if (i % 16 == 0)
507                                printf("%08x: ", i);
508                        printf("%02x ", buf[i] & 0xff);
509                        if (i % 16 == 15)
510                                printf("\n");
511                }
512                if (len % 16)
513                        printf("\n");
514        }
515
516        if ((l = send(so, buf, len, 0)) < 0) {
517                perror("send");
518                return NULL;
519        }
520
521        m = (struct sadb_msg *)rbuf;
522        do {
523                if ((l = recv(so, rbuf, sizeof(rbuf), 0)) < 0) {
524                        perror("recv");
525                        fail = 1;
526                        break;
527                }
528
529                if (PFKEY_UNUNIT64(m->sadb_msg_len) != l) {
530                        warnx("invalid keymsg length");
531                        fail = 1;
532                        break;
533                }
534
535                if (f_verbose) {
536                        kdebug_sadb(m);
537                        printf("\n");
538                }
539
540                if (m->sadb_msg_type != SADB_DUMP) {
541                        warnx("unexpected message type");
542                        fail = 1;
543                        break;
544                }
545
546                if (m->sadb_msg_errno != 0) {
547                        warnx("error encountered");
548                        fail = 1;
549                        break;
550                }
551
552                /* match satype */
553                if (m->sadb_msg_satype != satype)
554                        continue;
555
556                pfkey_align(m, mhp);
557                pfkey_check(mhp);
558
559                /* match src */
560                saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
561                if (saddr == NULL)
562                        continue;
563                s = (struct sockaddr *)(saddr + 1);
564                for (a = srcs; a; a = a->ai_next)
565                        if (memcmp(a->ai_addr, s, a->ai_addrlen) == 0)
566                                break;
567                if (a == NULL)
568                        continue;
569
570                /* match dst */
571                saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
572                if (saddr == NULL)
573                        continue;
574                s = (struct sockaddr *)(saddr + 1);
575                for (a = dsts; a; a = a->ai_next)
576                        if (memcmp(a->ai_addr, s, a->ai_addrlen) == 0)
577                                break;
578                if (a == NULL)
579                        continue;
580
581                if (*num_spi >= max_spi) {
582                        max_spi += 512;
583                        spi = realloc(spi, max_spi * sizeof(u_int32_t));
584                }
585
586                sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
587                if (sa != NULL)
588                        spi[(*num_spi)++] = (u_int32_t)ntohl(sa->sadb_sa_spi);
589
590                m = (struct sadb_msg *)((caddr_t)m + PFKEY_UNUNIT64(m->sadb_msg_len));
591
592                if (f_verbose) {
593                        kdebug_sadb(m);
594                        printf("\n");
595                }
596
597        } while (m->sadb_msg_seq);
598
599        if (fail) {
600                free(spi);
601                *num_spi = 0;
602                return NULL;
603        }
604
605        return spi;
606}
607
608int
609sendkeymsg(buf, len)
610        char *buf;
611        size_t len;
612{
613        u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */
614        ssize_t l;
615        struct sadb_msg *msg;
616
617        if (f_notreally) {
618                goto end;
619        }
620
621    {
622        struct timeval tv;
623        tv.tv_sec = 1;
624        tv.tv_usec = 0;
625        if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
626                perror("setsockopt");
627                goto end;
628        }
629    }
630
631        if (f_forever)
632                shortdump_hdr();
633again:
634        if (f_verbose) {
635                kdebug_sadb((struct sadb_msg *)buf);
636                printf("\n");
637        }
638        if (f_hexdump) {
639                int i;
640                for (i = 0; i < len; i++) {
641                        if (i % 16 == 0)
642                                printf("%08x: ", i);
643                        printf("%02x ", buf[i] & 0xff);
644                        if (i % 16 == 15)
645                                printf("\n");
646                }
647                if (len % 16)
648                        printf("\n");
649        }
650
651        if ((l = send(so, buf, len, 0)) < 0) {
652                perror("send");
653                goto end;
654        }
655
656        msg = (struct sadb_msg *)rbuf;
657        do {
658                if ((l = recv(so, rbuf, sizeof(rbuf), 0)) < 0) {
659                        perror("recv");
660                        goto end;
661                }
662
663                if (PFKEY_UNUNIT64(msg->sadb_msg_len) != l) {
664                        warnx("invalid keymsg length");
665                        break;
666                }
667
668                if (f_verbose) {
669                        kdebug_sadb(msg);
670                        printf("\n");
671                }
672                if (postproc(msg, l) < 0)
673                        break;
674        } while (msg->sadb_msg_errno || msg->sadb_msg_seq);
675
676        if (f_forever) {
677                fflush(stdout);
678                sleep(1);
679                goto again;
680        }
681
682end:
683        return (0);
684}
685
686int
687postproc(msg, len)
688        struct sadb_msg *msg;
689        int len;
690{
691#ifdef HAVE_PFKEY_POLICY_PRIORITY
692        static int priority_support_check = 0;
693#endif
694
695        if (msg->sadb_msg_errno != 0) {
696                char inf[80];
697                const char *errmsg = NULL;
698
699                if (f_mode == MODE_SCRIPT)
700                        snprintf(inf, sizeof(inf), "The result of line %d: ", lineno);
701                else
702                        inf[0] = '\0';
703
704                switch (msg->sadb_msg_errno) {
705                case ENOENT:
706                        switch (msg->sadb_msg_type) {
707                        case SADB_DELETE:
708                        case SADB_GET:
709                        case SADB_X_SPDDELETE:
710                                errmsg = "No entry";
711                                break;
712                        case SADB_DUMP:
713                                errmsg = "No SAD entries";
714                                break;
715                        case SADB_X_SPDDUMP:
716                                errmsg = "No SPD entries";
717                                break;
718                        }
719                        break;
720                default:
721                        errmsg = strerror(msg->sadb_msg_errno);
722                }
723                printf("%s%s.\n", inf, errmsg);
724                return (-1);
725        }
726
727        switch (msg->sadb_msg_type) {
728        case SADB_GET:
729                if (f_withports)
730                        pfkey_sadump_withports(msg);
731                else
732                        pfkey_sadump(msg);
733                break;
734
735        case SADB_DUMP:
736                /* filter out DEAD SAs */
737                if (!f_all) {
738                        caddr_t mhp[SADB_EXT_MAX + 1];
739                        struct sadb_sa *sa;
740                        pfkey_align(msg, mhp);
741                        pfkey_check(mhp);
742                        if ((sa = (struct sadb_sa *)mhp[SADB_EXT_SA]) != NULL) {
743                                if (sa->sadb_sa_state == SADB_SASTATE_DEAD)
744                                        break;
745                        }
746                }
747                if (f_forever) {
748                        /* TODO: f_withports */
749                        shortdump(msg);
750                } else {
751                        if (f_withports)
752                                pfkey_sadump_withports(msg);
753                        else
754                                pfkey_sadump(msg);
755                }
756                msg = (struct sadb_msg *)((caddr_t)msg +
757                                     PFKEY_UNUNIT64(msg->sadb_msg_len));
758                if (f_verbose) {
759                        kdebug_sadb((struct sadb_msg *)msg);
760                        printf("\n");
761                }
762                break;
763
764        case SADB_X_SPDGET:
765                if (f_withports) 
766                        pfkey_spdump_withports(msg);
767                else
768                        pfkey_spdump(msg);
769                break;
770
771        case SADB_X_SPDDUMP:
772                if (f_withports) 
773                        pfkey_spdump_withports(msg);
774                else
775                        pfkey_spdump(msg);
776                if (msg->sadb_msg_seq == 0) break;
777                msg = (struct sadb_msg *)((caddr_t)msg +
778                                     PFKEY_UNUNIT64(msg->sadb_msg_len));
779                if (f_verbose) {
780                        kdebug_sadb((struct sadb_msg *)msg);
781                        printf("\n");
782                }
783                break;
784#ifdef HAVE_PFKEY_POLICY_PRIORITY
785        case SADB_X_SPDADD:
786                if (last_msg_type == SADB_X_SPDADD && last_priority != 0 && 
787                    msg->sadb_msg_pid == getpid() && !priority_support_check) {
788                        priority_support_check = 1;     
789                        if (!verifypriority(msg))
790                                printf ("WARNING: Kernel does not support policy priorities\n");
791                }
792                break;
793#endif
794        }
795
796        return (0);
797}
798
799#ifdef HAVE_PFKEY_POLICY_PRIORITY
800int
801verifypriority(m)
802        struct sadb_msg *m;
803{
804        caddr_t mhp[SADB_EXT_MAX + 1];
805        struct sadb_x_policy *xpl;
806
807        /* check pfkey message. */
808        if (pfkey_align(m, mhp)) {
809                printf("(%s\n", ipsec_strerror());
810                return 0;
811        }
812        if (pfkey_check(mhp)) {
813                printf("%s\n", ipsec_strerror());
814                return 0;
815        }
816
817        xpl = (struct sadb_x_policy *) mhp[SADB_X_EXT_POLICY];
818
819        if (xpl == NULL) {
820                printf("no X_POLICY extension.\n");
821                return 0;
822        }
823
824        /* now make sure they match */
825        if (last_priority != xpl->sadb_x_policy_priority)
826                return 0;
827
828        return 1; 
829}
830#endif
831
832int
833fileproc(filename)
834        const char *filename;
835{
836        int fd;
837        ssize_t len, l;
838        u_char *p, *ep;
839        struct sadb_msg *msg;
840        u_char rbuf[1024 * 32]; /* XXX: Enough ? Should I do MSG_PEEK ? */
841
842        fd = open(filename, O_RDONLY);
843        if (fd < 0)
844                return -1;
845
846        l = 0;
847        while (1) {
848                len = read(fd, rbuf + l, sizeof(rbuf) - l);
849                if (len < 0) {
850                        close(fd);
851                        return -1;
852                } else if (len == 0)
853                        break;
854                l += len;
855        }
856
857        if (l < sizeof(struct sadb_msg)) {
858                close(fd);
859                errno = EINVAL;
860                return -1;
861        }
862        close(fd);
863
864        p = rbuf;
865        ep = rbuf + l;
866
867        while (p < ep) {
868                msg = (struct sadb_msg *)p;
869                len = PFKEY_UNUNIT64(msg->sadb_msg_len);
870                postproc(msg, len);
871                p += len;
872        }
873
874        return (0);
875}
876
877
878/*------------------------------------------------------------*/
879static const char *satype[] = {
880        NULL, NULL, "ah", "esp"
881};
882static const char *sastate[] = {
883        "L", "M", "D", "d"
884};
885static const char *ipproto[] = {
886/*0*/   "ip", "icmp", "igmp", "ggp", "ip4",
887        NULL, "tcp", NULL, "egp", NULL,
888/*10*/  NULL, NULL, NULL, NULL, NULL,
889        NULL, NULL, "udp", NULL, NULL,
890/*20*/  NULL, NULL, "idp", NULL, NULL,
891        NULL, NULL, NULL, NULL, "tp",
892/*30*/  NULL, NULL, NULL, NULL, NULL,
893        NULL, NULL, NULL, NULL, NULL,
894/*40*/  NULL, "ip6", NULL, "rt6", "frag6",
895        NULL, "rsvp", "gre", NULL, NULL,
896/*50*/  "esp", "ah", NULL, NULL, NULL,
897        NULL, NULL, NULL, "icmp6", "none",
898/*60*/  "dst6",
899};
900
901#define STR_OR_ID(x, tab) \
902        (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x))
903
904const char *
905numstr(x)
906        int x;
907{
908        static char buf[20];
909        snprintf(buf, sizeof(buf), "#%d", x);
910        return buf;
911}
912
913void
914shortdump_hdr()
915{
916        printf("%-4s %-3s %-1s %-8s %-7s %s -> %s\n",
917                "time", "p", "s", "spi", "ltime", "src", "dst");
918}
919
920void
921shortdump(msg)
922        struct sadb_msg *msg;
923{
924        caddr_t mhp[SADB_EXT_MAX + 1];
925        char buf[NI_MAXHOST], pbuf[NI_MAXSERV];
926        struct sadb_sa *sa;
927        struct sadb_address *saddr;
928        struct sadb_lifetime *lts, *lth, *ltc;
929        struct sockaddr *s;
930        u_int t;
931        time_t cur = time(0);
932
933        pfkey_align(msg, mhp);
934        pfkey_check(mhp);
935
936        printf("%02lu%02lu", (u_long)(cur % 3600) / 60, (u_long)(cur % 60));
937
938        printf(" %-3s", STR_OR_ID(msg->sadb_msg_satype, satype));
939
940        if ((sa = (struct sadb_sa *)mhp[SADB_EXT_SA]) != NULL) {
941                printf(" %-1s", STR_OR_ID(sa->sadb_sa_state, sastate));
942                printf(" %08x", (u_int32_t)ntohl(sa->sadb_sa_spi));
943        } else
944                printf("%-1s %-8s", "?", "?");
945
946        lts = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_SOFT];
947        lth = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD];
948        ltc = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_CURRENT];
949        if (lts && lth && ltc) {
950                if (ltc->sadb_lifetime_addtime == 0)
951                        t = (u_long)0;
952                else
953                        t = (u_long)(cur - ltc->sadb_lifetime_addtime);
954                if (t >= 1000)
955                        strlcpy(buf, " big/", sizeof(buf));
956                else
957                        snprintf(buf, sizeof(buf), " %3lu/", (u_long)t);
958                printf("%s", buf);
959
960                t = (u_long)lth->sadb_lifetime_addtime;
961                if (t >= 1000)
962                        strlcpy(buf, "big", sizeof(buf));
963                else
964                        snprintf(buf, sizeof(buf), "%-3lu", (u_long)t);
965                printf("%s", buf);
966        } else
967                printf(" ??\?/???");    /* backslash to avoid trigraph ??/ */
968
969        printf(" ");
970
971        if ((saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]) != NULL) {
972                if (saddr->sadb_address_proto)
973                        printf("%s ", STR_OR_ID(saddr->sadb_address_proto, ipproto));
974                s = (struct sockaddr *)(saddr + 1);
975                getnameinfo(s, sysdep_sa_len(s), buf, sizeof(buf),
976                        pbuf, sizeof(pbuf), NI_NUMERICHOST|NI_NUMERICSERV);
977                if (strcmp(pbuf, "0") != 0)
978                        printf("%s[%s]", buf, pbuf);
979                else
980                        printf("%s", buf);
981        } else
982                printf("?");
983
984        printf(" -> ");
985
986        if ((saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST]) != NULL) {
987                if (saddr->sadb_address_proto)
988                        printf("%s ", STR_OR_ID(saddr->sadb_address_proto, ipproto));
989
990                s = (struct sockaddr *)(saddr + 1);
991                getnameinfo(s, sysdep_sa_len(s), buf, sizeof(buf),
992                        pbuf, sizeof(pbuf), NI_NUMERICHOST|NI_NUMERICSERV);
993                if (strcmp(pbuf, "0") != 0)
994                        printf("%s[%s]", buf, pbuf);
995                else
996                        printf("%s", buf);
997        } else
998                printf("?");
999
1000        printf("\n");
1001}
1002
1003/* From: tcpdump(1):gmt2local.c and util.c */
1004/*
1005 * Print the timestamp
1006 */
1007static void
1008printdate()
1009{
1010        struct timeval tp;
1011        int s;
1012
1013        if (gettimeofday(&tp, NULL) == -1) {
1014                perror("gettimeofday");
1015                return;
1016        }
1017
1018        if (f_tflag == 1) {
1019                /* Default */
1020                s = (tp.tv_sec + thiszone ) % 86400;
1021                (void)printf("%02d:%02d:%02d.%06u ",
1022                    s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tp.tv_usec);
1023        } else if (f_tflag > 1) {
1024                /* Unix timeval style */
1025                (void)printf("%u.%06u ",
1026                    (u_int32_t)tp.tv_sec, (u_int32_t)tp.tv_usec);
1027        }
1028
1029        printf("\n");
1030}
1031
1032/*
1033 * Returns the difference between gmt and local time in seconds.
1034 * Use gmtime() and localtime() to keep things simple.
1035 */
1036int32_t
1037gmt2local(time_t t)
1038{
1039        register int dt, dir;
1040        register struct tm *gmt, *loc;
1041        struct tm sgmt;
1042
1043        if (t == 0)
1044                t = time(NULL);
1045        gmt = &sgmt;
1046        *gmt = *gmtime(&t);
1047        loc = localtime(&t);
1048        dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60 +
1049            (loc->tm_min - gmt->tm_min) * 60;
1050
1051        /*
1052         * If the year or julian day is different, we span 00:00 GMT
1053         * and must add or subtract a day. Check the year first to
1054         * avoid problems when the julian day wraps.
1055         */
1056        dir = loc->tm_year - gmt->tm_year;
1057        if (dir == 0)
1058                dir = loc->tm_yday - gmt->tm_yday;
1059        dt += dir * 24 * 60 * 60;
1060
1061        return (dt);
1062}
Note: See TracBrowser for help on using the repository browser.