aboutsummaryrefslogtreecommitdiffstats
path: root/src/manager/gateway.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/manager/gateway.c')
-rw-r--r--src/manager/gateway.c120
1 files changed, 110 insertions, 10 deletions
diff --git a/src/manager/gateway.c b/src/manager/gateway.c
index b918da26d..5f5a4b477 100644
--- a/src/manager/gateway.c
+++ b/src/manager/gateway.c
@@ -26,6 +26,10 @@
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <lib/xml.h>
typedef struct private_gateway_t private_gateway_t;
@@ -45,7 +49,7 @@ struct private_gateway_t {
char *name;
/**
- * connection information
+ * host to connect using tcp
*/
host_t *host;
@@ -55,22 +59,39 @@ struct private_gateway_t {
int fd;
};
+struct sockaddr_un unix_addr = { AF_UNIX, IPSEC_PIDDIR "/charon.xml"};
+
/**
* establish connection to gateway
*/
static bool connect_(private_gateway_t *this)
{
+ int family, len;
+ struct sockaddr *addr;
+
if (this->fd >= 0)
{
close(this->fd);
}
- this->fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (this->host)
+ {
+ family = AF_INET;
+ addr = this->host->get_sockaddr(this->host);
+ len = *this->host->get_sockaddr_len(this->host);
+ }
+ else
+ {
+ family = AF_UNIX;
+ addr = (struct sockaddr*)&unix_addr;
+ len = sizeof(unix_addr);
+ }
+
+ this->fd = socket(family, SOCK_STREAM, 0);
if (this->fd < 0)
{
return FALSE;
}
- if (connect(this->fd, this->host->get_sockaddr(this->host),
- *this->host->get_sockaddr_len(this->host)) != 0)
+ if (connect(this->fd, addr, len) != 0)
{
close(this->fd);
this->fd = -1;
@@ -79,7 +100,6 @@ static bool connect_(private_gateway_t *this)
return TRUE;
}
-
/**
* Implementation of gateway_t.request.
*/
@@ -119,7 +139,64 @@ static char* request(private_gateway_t *this, char *xml)
return strdup(buf);
}
}
+
+/**
+ * Implementation of gateway_t.query_ikesalist.
+ */
+static enumerator_t* query_ikesalist(private_gateway_t *this)
+{
+ char *str, *name, *value;
+ xml_t *xml;
+ enumerator_t *e1, *e2, *e3, *e4 = NULL;
+ str = request(this, "<message type=\"request\" id=\"1\">"
+ "<query>"
+ "<ikesalist/>"
+ "</query>"
+ "</message>");
+ if (str == NULL)
+ {
+ return NULL;
+ }
+ xml = xml_create(str);
+ if (xml == NULL)
+ {
+ return NULL;
+ }
+
+ e1 = xml->children(xml);
+ free(str);
+ while (e1->enumerate(e1, &xml, &name, &value))
+ {
+ if (streq(name, "message"))
+ {
+ e2 = xml->children(xml);
+ while (e2->enumerate(e2, &xml, &name, &value))
+ {
+ if (streq(name, "query"))
+ {
+ e3 = xml->children(xml);
+ while (e3->enumerate(e3, &xml, &name, &value))
+ {
+ if (streq(name, "ikesalist"))
+ {
+ e4 = xml->children(xml);
+ e1->destroy(e1);
+ e2->destroy(e2);
+ e3->destroy(e3);
+ return e4;
+ }
+ }
+ e3->destroy(e3);
+ }
+ }
+ e2->destroy(e2);
+ }
+ }
+ e1->destroy(e1);
+ return NULL;
+}
+
/**
* Implementation of gateway_t.destroy
*/
@@ -129,25 +206,48 @@ static void destroy(private_gateway_t *this)
{
close(this->fd);
}
- this->host->destroy(this->host);
+ if (this->host) this->host->destroy(this->host);
free(this->name);
free(this);
}
-/*
- * see header file
+/**
+ * generic constructor
*/
-gateway_t *gateway_create(char *name, host_t *host)
+static private_gateway_t *gateway_create(char *name)
{
private_gateway_t *this = malloc_thing(private_gateway_t);
this->public.request = (char*(*)(gateway_t*, char *xml))request;
+ this->public.query_ikesalist = (enumerator_t*(*)(gateway_t*))query_ikesalist;
this->public.destroy = (void(*)(gateway_t*))destroy;
this->name = strdup(name);
- this->host = host;
+ this->host = NULL;
this->fd = -1;
+ return this;
+}
+
+/**
+ * see header
+ */
+gateway_t *gateway_create_tcp(char *name, host_t *host)
+{
+ private_gateway_t *this = gateway_create(name);
+
+ this->host = host;
+
+ return &this->public;
+}
+
+/**
+ * see header
+ */
+gateway_t *gateway_create_unix(char *name)
+{
+ private_gateway_t *this = gateway_create(name);
+
return &this->public;
}