C hash table code

This code modified from internet,insert IP and MAC to hashtable. Key is the last 16bit of MAC.

too busy without search and delete function, you can add them if your interested.

#ifndef _ZHASH_H_
#define _ZHASH_H_
#include 
#include 
#include 

#define MAXHASHSIZE	16
#define ETH_ALEN	6
typedef struct _hashentry
{
    void *key;
    void *ipaddr;
    void *mac;
    struct _hashentry *next;
}hashentry;

typedef struct _hashtable
{
    unsigned int (*gethash)(void *);
    int (*compare)(void *,void *);
    int hashsize;
    int count;
    hashentry **hashlist;
}hashtable;
typedef enum bool_t {
    FALSE = 0,
    TRUE
}bool;
hashtable *hash_create_t(unsigned int (*keyfunc)(void *),
		       int (*comparefunc)(void *,void *),
	  	       int size);
void hash_insert(void *key, void *ipaddr, void *mac, hashtable *tab);
unsigned int lh_strhash(void *src);
int equal_str(void *k1, void *k2);
void hash_print(hashtable *tab);
//void help();
#define hash_create(size)	hash_create_t(lh_strhash,equal_str,size)
#define hashindex(key, tab)	((tab->gethash)(key)) % (tab->hashsize)
#endif
#include "zhash.h"

unsigned int lh_strhash(void * src)
{
    int i, l;
    unsigned long ret = 0;
    unsigned short *s;
    char *str = (char *)src;
    if (str == NULL)
	return(0);
    l = (strlen(str) + 1) / 2;
    s = (unsigned short *)str;

    for (i = 0; i < l; i++)
	ret ^= s[i]<<(i&0x0f);
    return(ret);
}

int equal_str(void *k1, void *k2)
{
    return (0 == strcmp((char *)k1, (char *)k2));
}
hashentry *hlist_new(void *key, void *ipaddr, void *mac)
{
    hashentry *new = (hashentry *)malloc(sizeof(hashentry));

    new->key = key;
    new->ipaddr = ipaddr;
    new->mac = mac;
    new->next = NULL;
    return new;
}

void hlist_append(hashentry **root, void *key, void *ipaddr, void *mac)
{
    hashentry *new, *pos;
    new = hlist_new(key, ipaddr, mac);
    if(*root == NULL)
    {
	*root = new;
    }
    else
    {
	pos = *root;
	while(pos->next != NULL)
	    pos = pos->next;
	pos->next = new;
    }
}
bool hlist_update(hashentry *root, void *key,void *ipaddr,void *mac,int (*compare)(void *,void *))
{
    hashentry *pos;
    for(pos = root; pos != NULL; pos = pos->next)
    {
	if(compare(key,pos->key))
	{
//	    free(pos->ipaddr);
//	    free(pos->mac);
	    pos->ipaddr = ipaddr;
	    pos->mac = mac;
//	    free(key);
	    return TRUE;
	}
    }
    return FALSE;
}

void hash_insert(void *key, void *ipaddr, void *mac, hashtable *tab)
{
    unsigned int index = hashindex(key, tab);
    hashentry *root = tab->hashlist[index];
    if(!(hlist_update(root, key, ipaddr, mac, tab->compare)))
    {
	hlist_append(&tab->hashlist[index],key,ipaddr, mac);
	tab->count++;
    }
}

hashtable *hash_create_t(unsigned int (*keyfunc)(void *),
			int (*comparefunc)(void *,void *),
			int size)
{
    int i;
    int len = sizeof(hashentry *) * size;
    hashtable *tab = (hashtable *)malloc(sizeof(hashtable));
    memset (tab, 0, sizeof(hashtable *));

    tab->hashlist = (hashentry**)malloc(len);
    if(tab->hashlist == NULL)
    {
	free(tab);
	return NULL;
    }
    memset(tab->hashlist,0,len);

    for(i = 0; ihashlist[i] = NULL;
    }
    tab->gethash = keyfunc;
    tab->compare = comparefunc;
    tab->hashsize = size;
    tab->count = 0;

    return tab;
}

void hash_print(hashtable *tab)
{
    int i;
    int *p;
    hashentry *temp;
    printf("index\t%-20s\t%-20s\n","mac","ipaddr");
    for(i = 0; i < MAXHASHSIZE; i++)
    {
	temp = tab->hashlist[i];
	if(temp == NULL)
	    printf("%-d\t%-20s\t%-20s\n",i,"NULL","NULL");
	else
	    printf("%d\t",i);
	while(temp != NULL)
	{
	    p = (int *)(temp->mac);
	    printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\t",p[0],p[1],p[2],p[3],p[4],p[5]);
	    p = (int *)(temp->ipaddr);
	    const char *format = (temp->next == NULL)?("%d.%d.%d.%d\n"):("%d.%d.%d.%d -->\n\t");
	    printf(format,p[0],p[1],p[2],p[3]);
	    temp = temp->next;
	}
    }
}
/*
void help()
{
    printf("command: \n");
    printf("  -insert\n");
    printf("\t--usage: insert mac ipaddr  eg. insert 00:11:22:33:44:55 192.168.0.1\n");
    printf("\t--description: insert mac,ip to hash table,mac divided by \":\",and ip by \".\"\n");
    printf("  -del\n");
    printf("\t--usage:del key  eg.del 4455\n");
    printf("\t--description: delete from hash table,key is the last 16 bits of mac\n");
    printf("  -print\n");
    printf("\t--usage: print\n");
    printf("\t--description: print all over the hash table\n");
}*/
#include "zhash.h"

int main(int argc, char **argv)
{
    hashtable *tab = hash_create(MAXHASHSIZE);
    unsigned int mac[ETH_ALEN]={0x00,0x68,0x30,0x3b,0x2a,0x56};
    unsigned int ipaddr[4]={0xC0,0xA8,0x01,0x01};
    unsigned int mac1[ETH_ALEN]={0x00,0x69,0x30,0x3b,0x2a,0x42};
    unsigned int ipaddr1[4]={0xC0,0xA8,0x01,0x02};
    char key[5];
//    char key1[5];
    memset(key,0,5);
//    memset(key1,0,5);
    sprintf(key,"%.2x%.2x",mac[4],mac[5]);
    hash_insert((void *)key,(void *)ipaddr,(void *)mac,tab);
    sprintf(key,"%.2x%.2x",mac1[4],mac1[5]);
    hash_insert((void *)key,(void *)ipaddr1,(void *)mac1,tab);
    hash_print(tab);
    return 0;
}
CC = gcc
CFLAGS = -Wall -g
TARGET = zhash
SOURCE = \
zhash.c \
test.c
OBJS = $(SOURCE:%.c=%.o)

%.o:%.c
	$(CC) $(CFLAGS) -c $< -o $@

$(TARGET):$(OBJS)
	$(CC) $(OBJS) -o $@ 

clean:
	@echo "cleanning object..."
	-rm zhash *.o
	@echo "clean finished!"
.PHONY:clean
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章