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

📄 fa_hash.c

📁 mobile ip 在linux下的一种实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	      ntohs(upper_fa_addr.sin_port));	res = own_sendto(up_interface->udp_sock, upper_fa_addr.sin_addr,			 upper_fa_addr.sin_port, buf, pos - buf);	dynamics_check_sendto(res, pos - buf, "fa_register");	own_req_pending = 1;}static int validate_fa_reg(char *msg, struct msg_extensions *ext,			   struct sockaddr_in *cli_addr){	struct fa_spi_entry *fa_spi;	if (ext->ff_auth == NULL) {		LOG2(LOG_ALERT, "FA reg. - no ff_auth ext - FA=%s\n",		     inet_ntoa(cli_addr->sin_addr));		return -1;	}	if (ext->fa_nai == NULL) {		LOG2(LOG_ALERT, "FA reg. - no fa_nai ext - FA=%s\n",		     inet_ntoa(cli_addr->sin_addr));		return -2;	}	fa_spi = get_fa_spi(0, cli_addr->sin_addr, SPI_AGENT_FA);	if (fa_spi == NULL) {		LOG2(LOG_ALERT, "FA reg. - no shared secret - FA=%s\n",		     inet_ntoa(cli_addr->sin_addr));		return -3;	}	if (!auth_check_vendor(AUTH_ALG_MD5, fa_spi->shared_secret,			       fa_spi->shared_secret_len,			       (unsigned char *) msg, ext->ff_auth)) {		LOG2(LOG_ALERT, "FA reg. - authentication failed - FA=%s\n",		     inet_ntoa(cli_addr->sin_addr));		return -4;	}	return 0;}static void send_fa_reg_reply(__u8 code, struct msg_extensions *ext,			      struct sockaddr_in *cli_addr,			      struct interface_entry *iface,			      __u8 *next_nonce){	char buf[MAXMSG], *pos;	struct fa_reg_rep *rep;	struct fa_spi_entry *fa_spi;	int res;	rep = (struct fa_reg_rep *) buf;	memset(rep, 0, sizeof(struct fa_reg_rep));	rep->type = FA_REP;	rep->code = code;	memcpy(&rep->down_nonce, &ext->fa_req->down_nonce, FA_REG_NONCE_LEN);	if (next_nonce != NULL)		memcpy(&rep->up_nonce, next_nonce, FA_REG_NONCE_LEN);	pos = (char *) (rep + 1);	if (ext->fa_nai != NULL) {		memcpy(pos, ext->fa_nai, GET_NAI_EXT_LEN(ext->fa_nai));		pos += GET_NAI_EXT_LEN(ext->fa_nai);	}	fa_spi = get_fa_spi(0, cli_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 reg. reply code %i to %s:%i\n",	      code, inet_ntoa(cli_addr->sin_addr), ntohs(cli_addr->sin_port));	res = own_sendto(iface->udp_sock, cli_addr->sin_addr,			 cli_addr->sin_port, buf, pos - buf);	dynamics_check_sendto(res, pos - buf, "send_fa_reg_reply");}static void forward_fa_reg_request(struct lower_fa_data *data, __u8 opts,				   struct msg_extensions *ext, __u8 *up_nonce){	char buf[MAXMSG], *pos;	struct fa_reg_req *req;	struct fa_spi_entry *fa_spi;	int res;	req = (struct fa_reg_req *) buf;	memset(req, 0, sizeof(struct fa_reg_req));	req->type = FA_REQ;	req->opts = opts;	req->lifetime = ext->fa_req->lifetime;	get_new_nonce(data->wait_nonce_rep);	memcpy(&req->down_nonce, data->wait_nonce_rep, FA_REG_NONCE_LEN);	if (up_nonce != NULL)		memcpy(&req->up_nonce, up_nonce, FA_REG_NONCE_LEN);	pos = (char *) (req + 1);	if (ext->fa_nai != NULL) {		memcpy(pos, ext->fa_nai, GET_NAI_EXT_LEN(ext->fa_nai));		pos += GET_NAI_EXT_LEN(ext->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, "Forwarding FA reg. request to %s:%i\n",	      inet_ntoa(upper_fa_addr.sin_addr),	      ntohs(upper_fa_addr.sin_port));	res = own_sendto(up_interface->udp_sock, upper_fa_addr.sin_addr,			 upper_fa_addr.sin_port, buf, pos - buf);	dynamics_check_sendto(res, pos - buf, "forward_fa_reg_request");}int handle_fa_req(char *msg, int n, struct msg_extensions *ext,		  struct sockaddr_in *cli_addr,		  struct interface_entry *iface){	int res, sync_nonce = 0;	struct lower_fa_data key, *data;	DEBUG(DEBUG_FLAG, "Handling FA request\n");	res = validate_fa_reg(msg, ext, cli_addr);	if (res == -1 || res == -2) {		send_fa_reg_reply(FA_REP_INVALID_REQ, ext, cli_addr, iface,				  NULL);		return -1;	} else if (res == -3 || res == -4) {		send_fa_reg_reply(FA_REP_AUTH_FAILED, ext, cli_addr, iface,				  NULL);		return -1;	} else if (res < 0)		return -1;	key.nai_len = GET_NAI_LEN(ext->fa_nai);	if (key.nai_len > MAX_NAI_LEN)		key.nai_len = MAX_NAI_LEN;	memcpy(key.nai, MSG_NAI_DATA(ext->fa_nai), key.nai_len);	data = (struct lower_fa_data *)		hashtable_fetch(fa_hash, lower_fa_hashfunc, &key,				lower_fa_cmpfunc);	if (data == NULL) {		DEBUG(DEBUG_FLAG, "\tno entry for this NAI found - adding "		      "and synchronizing nonces\n");		data = (struct lower_fa_data *)			malloc(sizeof(struct lower_fa_data));		if (data == NULL) {			LOG2(LOG_ALERT, "handle_fa_req - not enough memory\n");			return -1;		}		memset(data, 0, sizeof(struct lower_fa_data));		list_init_node(&data->node);		data->nai_len = GET_NAI_LEN(ext->fa_nai);		if (data->nai_len > MAX_NAI_LEN)			data->nai_len = MAX_NAI_LEN;		memcpy(data->nai, MSG_NAI_DATA(ext->fa_nai), data->nai_len);		data->req_iface = iface;		memcpy(&data->req_from, cli_addr, sizeof(data->req_from));		memcpy(&data->use_nonce_down, &ext->fa_req->down_nonce,		       FA_REG_NONCE_LEN);		data->req_lifetime = ntohs(ext->fa_req->lifetime);		time(&data->expire);		data->expire += data->req_lifetime;		DEBUG(DEBUG_FLAG, "\texpire entry: %s", ctime(&data->expire));		res = hashtable_add(fa_hash, lower_fa_hashfunc, (void *) data,				    &data->node);		if (res == 0) {			DEBUG(DEBUG_FLAG, "\thashtable_add failed\n");			free(data);			return -1;		}		sync_nonce = 1;	} else if (ext->fa_req->opts && FA_REQ_NONCE_SYNC)		sync_nonce = 1;	if (sync_nonce) {		DEBUG(DEBUG_FLAG, "\tsynchronizing nonces\n");		if (config->highest_FA) {			get_new_nonce(data->wait_nonce_req);			send_fa_reg_reply(FA_REP_NONCE_FAILED, ext, cli_addr,					  iface, data->wait_nonce_req);		} else			forward_fa_reg_request(data, ext->fa_req->opts |					       FA_REQ_NONCE_SYNC, ext, NULL);		return 0;	}	/* check nonce */	if (memcmp(data->wait_nonce_req, ext->fa_req->up_nonce,		   FA_REG_NONCE_LEN) != 0) {		DEBUG(DEBUG_FLAG, "\tnonce did not match\n");		get_new_nonce(data->wait_nonce_req);		send_fa_reg_reply(FA_REP_NONCE_FAILED, ext, cli_addr, iface,				  data->wait_nonce_req);		return -1;	}	time(&data->req_time);	if (config->highest_FA) {		data->iface = iface;		data->from = *cli_addr;		data->reply_time = data->req_time;		data->req_lifetime = data->lifetime =			ntohs(ext->fa_req->lifetime);		data->expire = data->reply_time + data->lifetime;		data->confirmed = 1;		get_new_nonce(data->wait_nonce_req);		send_fa_reg_reply(FA_REP_OK, ext, cli_addr, iface,				  data->wait_nonce_req);		update_next_hop(cli_addr->sin_addr, data->expire);	} else {		data->req_from = *cli_addr;		data->req_iface = iface;		data->req_lifetime = ntohs(ext->fa_req->lifetime);		memcpy(&data->use_nonce_down, &ext->fa_req->down_nonce,		       FA_REG_NONCE_LEN);		forward_fa_reg_request(data, ext->fa_req->opts, ext,				       data->use_nonce_up);	}	return 0;}static void forward_fa_reg_reply(struct lower_fa_data *data,				 struct msg_extensions *ext){	char buf[MAXMSG], *pos;	struct fa_reg_rep *rep;	struct fa_spi_entry *fa_spi;	int res;	rep = (struct fa_reg_rep *) buf;	memset(rep, 0, sizeof(struct fa_reg_rep));	rep->type = FA_REP;	rep->code = ext->fa_rep->code;	get_new_nonce(data->wait_nonce_req);	memcpy(&rep->down_nonce, data->use_nonce_down, FA_REG_NONCE_LEN);	memcpy(&rep->up_nonce, data->wait_nonce_req, FA_REG_NONCE_LEN);	pos = (char *) (rep + 1);	if (ext->fa_nai != NULL) {		memcpy(pos, ext->fa_nai, GET_NAI_EXT_LEN(ext->fa_nai));		pos += GET_NAI_EXT_LEN(ext->fa_nai);	}	fa_spi = get_fa_spi(0, data->req_from.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, "Forwarding FA reg. reply to %s:%i\n",	      inet_ntoa(data->req_from.sin_addr),	      ntohs(data->req_from.sin_port));	res = own_sendto(data->req_iface->udp_sock, data->req_from.sin_addr,			 data->req_from.sin_port, buf, pos - buf);	dynamics_check_sendto(res, pos - buf, "forward_fa_reg_reply");}int handle_fa_rep(char *msg, int n, struct msg_extensions *ext,		  struct sockaddr_in *cli_addr,		  struct interface_entry *iface){	struct lower_fa_data key, *data;	DEBUG(DEBUG_FLAG, "Handling FA reply\n");	if (validate_fa_reg(msg, ext, cli_addr) < 0)		return -1;	/* check for a reply to own registration */	if (!config->highest_FA && fa_nai != NULL &&	    GET_NAI_LEN(fa_nai) == GET_NAI_LEN(ext->fa_nai) &&	    memcmp(MSG_NAI_DATA(fa_nai), MSG_NAI_DATA(ext->fa_nai),		   GET_NAI_LEN(fa_nai)) == 0) {		DEBUG(DEBUG_FLAG, "\treply to own request\n");		if (!own_req_pending) {			DEBUG(DEBUG_FLAG, "\tno pending request - reply "			      "dropped\n");			return -1;		}		if (memcmp(&next_wait_nonce, &ext->fa_rep->down_nonce,			   FA_REG_NONCE_LEN) != 0) {			DEBUG(DEBUG_FLAG, "\tnonce mismatch - reply "			      "dropped\n");			return -1;		}		own_req_pending = 0;		if (ext->fa_rep->code == FA_REP_OK) {			DEBUG(DEBUG_FLAG, "\tregistration succeeded\n");			time(&last_reg_ok);			fa_reg_next_try = last_reg_ok +				config->fa_reg_lifetime -				(get_rand32() % 60);			DEBUG(DEBUG_FLAG, "\tnext registration: %s",			      ctime(&fa_reg_next_try));			next_wait_time = 1;			denial_replies = 0;		} else {			DEBUG(DEBUG_FLAG, "\tregistration failed - code=%i\n",			      ext->fa_rep->code);			if (ext->fa_rep->code == FA_REP_NONCE_FAILED &&			    denial_replies == 0) {				DEBUG(DEBUG_FLAG, "\tfirst nonce synch => "				      "retry immediately\n");				next_wait_time = 1;				time(&fa_reg_next_try);			}			denial_replies++;		}		memcpy(&next_send_nonce, &ext->fa_rep->up_nonce,		       FA_REG_NONCE_LEN);		return 0;	}	key.nai_len = GET_NAI_LEN(ext->fa_nai);	if (key.nai_len > MAX_NAI_LEN)		key.nai_len = MAX_NAI_LEN;	memcpy(key.nai, MSG_NAI_DATA(ext->fa_nai), key.nai_len);	data = (struct lower_fa_data *)		hashtable_fetch(fa_hash, lower_fa_hashfunc, &key,				lower_fa_cmpfunc);	if (data == NULL) {		DEBUG(DEBUG_FLAG, "\tno entry found - reply dropped\n");		return -1;	}	if (data->req_iface == NULL) {		DEBUG(DEBUG_FLAG, "\tno pending request - reply dropped\n");		return -1;	}	if (memcmp(data->wait_nonce_rep, &ext->fa_rep->down_nonce,		   FA_REG_NONCE_LEN) != 0) {		DEBUG(DEBUG_FLAG, "\tnonce mismatch - reply dropped\n");		return -1;	}	forward_fa_reg_reply(data, ext);	if (ext->fa_rep->code == FA_REP_OK) {		DEBUG(DEBUG_FLAG, "\tregistration succeeded - updating "		      "data\n");		data->confirmed = 1;		time(&data->reply_time);		data->lifetime = data->req_lifetime;		data->expire = data->reply_time + data->lifetime;		data->iface = data->req_iface;		data->from = data->req_from;		data->req_iface = NULL;		update_next_hop(data->from.sin_addr, data->expire);	} else		DEBUG(DEBUG_FLAG, "\tregistration failed\n");	memcpy(data->use_nonce_up, &ext->fa_rep->up_nonce, FA_REG_NONCE_LEN);	return 0;}

⌨️ 快捷键说明

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