4 * @brief Implementation of gateway_t.
9 * Copyright (C) 2007 Martin Willi
10 * Hochschule fuer Technik Rapperswil
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 #include <sys/types.h>
26 #include <sys/socket.h>
29 #include <sys/socket.h>
34 typedef struct private_gateway_t private_gateway_t
;
37 * private data of gateway
39 struct private_gateway_t
{
52 * host to connect using tcp
57 * socket file descriptor, > 0 if connected
62 * unique id assigned to each xml message
67 struct sockaddr_un unix_addr
= { AF_UNIX
, IPSEC_PIDDIR
"/charon.xml"};
70 * establish connection to gateway
72 static bool connect_(private_gateway_t
*this)
75 struct sockaddr
*addr
;
84 addr
= this->host
->get_sockaddr(this->host
);
85 len
= *this->host
->get_sockaddr_len(this->host
);
90 addr
= (struct sockaddr
*)&unix_addr
;
91 len
= sizeof(unix_addr
);
94 this->fd
= socket(family
, SOCK_STREAM
, 0);
99 if (connect(this->fd
, addr
, len
) != 0)
109 * Implementation of gateway_t.request.
111 static char* request(private_gateway_t
*this, char *xml
, ...)
127 len
= vsnprintf(buf
, sizeof(buf
), xml
, args
);
129 if (len
< 0 || len
>= sizeof(buf
))
133 if (send(this->fd
, buf
, len
, 0) != len
)
141 len
= recv(this->fd
, buf
, sizeof(buf
) - 1, 0);
156 * Implementation of gateway_t.query_ikesalist.
158 static enumerator_t
* query_ikesalist(private_gateway_t
*this)
160 char *str
, *name
, *value
;
162 enumerator_t
*e1
, *e2
, *e3
, *e4
= NULL
;
164 str
= request(this, "<message type=\"request\" id=\"%d\">"
168 "</message>", this->xmlid
++);
173 xml
= xml_create(str
);
179 e1
= xml
->children(xml
);
181 while (e1
->enumerate(e1
, &xml
, &name
, &value
))
183 if (streq(name
, "message"))
185 e2
= xml
->children(xml
);
186 while (e2
->enumerate(e2
, &xml
, &name
, &value
))
188 if (streq(name
, "query"))
190 e3
= xml
->children(xml
);
191 while (e3
->enumerate(e3
, &xml
, &name
, &value
))
193 if (streq(name
, "ikesalist"))
195 e4
= xml
->children(xml
);
214 * Implementation of gateway_t.query_configlist.
216 static enumerator_t
* query_configlist(private_gateway_t
*this)
218 char *str
, *name
, *value
;
220 enumerator_t
*e1
, *e2
, *e3
, *e4
= NULL
;
222 str
= request(this, "<message type=\"request\" id=\"%d\">"
226 "</message>", this->xmlid
++);
231 xml
= xml_create(str
);
237 e1
= xml
->children(xml
);
239 while (e1
->enumerate(e1
, &xml
, &name
, &value
))
241 if (streq(name
, "message"))
243 e2
= xml
->children(xml
);
244 while (e2
->enumerate(e2
, &xml
, &name
, &value
))
246 if (streq(name
, "query"))
248 e3
= xml
->children(xml
);
249 while (e3
->enumerate(e3
, &xml
, &name
, &value
))
251 if (streq(name
, "configlist"))
253 e4
= xml
->children(xml
);
271 * create enumerator over control elements children of a control response
273 static enumerator_t
* read_result(private_gateway_t
*this, char *res
)
277 enumerator_t
*e1
, *e2
, *e3
;
283 xml
= xml_create(res
);
288 e1
= xml
->children(xml
);
290 while (e1
->enumerate(e1
, &xml
, &name
, &value
))
292 if (streq(name
, "message"))
294 e2
= xml
->children(xml
);
295 while (e2
->enumerate(e2
, &xml
, &name
, &value
))
297 if (streq(name
, "control"))
299 e3
= xml
->children(xml
);
313 * Implementation of gateway_t.initiate.
315 static enumerator_t
* initiate(private_gateway_t
*this, bool ike
, char *name
)
327 str
= request(this, "<message type=\"request\" id=\"%d\">"
329 "<%ssainitiate>%s</%ssainitiate>"
331 "</message>", this->xmlid
++, kind
, name
, kind
);
332 return read_result(this, str
);
336 * Implementation of gateway_t.terminate.
338 static enumerator_t
* terminate(private_gateway_t
*this, bool ike
, u_int32_t id
)
350 str
= request(this, "<message type=\"request\" id=\"%d\">"
352 "<%ssaterminate>%d</%ssaterminate>"
354 "</message>", this->xmlid
++, kind
, id
, kind
);
355 return read_result(this, str
);
359 * Implementation of gateway_t.destroy
361 static void destroy(private_gateway_t
*this)
367 if (this->host
) this->host
->destroy(this->host
);
373 * generic constructor
375 static private_gateway_t
*gateway_create(char *name
)
377 private_gateway_t
*this = malloc_thing(private_gateway_t
);
379 this->public.request
= (char*(*)(gateway_t
*, char *xml
))request
;
380 this->public.query_ikesalist
= (enumerator_t
*(*)(gateway_t
*))query_ikesalist
;
381 this->public.query_configlist
= (enumerator_t
*(*)(gateway_t
*))query_configlist
;
382 this->public.initiate
= (enumerator_t
*(*)(gateway_t
*, bool ike
, char *name
))initiate
;
383 this->public.terminate
= (enumerator_t
*(*)(gateway_t
*, bool ike
, u_int32_t id
))terminate
;
384 this->public.destroy
= (void(*)(gateway_t
*))destroy
;
386 this->name
= strdup(name
);
397 gateway_t
*gateway_create_tcp(char *name
, host_t
*host
)
399 private_gateway_t
*this = gateway_create(name
);
403 return &this->public;
409 gateway_t
*gateway_create_unix(char *name
)
411 private_gateway_t
*this = gateway_create(name
);
413 return &this->public;