2 * Copyright (C) 2007 Martin Willi
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 #include <sys/types.h>
19 #include <sys/socket.h>
22 #include <sys/socket.h>
27 typedef struct private_gateway_t private_gateway_t
;
30 * private data of gateway
32 struct private_gateway_t
{
45 * host to connect using tcp
50 * socket file descriptor, > 0 if connected
55 * unique id assigned to each xml message
60 struct sockaddr_un unix_addr
= { AF_UNIX
, IPSEC_PIDDIR
"/charon.xml"};
63 * establish connection to gateway
65 static bool connect_(private_gateway_t
*this)
68 struct sockaddr
*addr
;
77 addr
= this->host
->get_sockaddr(this->host
);
78 len
= *this->host
->get_sockaddr_len(this->host
);
83 addr
= (struct sockaddr
*)&unix_addr
;
84 len
= sizeof(unix_addr
);
87 this->fd
= socket(family
, SOCK_STREAM
, 0);
92 if (connect(this->fd
, addr
, len
) != 0)
102 * Implementation of gateway_t.request.
104 static char* request(private_gateway_t
*this, char *xml
, ...)
120 len
= vsnprintf(buf
, sizeof(buf
), xml
, args
);
122 if (len
< 0 || len
>= sizeof(buf
))
126 if (send(this->fd
, buf
, len
, 0) != len
)
134 len
= recv(this->fd
, buf
, sizeof(buf
) - 1, 0);
149 * Implementation of gateway_t.query_ikesalist.
151 static enumerator_t
* query_ikesalist(private_gateway_t
*this)
153 char *str
, *name
, *value
;
155 enumerator_t
*e1
, *e2
, *e3
, *e4
= NULL
;
157 str
= request(this, "<message type=\"request\" id=\"%d\">"
161 "</message>", this->xmlid
++);
166 xml
= xml_create(str
);
172 e1
= xml
->children(xml
);
174 while (e1
->enumerate(e1
, &xml
, &name
, &value
))
176 if (streq(name
, "message"))
178 e2
= xml
->children(xml
);
179 while (e2
->enumerate(e2
, &xml
, &name
, &value
))
181 if (streq(name
, "query"))
183 e3
= xml
->children(xml
);
184 while (e3
->enumerate(e3
, &xml
, &name
, &value
))
186 if (streq(name
, "ikesalist"))
188 e4
= xml
->children(xml
);
207 * Implementation of gateway_t.query_configlist.
209 static enumerator_t
* query_configlist(private_gateway_t
*this)
211 char *str
, *name
, *value
;
213 enumerator_t
*e1
, *e2
, *e3
, *e4
= NULL
;
215 str
= request(this, "<message type=\"request\" id=\"%d\">"
219 "</message>", this->xmlid
++);
224 xml
= xml_create(str
);
230 e1
= xml
->children(xml
);
232 while (e1
->enumerate(e1
, &xml
, &name
, &value
))
234 if (streq(name
, "message"))
236 e2
= xml
->children(xml
);
237 while (e2
->enumerate(e2
, &xml
, &name
, &value
))
239 if (streq(name
, "query"))
241 e3
= xml
->children(xml
);
242 while (e3
->enumerate(e3
, &xml
, &name
, &value
))
244 if (streq(name
, "configlist"))
246 e4
= xml
->children(xml
);
264 * create enumerator over control elements children of a control response
266 static enumerator_t
* read_result(private_gateway_t
*this, char *res
)
270 enumerator_t
*e1
, *e2
, *e3
;
276 xml
= xml_create(res
);
281 e1
= xml
->children(xml
);
283 while (e1
->enumerate(e1
, &xml
, &name
, &value
))
285 if (streq(name
, "message"))
287 e2
= xml
->children(xml
);
288 while (e2
->enumerate(e2
, &xml
, &name
, &value
))
290 if (streq(name
, "control"))
292 e3
= xml
->children(xml
);
306 * Implementation of gateway_t.initiate.
308 static enumerator_t
* initiate(private_gateway_t
*this, bool ike
, char *name
)
320 str
= request(this, "<message type=\"request\" id=\"%d\">"
322 "<%ssainitiate>%s</%ssainitiate>"
324 "</message>", this->xmlid
++, kind
, name
, kind
);
325 return read_result(this, str
);
329 * Implementation of gateway_t.terminate.
331 static enumerator_t
* terminate(private_gateway_t
*this, bool ike
, u_int32_t id
)
343 str
= request(this, "<message type=\"request\" id=\"%d\">"
345 "<%ssaterminate>%d</%ssaterminate>"
347 "</message>", this->xmlid
++, kind
, id
, kind
);
348 return read_result(this, str
);
352 * Implementation of gateway_t.destroy
354 static void destroy(private_gateway_t
*this)
360 if (this->host
) this->host
->destroy(this->host
);
366 * generic constructor
368 static private_gateway_t
*gateway_create(char *name
)
370 private_gateway_t
*this = malloc_thing(private_gateway_t
);
372 this->public.request
= (char*(*)(gateway_t
*, char *xml
))request
;
373 this->public.query_ikesalist
= (enumerator_t
*(*)(gateway_t
*))query_ikesalist
;
374 this->public.query_configlist
= (enumerator_t
*(*)(gateway_t
*))query_configlist
;
375 this->public.initiate
= (enumerator_t
*(*)(gateway_t
*, bool ike
, char *name
))initiate
;
376 this->public.terminate
= (enumerator_t
*(*)(gateway_t
*, bool ike
, u_int32_t id
))terminate
;
377 this->public.destroy
= (void(*)(gateway_t
*))destroy
;
379 this->name
= strdup(name
);
390 gateway_t
*gateway_create_tcp(char *name
, host_t
*host
)
392 private_gateway_t
*this = gateway_create(name
);
396 return &this->public;
402 gateway_t
*gateway_create_unix(char *name
)
404 private_gateway_t
*this = gateway_create(name
);
406 return &this->public;