e54931ad5aaa8a17d424e367833c8e276e5e37f3
1 /* Stroke for charon is the counterpart to whack from pluto
2 * Copyright (C) 2006 Martin Willi - Hochschule fuer Technik Rapperswil
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * RCSID $Id: starterstroke.c $
17 #include <sys/types.h>
18 #include <sys/socket.h>
20 #include <linux/stddef.h>
24 #include <netinet/in.h>
25 #include <arpa/inet.h>
29 #include <constants.h>
35 #include "starterstroke.h"
39 static char* push_string(stroke_msg_t
*msg
, char *string
)
41 u_int string_start
= msg
->length
;
43 if (string
== NULL
|| msg
->length
+ strlen(string
) >= sizeof(stroke_msg_t
))
49 msg
->length
+= strlen(string
) + 1;
50 strcpy((char*)msg
+ string_start
, string
);
51 return (char*)string_start
;
55 static int send_stroke_msg (stroke_msg_t
*msg
)
57 struct sockaddr_un ctl_addr
= { AF_UNIX
, CHARON_CTL_FILE
};
61 int sock
= socket(AF_UNIX
, SOCK_STREAM
, 0);
65 plog("socket() failed: %s", strerror(errno
));
68 if (connect(sock
, (struct sockaddr
*)&ctl_addr
, offsetof(struct sockaddr_un
, sun_path
) + strlen(ctl_addr
.sun_path
)) < 0)
70 plog("connect(charon_ctl) failed: %s", strerror(errno
));
76 if (write(sock
, msg
, msg
->length
) != msg
->length
)
78 plog("write(charon_ctl) failed: %s", strerror(errno
));
82 while ((byte_count
= read(sock
, buffer
, sizeof(buffer
)-1)) > 0)
84 buffer
[byte_count
] = '\0';
89 plog("read() failed: %s", strerror(errno
));
96 static char* connection_name(starter_conn_t
*conn
)
98 /* if connection name is '%auto', create a new name like conn_xxxxx */
101 if (streq(conn
->name
, "%auto"))
103 sprintf(buf
, "conn_%ld", conn
->id
);
109 static void ip_address2string(ip_address
*addr
, char *buffer
, size_t len
)
111 switch (((struct sockaddr
*)addr
)->sa_family
)
115 struct sockaddr_in
* sin
= (struct sockaddr_in
*)addr
;
116 if (inet_ntop(AF_INET
, &sin
->sin_addr
, buffer
, len
))
124 struct sockaddr_in6
* sin6
= (struct sockaddr_in6
*)addr
;
125 if (inet_ntop(AF_INET6
, &sin6
->sin6_addr
, buffer
, len
))
135 snprintf(buffer
, len
, "0.0.0.0");
139 static void starter_stroke_add_end(stroke_msg_t
*msg
, stroke_end_t
*msg_end
, starter_end_t
*conn_end
)
141 char buffer
[INET6_ADDRSTRLEN
];
143 msg_end
->id
= push_string(msg
, conn_end
->id
);
144 msg_end
->cert
= push_string(msg
, conn_end
->cert
);
145 msg_end
->ca
= push_string(msg
, conn_end
->ca
);
146 msg_end
->updown
= push_string(msg
, conn_end
->updown
);
147 ip_address2string(&conn_end
->addr
, buffer
, sizeof(buffer
));
148 msg_end
->address
= push_string(msg
, buffer
);
149 ip_address2string(&conn_end
->subnet
.addr
, buffer
, sizeof(buffer
));
150 msg_end
->subnet
= push_string(msg
, buffer
);
151 msg_end
->subnet_mask
= conn_end
->subnet
.maskbits
;
152 msg_end
->sendcert
= conn_end
->sendcert
;
153 msg_end
->protocol
= conn_end
->protocol
;
154 msg_end
->port
= conn_end
->port
;
157 int starter_stroke_add_conn(starter_conn_t
*conn
)
161 msg
.type
= STR_ADD_CONN
;
162 msg
.length
= offsetof(stroke_msg_t
, buffer
);
163 msg
.add_conn
.ikev2
= conn
->keyexchange
== KEY_EXCHANGE_IKEV2
;
164 msg
.add_conn
.name
= push_string(&msg
, connection_name(conn
));
165 if (conn
->policy
& POLICY_DONT_REKEY
)
167 msg
.add_conn
.rekey
.ipsec_lifetime
= 0;
168 msg
.add_conn
.rekey
.ike_lifetime
= 0;
169 msg
.add_conn
.rekey
.margin
= 0;
170 msg
.add_conn
.rekey
.tries
= 0;
171 msg
.add_conn
.rekey
.fuzz
= 0;
175 msg
.add_conn
.rekey
.ipsec_lifetime
= conn
->sa_ipsec_life_seconds
;
176 msg
.add_conn
.rekey
.ike_lifetime
= conn
->sa_ike_life_seconds
;
177 msg
.add_conn
.rekey
.margin
= conn
->sa_rekey_margin
;
178 msg
.add_conn
.rekey
.tries
= conn
->sa_keying_tries
;
179 msg
.add_conn
.rekey
.fuzz
= conn
->sa_rekey_fuzz
;
181 msg
.add_conn
.algorithms
.ike
= push_string(&msg
, conn
->ike
);
182 msg
.add_conn
.algorithms
.esp
= push_string(&msg
, conn
->esp
);
183 msg
.add_conn
.dpd
.delay
= conn
->dpd_delay
;
184 msg
.add_conn
.dpd
.action
= conn
->dpd_action
;
186 starter_stroke_add_end(&msg
, &msg
.add_conn
.me
, &conn
->right
);
187 starter_stroke_add_end(&msg
, &msg
.add_conn
.other
, &conn
->left
);
189 return send_stroke_msg(&msg
);
192 int starter_stroke_del_conn(starter_conn_t
*conn
)
196 msg
.type
= STR_DEL_CONN
;
197 msg
.length
= offsetof(stroke_msg_t
, buffer
);
198 msg
.del_conn
.name
= push_string(&msg
, connection_name(conn
));
199 return send_stroke_msg(&msg
);
202 int starter_stroke_route_conn(starter_conn_t
*conn
)
206 msg
.type
= STR_ROUTE
;
207 msg
.length
= offsetof(stroke_msg_t
, buffer
);
208 msg
.route
.name
= push_string(&msg
, connection_name(conn
));
209 return send_stroke_msg(&msg
);
212 int starter_stroke_initiate_conn(starter_conn_t
*conn
)
216 msg
.type
= STR_INITIATE
;
217 msg
.length
= offsetof(stroke_msg_t
, buffer
);
218 msg
.initiate
.name
= push_string(&msg
, connection_name(conn
));
219 return send_stroke_msg(&msg
);