]>
Commit | Line | Data |
---|---|---|
4749578d MW |
1 | /* Stroke for charon is the counterpart to whack from pluto |
2 | * Copyright (C) 2006 Martin Willi - Hochschule fuer Technik Rapperswil | |
3 | * | |
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>. | |
8 | * | |
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 | |
12 | * for more details. | |
13 | */ | |
14 | ||
f2ee13a7 MW |
15 | #include <stdlib.h> |
16 | #include <sys/types.h> | |
17 | #include <sys/stat.h> | |
18 | #include <sys/socket.h> | |
4749578d | 19 | #include <sys/un.h> |
f2ee13a7 | 20 | #include <sys/fcntl.h> |
4749578d | 21 | #include <unistd.h> |
f2ee13a7 | 22 | #include <dirent.h> |
4749578d | 23 | #include <errno.h> |
f2ee13a7 MW |
24 | #include <stdio.h> |
25 | #include <linux/stddef.h> | |
4749578d | 26 | |
f2ee13a7 | 27 | #include "stroke.h" |
4749578d MW |
28 | |
29 | static char* push_string(stroke_msg_t **strm, char *string) | |
30 | { | |
31 | stroke_msg_t *stroke_msg; | |
32 | size_t string_length; | |
33 | ||
34 | if (string == NULL) | |
35 | { | |
36 | return NULL; | |
37 | } | |
38 | stroke_msg = *strm; | |
39 | string_length = strlen(string) + 1; | |
40 | stroke_msg->length += string_length; | |
41 | ||
42 | stroke_msg = realloc(stroke_msg, stroke_msg->length); | |
43 | strcpy((char*)stroke_msg + stroke_msg->length - string_length, string); | |
44 | ||
45 | *strm = stroke_msg; | |
46 | return (char*)(u_int)stroke_msg->length - string_length; | |
47 | } | |
48 | ||
49 | static int send_stroke_msg (stroke_msg_t *msg) | |
50 | { | |
51 | struct sockaddr_un ctl_addr = { AF_UNIX, STROKE_SOCKET }; | |
52 | int sock; | |
f2ee13a7 MW |
53 | char buffer[64]; |
54 | int byte_count; | |
4749578d MW |
55 | |
56 | sock = socket(AF_UNIX, SOCK_STREAM, 0); | |
57 | if (sock < 0) | |
58 | { | |
f2ee13a7 | 59 | fprintf(stderr, "Opening unix socket %s: %s\n", STROKE_SOCKET, strerror(errno)); |
4749578d MW |
60 | return -1; |
61 | } | |
62 | if (connect(sock, (struct sockaddr *)&ctl_addr, | |
63 | offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0) | |
64 | { | |
f2ee13a7 | 65 | fprintf(stderr, "Connect to socket failed: %s\n", strerror(errno)); |
4749578d MW |
66 | close(sock); |
67 | return -1; | |
68 | } | |
69 | ||
4749578d MW |
70 | /* send message */ |
71 | if (write(sock, msg, msg->length) != msg->length) | |
72 | { | |
f2ee13a7 | 73 | fprintf(stderr, "writing to socket failed: %s\n", strerror(errno)); |
4749578d MW |
74 | close(sock); |
75 | return -1; | |
76 | } | |
f2ee13a7 MW |
77 | |
78 | while ((byte_count = read(sock, buffer, sizeof(buffer)-1)) > 0) | |
79 | { | |
80 | buffer[byte_count] = '\0'; | |
81 | printf("%s", buffer); | |
82 | } | |
83 | if (byte_count < 0) | |
84 | { | |
85 | fprintf(stderr, "reading from socket failed: %s\n", strerror(errno)); | |
86 | } | |
87 | ||
4749578d MW |
88 | close(sock); |
89 | return 0; | |
90 | } | |
91 | ||
92 | static int add_connection(char *name, | |
dec59822 | 93 | char *my_id, char *other_id, |
f2ee13a7 MW |
94 | char *my_cert, char *other_cert, |
95 | char *my_addr, char *other_addr, | |
dec59822 | 96 | char *my_net, char *other_net, |
f2ee13a7 | 97 | u_int my_netmask, u_int other_netmask) |
4749578d MW |
98 | { |
99 | stroke_msg_t *msg = malloc(sizeof(stroke_msg_t)); | |
100 | int res; | |
101 | ||
102 | msg->length = sizeof(stroke_msg_t); | |
103 | msg->type = STR_ADD_CONN; | |
104 | ||
105 | msg->add_conn.name = push_string(&msg, name); | |
106 | ||
107 | msg->add_conn.me.id = push_string(&msg, my_id); | |
f2ee13a7 | 108 | msg->add_conn.me.cert = push_string(&msg, my_cert); |
4749578d MW |
109 | msg->add_conn.me.address = push_string(&msg, my_addr); |
110 | msg->add_conn.me.subnet = push_string(&msg, my_net); | |
111 | msg->add_conn.me.subnet_mask = my_netmask; | |
112 | ||
113 | msg->add_conn.other.id = push_string(&msg, other_id); | |
f2ee13a7 | 114 | msg->add_conn.other.cert = push_string(&msg, other_cert); |
4749578d MW |
115 | msg->add_conn.other.address = push_string(&msg, other_addr); |
116 | msg->add_conn.other.subnet = push_string(&msg, other_net); | |
117 | msg->add_conn.other.subnet_mask = other_netmask; | |
118 | ||
119 | res = send_stroke_msg(msg); | |
120 | free(msg); | |
121 | return res; | |
122 | } | |
123 | ||
124 | static int initiate_connection(char *name) | |
125 | { | |
126 | stroke_msg_t *msg = malloc(sizeof(stroke_msg_t)); | |
127 | int res; | |
128 | ||
129 | msg->length = sizeof(stroke_msg_t); | |
130 | msg->type = STR_INITIATE; | |
131 | msg->initiate.name = push_string(&msg, name); | |
132 | res = send_stroke_msg(msg); | |
133 | free(msg); | |
134 | return res; | |
135 | } | |
136 | ||
f2ee13a7 MW |
137 | static int terminate_connection(char *name) |
138 | { | |
139 | stroke_msg_t *msg = malloc(sizeof(stroke_msg_t)); | |
140 | int res; | |
141 | ||
142 | msg->length = sizeof(stroke_msg_t); | |
143 | msg->type = STR_TERMINATE; | |
144 | msg->initiate.name = push_string(&msg, name); | |
145 | res = send_stroke_msg(msg); | |
146 | free(msg); | |
147 | return res; | |
148 | } | |
149 | ||
150 | static int show_status() | |
151 | { | |
152 | stroke_msg_t *msg = malloc(sizeof(stroke_msg_t)); | |
153 | int res; | |
154 | ||
155 | msg->length = sizeof(stroke_msg_t); | |
156 | msg->type = STR_STATUS; | |
157 | res = send_stroke_msg(msg); | |
158 | free(msg); | |
159 | return res; | |
160 | } | |
161 | ||
162 | static int set_logtype(char *context, char *type, int enable) | |
163 | { | |
164 | stroke_msg_t *msg = malloc(sizeof(stroke_msg_t)); | |
165 | int res; | |
166 | ||
167 | msg->length = sizeof(stroke_msg_t); | |
168 | msg->type = STR_LOGTYPE; | |
169 | msg->logtype.context = push_string(&msg, context); | |
170 | msg->logtype.type = push_string(&msg, type); | |
171 | msg->logtype.enable = enable; | |
172 | res = send_stroke_msg(msg); | |
173 | free(msg); | |
174 | return res; | |
175 | } | |
176 | ||
177 | static int set_loglevel(char *context, u_int level) | |
178 | { | |
179 | stroke_msg_t *msg = malloc(sizeof(stroke_msg_t)); | |
180 | int res; | |
181 | ||
182 | msg->length = sizeof(stroke_msg_t); | |
183 | msg->type = STR_LOGLEVEL; | |
184 | msg->loglevel.context = push_string(&msg, context); | |
185 | msg->loglevel.level = level; | |
186 | res = send_stroke_msg(msg); | |
187 | free(msg); | |
188 | return res; | |
189 | } | |
190 | ||
191 | static void exit_error(char *error) | |
192 | { | |
193 | if (error) | |
194 | { | |
195 | fprintf(stderr, "%s\n", error); | |
196 | } | |
197 | exit(-1); | |
198 | } | |
199 | ||
200 | static void exit_usage(char *error) | |
201 | { | |
202 | printf("Usage:\n"); | |
203 | printf(" Add a connection:\n"); | |
204 | printf(" stroke add NAME MY_ID OTHER_ID MY_CERT OTHER_CERT\\\n"); | |
205 | printf(" MY_ADDR OTHER_ADDR MY_NET OTHER_NET\\\n"); | |
206 | printf(" MY_NETBITS OTHER_NETBITS\n"); | |
207 | printf(" where: ID is any IKEv2 ID (currently only IPv4 adresses\n"); | |
208 | printf(" CERT is a certificate filename\n"); | |
209 | printf(" ADDR is a IPv4 address\n"); | |
210 | printf(" NET is a IPv4 address of the subnet to tunnel\n"); | |
211 | printf(" NETBITS is the size of the subnet, as the \"24\" in 192.168.0.0/24\n"); | |
212 | printf(" Initiate a connection:\n"); | |
213 | printf(" stroke up NAME\n"); | |
214 | printf(" where: NAME is a connection name added with \"stroke add\"\n"); | |
215 | printf(" Terminate a connection:\n"); | |
216 | printf(" stroke down NAME\n"); | |
217 | printf(" where: NAME is a connection name added with \"stroke add\"\n"); | |
218 | printf(" Set logtype for a logging context:\n"); | |
219 | printf(" stroke logtype CONTEXT TYPE ENABLE\n"); | |
220 | printf(" where: CONTEXT is PARSR|GNRAT|IKESA|SAMGR|CHDSA|MESSG|TPOOL|WORKR|SCHED|\n"); | |
221 | printf(" SENDR|RECVR|SOCKT|TESTR|DAEMN|CONFG|ENCPL|PAYLD\n"); | |
222 | printf(" TYPE is CONTROL|ERROR|AUDIT|RAW|PRIVATE\n"); | |
223 | printf(" ENABLE is 0|1\n"); | |
224 | printf(" Set loglevel for a logging context:\n"); | |
225 | printf(" stroke loglevel CONTEXT LEVEL\n"); | |
226 | printf(" where: CONTEXT is PARSR|GNRAT|IKESA|SAMGR|CHDSA|MESSG|TPOOL|WORKR|SCHED|\n"); | |
227 | printf(" SENDR|RECVR|SOCKT|TESTR|DAEMN|CONFG|ENCPL|PAYLD\n"); | |
228 | printf(" LEVEL is 0|1|2|3\n"); | |
229 | printf(" Show connection status:\n"); | |
230 | printf(" stroke status\n"); | |
231 | exit_error(error); | |
232 | } | |
233 | ||
4749578d MW |
234 | int main(int argc, char *argv[]) |
235 | { | |
f2ee13a7 MW |
236 | int res; |
237 | ||
238 | if (argc < 2) | |
239 | { | |
240 | exit_usage(NULL); | |
241 | } | |
4749578d | 242 | |
f2ee13a7 MW |
243 | if (strcmp(argv[1], "status") == 0 || |
244 | strcmp(argv[1], "statusall") == 0) | |
245 | { | |
246 | res = show_status(); | |
247 | } | |
4749578d | 248 | |
f2ee13a7 MW |
249 | else if (strcmp(argv[1], "up") == 0) |
250 | { | |
251 | if (argc < 3) | |
252 | { | |
253 | exit_usage("\"up\" needs a connection name"); | |
254 | } | |
255 | res = initiate_connection(argv[2]); | |
256 | } | |
257 | else if (strcmp(argv[1], "down") == 0) | |
4749578d | 258 | { |
f2ee13a7 MW |
259 | if (argc < 3) |
260 | { | |
261 | exit_usage("\"down\" needs a connection name"); | |
262 | } | |
263 | res = terminate_connection(argv[2]); | |
264 | } | |
265 | else if (strcmp(argv[1], "add") == 0) | |
266 | { | |
267 | if (argc < 13) | |
268 | { | |
269 | exit_usage("\"add\" needs more parameters..."); | |
270 | } | |
271 | res = add_connection(argv[2], | |
272 | argv[3], argv[4], | |
273 | argv[5], argv[6], | |
274 | argv[7], argv[8], | |
275 | argv[9], argv[10], | |
276 | atoi(argv[11]), atoi(argv[12])); | |
277 | } | |
278 | else if (strcmp(argv[1], "logtype") == 0) | |
279 | { | |
280 | if (argc < 5) | |
281 | { | |
282 | exit_usage("\"logtype\" needs more parameters..."); | |
283 | } | |
284 | res = set_logtype(argv[2], argv[3], atoi(argv[4])); | |
285 | } | |
286 | else if (strcmp(argv[1], "loglevel") == 0) | |
287 | { | |
288 | if (argc < 4) | |
289 | { | |
290 | exit_usage("\"logtype\" needs more parameters..."); | |
291 | } | |
292 | res = set_loglevel(argv[2], atoi(argv[3])); | |
293 | } | |
294 | else | |
295 | { | |
296 | exit_usage(NULL); | |
4749578d MW |
297 | } |
298 | ||
f2ee13a7 MW |
299 | if (res) |
300 | { | |
301 | exit_error("communication with charon failed!\n"); | |
302 | } | |
4749578d MW |
303 | return 0; |
304 | } |