1/* PPPoE support library "libpppoe"
2 *
3 * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
4 *		  Jamal Hadi Salim <hadi@cyberus.ca>
5 *
6 *  This program is free software; you can redistribute it and/or
7 *  modify it under the terms of the GNU General Public License
8 *  as published by the Free Software Foundation; either version
9 *  2 of the License, or (at your option) any later version.
10 */
11#include <pppoe.h>
12
13
14#define PPPOE_HASH_SIZE 16
15
16
17static inline int keycmp(char *a, char *b, int x, int y){
18    return x==y && !memcmp(a,b,x);
19}
20
21static int hash_con(int key_len, char* key)
22{
23    int i = 0;
24    char hash[sizeof(int)]={0,};
25
26    for (i = 0; i < key_len ; ++i)
27	hash[i% sizeof(int)] = hash[i%sizeof(int)] ^ key[i];
28
29    i = (*((int*)hash)) ;
30    i &= PPPOE_HASH_SIZE - 1;
31
32    return i;
33}
34
35static struct pppoe_con *con_ht[PPPOE_HASH_SIZE] = { 0, };
36
37struct pppoe_con *get_con(int len, char *key)
38{
39    int hash = hash_con(len, key);
40    struct pppoe_con *ret;
41
42    ret = con_ht[hash];
43
44    while (ret && !keycmp(ret->key,key, ret->key_len, len))
45	ret = ret->next;
46
47    return ret;
48}
49
50int store_con(struct pppoe_con *pc)
51{
52    int hash = hash_con(pc->key_len, pc->key);
53    struct pppoe_con *ret;
54
55    ret = con_ht[hash];
56    while (ret) {
57	if (!keycmp(ret->key, pc->key, ret->key_len, pc->key_len))
58	    return -EALREADY;
59
60	ret = ret->next;
61    }
62
63    if (!ret) {
64	pc->next = con_ht[hash];
65	con_ht[hash] = pc;
66    }
67
68    return 0;
69}
70
71struct pppoe_con *delete_con(unsigned long len, char *key)
72{
73    int hash = hash_con(len, key);
74    struct pppoe_con *ret, **src;
75
76    ret = con_ht[hash];
77    src = &con_ht[hash];
78
79    while (ret) {
80	if (keycmp(ret->key,key, ret->key_len, len)) {
81	    *src = ret->next;
82	    break;
83	}
84
85	src = &ret->next;
86	ret = ret->next;
87    }
88
89    return ret;
90}
91
92