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

📄 sha_utils.c

📁 mobile ip 在linux下的一种实现
💻 C
字号:
/* $Id: sha_utils.c,v 1.6 2001/02/25 09:38:34 jm Exp $ * Surrogate Home Agent - independent help routines * * Dynamic hierarchial IP tunnel * Copyright (C) 1998-2001, Jouni Malinen * * 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. */#include <stdlib.h>#include <unistd.h>#include <syslog.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <string.h>#include "dyn_ip.h"#include "binding.h"#include "debug.h"#include "tunnel.h"#include "sha.h"#include "sha_utils.h"static voidfree_unconfirmed_data(struct unconfirmed_request *unc){	struct unconfirmed_request *prev;	while (unc != NULL) {		prev = unc;		unc = unc->next;		free(prev);	}}static voidfree_binding(struct bindingentry *binding, int *count){	struct tunnel_data *t_data;	if (binding == NULL || binding->data == NULL)		return;	t_data = (struct tunnel_data *) binding->data;	free_unconfirmed_data(t_data->unc_req);	if (t_data->confirmed && count != NULL)		*count -= 1;	free(binding->data);	free(binding);}static intelim_binding(struct node *node, void *data, int force){	struct bindingentry *binding;	int *count, type;	struct tunnel_data *t_data;	binding = (struct bindingentry *) node;	t_data = (struct tunnel_data *) binding->data;	count = (int *) data;	if (t_data->confirmed) {		if (tunnel_unconnect(t_data->up_tunl, t_data->down_tunl,				     binding->mn_addr, 1, force, NULL, NULL) <		    0) {			LOG2(LOG_WARNING, "tunnel unconnect failed "			     "(tun_dev=%s)\n", binding->tun_dev);		}		if (tunnel_delete_ptr(t_data->down_tunl, force) == -1) {			LOG2(LOG_WARNING,			     "tunnel down - tunnel_delete failed\n");		}		if (tunnel_delete_ptr(t_data->up_tunl, force) == -1) {			LOG2(LOG_WARNING,			     "tunnel up - tunnel_delete failed\n");		}	}	if (t_data->up_type == TUNNEL_IPIP)		type = -1;	else		type = t_data->up_key;	binding_remove(binding);	free_binding(binding, count);	return TRUE;}inteliminate_binding_entry(struct node *node, void *data){	return elim_binding(node, data, 0);}inteliminate_binding_entry_force(struct node *node, void *data){	return elim_binding(node, data, 1);}static voidremove_binding_tunnels(struct bindingentry *binding, struct hashtable *thash,		       int *bindingcount){	struct tunnel_data *t_data;	struct in_addr dst_addr, mn_addr, ha_addr;	int up_type;	__u32 up_key ;	t_data = binding->data;	up_type = t_data->up_type;	up_key = t_data->up_key;	if (t_data->up_tunl)		dst_addr = t_data->up_tunl->dst_addr;	else		dst_addr.s_addr = 0;	/* Remove possible tunnel upwards to HA also */	mn_addr.s_addr = binding->mn_addr.s_addr;	ha_addr.s_addr = binding->ha_addr.s_addr;	eliminate_binding_entry((struct node *) binding, bindingcount);}/* Check and remove expired bindings */voidcheck_bindings(struct bindingtable *bhash, struct hashtable *thash,	       int *bindingcount, time_t now){	static time_t prev_check;	static int first = 1;	struct bindingentry *binding;	static time_t advance_expire_time;	int diff;	time_t time_check;	if (first) {		time(&prev_check);		time(&advance_expire_time);		first = 0;	}	/* don't check too frequently */	if (now - prev_check < 1)		return;	prev_check = now;	time(&time_check);	diff = time_check - advance_expire_time;	advance_expire_time = time_check;	if (diff < 0) {		LOG2(LOG_WARNING,		     "check_bindings: diff(%i) < 0 - system time changed?\n",		     diff);		diff = 0;	}	binding = binding_getexpired(bhash, diff);	while (binding != NULL) {		struct tunnel_data *t_data;		t_data = (struct tunnel_data *) binding->data;		DEBUG(DEBUG_FLAG, "check_bindings: binding expired\n");		DEBUG(DEBUG_FLAG, "\tdiff = %d, expiretime = %d\n",		      diff, binding->timeout);		DEBUG(DEBUG_FLAG, "\tbinding->mn_addr = %s\n",		      inet_ntoa(binding->mn_addr));		DEBUG(DEBUG_FLAG, "\tbinding->lower_addr = %s\n",		      inet_ntoa(binding->lower_addr));		remove_binding_tunnels(binding, thash, bindingcount);		binding = binding_getexpired(bhash, 0);	}}struct bindingentry *make_new_binding(struct bindingtable *bhash, struct msg_extensions *ext,		 struct sockaddr_in *addr, int max_lifetime){	struct bindingentry *binding;	struct tunnel_data *t_data;	binding = (struct bindingentry *) malloc(sizeof(struct bindingentry));	if (binding == NULL)		return NULL;	t_data = (struct tunnel_data *) malloc(sizeof(struct tunnel_data));	if (t_data == NULL) {		free(binding);		return NULL;	}	memset(binding, 0, sizeof(struct bindingentry));	memset(t_data, 0, sizeof(struct tunnel_data));	binding->data = t_data;	time(&binding->create_time);	time(&binding->mod_time);	binding->mn_addr.s_addr = ext->req->home_addr.s_addr;	binding->ha_addr.s_addr = ext->req->ha_addr.s_addr;	if (ext->priv_ha != NULL)		binding->priv_ha = ntohl(ext->priv_ha->priv_ha);	else		binding->priv_ha = 0;	t_data->confirmed = FALSE;	/* add default values for upper tunnel - changed if needed */	t_data->up_type = TUNNEL_IPIP;	t_data->up_key = 0;	if (ntohs(ext->req->lifetime) < max_lifetime)		binding->timeout = ntohs(ext->req->lifetime);	else		binding->timeout = max_lifetime;	if (!binding_add(bhash, binding)) {		free_binding(binding, NULL);		return NULL;	}	DEBUG(DEBUG_FLAG, "Created binding (MN=%s, ",	      inet_ntoa(binding->mn_addr));	DEBUG(DEBUG_FLAG, "HA=%s, priv_ha=%i)\n",	      inet_ntoa(binding->ha_addr), binding->priv_ha);	return binding;}/* check if given binding has unconfirmed requests that have timeouted and * remove them */voidcheck_unconfirmed_timeout(struct bindingentry *binding){	time_t now;	struct tunnel_data *t_data;	struct unconfirmed_request *unc, *prev;	time(&now);	t_data = binding->data;	unc = t_data->unc_req;	prev = NULL;	while (unc != NULL) {		if (now - unc->created > UNCONFIRMED_TIMEOUT) {			DEBUG(DEBUG_FLAG, "Freeing unconfirmed requests that "			      "have timed out\n");			free_unconfirmed_data(unc);			if (prev == NULL)				t_data->unc_req = NULL;			else				prev->next = NULL;			break;		}		prev = unc;		unc = unc->next;	}}intupdate_binding(struct bindingtable *hash, struct bindingentry *binding,	       int *count){	if (!binding_update(hash, binding)) {		LOG2(LOG_WARNING, "binding_update failed\n");		free_binding(binding, count);		return 1;	}	return 0;}/* try to avoid looping messages to own addresses, return TRUE if the address * is okay or FALSE if it is not */intsend_address_ok(struct in_addr to_addr){	char dev[IFNAMSIZ];	/* check that destionation interface != lo */	if (dyn_ip_route_get(to_addr, dev, IFNAMSIZ) == 0 &&	    strcmp(dev, "lo") == 0) {		LOG2(LOG_ALERT,		     "send_address_ok: destination to 'lo' "		     "interface - possible loop => refusing\n");		return FALSE;	}	return TRUE;}

⌨️ 快捷键说明

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