summaryrefslogtreecommitdiff
path: root/accel-pppd/ctrl/l2tp/dict.c
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pppd/ctrl/l2tp/dict.c')
-rw-r--r--accel-pppd/ctrl/l2tp/dict.c271
1 files changed, 271 insertions, 0 deletions
diff --git a/accel-pppd/ctrl/l2tp/dict.c b/accel-pppd/ctrl/l2tp/dict.c
new file mode 100644
index 0000000..c93ccd4
--- /dev/null
+++ b/accel-pppd/ctrl/l2tp/dict.c
@@ -0,0 +1,271 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include "list.h"
+#include "l2tp.h"
+#include "log.h"
+#include "triton.h"
+
+#include "memdebug.h"
+
+struct l2tp_dict_t
+{
+ struct list_head items;
+};
+
+static struct l2tp_dict_t *dict;
+
+#define BUF_SIZE 1024
+static char *path, *fname1, *buf;
+
+struct l2tp_dict_attr_t *l2tp_dict_find_attr_by_name(const char *name)
+{
+ struct l2tp_dict_attr_t *attr;
+
+ list_for_each_entry(attr, &dict->items, entry) {
+ if (!strcmp(attr->name, name))
+ return attr;
+ }
+
+ return NULL;
+}
+
+struct l2tp_dict_attr_t *l2tp_dict_find_attr_by_id(int id)
+{
+ struct l2tp_dict_attr_t *attr;
+
+ list_for_each_entry(attr, &dict->items, entry) {
+ if (attr->id == id)
+ return attr;
+ }
+
+ return NULL;
+}
+
+struct l2tp_dict_value_t *l2tp_dict_find_value(struct l2tp_dict_attr_t *attr, l2tp_value_t val)
+{
+ struct l2tp_dict_value_t *v;
+
+ list_for_each_entry(v, &attr->values, entry) {
+ switch (attr->type) {
+ case ATTR_TYPE_INT16:
+ if (v->val.int16 == val.int16)
+ return v;
+ break;
+ case ATTR_TYPE_INT32:
+ if (v->val.int32 == val.int32)
+ return v;
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static char *skip_word(char *ptr)
+{
+ for(; *ptr; ptr++)
+ if (*ptr == ' ' || *ptr == '\t' || *ptr == '\n')
+ break;
+ return ptr;
+}
+
+static char *skip_space(char *ptr)
+{
+ for(; *ptr; ptr++)
+ if (*ptr != ' ' && *ptr != '\t')
+ break;
+ return ptr;
+}
+
+static int split(char *buf, char **ptr)
+{
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ buf = skip_word(buf);
+ if (!*buf)
+ return i;
+
+ *buf = 0;
+
+ buf = skip_space(buf + 1);
+ if (!*buf)
+ return i;
+
+ ptr[i] = buf;
+ }
+
+ buf = skip_word(buf);
+ //if (*buf == '\n')
+ *buf = 0;
+ //else if (*buf)
+ // return -1;
+
+ return i;
+}
+
+
+static int dict_load(const char *fname)
+{
+ FILE *f;
+ char *ptr[6], *endptr;
+ struct l2tp_dict_attr_t *attr;
+ struct l2tp_dict_value_t *value;
+ struct list_head *items;
+ int i, r, n = 0;
+
+ f = fopen(fname, "r");
+ if (!f) {
+ log_emerg("l2tp: open '%s': %s\n", fname, strerror(errno));
+ return -1;
+ }
+
+ items = &dict->items;
+ while (fgets(buf, BUF_SIZE, f)) {
+ n++;
+ if (buf[0] == '#' || buf[0] == '\n' || buf[0] == 0)
+ continue;
+
+ r = split(buf, ptr);
+
+ if (!strcmp(buf, "$INCLUDE")) {
+ if (r != 1)
+ goto out_syntax;
+
+ for (i = strlen(path) - 1; i; i--) {
+ if (path[i] == '/') {
+ path[i + 1] = 0;
+ break;
+ }
+ }
+
+ strcpy(fname1, path);
+ strcat(fname1, ptr[0]);
+
+ if (dict_load(fname1))
+ goto out_err;
+ } else if (!strcmp(buf, "ATTRIBUTE")) {
+ if (r < 3)
+ goto out_syntax;
+
+ attr = malloc(sizeof(*attr));
+ memset(attr, 0, sizeof(*attr));
+ list_add_tail(&attr->entry, items);
+ INIT_LIST_HEAD(&attr->values);
+
+ attr->name = strdup(ptr[0]);
+ attr->id = strtol(ptr[1], &endptr, 10);
+ if (*endptr != 0)
+ goto out_syntax;
+
+ if (!strcmp(ptr[2], "none"))
+ attr->type = ATTR_TYPE_NONE;
+ else if (!strcmp(ptr[2], "int16"))
+ attr->type = ATTR_TYPE_INT16;
+ else if (!strcmp(ptr[2], "int32"))
+ attr->type = ATTR_TYPE_INT32;
+ else if (!strcmp(ptr[2], "int64"))
+ attr->type = ATTR_TYPE_INT64;
+ else if (!strcmp(ptr[2], "octets"))
+ attr->type = ATTR_TYPE_OCTETS;
+ else if (!strcmp(ptr[2], "string"))
+ attr->type = ATTR_TYPE_STRING;
+ else
+ goto out_syntax;
+
+ attr->M = -1;
+ attr->H = -1;
+
+ for (i = 3; i < r; i++) {
+ if (!strcmp(ptr[i], "M=0"))
+ attr->M = 0;
+ else if (!strcmp(ptr[i], "M=1"))
+ attr->M = 1;
+ else if (!strcmp(ptr[i], "H=0"))
+ attr->H = 0;
+ else if (!strcmp(ptr[i], "H=1"))
+ attr->H = 1;
+ else
+ goto out_syntax;
+ }
+ } else if (!strcmp(buf, "VALUE")) {
+ if (r != 3)
+ goto out_syntax;
+
+ attr = l2tp_dict_find_attr_by_name(ptr[0]);
+ if (!attr) {
+ log_emerg("l2tp:%s:%i: attribute not found\n", fname, n);
+ goto out_err;
+ }
+
+ value = malloc(sizeof(*value));
+ memset(value, 0, sizeof(*value));
+ list_add_tail(&value->entry, &attr->values);
+
+ value->name = strdup(ptr[1]);
+ switch (attr->type) {
+ case ATTR_TYPE_INT16:
+ case ATTR_TYPE_INT32:
+ value->val.int16 = strtol(ptr[2], &endptr, 10);
+ if (*endptr != 0)
+ goto out_syntax;
+ break;
+ case ATTR_TYPE_STRING:
+ value->val.string = strdup(ptr[2]);
+ break;
+ }
+ } else
+ goto out_syntax;
+ }
+
+ fclose(f);
+
+ return 0;
+
+out_syntax:
+ log_emerg("l2tp:%s:%i: syntaxis error\n", fname, n);
+out_err:
+ fclose(f);
+ return -1;
+}
+
+static int l2tp_dict_load(const char *fname)
+{
+ int r;
+
+ dict = _malloc(sizeof(*dict));
+ memset(dict, 0, sizeof(*dict));
+ INIT_LIST_HEAD(&dict->items);
+
+ path = _malloc(PATH_MAX);
+ fname1 = _malloc(PATH_MAX);
+ buf = _malloc(BUF_SIZE);
+
+ strcpy(path, fname);
+
+ r = dict_load(fname);
+
+ _free(buf);
+ _free(fname1);
+ _free(path);
+
+ return r;
+}
+
+static void __init dict_init(void)
+{
+ char *opt;
+
+ opt = conf_get_opt("l2tp", "dictionary");
+ if (!opt)
+ opt = DICTIONARY;
+
+ if (l2tp_dict_load(opt))
+ _exit(EXIT_FAILURE);
+}
+