--- /dev/null
+/* PPPoE support library "libpppoe"
+ *
+ * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
+ * Jamal Hadi Salim <hadi@cyberus.ca>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "pppoe.h"
+
+
+#define PPPOE_HASH_SIZE 16
+
+
+static inline int keycmp(char *a, char *b, int x, int y){
+ return x==y && !memcmp(a,b,x);
+}
+
+static int hash_con(int key_len, char* key)
+{
+ int i = 0;
+ char hash[sizeof(int)]={0,};
+
+ for (i = 0; i < key_len ; ++i)
+ hash[i% sizeof(int)] = hash[i%sizeof(int)] ^ key[i];
+
+ i = (*((int*)hash)) ;
+ i &= PPPOE_HASH_SIZE - 1;
+
+ return i;
+}
+
+static struct pppoe_con *con_ht[PPPOE_HASH_SIZE] = { 0, };
+
+struct pppoe_con *get_con(int len, char *key)
+{
+ int hash = hash_con(len, key);
+ struct pppoe_con *ret;
+
+ ret = con_ht[hash];
+
+ while (ret && !keycmp(ret->key,key, ret->key_len, len))
+ ret = ret->next;
+
+ return ret;
+}
+
+int store_con(struct pppoe_con *pc)
+{
+ int hash = hash_con(pc->key_len, pc->key);
+ struct pppoe_con *ret;
+
+ ret = con_ht[hash];
+ while (ret) {
+ if (!keycmp(ret->key, pc->key, ret->key_len, pc->key_len))
+ return -EALREADY;
+
+ ret = ret->next;
+ }
+
+ if (!ret) {
+ pc->next = con_ht[hash];
+ con_ht[hash] = pc;
+ }
+
+ return 0;
+}
+
+struct pppoe_con *delete_con(unsigned long len, char *key)
+{
+ int hash = hash_con(len, key);
+ struct pppoe_con *ret, **src;
+
+ ret = con_ht[hash];
+ src = &con_ht[hash];
+
+ while (ret) {
+ if (keycmp(ret->key,key, ret->key_len, len)) {
+ *src = ret->next;
+ break;
+ }
+
+ src = &ret->next;
+ ret = ret->next;
+ }
+
+ return ret;
+}
+