aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/interceptor/sshinetencode.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/interceptor/sshinetencode.c')
-rw-r--r--drivers/interceptor/sshinetencode.c130
1 files changed, 130 insertions, 0 deletions
diff --git a/drivers/interceptor/sshinetencode.c b/drivers/interceptor/sshinetencode.c
new file mode 100644
index 0000000..35b406f
--- /dev/null
+++ b/drivers/interceptor/sshinetencode.c
@@ -0,0 +1,130 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 Samsung Electronics
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * sshinetencode.c
+ *
+ * Implementation of inet API IP address encoding and decoding functions.
+ *
+ */
+
+#include "sshincludes.h"
+#include "sshencode.h"
+#include "sshinetencode.h"
+
+size_t ssh_encode_ipaddr_array(unsigned char *buf, size_t bufsize,
+ const SshIpAddr ip)
+{
+ if (!ip || ip->type == SSH_IP_TYPE_NONE)
+ return ssh_encode_array(buf, bufsize,
+ SSH_ENCODE_CHAR(SSH_IP_TYPE_NONE),
+ SSH_FORMAT_END);
+ return ssh_encode_array(buf, bufsize,
+ SSH_ENCODE_CHAR(ip->type),
+ SSH_ENCODE_UINT32(ip->mask_len),
+ SSH_ENCODE_DATA(ip->addr_data,
+ SSH_IP_ADDR_LEN(ip)),
+#ifdef WITH_IPV6
+ SSH_ENCODE_UINT32(ip->scope_id.scope_id_union.ui32),
+#endif /* WITH_IPV6 */
+ SSH_FORMAT_END);
+}
+
+size_t ssh_encode_ipaddr_array_alloc(unsigned char **buf_return,
+ const SshIpAddr ip)
+{
+ size_t req, got;
+
+ if (ip->type == SSH_IP_TYPE_NONE)
+ req = 1;
+ else
+#ifdef WITH_IPV6
+ req = 1 + 8 + SSH_IP_ADDR_LEN(ip);
+#else /* WITH_IPV6 */
+ req = 1 + 4 + SSH_IP_ADDR_LEN(ip);
+#endif /* WITH_IPV6 */
+
+ if (buf_return == NULL)
+ return req;
+
+ if ((*buf_return = ssh_malloc(req)) == NULL)
+ return 0;
+
+ got = ssh_encode_ipaddr_array(*buf_return, req, ip);
+
+ if (got != req)
+ {
+ ssh_free(*buf_return);
+ *buf_return = NULL;
+ return 0;
+ }
+
+ return got;
+}
+
+int ssh_decode_ipaddr_array(const unsigned char *buf, size_t len,
+ void * ipaddr)
+{
+ size_t point, got;
+ SshUInt32 mask_len;
+#ifdef WITH_IPV6
+ SshUInt32 scope_id;
+#endif /* WITH_IPV6 */
+ unsigned int type;
+ SshIpAddr ip = (SshIpAddr)ipaddr;
+ point = 0;
+
+ if ((got = ssh_decode_array(buf + point, len - point,
+ SSH_DECODE_CHAR(&type),
+ SSH_FORMAT_END)) != 1)
+ return 0;
+
+ /* Make sure scope-id (that is not present at the kernel) is
+ zeroed */
+ memset(ip, 0, sizeof(*ip));
+
+ ip->type = (SshUInt8) type;
+
+ point += got;
+
+ if (ip->type == SSH_IP_TYPE_NONE)
+ return point;
+
+ if ((got = ssh_decode_array(buf + point, len - point,
+ SSH_DECODE_UINT32(&mask_len),
+ SSH_DECODE_DATA(ip->addr_data,
+ SSH_IP_ADDR_LEN(ip)),
+#ifdef WITH_IPV6
+ SSH_DECODE_UINT32(&scope_id),
+ SSH_FORMAT_END)) != ((2 * sizeof(SshUInt32))
+ + SSH_IP_ADDR_LEN(ip)))
+#else /* WITH_IPV6 */
+ SSH_FORMAT_END)) != (4 + SSH_IP_ADDR_LEN(ip)))
+#endif /* WITH_IPV6 */
+ return 0;
+
+ /* Sanity check */
+ if (mask_len > 255)
+ return 0;
+
+ ip->mask_len = (SshUInt8) mask_len;
+
+ point += got;
+
+#ifdef WITH_IPV6
+ ip->scope_id.scope_id_union.ui32 = scope_id;
+#endif /* WITH_IPV6 */
+
+ /* Sanity check */
+ if (!SSH_IP_IS4(ip) && !SSH_IP_IS6(ip))
+ return 0;
+
+ return point;
+}