1 /* $NetBSD: racoonctl.c,v 1.7 2006/10/02 07:12:26 manu Exp $ */
3 /* Id: racoonctl.c,v 1.11 2006/04/06 17:06:25 manubsd Exp */
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
41 #include <netinet/in.h>
42 #include <arpa/inet.h>
44 #include <System/net/pfkeyv2.h>
50 #if TIME_WITH_SYS_TIME
51 # include <sys/time.h>
55 # include <sys/time.h>
65 #include <sys/ioctl.h>
73 #include "racoonctl.h"
80 #include "isakmp_var.h"
82 #include "isakmp_xauth.h"
83 #include "isakmp_cfg.h"
84 #include "isakmp_unity.h"
85 #include "ipsec_doi.h"
88 char *adminsock_path
= ADMINSOCK_PATH
;
90 static void usage
__P((void));
91 static vchar_t
*get_combuf
__P((int, char **));
92 static int handle_recv
__P((vchar_t
*));
93 static vchar_t
*f_reload
__P((int, char **));
94 static vchar_t
*f_getsched
__P((int, char **));
95 static vchar_t
*f_getsa
__P((int, char **));
96 static vchar_t
*f_flushsa
__P((int, char **));
97 static vchar_t
*f_deletesa
__P((int, char **));
98 static vchar_t
*f_exchangesa
__P((int, char **));
99 static vchar_t
*f_vpnc
__P((int, char **));
100 static vchar_t
*f_exchangesatest
__P((int, char **));
101 static vchar_t
*f_vpntest
__P((int, char **));
102 static vchar_t
*f_vpnd
__P((int, char **));
103 static vchar_t
*f_getevt
__P((int, char **));
105 static vchar_t
*f_logoutusr
__P((int, char **));
109 vchar_t
*(*func
) __P((int, char **));
113 { f_reload
, ADMIN_RELOAD_CONF
, "reload-config" },
114 { f_reload
, ADMIN_RELOAD_CONF
, "rc" },
115 { f_getsched
, ADMIN_SHOW_SCHED
, "show-schedule" },
116 { f_getsched
, ADMIN_SHOW_SCHED
, "sc" },
117 { f_getsa
, ADMIN_SHOW_SA
, "show-sa" },
118 { f_getsa
, ADMIN_SHOW_SA
, "ss" },
119 { f_flushsa
, ADMIN_FLUSH_SA
, "flush-sa" },
120 { f_flushsa
, ADMIN_FLUSH_SA
, "fs" },
121 { f_deletesa
, ADMIN_DELETE_SA
, "delete-sa" },
122 { f_deletesa
, ADMIN_DELETE_SA
, "ds" },
123 { f_exchangesa
, ADMIN_ESTABLISH_SA
, "establish-sa" },
124 { f_exchangesa
, ADMIN_ESTABLISH_SA
, "es" },
125 { f_vpnc
, ADMIN_ESTABLISH_SA
, "vpn-connect" },
126 { f_vpnc
, ADMIN_ESTABLISH_SA
, "vc" },
127 { f_vpntest
, ADMIN_ESTABLISH_SA_VPNCONTROL
, "vpntest" },
128 { f_vpnd
, ADMIN_DELETE_ALL_SA_DST
,"vpn-disconnect" },
129 { f_vpnd
, ADMIN_DELETE_ALL_SA_DST
,"vd" },
130 { f_getevt
, ADMIN_SHOW_EVT
, "show-event" },
131 { f_getevt
, ADMIN_SHOW_EVT
, "se" },
133 { f_logoutusr
, ADMIN_LOGOUT_USER
, "logout-user" },
134 { f_logoutusr
, ADMIN_LOGOUT_USER
, "lu" },
142 enum { UNSPEC
, ERROR
, INFO
} level
;
144 { EVTT_PHASE1_UP
, "Phase 1 established", INFO
},
145 { EVTT_PHASE1_DOWN
, "Phase 1 deleted", INFO
},
146 { EVTT_XAUTH_SUCCESS
, "Xauth exchange passed", INFO
},
147 { EVTT_ISAKMP_CFG_DONE
, "ISAKMP mode config done", INFO
},
148 { EVTT_PHASE2_UP
, "Phase 2 established", INFO
},
149 { EVTT_PHASE2_DOWN
, "Phase 2 deleted", INFO
},
150 { EVTT_DPD_TIMEOUT
, "Peer not reachable anymore", ERROR
},
151 { EVTT_PEER_NO_RESPONSE
, "Peer not responding", ERROR
},
152 { EVTT_PEER_DELETE
, "Peer terminated security association", ERROR
},
153 { EVTT_RACOON_QUIT
, "Raccon terminated", ERROR
},
154 { EVTT_OVERFLOW
, "Event queue overflow", ERROR
},
155 { EVTT_XAUTH_FAILED
, "Xauth exchange failed", ERROR
},
156 { EVTT_PEERPH1AUTH_FAILED
, "Peer failed phase 1 authentication "
157 "(certificate problem?)", ERROR
},
158 { EVTT_PEERPH1_NOPROP
, "Peer failed phase 1 initiation "
159 "(proposal problem?)", ERROR
},
161 { EVTT_NO_ISAKMP_CFG
, "No need for ISAKMP mode config ", INFO
},
164 static int get_proto
__P((char *));
165 static vchar_t
*get_index
__P((int, char **));
166 static int get_family
__P((char *));
167 static vchar_t
*get_comindexes
__P((int, int, char **));
168 static int get_comindex
__P((char *, char **, char **, char **));
169 static int get_ulproto
__P((char *));
175 { ADMIN_PROTO_ISAKMP
, "isakmp" },
176 { ADMIN_PROTO_IPSEC
, "ipsec" },
177 { ADMIN_PROTO_AH
, "ah" },
178 { ADMIN_PROTO_ESP
, "esp" },
179 { ADMIN_PROTO_INTERNAL
, "internal" },
188 { IPPROTO_ICMP
, "icmp" },
189 { IPPROTO_TCP
, "tcp" },
190 { IPPROTO_UDP
, "udp" },
196 static char _addr1_
[NI_MAXHOST
], _addr2_
[NI_MAXHOST
];
201 #define EVTF_NONE 0x0000 /* Ignore any events */
202 #define EVTF_LOOP 0x0001 /* Loop awaiting for new events */
203 #define EVTF_CFG_STOP 0x0002 /* Stop after ISAKMP mode config */
204 #define EVTF_CFG 0x0004 /* Print ISAKMP mode config info */
205 #define EVTF_ALL 0x0008 /* Print any events */
206 #define EVTF_PURGE 0x0010 /* Print all available events */
207 #define EVTF_PH1DOWN_STOP 0x0020 /* Stop when phase 1 SA gets down */
208 #define EVTF_PH1DOWN 0x0040 /* Print that phase 1 SA got down */
209 #define EVTF_ERR 0x0080 /* Print any error */
210 #define EVTF_ERR_STOP 0x0100 /* Stop on any error */
212 int evt_filter
= EVTF_NONE
;
215 void dump_isakmp_sa
__P((char *, int));
216 void dump_internal
__P((char *, int));
217 char *pindex_isakmp
__P((isakmp_index
*));
218 void print_schedule
__P((caddr_t
, int));
219 void print_evt
__P((caddr_t
, int));
220 void print_cfg
__P((caddr_t
, int));
221 void print_err
__P((caddr_t
, int));
222 void print_ph1down
__P((caddr_t
, int));
223 void print_ph1up
__P((caddr_t
, int));
224 int evt_poll
__P((void));
225 char * fixed_addr
__P((char *, char *, int));
232 " %s reload-config\n"
233 " %s [-l [-l]] show-sa [protocol]\n"
234 " %s flush-sa [protocol]\n"
235 " %s delete-sa <saopts>\n"
236 " %s establish-sa [-u identity] <saopts>\n"
237 " %s vpn-connect [-u identity] vpn_gateway\n"
238 " %s vpn-disconnect vpn_gateway\n"
240 " <protocol>: \"isakmp\", \"esp\" or \"ah\".\n"
241 " In the case of \"show-sa\" or \"flush-sa\", you can use \"ipsec\".\n"
243 " <saopts>: \"isakmp\" <family> <src> <dst>\n"
244 " : {\"esp\",\"ah\"} <family> <src/prefixlen/port> <dst/prefixlen/port>\n"
246 " <family>: \"inet\" or \"inet6\"\n"
247 " <ul_proto>: \"icmp\", \"tcp\", \"udp\" or \"any\"\n",
248 pname
, pname
, pname
, pname
, pname
, pname
, pname
);
252 * Check for proper racoonctl interface
254 #if ((RACOONCTL_INTERFACE_MAJOR != 1) || (RACOONCTL_INTERFACE < 20041230))
255 #error "Incompatible racoonctl interface"
269 * Check for proper racoonctl interface
271 if ((racoonctl_interface_major
!= RACOONCTL_INTERFACE_MAJOR
) ||
272 (racoonctl_interface
< RACOONCTL_INTERFACE
))
273 errx(1, "Incompatible racoonctl interface");
275 while ((c
= getopt(ac
, av
, "lds:")) != -1) {
286 adminsock_path
= optarg
;
298 combuf
= get_combuf(ac
, av
);
303 hexdump(combuf
, ((struct admin_com
*)combuf
)->ac_len
);
307 if (com_send(combuf
) != 0)
312 if (com_recv(&combuf
) != 0)
314 if (handle_recv(combuf
) != 0)
319 if (evt_filter
!= EVTF_NONE
)
335 if ((sendbuf
= f_getevt(0, NULL
)) == NULL
)
336 errx(1, "Cannot make combuf");
338 while (evt_filter
& (EVTF_LOOP
|EVTF_PURGE
)) {
339 /* handle_recv closes the socket time, so open it each time */
341 if (com_send(sendbuf
) != 0)
342 errx(1, "Cannot send combuf");
344 if (com_recv(&recvbuf
) == 0) {
345 handle_recv(recvbuf
);
351 (void)select(0, NULL
, NULL
, NULL
, &tv
);
360 * return command buffer.
374 /* checking the string of command. */
375 for (cp
= &cmdtab
[0]; cp
->str
; cp
++) {
376 if (strcmp(*av
, cp
->str
) == 0) {
381 printf("Invalid command [%s]\n", *av
);
388 return (cp
->func
)(ac
, av
);
397 struct admin_com
*head
;
399 buf
= vmalloc(sizeof(*head
));
401 errx(1, "not enough core");
403 head
= (struct admin_com
*)buf
->v
;
404 head
->ac_len
= buf
->l
;
405 head
->ac_cmd
= ADMIN_RELOAD_CONF
;
418 struct admin_com
*head
;
421 * There are 3 ways of getting here
422 * 1) racoonctl vc => evt_filter = (EVTF_LOOP|EVTF_CFG| ... )
423 * 2) racoonctl es => evt_filter = EVTF_NONE
424 * 3) racoonctl es -l => evt_filter = EVTF_LOOP
425 * Catch the second case: show-event is here to purge all
427 if (evt_filter
== EVTF_NONE
)
428 evt_filter
= (EVTF_ALL
|EVTF_PURGE
);
430 if ((ac
>= 1) && (strcmp(av
[0], "-l") == 0))
431 evt_filter
|= EVTF_LOOP
;
434 errx(1, "too many arguments");
436 buf
= vmalloc(sizeof(*head
));
438 errx(1, "not enough core");
440 head
= (struct admin_com
*)buf
->v
;
441 head
->ac_len
= buf
->l
;
442 head
->ac_cmd
= ADMIN_SHOW_EVT
;
455 struct admin_com
*head
;
457 buf
= vmalloc(sizeof(*head
));
459 errx(1, "not enough core");
461 head
= (struct admin_com
*)buf
->v
;
462 head
->ac_len
= buf
->l
;
463 head
->ac_cmd
= ADMIN_SHOW_SCHED
;
476 struct admin_com
*head
;
481 errx(1, "insufficient arguments");
482 proto
= get_proto(*av
);
484 errx(1, "unknown protocol %s", *av
);
486 buf
= vmalloc(sizeof(*head
));
488 errx(1, "not enough core");
490 head
= (struct admin_com
*)buf
->v
;
491 head
->ac_len
= buf
->l
;
492 head
->ac_cmd
= ADMIN_SHOW_SA
;
494 head
->ac_proto
= proto
;
505 struct admin_com
*head
;
510 errx(1, "insufficient arguments");
511 proto
= get_proto(*av
);
513 errx(1, "unknown protocol %s", *av
);
515 buf
= vmalloc(sizeof(*head
));
517 errx(1, "not enough core");
519 head
= (struct admin_com
*)buf
->v
;
520 head
->ac_len
= buf
->l
;
521 head
->ac_cmd
= ADMIN_FLUSH_SA
;
523 head
->ac_proto
= proto
;
533 vchar_t
*buf
, *index
;
534 struct admin_com
*head
;
539 errx(1, "insufficient arguments");
540 proto
= get_proto(*av
);
542 errx(1, "unknown protocol %s", *av
);
548 case ADMIN_PROTO_ISAKMP
:
549 index
= get_index(ac
, av
);
554 case ADMIN_PROTO_ESP
:
555 index
= get_index(ac
, av
);
560 errno
= EPROTONOSUPPORT
;
564 buf
= vmalloc(sizeof(*head
) + index
->l
);
568 head
= (struct admin_com
*)buf
->v
;
569 head
->ac_len
= buf
->l
+ index
->l
;
570 head
->ac_cmd
= ADMIN_DELETE_SA
;
572 head
->ac_proto
= proto
;
574 memcpy(buf
->v
+sizeof(*head
), index
->v
, index
->l
);
584 f_deleteallsadst(ac
, av
)
588 vchar_t
*buf
, *index
;
589 struct admin_com
*head
;
594 errx(1, "insufficient arguments");
595 proto
= get_proto(*av
);
597 errx(1, "unknown protocol %s", *av
);
603 case ADMIN_PROTO_ISAKMP
:
604 index
= get_index(ac
, av
);
609 case ADMIN_PROTO_ESP
:
610 index
= get_index(ac
, av
);
615 errno
= EPROTONOSUPPORT
;
619 buf
= vmalloc(sizeof(*head
) + index
->l
);
623 head
= (struct admin_com
*)buf
->v
;
624 head
->ac_len
= buf
->l
+ index
->l
;
625 head
->ac_cmd
= ADMIN_DELETE_ALL_SA_DST
;
627 head
->ac_proto
= proto
;
629 memcpy(buf
->v
+sizeof(*head
), index
->v
, index
->l
);
643 vchar_t
*buf
, *index
;
644 struct admin_com
*head
;
646 int cmd
= ADMIN_ESTABLISH_SA
;
650 struct admin_com_psk
*acp
;
653 errx(1, "insufficient arguments");
655 /* Optional -u identity */
656 if (strcmp(av
[0], "-u") == 0) {
658 errx(1, "-u require an argument");
661 if ((key
= getpass("Password: ")) == NULL
)
662 errx(1, "getpass() failed: %s", strerror(errno
));
664 com_len
+= sizeof(*acp
) + strlen(id
) + 1 + strlen(key
) + 1;
665 cmd
= ADMIN_ESTABLISH_SA_PSK
;
673 errx(1, "insufficient arguments");
674 if ((proto
= get_proto(*av
)) == -1)
675 errx(1, "unknown protocol %s", *av
);
681 case ADMIN_PROTO_ISAKMP
:
682 index
= get_index(ac
, av
);
687 case ADMIN_PROTO_ESP
:
688 index
= get_index(ac
, av
);
693 errno
= EPROTONOSUPPORT
;
697 com_len
+= sizeof(*head
) + index
->l
;
698 if ((buf
= vmalloc(com_len
)) == NULL
)
699 errx(1, "Cannot allocate buffer");
701 head
= (struct admin_com
*)buf
->v
;
702 head
->ac_len
= buf
->l
;
705 head
->ac_proto
= proto
;
707 memcpy(buf
->v
+sizeof(*head
), index
->v
, index
->l
);
710 // overload com_len to track the number of unused bytes in buf->v
712 acp
= (struct admin_com_psk
*)
713 (buf
->v
+ sizeof(*head
) + index
->l
);
714 com_len
-= sizeof(*head
) + index
->l
;
716 acp
->id_type
= IDTYPE_USERFQDN
;
717 acp
->id_len
= strlen(id
) + 1;
718 acp
->key_len
= strlen(key
) + 1;
720 data
= (char *)(acp
+ 1);
721 com_len
-= sizeof(*acp
);
722 strlcpy(data
, id
, com_len
);
724 data
= (char *)(data
+ acp
->id_len
);
725 com_len
-= acp
->id_len
;
726 strlcpy(data
, key
, com_len
);
736 f_exchangesatest(ac
, av
)
740 vchar_t
*buf
, *index
;
741 struct admin_com
*head
;
743 int cmd
= ADMIN_ESTABLISH_SA_VPNCONTROL
;
747 struct admin_com_psk
*acp
;
750 errx(1, "insufficient arguments");
752 /* Optional -u identity */
753 if (strcmp(av
[0], "-u") == 0) {
755 errx(1, "-u require an argument");
758 if ((key
= getpass("Password: ")) == NULL
)
759 errx(1, "getpass() failed: %s", strerror(errno
));
761 com_len
+= sizeof(*acp
) + strlen(id
) + 1 + strlen(key
) + 1;
762 cmd
= ADMIN_ESTABLISH_SA_VPNCONTROL
;
770 errx(1, "insufficient arguments");
771 if ((proto
= get_proto(*av
)) == -1)
772 errx(1, "unknown protocol %s", *av
);
778 case ADMIN_PROTO_ISAKMP
:
779 index
= get_index(ac
, av
);
784 case ADMIN_PROTO_ESP
:
785 index
= get_index(ac
, av
);
790 errno
= EPROTONOSUPPORT
;
794 com_len
+= sizeof(*head
) + index
->l
;
795 if ((buf
= vmalloc(com_len
)) == NULL
)
796 errx(1, "Cannot allocate buffer");
798 head
= (struct admin_com
*)buf
->v
;
799 head
->ac_len
= buf
->l
;
802 head
->ac_proto
= proto
;
804 memcpy(buf
->v
+sizeof(*head
), index
->v
, index
->l
);
807 // overload com_len to track the number of unused bytes in buf->v
809 acp
= (struct admin_com_psk
*)
810 (buf
->v
+ sizeof(*head
) + index
->l
);
811 com_len
-= sizeof(*head
) + index
->l
;
813 acp
->id_type
= IDTYPE_USERFQDN
;
814 acp
->id_len
= strlen(id
) + 1;
815 acp
->key_len
= strlen(key
) + 1;
817 data
= (char *)(acp
+ 1);
818 strlcpy(data
, id
, com_len
);
820 data
= (char *)(data
+ acp
->id_len
);
821 com_len
-= acp
->id_len
;
822 strlcpy(data
, key
, com_len
);
835 char *nav
[] = {NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
837 char *isakmp
= "isakmp";
840 struct addrinfo hints
, *res
;
841 struct sockaddr_storage
*src
;
845 errx(1, "insufficient arguments");
847 evt_filter
= (EVTF_LOOP
|EVTF_CFG
|EVTF_CFG_STOP
|EVTF_ERR
|EVTF_ERR_STOP
);
850 /* Optional -u identity */
851 if (strcmp(av
[0], "-u") == 0) {
853 errx(1, "-u require an argument");
863 errx(1, "VPN gateway required");
865 warnx("Extra arguments");
868 * Find the source address
870 memset(&hints
, 0, sizeof(hints
));
871 hints
.ai_family
= PF_UNSPEC
;
872 hints
.ai_socktype
= SOCK_DGRAM
;
873 if (getaddrinfo(av
[0], "4500", &hints
, &res
) != 0)
874 errx(1, "Cannot resolve destination address");
876 if ((src
= getlocaladdr(res
->ai_addr
)) == NULL
)
877 errx(1, "cannot find source address");
879 if ((srcaddr
= saddr2str(src
)) == NULL
)
880 errx(1, "cannot read source address");
882 /* We get "ip[port]" strip the port */
883 if ((idx
= index(srcaddr
, '[')) == NULL
)
884 errx(1, "unexpected source address format");
889 nav
[nac
++] = srcaddr
;
892 return f_exchangesa(nac
, nav
);
901 char *nav
[] = {NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
903 char *isakmp
= "isakmp";
906 struct addrinfo hints
, *res
;
907 struct sockaddr_storage
*src
;
911 errx(1, "insufficient arguments");
913 evt_filter
= (EVTF_LOOP
|EVTF_CFG
|EVTF_CFG_STOP
|EVTF_ERR
|EVTF_ERR_STOP
);
916 /* Optional -u identity */
917 if (strcmp(av
[0], "-u") == 0) {
919 errx(1, "-u require an argument");
929 errx(1, "VPN gateway required");
931 warnx("Extra arguments");
934 * Find the source address
936 memset(&hints
, 0, sizeof(hints
));
937 hints
.ai_family
= PF_UNSPEC
;
938 hints
.ai_socktype
= SOCK_DGRAM
;
939 if (getaddrinfo(av
[0], "4500", &hints
, &res
) != 0)
940 errx(1, "Cannot resolve destination address");
942 if ((src
= getlocaladdr(res
->ai_addr
)) == NULL
)
943 errx(1, "cannot find source address");
945 if ((srcaddr
= saddr2str(src
)) == NULL
)
946 errx(1, "cannot read source address");
948 /* We get "ip[port]" strip the port */
949 if ((idx
= index(srcaddr
, '[')) == NULL
)
950 errx(1, "unexpected source address format");
955 nav
[nac
++] = srcaddr
;
958 return f_exchangesa(nac
, nav
);
966 char *nav
[] = {NULL
, NULL
, NULL
, NULL
};
968 char *isakmp
= "isakmp";
970 char *anyaddr
= "0.0.0.0";
974 errx(1, "VPN gateway required");
976 warnx("Extra arguments");
979 (EVTF_PH1DOWN
|EVTF_PH1DOWN_STOP
|EVTF_LOOP
|EVTF_ERR
|EVTF_ERR_STOP
);
983 nav
[nac
++] = anyaddr
;
986 return f_deleteallsadst(nac
, nav
);
996 struct admin_com
*head
;
1001 errx(1, "insufficient arguments");
1003 if ((user
== NULL
) || ((strlen(user
) + 1) > LOGINLEN
))
1004 errx(1, "bad login (too long?)");
1006 buf
= vmalloc(sizeof(*head
) + LOGINLEN
);
1010 head
= (struct admin_com
*)buf
->v
;
1011 head
->ac_len
= buf
->l
;
1012 head
->ac_cmd
= ADMIN_LOGOUT_USER
;
1016 strlcpy((char *)(head
+ 1), user
, LOGINLEN
);
1020 #endif /* ENABLE_HYBRID */
1027 struct proto_tag
*cp
;
1034 /* checking the string of command. */
1035 for (cp
= &prototab
[0]; cp
->str
; cp
++) {
1036 if (strcmp(str
, cp
->str
) == 0)
1051 if (ac
!= 3 && ac
!= 4) {
1056 /* checking the string of family */
1057 family
= get_family(*av
);
1063 return get_comindexes(family
, ac
, av
);
1070 if (strcmp("inet", str
) == 0)
1073 else if (strcmp("inet6", str
) == 0)
1076 errno
= EAFNOSUPPORT
;
1081 get_comindexes(family
, ac
, av
)
1087 struct admin_com_indexes
*ci
;
1088 char *p_name
= NULL
, *p_port
= NULL
;
1089 char *p_prefs
= NULL
, *p_prefd
= NULL
;
1090 struct sockaddr_storage
*src
= NULL
, *dst
= NULL
;
1093 if (ac
!= 2 && ac
!= 3) {
1098 if (get_comindex(*av
, &p_name
, &p_port
, &p_prefs
) == -1)
1100 src
= get_sockaddr(family
, p_name
, p_port
);
1102 racoon_free(p_name
);
1106 racoon_free(p_port
);
1113 if (get_comindex(*av
, &p_name
, &p_port
, &p_prefd
) == -1)
1115 dst
= get_sockaddr(family
, p_name
, p_port
);
1117 racoon_free(p_name
);
1121 racoon_free(p_port
);
1127 buf
= vmalloc(sizeof(*ci
));
1134 ulproto
= get_ulproto(*av
);
1140 ci
= (struct admin_com_indexes
*)buf
->v
;
1142 ci
->prefs
= (u_int8_t
)atoi(p_prefs
); /* XXX should be handled error. */
1146 ci
->prefd
= (u_int8_t
)atoi(p_prefd
); /* XXX should be handled error. */
1149 ci
->ul_proto
= ulproto
;
1150 memcpy(&ci
->src
, src
, sysdep_sa_len(src
));
1151 memcpy(&ci
->dst
, dst
, sysdep_sa_len(dst
));
1154 racoon_free(p_name
);
1160 racoon_free(p_name
);
1162 racoon_free(p_port
);
1164 racoon_free(p_prefs
);
1166 racoon_free(p_prefd
);
1171 get_comindex(str
, name
, port
, pref
)
1172 char *str
, **name
, **port
, **pref
;
1176 *name
= *port
= *pref
= NULL
;
1178 *name
= racoon_strdup(str
);
1179 STRDUP_FATAL(*name
);
1180 p
= strpbrk(*name
, "/[");
1182 if (*(p
+ 1) == '\0')
1186 *pref
= racoon_strdup(p
+ 1);
1187 STRDUP_FATAL(*pref
);
1188 p
= strchr(*pref
, '[');
1190 if (*(p
+ 1) == '\0')
1193 *port
= racoon_strdup(p
+ 1);
1194 STRDUP_FATAL(*port
);
1195 p
= strchr(*pref
, ']');
1200 } else if (*p
== '[') {
1204 *port
= racoon_strdup(p
+ 1);
1205 STRDUP_FATAL(*port
);
1206 p
= strchr(*pref
, ']');
1225 *name
= *port
= *pref
= NULL
;
1233 struct ulproto_tag
*cp
;
1240 /* checking the string of upper layer protocol. */
1241 for (cp
= &ulprototab
[0]; cp
->str
; cp
++) {
1242 if (strcmp(str
, cp
->str
) == 0)
1243 return cp
->ul_proto
;
1252 dump_isakmp_sa(buf
, len
)
1261 /* isakmp status header */
1263 1234567890123456789012 0000000000000000:0000000000000000 000000000000
1266 "Destination Cookies Created";
1268 /* semi long header;
1269 1234567890123456789012 0000000000000000:0000000000000000 00 X 00 X 0000-00-00 00:00:00 000000
1272 "Destination Cookies ST S V E Created Phase2";
1275 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000000000000000:0000000000000000 00 X 00 X 0000-00-00 00:00:00 000000
1278 "Source Destination Cookies ST S V E Created Phase2";
1280 /* phase status header */
1282 side stats source address destination address
1283 xxx xxxxx 1234567890123456789012 1234567890123456789012
1286 static char *estr
[] = { "", "B", "M", "U", "A", "I", };
1288 switch (long_format
) {
1290 printf("%s\n", header1
);
1293 printf("%s\n", header2
);
1297 printf("%s\n", header3
);
1301 if (len
% sizeof(*pd
))
1302 printf("invalid length %d\n", len
);
1305 pd
= (struct ph1dump
*)buf
;
1308 /* source address */
1309 if (long_format
>= 2) {
1310 GETNAMEINFO((struct sockaddr_storage
*)&pd
->local
, _addr1_
, _addr2_
);
1311 switch (long_format
) {
1315 p
= fixed_addr(_addr1_
, _addr2_
, 22);
1319 p
= fixed_addr(_addr1_
, _addr2_
, 45);
1325 /* destination address */
1326 GETNAMEINFO((struct sockaddr_storage
*)&pd
->remote
, _addr1_
, _addr2_
);
1327 switch (long_format
) {
1330 p
= fixed_addr(_addr1_
, _addr2_
, 22);
1334 p
= fixed_addr(_addr1_
, _addr2_
, 45);
1339 printf("%s ", pindex_isakmp(&pd
->index
));
1341 /* statuc, side and version */
1342 if (long_format
>= 1) {
1343 printf("%2d %c %2x ",
1345 pd
->side
== INITIATOR
? 'I' : 'R',
1347 if (ARRAYLEN(estr
) > pd
->etype
)
1348 printf("%s ", estr
[pd
->etype
]);
1353 tm
= localtime(&pd
->created
);
1354 strftime(tbuf
, sizeof(tbuf
), "%Y-%m-%d %T", tm
);
1356 snprintf(tbuf
, sizeof(tbuf
), " ");
1357 printf("%s ", tbuf
);
1359 /* counter of phase 2 */
1360 if (long_format
>= 1)
1361 printf("%6d ", pd
->ph2cnt
);
1373 dump_internal(buf
, tlen
)
1377 struct ph2handle
*iph2
;
1378 struct sockaddr_storage
*addr
;
1382 source address destination address
1383 1234567890123456789012 1234567890123456789012
1386 "Source Destination ";
1390 source address destination address
1391 123456789012345678901234567890123456789012345 123456789012345678901234567890123456789012345
1392 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000:0000:0000:0000:0000:0000:0000:0000.00000 0000:0000:0000:0000:0000:0000:0000:0000.00000
1395 "Source Destination ";
1397 printf("%s\n", long_format
? long_h1
: short_h1
);
1400 iph2
= (struct ph2handle
*)buf
;
1401 addr
= (struct sockaddr_storage
*)(++iph2
);
1403 GETNAMEINFO(addr
, _addr1_
, _addr2_
);
1404 printf("%s ", long_format
?
1405 fixed_addr(_addr1_
, _addr2_
, 45)
1406 : fixed_addr(_addr1_
, _addr2_
, 22));
1408 tlen
-= sysdep_sa_len(addr
);
1410 GETNAMEINFO(addr
, _addr1_
, _addr2_
);
1411 printf("%s ", long_format
?
1412 fixed_addr(_addr1_
, _addr2_
, 45)
1413 : fixed_addr(_addr1_
, _addr2_
, 22));
1415 tlen
-= sysdep_sa_len(addr
);
1425 pindex_isakmp(index
)
1426 isakmp_index
*index
;
1428 static char buf
[64];
1432 memset(buf
, 0, sizeof(buf
));
1435 p
= (u_char
*)index
;
1436 for (j
= 0, i
= 0; i
< sizeof(isakmp_index
); i
++) {
1437 snprintf((char *)&buf
[j
], sizeof(buf
) - j
, "%02x", p
[i
]);
1451 /* print schedule */
1452 char *str_sched_stat
[] = {
1458 char *str_sched_id
[] = {
1467 print_schedule(buf
, len
)
1471 struct scheddump
*sc
= (struct scheddump
*)buf
;
1475 if (len
% sizeof(*sc
))
1476 printf("invalid length %d\n", len
);
1479 /* 00000000 00000000 00000000 xxx........*/
1480 printf("index tick xtime created\n");
1483 tm
= localtime(&sc
->created
);
1484 strftime(tbuf
, sizeof(tbuf
), "%Y-%m-%d %T", tm
);
1486 printf("%-8ld %-8ld %-8ld %s\n",
1503 struct evtdump
*evtdump
= (struct evtdump
*)buf
;
1508 for (i
= 0; evtmsg
[i
].msg
; i
++)
1509 if (evtmsg
[i
].type
== evtdump
->type
)
1512 if (evtmsg
[i
].msg
== NULL
)
1513 printf("Event %d: ", evtdump
->type
);
1515 printf("%s : ", evtmsg
[i
].msg
);
1517 if ((srcstr
= saddr2str((struct sockaddr_storage
*)&evtdump
->src
)) == NULL
)
1520 printf("%s", srcstr
);
1522 if ((dststr
= saddr2str((struct sockaddr_storage
*)&evtdump
->dst
)) == NULL
)
1525 printf("%s", dststr
);
1536 struct evtdump
*evtdump
= (struct evtdump
*)buf
;
1540 for (i
= 0; evtmsg
[i
].msg
; i
++)
1541 if (evtmsg
[i
].type
== evtdump
->type
)
1544 if (evtmsg
[i
].level
!= ERROR
)
1547 if (evtmsg
[i
].msg
== NULL
)
1548 printf("Error: Event %d\n", evtdump
->type
);
1550 printf("Error: %s\n", evtmsg
[i
].msg
);
1552 if (evt_filter
& EVTF_ERR_STOP
)
1553 evt_filter
&= ~EVTF_LOOP
;
1559 * Print a message when phase 1 SA goes down
1562 print_ph1down(buf
, len
)
1566 struct evtdump
*evtdump
= (struct evtdump
*)buf
;
1568 if (evtdump
->type
!= EVTT_PHASE1_DOWN
)
1571 printf("VPN connexion terminated\n");
1573 if (evt_filter
& EVTF_PH1DOWN_STOP
)
1574 evt_filter
&= ~EVTF_LOOP
;
1580 * Print ISAKMP mode config info (IP and banner)
1587 struct evtdump
*evtdump
= (struct evtdump
*)buf
;
1588 struct isakmp_data
*attr
;
1589 char *banner
= NULL
;
1590 struct in_addr addr4
;
1592 memset(&addr4
, 0, sizeof(addr4
));
1594 if (evtdump
->type
!= EVTT_ISAKMP_CFG_DONE
&&
1595 evtdump
->type
!= EVTT_NO_ISAKMP_CFG
)
1598 len
-= sizeof(*evtdump
);
1599 attr
= (struct isakmp_data
*)(evtdump
+ 1);
1602 if (len
< sizeof(*attr
)) {
1603 printf("short attribute too short\n");
1607 if ((ntohs(attr
->type
) & ISAKMP_GEN_MASK
) == ISAKMP_GEN_TV
) {
1608 /* Short attribute, skip */
1609 len
-= sizeof(*attr
);
1611 } else { /* Long attribute */
1614 if (len
< (sizeof(*attr
) + ntohs(attr
->lorv
))) {
1615 printf("long attribute too long\n");
1619 switch (ntohs(attr
->type
) & ~ISAKMP_GEN_MASK
) {
1620 case INTERNAL_IP4_ADDRESS
:
1621 if (ntohs(attr
->lorv
) < sizeof(addr4
)) {
1622 printf("addr4 attribute too short\n");
1625 memcpy(&addr4
, attr
+ 1, sizeof(addr4
));
1629 banner
= racoon_malloc(ntohs(attr
->lorv
) + 1);
1630 if (banner
== NULL
) {
1631 printf("malloc failed\n");
1634 memcpy(banner
, attr
+ 1, ntohs(attr
->lorv
));
1635 banner
[ntohs(attr
->lorv
)] = '\0';
1642 len
-= (sizeof(*attr
) + ntohs(attr
->lorv
));
1644 attr
= (struct isakmp_data
*)
1645 (n
+ sizeof(*attr
) + ntohs(attr
->lorv
));
1649 if (evtdump
->type
== EVTT_ISAKMP_CFG_DONE
)
1650 printf("Bound to address %s\n", inet_ntoa(addr4
));
1652 printf("VPN connexion established\n");
1659 if (ioctl(1, TIOCGWINSZ
, &win
) != 1)
1662 for (i
= 0; i
< col
; i
++)
1664 printf("\n%s\n", banner
);
1665 for (i
= 0; i
< col
; i
++)
1668 racoon_free(banner
);
1671 if (evt_filter
& EVTF_CFG_STOP
)
1672 evt_filter
&= ~EVTF_LOOP
;
1679 fixed_addr(addr
, port
, len
)
1683 static char _addr_buf_
[BUFSIZ
];
1688 memset(_addr_buf_
, ' ', sizeof(_addr_buf_
));
1690 plen
= strlen(port
);
1695 for (i
= 0; i
< len
- plen
- 1 && addr
[i
] != '\0'; /*noting*/)
1699 for (i
= 0; i
< plen
&& port
[i
] != '\0'; /*noting*/)
1702 _addr_buf_
[len
] = '\0';
1711 struct admin_com h
, *com
;
1715 com
= (struct admin_com
*)combuf
->v
;
1716 len
= com
->ac_len
- sizeof(*com
);
1717 buf
= combuf
->v
+ sizeof(*com
);
1719 switch (com
->ac_cmd
) {
1720 case ADMIN_SHOW_SCHED
:
1721 print_schedule(buf
, len
);
1724 case ADMIN_SHOW_EVT
: {
1725 struct evtdump
*evtdump
;
1727 /* We got no event */
1729 /* If we were purging the queue, it is now done */
1730 if (evt_filter
& EVTF_PURGE
)
1731 evt_filter
&= ~EVTF_PURGE
;
1735 if (len
< sizeof(struct evtdump
))
1736 errx(1, "Short buffer\n");
1738 /* Toss outdated events */
1739 evtdump
= (struct evtdump
*)buf
;
1740 if (evtdump
->timestamp
< evt_start
)
1743 if (evt_filter
& EVTF_ALL
)
1744 print_evt(buf
, len
);
1745 if (evt_filter
& EVTF_ERR
)
1746 print_err(buf
, len
);
1747 if (evt_filter
& EVTF_CFG
)
1748 print_cfg(buf
, len
);
1749 if (evt_filter
& EVTF_PH1DOWN
)
1750 print_ph1down(buf
, len
);
1756 switch (com
->ac_proto
) {
1757 case ADMIN_PROTO_ISAKMP
:
1758 dump_isakmp_sa(buf
, len
);
1760 case ADMIN_PROTO_IPSEC
:
1761 case ADMIN_PROTO_AH
:
1762 case ADMIN_PROTO_ESP
:
1764 struct sadb_msg
*msg
= (struct sadb_msg
*)buf
;
1766 switch (msg
->sadb_msg_errno
) {
1768 switch (msg
->sadb_msg_type
) {
1771 printf("No entry.\n");
1774 printf("No SAD entries.\n");
1781 if (msg
->sadb_msg_seq
== 0)
1783 msg
= (struct sadb_msg
*)((caddr_t
)msg
+
1784 PFKEY_UNUNIT64(msg
->sadb_msg_len
));
1788 printf("%s.\n", strerror(msg
->sadb_msg_errno
));
1792 case ADMIN_PROTO_INTERNAL
:
1793 dump_internal(buf
, len
);
1796 printf("Invalid proto [%d]\n", com
->ac_proto
);