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

📄 fa_hash.c

📁 mobile ip 在linux下的一种实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: fa_hash.c,v 1.8 2001/06/23 22:23:51 jm Exp $ * Foreign Agent - lower FA hash * * Dynamic hierarchial IP tunnel * Copyright (C) 1998-2001, 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. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdlib.h>#include <stddef.h>#include <assert.h>#include <string.h>#include <time.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <syslog.h>#include "debug.h"#include "hashtable.h"#include "agent_utils.h"#include "util.h"#include "tunnel.h"#include "fa.h"#include "fa_hash.h"#define DEBUG_FLAG 'F'#define EXPIRY_CHECK_INTERVAL 10extern struct sockaddr_in upper_fa_addr;extern struct interface_entry *up_interface;extern struct fa_nai_ext *fa_nai;extern struct fa_config *config;extern struct hashtable *tunnels_hash;/* hashtable containing 'struct lower_fa_data's */static struct hashtable *fa_hash = NULL;/* hashtable containing 'struct next_hop_data's */static struct hashtable *next_hash = NULL;/* the nonce value to be used in the next own FA registration request */static __u8 next_send_nonce[FA_REG_NONCE_LEN];/* the nonce value sent in the previous request */static __u8 next_wait_nonce[FA_REG_NONCE_LEN];static time_t last_reg_ok = 0; /* timestamp of the last acknowledged own FA				* reg. */static int next_wait_time = 1; /* seconds to wait between own FA reg. retries				*/static int denial_replies = 0; /* how many denial replies since the last				* succesful registration */#define MAX_WAIT_TIME 600time_t fa_reg_next_try = 0; /* next time the FA registration should be done */static int own_req_pending = 0; /* whether this FA waits a reply to its own				 * request */static void get_new_nonce(__u8 *nonce){	int i;	__u32 r;	for (i = 0; i < FA_REG_NONCE_LEN / 4; i++) {		r = get_rand32();		memcpy(&nonce[i * 4], &r, 4);	}}static intlower_fa_hashfunc(void *key, const int hashsize){        __u8 hash;        struct lower_fa_data *data;	int i;        data = (struct lower_fa_data *) key;	if (data->nai_len == 0)		return 0;	hash = data->nai[0];	for (i = 1; i < data->nai_len; i++) {		hash ^= data->nai[i];	}        return ((int) hash);}static intlower_fa_cmpfunc(void *key, struct node *cmprd){        struct lower_fa_data *data1, *data2;        assert(key != NULL && cmprd != NULL);        data1 = (struct lower_fa_data *) key;        data2 = (struct lower_fa_data *) cmprd;	if (data1->nai_len != data2->nai_len)		return 0;	if (memcmp(data1->nai, data2->nai, data1->nai_len) != 0)		return 0;	return 1;}static intnext_hop_hashfunc(void *key, const int hashsize){        __u8 *data = (__u8 *) key;        return ((int) (data[0] ^ data[1] ^ data[2] ^ data[3]));}static intnext_hop_cmpfunc(void *key, struct node *cmprd){	struct in_addr *addr;        struct next_hop_data *data;        assert(key != NULL && cmprd != NULL);	addr = (struct in_addr *) key;	data = (struct next_hop_data *) cmprd;	if (addr->s_addr != data->addr.s_addr)		return 0;	return 1;}int fa_hash_init(void){	fa_hash = hashtable_init(256);	if (fa_hash == NULL)		return 0;	next_hash = hashtable_init(256);	if (next_hash == NULL) {		hashtable_destroy(fa_hash);		fa_hash = NULL;		return 0;	}	return 1;}static intremove_fa_entry(struct node *node, void *data){	struct lower_fa_data *hdata;	time_t *now;	int i;	if (data == NULL) {		hashtable_remove(node);		free(node);		return 1;	}	hdata = (struct lower_fa_data *) node;	now = (time_t *) data;	if (hdata->expire + FA_HASH_EXPIRE_TIME < *now ||	    (hdata->expire < *now && !hdata->confirmed)) {		DEBUG(DEBUG_FLAG, "FA NAI[");		for (i = 0; i < hdata->nai_len; i++)			DEBUG(DEBUG_FLAG, "%c", hdata->nai[i]);		DEBUG(DEBUG_FLAG, "] expired\n");		hashtable_remove(node);		free(node);	}	return 1;}static intremove_next_hop_entry(struct node *node, void *data){	struct next_hop_data *hdata;	time_t *now;	hdata = (struct next_hop_data *) node;	if (data == NULL) {		/* forced deletion at cleanup, do not check tunnel removal		 * settings */		hashtable_remove(node);		free(node);		return 1;	}	now = (time_t *) data;	if (hdata->expire < *now) {		DEBUG(DEBUG_FLAG, "Next hop FA %s expired\n",		      inet_ntoa(hdata->addr));		tunnel_set_remove_all(tunnels_hash, hdata->addr);		hashtable_remove(node);		free(node);	}	return 1;}void fa_hash_destroy(void){	if (fa_hash != NULL) {		DEBUG(DEBUG_FLAG, "Removing dynamic FA information..\n");		hashtable_iterator(fa_hash, remove_fa_entry, NULL);		hashtable_destroy(fa_hash);	}	if (next_hash != NULL) {		DEBUG(DEBUG_FLAG, "Removing dynamic next lower FA "		      "information..\n");		hashtable_iterator(next_hash, remove_next_hop_entry, NULL);		hashtable_destroy(next_hash);	}}/* Check whether given FA NAI exists in the hashtable * Returns: NULL if NAI not found or pointer to interface_entry if NAI found */struct interface_entry* fa_hash_check(struct fa_nai_ext *nai){	struct lower_fa_data key, *data;	time_t now;	key.nai_len = GET_NAI_LEN(nai);	if (key.nai_len > MAX_NAI_LEN)		key.nai_len = MAX_NAI_LEN;	memcpy(key.nai, MSG_NAI_DATA(nai), key.nai_len);	data = (struct lower_fa_data *)		hashtable_fetch(fa_hash, lower_fa_hashfunc, &key,				lower_fa_cmpfunc);	if (data == NULL || !data->confirmed)		return NULL;	time(&now);	if (now > data->expire) {		DEBUG(DEBUG_FLAG, "FA reg. entry expired - marking it "		      "unconfirmed\n");		data->confirmed = 0;		return NULL;	}	return data->iface;}/* Check whether a valid entry for a given next hop address exists in the * hashtable * Returns: 0 not found, 1 found */int fa_hash_check_next_hop(struct in_addr addr){	struct next_hop_data *data;	time_t now;	data = (struct next_hop_data *)		hashtable_fetch(next_hash, next_hop_hashfunc, &addr,				next_hop_cmpfunc);	if (data == NULL)		return 0;	time(&now);	if (now > data->expire) {		DEBUG(DEBUG_FLAG, "Searched FA reg. entry expired - removing "		      "it\n");		tunnel_set_remove_all(tunnels_hash, addr);		hashtable_remove(&data->node);		free(data);		return 0;	}	return 1;}/* Remove expired entries from the hashtable */void fa_hash_expire(void){	static time_t last_check = 0;	time_t now;	time(&now);	if (now < last_check + EXPIRY_CHECK_INTERVAL)		return;	hashtable_iterator(fa_hash, remove_fa_entry, &now);	hashtable_iterator(next_hash, remove_next_hop_entry, &now);	last_check = now;}static void update_next_hop(struct in_addr addr, time_t expire){	struct next_hop_data *data;	data = (struct next_hop_data *)		hashtable_fetch(next_hash, next_hop_hashfunc, &addr,				next_hop_cmpfunc);	if (data == NULL) {		data = (struct next_hop_data *)			malloc(sizeof(struct next_hop_data));		if (data == NULL) {			DEBUG(DEBUG_FLAG, "update_next_hop - malloc failed\n");			return;		}		memset(data, 0, sizeof(struct next_hop_data));		list_init_node(&data->node);		data->addr = addr;		data->expire = expire;		hashtable_add(next_hash, next_hop_hashfunc, (void *) &addr,			      &data->node);		DEBUG(DEBUG_FLAG, "\tadded new next hop entry: %s, expire %s",		      inet_ntoa(addr), ctime(&expire));		return;	}	if (data->expire < expire) {		data->expire = expire;		DEBUG(DEBUG_FLAG, "\tupdated next hop entry: %s, expire %s",		      inet_ntoa(data->addr), ctime(&data->expire));	}}void fa_register(int dereg){	time_t now;	char buf[MAXMSG], *pos;	struct fa_reg_req *req;	struct fa_spi_entry *fa_spi;	int res;	if (config->highest_FA || fa_nai == NULL)		return;	time(&now);	if (dereg == FA_REGISTER && now < fa_reg_next_try)		return;	fa_reg_next_try = now + next_wait_time;	next_wait_time *= 2;	if (next_wait_time > MAX_WAIT_TIME)		next_wait_time = MAX_WAIT_TIME;	DEBUG(DEBUG_FLAG, "\tnext registration retry: %s",	      ctime(&fa_reg_next_try));	/* send FA registration request */	req = (struct fa_reg_req *) buf;	memset(req, 0, sizeof(struct fa_reg_req));	req->type = FA_REQ;	req->lifetime = dereg ? 0 : htons(config->fa_reg_lifetime);	get_new_nonce(next_wait_nonce);	memcpy(&req->down_nonce, next_wait_nonce, FA_REG_NONCE_LEN);	memcpy(&req->up_nonce, next_send_nonce, FA_REG_NONCE_LEN);	pos = (char *) (req + 1);	memcpy(pos, fa_nai, GET_NAI_EXT_LEN(fa_nai));	pos += GET_NAI_EXT_LEN(fa_nai);	fa_spi = get_fa_spi(0, upper_fa_addr.sin_addr, SPI_AGENT_FA);	if (fa_spi != NULL) {		pos += auth_add_vendor(			AUTH_ALG_MD5, fa_spi->shared_secret,			fa_spi->shared_secret_len, (unsigned char *) buf,			(struct vendor_msg_auth *) pos,			VENDOR_EXT_DYNAMICS_FF_AUTH,			htonl(fa_spi->spi));	}	DEBUG(DEBUG_FLAG, "Sending FA %sreg. request to %s:%i\n",	      dereg ? "de" : "", inet_ntoa(upper_fa_addr.sin_addr),

⌨️ 快捷键说明

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