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