⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fa_mn_addr.c

📁 mobile ip 在linux下的一种实现
💻 C
字号:
/* $Id: fa_mn_addr.c,v 1.6 2000/07/26 17:06:58 jm Exp $ * Foreign Agent - MN home address hash tables * * Dynamic hierarchial IP tunnel * Copyright (C) 1998-2000, Dynamics group * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. See README and COPYING for * more details. *//* MN home address hash tables are used to select a suitable upper tunnel type * in the lower FAs so that the non-unique addresses can be routed correctly * (i.e. do not use the same tunnel with two equal MN home addresses) */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdlib.h>#include <stddef.h>#include <assert.h>#include <string.h>#include <time.h>#include "debug.h"#include "hashtable.h"#include "fa_mn_addr.h"#define DEBUG_FLAG 'F'/* dynamically generated hashtable of FAs that are below this FA */struct mn_addr_data {	struct node node;	struct in_addr addr;};/* MN home address hashes for IPIP/keyed GRE selection */static struct hashtable *mn_addr_IPIP = NULL;static struct hashtable **mn_addr_GRE = NULL;static int mn_addr_GRE_count = 0;#define INIT_GRE_HASHES 8static intaddr_hash(void *key, const int hashsize){	unsigned char *c = key;	return *c ^ *(c + 1) ^ *(c + 2) ^ *(c + 3);}static intaddr_cmp(void *key, struct node *cmprd){	struct mn_addr_data *data = (struct mn_addr_data *) cmprd;	if (memcmp(key, &data->addr, 4) == 0)		return 1;	return 0;}/** * mn_addr_init: * * Initialize the MN home address hash tables * * Returns: 0 on success or -1 on failure.  */intmn_addr_init(void){	int i;	mn_addr_IPIP = hashtable_init(256);	if (mn_addr_IPIP == NULL)		return -1;	mn_addr_GRE = (struct hashtable **)		malloc(INIT_GRE_HASHES * sizeof(struct hashtable *));	if (mn_addr_GRE == NULL) {		free(mn_addr_IPIP);		mn_addr_IPIP = NULL;		return -1;	}	mn_addr_GRE_count = INIT_GRE_HASHES;	for (i = 0; i < INIT_GRE_HASHES; i++)		mn_addr_GRE[i] = NULL;	return 0;}/* Help function for mn_addr_free() - remove an entry from a hash table */static intremove_addr(struct node *node, void *data){	hashtable_remove(node);	return 1;}/** * mn_addr_free: * * Free the memory used by MN home address hash tables  */voidmn_addr_free(void){	int i;	if (mn_addr_IPIP != NULL) {		hashtable_iterator(mn_addr_IPIP, remove_addr, NULL);		hashtable_destroy(mn_addr_IPIP);	}	for (i = 0; i < mn_addr_GRE_count; i++) {		if (mn_addr_GRE[i] != NULL) {			hashtable_iterator(mn_addr_GRE[i], remove_addr, NULL);			hashtable_destroy(mn_addr_GRE[i]);		}	}}/** * mn_addr_add: * @addr: Address of MN * * Get a appropriate upper tunnel type for a new MN home address and add the * address to the hash table. * * Returns: * MN_ADDR_TUNNEL_ERROR (-2): failure (out of memory), * MN_ADDR_TUNNEL_IPIP (-1): use IPIP tunnel (no key) * >= 0: use GRE with the return value as the key  */intmn_addr_add(struct in_addr *addr){	struct mn_addr_data *entry;	int i, j;	entry = (struct mn_addr_data *) malloc(sizeof(struct mn_addr_data));	if (entry == NULL)		return MN_ADDR_TUNNEL_ERROR;	memset(entry, 0, sizeof(struct mn_addr_data));	list_init_node(&entry->node);	entry->addr.s_addr = addr->s_addr;	if (hashtable_fetch(mn_addr_IPIP, addr_hash, addr, addr_cmp) == NULL) {		hashtable_add(mn_addr_IPIP, addr_hash, addr, &entry->node);		return MN_ADDR_TUNNEL_IPIP;	}	for (i = 0; i < mn_addr_GRE_count; i++) {		if (mn_addr_GRE[i] == NULL) {			mn_addr_GRE[i] = hashtable_init(256);			if (mn_addr_GRE[i] == NULL) {				free(entry);				return MN_ADDR_TUNNEL_ERROR;			}			break;		}		if (hashtable_fetch(mn_addr_GRE[i], addr_hash, addr, addr_cmp)		    == NULL)			break;	}	if (i >= mn_addr_GRE_count) {		void *tmp;		/* no place found in the reserved hash tables - allocate more		 * space for tables */		tmp = realloc(mn_addr_GRE, 2 * mn_addr_GRE_count *			      sizeof(struct hashtable *));		if (tmp == NULL) {			free(entry);			return MN_ADDR_TUNNEL_ERROR;		}		mn_addr_GRE = (struct hashtable **) tmp;		for (j = mn_addr_GRE_count; j < 2 * mn_addr_GRE_count; j++)			mn_addr_GRE[j] = NULL;		i = mn_addr_GRE_count;		mn_addr_GRE_count *= 2;		mn_addr_GRE[i] = hashtable_init(256);		if (mn_addr_GRE[i] == NULL) {			free(entry);			return MN_ADDR_TUNNEL_ERROR;		}	}	hashtable_add(mn_addr_GRE[i], addr_hash, addr, &entry->node);	return i;}/** * mn_addr_remove: * @addr: * @type: -1  IPIP (no key) *        >= 0  GRE (type = key) * * Remove the given MN home address from the hash tables. * * Returns: 0 on success or -1 on failure.  */intmn_addr_remove(struct in_addr *addr, int type){	struct node *node;	if (type < -1)		return -1;	if (type == -1) {		if (mn_addr_IPIP == NULL)			return -1;		node = hashtable_fetch(mn_addr_IPIP, addr_hash, addr,				       addr_cmp);	} else {		if (type >= mn_addr_GRE_count || (mn_addr_GRE[type] == NULL))			return -1;		node = hashtable_fetch(mn_addr_GRE[type], addr_hash, addr,				       addr_cmp);	}	if (node != NULL) {		hashtable_remove(node);		return 0;	}	return -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -