1 /* $NetBSD: racoonctl.c,v 1.16 2009/03/12 10:57:26 tteras 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.
7 * Copyright (C) 2008 Timo Teras.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the project nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <sys/socket.h>
42 #include <netinet/in.h>
43 #include <arpa/inet.h>
44 #include <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_getsacert
__P((int, char **));
97 static vchar_t
*f_flushsa
__P((int, char **));
98 static vchar_t
*f_deletesa
__P((int, char **));
99 static vchar_t
*f_exchangesa
__P((int, char **));
100 static vchar_t
*f_vpnc
__P((int, char **));
101 static vchar_t
*f_vpnd
__P((int, char **));
102 static vchar_t
*f_getevt
__P((int, char **));
104 static vchar_t
*f_logoutusr
__P((int, char **));
108 vchar_t
*(*func
) __P((int, char **));
111 { f_reload
, "reload-config" },
113 { f_getsched
, "show-schedule" },
114 { f_getsched
, "sc" },
115 { f_getsa
, "show-sa" },
117 { f_getsacert
, "get-cert" },
118 { f_getsacert
, "gc" },
119 { f_flushsa
, "flush-sa" },
121 { f_deletesa
, "delete-sa" },
122 { f_deletesa
, "ds" },
123 { f_exchangesa
, "establish-sa" },
124 { f_exchangesa
, "es" },
125 { f_vpnc
, "vpn-connect" },
127 { f_vpnd
, "vpn-disconnect" },
129 { f_getevt
, "show-event" },
132 { f_logoutusr
, "logout-user" },
133 { f_logoutusr
, "lu" },
142 { EVT_RACOON_QUIT
, "Racoon terminated" },
144 { EVT_PHASE1_UP
, "Phase 1 established" },
145 { EVT_PHASE1_DOWN
, "Phase 1 deleted" },
146 { EVT_PHASE1_NO_RESPONSE
, "Phase 1 error: peer not responding" },
147 { EVT_PHASE1_NO_PROPOSAL
, "Phase 1 error: no proposal chosen" },
148 { EVT_PHASE1_AUTH_FAILED
,
149 "Phase 1 error: authentication failed (bad certificate?)" },
150 { EVT_PHASE1_DPD_TIMEOUT
, "Phase 1 error: dead peer detected" },
151 { EVT_PHASE1_MODE_CFG
, "Phase 1 mode configuration done" },
152 { EVT_PHASE1_XAUTH_SUCCESS
, "Phase 1 Xauth succeeded" },
153 { EVT_PHASE1_XAUTH_FAILED
, "Phase 1 Xauth failed" },
155 { EVT_PHASE2_NO_PHASE1
, "Phase 2 error: no suitable phase 1" },
156 { EVT_PHASE2_UP
, "Phase 2 established" },
157 { EVT_PHASE2_DOWN
, "Phase 2 deleted" },
158 { EVT_PHASE2_NO_RESPONSE
, "Phase 2 error: no response" },
161 static vchar_t
*get_proto_and_index
__P((int, char **, u_int16_t
*));
162 static int get_proto
__P((char *));
163 static vchar_t
*get_index
__P((int, char **));
164 static int get_family
__P((char *));
165 static vchar_t
*get_comindexes
__P((int, int, char **));
166 static int get_comindex
__P((char *, char **, char **, char **));
167 static int get_ulproto
__P((char *));
173 { ADMIN_PROTO_ISAKMP
, "isakmp" },
174 { ADMIN_PROTO_IPSEC
, "ipsec" },
175 { ADMIN_PROTO_AH
, "ah" },
176 { ADMIN_PROTO_ESP
, "esp" },
177 { ADMIN_PROTO_INTERNAL
, "internal" },
186 { IPPROTO_ICMP
, "icmp" },
187 { IPPROTO_TCP
, "tcp" },
188 { IPPROTO_UDP
, "udp" },
189 { IPPROTO_GRE
, "gre" },
195 static char _addr1_
[NI_MAXHOST
], _addr2_
[NI_MAXHOST
];
199 int evt_quit_event
= 0;
201 void dump_isakmp_sa
__P((char *, int));
202 void dump_internal
__P((char *, int));
203 char *pindex_isakmp
__P((isakmp_index
*));
204 void print_schedule
__P((caddr_t
, int));
205 void print_evt
__P((struct evt_async
*));
206 char * fixed_addr
__P((char *, char *, int));
213 " %s [opts] reload-config\n"
214 " %s [opts] show-schedule\n"
215 " %s [opts] show-sa [protocol]\n"
216 " %s [opts] flush-sa [protocol]\n"
217 " %s [opts] delete-sa <saopts>\n"
218 " %s [opts] establish-sa [-u identity] [-n remoteconf] [-w] <saopts>\n"
219 " %s [opts] vpn-connect [-u identity] vpn_gateway\n"
220 " %s [opts] vpn-disconnect vpn_gateway\n"
221 " %s [opts] show-event\n"
222 " %s [opts] logout-user login\n"
225 " -d Debug: hexdump admin messages before sending\n"
226 " -l Increase output verbosity (mainly for show-sa)\n"
227 " -s <socket> Specify adminport socket to use (default: %s)\n"
229 "Parameter specifications:\n"
230 " <protocol>: \"isakmp\", \"esp\" or \"ah\".\n"
231 " In the case of \"show-sa\" or \"flush-sa\", you can use \"ipsec\".\n"
233 " <saopts>: \"isakmp\" <family> <src> <dst>\n"
234 " : {\"esp\",\"ah\"} <family> <src/prefixlen/port> <dst/prefixlen/port>\n"
236 " <family>: \"inet\" or \"inet6\"\n"
237 " <ul_proto>: \"icmp\", \"tcp\", \"udp\", \"gre\" or \"any\"\n"
239 pname
, pname
, pname
, pname
, pname
, pname
, pname
, pname
, pname
, pname
,
244 * Check for proper racoonctl interface
246 #if ((RACOONCTL_INTERFACE_MAJOR != 1) || (RACOONCTL_INTERFACE < 20041230))
247 #error "Incompatible racoonctl interface"
261 * Check for proper racoonctl interface
263 if ((racoonctl_interface_major
!= RACOONCTL_INTERFACE_MAJOR
) ||
264 (racoonctl_interface
< RACOONCTL_INTERFACE
))
265 errx(1, "Incompatible racoonctl interface");
269 * Disable GNU extensions that will prevent racoonct vc -u login
270 * from working (GNU getopt(3) does not like options after vc)
272 setenv("POSIXLY_CORRECT", "1", 0);
274 while ((c
= getopt(ac
, av
, "lds:")) != -1) {
285 adminsock_path
= optarg
;
297 combuf
= get_combuf(ac
, av
);
302 racoon_hexdump(combuf
, ((struct admin_com
*)combuf
)->ac_len
);
306 if (com_send(combuf
) != 0)
312 if (com_recv(&combuf
) != 0)
314 if (handle_recv(combuf
) != 0)
317 } while (evt_quit_event
!= 0);
331 * return command buffer.
345 /* checking the string of command. */
346 for (cp
= &cmdtab
[0]; cp
->str
; cp
++) {
347 if (strcmp(*av
, cp
->str
) == 0) {
352 printf("Invalid command [%s]\n", *av
);
359 return (cp
->func
)(ac
, av
);
363 make_request(u_int16_t cmd
, u_int16_t proto
, size_t len
)
366 struct admin_com
*head
;
368 buf
= vmalloc(sizeof(struct admin_com
) + len
);
370 errx(1, "not enough core");
372 head
= (struct admin_com
*) buf
->v
;
373 head
->ac_len
= buf
->l
;
374 head
->ac_cmd
= ADMIN_FLAG_VERSION
| cmd
;
375 head
->ac_version
= 1;
376 head
->ac_proto
= proto
;
386 return make_request(ADMIN_RELOAD_CONF
, 0, 0);
396 errx(1, "too many arguments");
398 return make_request(ADMIN_SHOW_EVT
, 0, 0);
406 return make_request(ADMIN_SHOW_SCHED
, 0, 0);
418 errx(1, "insufficient arguments");
419 proto
= get_proto(*av
);
421 errx(1, "unknown protocol %s", *av
);
423 return make_request(ADMIN_SHOW_SA
, proto
, 0);
431 vchar_t
*buf
, *index
;
432 struct admin_com_indexes
*com
;
434 index
= get_index(ac
, av
);
438 com
= (struct admin_com_indexes
*) index
->v
;
439 buf
= make_request(ADMIN_GET_SA_CERT
, ADMIN_PROTO_ISAKMP
, index
->l
);
441 errx(1, "Cannot allocate buffer");
443 memcpy(buf
->v
+sizeof(struct admin_com
), index
->v
, index
->l
);
456 struct admin_com
*head
;
461 errx(1, "insufficient arguments");
462 proto
= get_proto(*av
);
464 errx(1, "unknown protocol %s", *av
);
466 return make_request(ADMIN_FLUSH_SA
, proto
, 0);
474 vchar_t
*buf
, *index
;
479 errx(1, "insufficient arguments");
480 proto
= get_proto(*av
);
482 errx(1, "unknown protocol %s", *av
);
488 case ADMIN_PROTO_ISAKMP
:
489 index
= get_index(ac
, av
);
494 case ADMIN_PROTO_ESP
:
495 index
= get_index(ac
, av
);
500 errno
= EPROTONOSUPPORT
;
504 buf
= make_request(ADMIN_DELETE_SA
, proto
, index
->l
);
508 memcpy(buf
->v
+ sizeof(struct admin_com
), index
->v
, index
->l
);
518 f_deleteallsadst(ac
, av
)
522 vchar_t
*buf
, *index
;
525 index
= get_proto_and_index(ac
, av
, &proto
);
529 buf
= make_request(ADMIN_DELETE_ALL_SA_DST
, proto
, index
->l
);
533 memcpy(buf
->v
+sizeof(struct admin_com
), index
->v
, index
->l
);
547 vchar_t
*buf
, *index
;
549 int cmd
= ADMIN_ESTABLISH_SA
;
553 char *remoteconf
= NULL
;
554 struct admin_com_psk
*acp
;
558 errx(1, "insufficient arguments");
560 /* Optional -u identity */
561 if (strcmp(av
[0], "-u") == 0) {
563 errx(1, "-u require an argument");
566 if ((key
= getpass("Password: ")) == NULL
)
567 errx(1, "getpass() failed: %s", strerror(errno
));
569 com_len
+= sizeof(*acp
) + strlen(id
) + 1 + strlen(key
) + 1;
570 cmd
= ADMIN_ESTABLISH_SA_PSK
;
576 if (ac
>= 2 && strcmp(av
[0], "-n") == 0) {
577 /* Remoteconf name */
583 if (ac
>= 1 && strcmp(av
[0], "-w") == 0) {
589 index
= get_proto_and_index(ac
, av
, &proto
);
593 if (proto
== ADMIN_PROTO_ISAKMP
&& cmd
== ADMIN_ESTABLISH_SA
&&
595 com_len
+= strlen(remoteconf
) + 1;
599 case ADMIN_PROTO_ISAKMP
:
600 evt_quit_event
= EVT_PHASE1_MODE_CFG
;
603 case ADMIN_PROTO_ESP
:
604 evt_quit_event
= EVT_PHASE2_UP
;
607 errno
= EPROTONOSUPPORT
;
613 buf
= make_request(cmd
, proto
, com_len
);
615 errx(1, "Cannot allocate buffer");
617 memcpy(buf
->v
+sizeof(struct admin_com
), index
->v
, index
->l
);
619 if (proto
== ADMIN_PROTO_ISAKMP
&& cmd
== ADMIN_ESTABLISH_SA
&&
620 remoteconf
!= NULL
) {
621 strcpy(buf
->v
+ sizeof(struct admin_com
) + index
->l
,
623 } else if (id
&& key
) {
625 acp
= (struct admin_com_psk
*)
626 (buf
->v
+ sizeof(struct admin_com
) + index
->l
);
628 acp
->id_type
= IDTYPE_USERFQDN
;
629 acp
->id_len
= strlen(id
) + 1;
630 acp
->key_len
= strlen(key
) + 1;
632 data
= (char *)(acp
+ 1);
635 data
= (char *)(data
+ acp
->id_len
);
649 char *nav
[] = {NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
651 char *isakmp
= "isakmp";
654 struct addrinfo hints
, *res
;
655 struct sockaddr
*src
;
659 errx(1, "insufficient arguments");
661 evt_quit_event
= EVT_PHASE1_MODE_CFG
;
663 /* Optional -u identity */
664 if (strcmp(av
[0], "-u") == 0) {
666 errx(1, "-u require an argument");
676 errx(1, "VPN gateway required");
678 warnx("Extra arguments");
681 * Find the source address
683 memset(&hints
, 0, sizeof(hints
));
684 hints
.ai_family
= PF_UNSPEC
;
685 hints
.ai_socktype
= SOCK_DGRAM
;
686 if (getaddrinfo(av
[0], "4500", &hints
, &res
) != 0)
687 errx(1, "Cannot resolve destination address");
689 if ((src
= getlocaladdr(res
->ai_addr
)) == NULL
)
690 errx(1, "cannot find source address");
692 if ((srcaddr
= saddr2str(src
)) == NULL
)
693 errx(1, "cannot read source address");
695 /* We get "ip[port]" strip the port */
696 if ((idx
= index(srcaddr
, '[')) == NULL
)
697 errx(1, "unexpected source address format");
702 nav
[nac
++] = srcaddr
;
705 return f_exchangesa(nac
, nav
);
713 char *nav
[] = {NULL
, NULL
, NULL
, NULL
};
715 char *isakmp
= "isakmp";
717 char *anyaddr
= "0.0.0.0";
721 errx(1, "VPN gateway required");
723 warnx("Extra arguments");
725 evt_quit_event
= EVT_PHASE1_DOWN
;
729 nav
[nac
++] = anyaddr
;
732 return f_deleteallsadst(nac
, nav
);
747 errx(1, "insufficient arguments");
749 userlen
= strlen(user
);
750 if ((user
== NULL
) || (userlen
> LOGINLEN
))
751 errx(1, "bad login (too long?)");
753 buf
= make_request(ADMIN_LOGOUT_USER
, 0, userlen
);
757 strncpy(buf
->v
+ sizeof(struct admin_com
), user
, userlen
);
761 #endif /* ENABLE_HYBRID */
764 get_proto_and_index(ac
, av
, proto
)
769 vchar_t
*index
= NULL
;
773 errx(1, "insufficient arguments");
774 *proto
= get_proto(*av
);
775 if (*proto
== (u_int16_t
) -1)
776 errx(1, "unknown protocol %s", *av
);
782 case ADMIN_PROTO_ISAKMP
:
784 case ADMIN_PROTO_ESP
:
785 index
= get_index(ac
, av
);
788 errno
= EPROTONOSUPPORT
;
798 struct proto_tag
*cp
;
805 /* checking the string of command. */
806 for (cp
= &prototab
[0]; cp
->str
; cp
++) {
807 if (strcmp(str
, cp
->str
) == 0)
822 if (ac
!= 3 && ac
!= 4) {
827 /* checking the string of family */
828 family
= get_family(*av
);
834 return get_comindexes(family
, ac
, av
);
841 if (strcmp("inet", str
) == 0)
844 else if (strcmp("inet6", str
) == 0)
847 errno
= EAFNOSUPPORT
;
852 get_comindexes(family
, ac
, av
)
858 struct admin_com_indexes
*ci
;
859 char *p_name
= NULL
, *p_port
= NULL
;
860 char *p_prefs
= NULL
, *p_prefd
= NULL
;
861 struct sockaddr
*src
= NULL
, *dst
= NULL
;
864 if (ac
!= 2 && ac
!= 3) {
869 if (get_comindex(*av
, &p_name
, &p_port
, &p_prefs
) == -1)
871 src
= get_sockaddr(family
, p_name
, p_port
);
884 if (get_comindex(*av
, &p_name
, &p_port
, &p_prefd
) == -1)
886 dst
= get_sockaddr(family
, p_name
, p_port
);
898 buf
= vmalloc(sizeof(*ci
));
905 ulproto
= get_ulproto(*av
);
911 ci
= (struct admin_com_indexes
*)buf
->v
;
913 ci
->prefs
= (u_int8_t
)atoi(p_prefs
); /* XXX should be handled error. */
917 ci
->prefd
= (u_int8_t
)atoi(p_prefd
); /* XXX should be handled error. */
920 ci
->ul_proto
= ulproto
;
921 memcpy(&ci
->src
, src
, sysdep_sa_len(src
));
922 memcpy(&ci
->dst
, dst
, sysdep_sa_len(dst
));
935 racoon_free(p_prefs
);
937 racoon_free(p_prefd
);
942 get_comindex(str
, name
, port
, pref
)
943 char *str
, **name
, **port
, **pref
;
947 *name
= *port
= *pref
= NULL
;
949 *name
= racoon_strdup(str
);
951 p
= strpbrk(*name
, "/[");
953 if (*(p
+ 1) == '\0')
957 *pref
= racoon_strdup(p
+ 1);
959 p
= strchr(*pref
, '[');
961 if (*(p
+ 1) == '\0')
964 *port
= racoon_strdup(p
+ 1);
966 p
= strchr(*pref
, ']');
971 } else if (*p
== '[') {
975 *port
= racoon_strdup(p
+ 1);
977 p
= strchr(*pref
, ']');
996 *name
= *port
= *pref
= NULL
;
1004 struct ulproto_tag
*cp
;
1011 /* checking the string of upper layer protocol. */
1012 for (cp
= &ulprototab
[0]; cp
->str
; cp
++) {
1013 if (strcmp(str
, cp
->str
) == 0)
1014 return cp
->ul_proto
;
1023 dump_isakmp_sa(buf
, len
)
1032 /* isakmp status header */
1034 1234567890123456789012 0000000000000000:0000000000000000 000000000000
1037 "Destination Cookies Created";
1039 /* semi long header;
1040 1234567890123456789012 0000000000000000:0000000000000000 00 X 00 X 0000-00-00 00:00:00 000000
1043 "Destination Cookies ST S V E Created Phase2";
1046 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
1049 "Source Destination Cookies ST S V E Created Phase2";
1051 /* phase status header */
1053 side stats source address destination address
1054 xxx xxxxx 1234567890123456789012 1234567890123456789012
1057 static char *estr
[] = { "", "B", "M", "U", "A", "I", };
1059 switch (long_format
) {
1061 printf("%s\n", header1
);
1064 printf("%s\n", header2
);
1068 printf("%s\n", header3
);
1072 if (len
% sizeof(*pd
))
1073 printf("invalid length %d\n", len
);
1076 pd
= (struct ph1dump
*)buf
;
1079 /* source address */
1080 if (long_format
>= 2) {
1081 GETNAMEINFO((struct sockaddr
*)&pd
->local
, _addr1_
, _addr2_
);
1082 switch (long_format
) {
1086 p
= fixed_addr(_addr1_
, _addr2_
, 22);
1090 p
= fixed_addr(_addr1_
, _addr2_
, 45);
1096 /* destination address */
1097 GETNAMEINFO((struct sockaddr
*)&pd
->remote
, _addr1_
, _addr2_
);
1098 switch (long_format
) {
1101 p
= fixed_addr(_addr1_
, _addr2_
, 22);
1105 p
= fixed_addr(_addr1_
, _addr2_
, 45);
1110 printf("%s ", pindex_isakmp(&pd
->index
));
1112 /* statuc, side and version */
1113 if (long_format
>= 1) {
1114 printf("%2d %c %2x ",
1116 pd
->side
== INITIATOR
? 'I' : 'R',
1118 if (ARRAYLEN(estr
) > pd
->etype
)
1119 printf("%s ", estr
[pd
->etype
]);
1124 tm
= localtime(&pd
->created
);
1125 strftime(tbuf
, sizeof(tbuf
), "%Y-%m-%d %T", tm
);
1127 snprintf(tbuf
, sizeof(tbuf
), " ");
1128 printf("%s ", tbuf
);
1130 /* counter of phase 2 */
1131 if (long_format
>= 1)
1132 printf("%6d ", pd
->ph2cnt
);
1144 dump_internal(buf
, tlen
)
1148 struct ph2handle
*iph2
;
1149 struct sockaddr
*addr
;
1153 source address destination address
1154 1234567890123456789012 1234567890123456789012
1157 "Source Destination ";
1161 source address destination address
1162 123456789012345678901234567890123456789012345 123456789012345678901234567890123456789012345
1163 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
1166 "Source Destination ";
1168 printf("%s\n", long_format
? long_h1
: short_h1
);
1171 iph2
= (struct ph2handle
*)buf
;
1172 addr
= (struct sockaddr
*)(++iph2
);
1174 GETNAMEINFO(addr
, _addr1_
, _addr2_
);
1175 printf("%s ", long_format
?
1176 fixed_addr(_addr1_
, _addr2_
, 45)
1177 : fixed_addr(_addr1_
, _addr2_
, 22));
1179 tlen
-= sysdep_sa_len(addr
);
1181 GETNAMEINFO(addr
, _addr1_
, _addr2_
);
1182 printf("%s ", long_format
?
1183 fixed_addr(_addr1_
, _addr2_
, 45)
1184 : fixed_addr(_addr1_
, _addr2_
, 22));
1186 tlen
-= sysdep_sa_len(addr
);
1196 pindex_isakmp(index
)
1197 isakmp_index
*index
;
1199 static char buf
[64];
1203 memset(buf
, 0, sizeof(buf
));
1206 p
= (u_char
*)index
;
1207 for (j
= 0, i
= 0; i
< sizeof(isakmp_index
); i
++) {
1208 snprintf((char *)&buf
[j
], sizeof(buf
) - j
, "%02x", p
[i
]);
1222 /* print schedule */
1223 char *str_sched_stat
[] = {
1229 char *str_sched_id
[] = {
1238 print_schedule(buf
, len
)
1242 struct scheddump
*sc
= (struct scheddump
*)buf
;
1246 if (len
% sizeof(*sc
))
1247 printf("invalid length %d\n", len
);
1250 /* 00000000 00000000 00000000 xxx........*/
1251 printf("index tick xtime created\n");
1254 tm
= localtime(&sc
->created
);
1255 strftime(tbuf
, sizeof(tbuf
), "%Y-%m-%d %T", tm
);
1257 printf("%-8ld %-8ld %-8ld %s\n",
1271 struct evt_async
*evtdump
;
1277 for (i
= 0; i
< sizeof(evtmsg
) / sizeof(evtmsg
[0]); i
++)
1278 if (evtmsg
[i
].type
== evtdump
->ec_type
)
1281 if (evtmsg
[i
].msg
== NULL
)
1282 printf("Event %d: ", evtdump
->ec_type
);
1284 printf("%s : ", evtmsg
[i
].msg
);
1286 if ((srcstr
= saddr2str((struct sockaddr
*)&evtdump
->ec_ph1src
)) == NULL
)
1289 printf("%s", srcstr
);
1291 if ((dststr
= saddr2str((struct sockaddr
*)&evtdump
->ec_ph1dst
)) == NULL
)
1294 printf("%s", dststr
);
1299 * Print ISAKMP mode config info (IP and banner)
1306 struct evt_async
*evtdump
= (struct evt_async
*)buf
;
1307 struct isakmp_data
*attr
;
1308 char *banner
= NULL
;
1309 struct in_addr addr4
;
1311 memset(&addr4
, 0, sizeof(addr4
));
1313 if (evtdump
->ec_type
!= EVT_PHASE1_MODE_CFG
)
1316 len
-= sizeof(*evtdump
);
1317 attr
= (struct isakmp_data
*)(evtdump
+ 1);
1320 if (len
< sizeof(*attr
)) {
1321 printf("short attribute too short\n");
1325 if ((ntohs(attr
->type
) & ISAKMP_GEN_MASK
) == ISAKMP_GEN_TV
) {
1326 /* Short attribute, skip */
1327 len
-= sizeof(*attr
);
1329 } else { /* Long attribute */
1332 if (len
< (sizeof(*attr
) + ntohs(attr
->lorv
))) {
1333 printf("long attribute too long\n");
1337 switch (ntohs(attr
->type
) & ~ISAKMP_GEN_MASK
) {
1338 case INTERNAL_IP4_ADDRESS
:
1339 if (ntohs(attr
->lorv
) < sizeof(addr4
)) {
1340 printf("addr4 attribute too short\n");
1343 memcpy(&addr4
, attr
+ 1, sizeof(addr4
));
1347 banner
= racoon_malloc(ntohs(attr
->lorv
) + 1);
1348 if (banner
== NULL
) {
1349 printf("malloc failed\n");
1352 memcpy(banner
, attr
+ 1, ntohs(attr
->lorv
));
1353 banner
[ntohs(attr
->lorv
)] = '\0';
1360 len
-= (sizeof(*attr
) + ntohs(attr
->lorv
));
1362 attr
= (struct isakmp_data
*)
1363 (n
+ sizeof(*attr
) + ntohs(attr
->lorv
));
1368 printf("Bound to address %s\n", inet_ntoa(addr4
));
1370 printf("VPN connexion established\n");
1377 if (ioctl(1, TIOCGWINSZ
, &win
) != 1)
1380 for (i
= 0; i
< col
; i
++)
1382 printf("\n%s\n", banner
);
1383 for (i
= 0; i
< col
; i
++)
1386 racoon_free(banner
);
1392 fixed_addr(addr
, port
, len
)
1396 static char _addr_buf_
[BUFSIZ
];
1401 memset(_addr_buf_
, ' ', sizeof(_addr_buf_
));
1403 plen
= strlen(port
);
1408 for (i
= 0; i
< len
- plen
- 1 && addr
[i
] != '\0'; /*noting*/)
1412 for (i
= 0; i
< plen
&& port
[i
] != '\0'; /*noting*/)
1415 _addr_buf_
[len
] = '\0';
1424 struct admin_com
*com
;
1428 com
= (struct admin_com
*)combuf
->v
;
1429 len
= com
->ac_len
- sizeof(*com
);
1430 buf
= combuf
->v
+ sizeof(*com
);
1432 switch (com
->ac_cmd
) {
1433 case ADMIN_SHOW_SCHED
:
1434 print_schedule(buf
, len
);
1437 case ADMIN_SHOW_EVT
: {
1438 struct evt_async
*ec
;
1440 /* We got no event? */
1444 if (len
< sizeof(struct evt_async
))
1445 errx(1, "Short buffer\n");
1447 ec
= (struct evt_async
*) buf
;
1448 if (evt_quit_event
<= 0)
1450 else if (evt_quit_event
== ec
->ec_type
) {
1451 switch (ec
->ec_type
) {
1452 case EVT_PHASE1_MODE_CFG
:
1464 case ADMIN_GET_SA_CERT
:
1465 fwrite(buf
, len
, 1, stdout
);
1470 switch (com
->ac_proto
) {
1471 case ADMIN_PROTO_ISAKMP
:
1472 dump_isakmp_sa(buf
, len
);
1474 case ADMIN_PROTO_IPSEC
:
1475 case ADMIN_PROTO_AH
:
1476 case ADMIN_PROTO_ESP
:
1478 struct sadb_msg
*msg
= (struct sadb_msg
*)buf
;
1480 switch (msg
->sadb_msg_errno
) {
1482 switch (msg
->sadb_msg_type
) {
1485 printf("No entry.\n");
1488 printf("No SAD entries.\n");
1495 if (msg
->sadb_msg_seq
== 0)
1497 msg
= (struct sadb_msg
*)((caddr_t
)msg
+
1498 PFKEY_UNUNIT64(msg
->sadb_msg_len
));
1502 printf("%s.\n", strerror(msg
->sadb_msg_errno
));
1506 case ADMIN_PROTO_INTERNAL
:
1507 dump_internal(buf
, len
);
1510 printf("Invalid proto [%d]\n", com
->ac_proto
);