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

📄 fa_ipay.c

📁 mobile ip 在linux下的一种实现
💻 C
字号:
/* $Id: fa_ipay.c,v 1.3 2000/04/06 07:26:51 jm Exp $ * Foreign Agent - Ipay interface routines * * 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. */#ifdef INCLUDE_IPAY#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <string.h>#include <errno.h>#include <ctype.h>#include <netinet/in.h>#include <arpa/inet.h>#include <assert.h>#include "binding.h"#include "debug.h"#include "ipay-msg.h"#include "fa.h"#include "fa_ipay.h"extern struct fa_config *config;extern struct bindingtable *bindings_hash;#define DEBUG_IPAY 'i'static void show_ipay_char(char *title, char *p){	int i;	DEBUG(DEBUG_IPAY, "\t  %s: ", title);	for (i = 0; i < IPAY_CHAR_LEN; i++) {		if (p[i] == '\0')			break;		if (isprint(p[i]))			DEBUG(DEBUG_IPAY, "%c", p[i]);		else			DEBUG(DEBUG_IPAY, "<%u>", (unsigned int) p[i]);	}	DEBUG(DEBUG_IPAY, "\n");}static int ipay_check_len(int len, int expected){	if (len != expected) {		DEBUG(DEBUG_IPAY, "\t - length mismatch (expected %i bytes)\n",		      expected);		if (len < expected) {			DEBUG(DEBUG_IPAY, "\t - too short - cannot parse\n");			return -1;		}		DEBUG(DEBUG_IPAY, "\t - ignoring extra bytes\n");	}	return 0;}static void handle_purchase(int s, char *msg, int len){	struct ipay_purchase *pur;	struct sockaddr_in addr;	int res;	DEBUG(DEBUG_IPAY, "\tpurchase message\n");	if (ipay_check_len(len, sizeof(struct ipay_purchase)) < 0)		return;	pur = (struct ipay_purchase *) msg;	DEBUG(DEBUG_IPAY, "\t  timeStamp: %u\n", ntohl(pur->timeStamp));	show_ipay_char("mnIdentifier", pur->mnIdentifier);	show_ipay_char("faIdentifier", pur->faIdentifier);	DEBUG(DEBUG_IPAY, "\t  purchaseSerialNumber: %u\n",	      ntohl(pur->purchaseSerialNumber));	DEBUG(DEBUG_IPAY, "\t  microPaymentUnit: %u\n",	      ntohl(pur->microPaymentUnit));	DEBUG(DEBUG_IPAY, "\t  maxNumberOfUnits: %u\n",	      ntohl(pur->maxNumberOfUnits));	show_ipay_char("firstPayment", pur->firstPayment);	DEBUG(DEBUG_IPAY, "\t  timePrice: %u\n", ntohl(pur->timePrice));	DEBUG(DEBUG_IPAY, "\t  bytePrice: %u\n", ntohl(pur->bytePrice));	show_ipay_char("signature", pur->signature);	addr.sin_family = AF_INET;	if (config->highest_FA) {		DEBUG(DEBUG_IPAY, "\tforwarding message to AAAF\n");		addr.sin_addr = config->aaaf_addr;		addr.sin_port = htons(config->aaaf_port);	} else {		DEBUG(DEBUG_IPAY, "\tforwarding message to upper FA\n");		addr.sin_addr = config->upper_fa_addr;		addr.sin_port = htons(config->ipay_port);	}	DEBUG(DEBUG_IPAY, "\tsending %i bytes to %s:%i\n", len,	      inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));	res = sendto(s, msg, len, 0, (struct sockaddr *) &addr, sizeof(addr));	if (res < 0) {		DEBUG(DEBUG_IPAY, "\tsendto - %s\n", strerror(errno));	} else if (res != len) {		DEBUG(DEBUG_IPAY, "\tsend only %i/%i bytes\n", res, len);	}}static struct bindingentry *found_binding;static int fetch_iter(struct node *node, void *data){	struct bindingentry *entry = (struct bindingentry *) node;	struct nai_data *key = (struct nai_data *) data;	struct tunnel_data *t_data = (struct tunnel_data *) entry->data;	if (key->len == t_data->mn_nai.len && t_data->mn_nai.nai != NULL &&	    memcmp(key->nai, t_data->mn_nai.nai, key->len) == 0) {		found_binding = entry;		return 0;	}	return 1;}static int get_dest_mn_nai(IPAY_CHAR nai, struct sockaddr_in *addr){	struct nai_data key;	key.len = 0;	while (key.len < IPAY_CHAR_LEN && nai[key.len] != '\0')		key.len++;	key.nai = malloc(key.len);	if (key.nai == NULL) {		DEBUG(DEBUG_IPAY, "\tget_dest_mn_nai - malloc failed\n");		return -1;	}	memcpy(key.nai, nai, key.len);	found_binding = NULL;	hashtable_iterator(bindings_hash->hashtable, fetch_iter, &key);	if (found_binding == NULL)		return -1;	addr->sin_family = AF_INET;	addr->sin_addr = found_binding->lower_addr;	addr->sin_port = htons(config->ipay_port);	return 0;}static void handle_allowance(int s, char *msg, int len){	struct ipay_allowance *allow;	struct sockaddr_in addr;	int res;	DEBUG(DEBUG_IPAY, "\tallowance message\n");	if (ipay_check_len(len, sizeof(struct ipay_allowance)))		return;	allow = (struct ipay_allowance *) msg;	DEBUG(DEBUG_IPAY, "\t  allowance: %u\n", ntohl(allow->allowance));	show_ipay_char("mnIdentifier", allow->mnIdentifier);	DEBUG(DEBUG_IPAY, "\t  timePrice: %u\n", ntohl(allow->timePrice));	DEBUG(DEBUG_IPAY, "\t  bytePrice: %u\n", ntohl(allow->bytePrice));	DEBUG(DEBUG_IPAY, "\t  apporovedNumberOfUnits: %u\n",	      ntohl(allow->approvedNumberOfUnits));	show_ipay_char("sessionKey", allow->sessionKey);	show_ipay_char("signature", allow->signature);	if (get_dest_mn_nai(allow->mnIdentifier, &addr) < 0) {		DEBUG(DEBUG_IPAY, "\tno matching binding for MN NAI found\n");		return;	}	if (found_binding != NULL) {		struct tunnel_data *t_data;		t_data = (struct tunnel_data *) found_binding->data;		if (!t_data->ipay_send_stats) {			t_data->ipay_send_stats = 1;			time(&t_data->ipay_last_stats);		}	}	DEBUG(DEBUG_IPAY, "\tsending %i bytes to %s:%i\n", len,	      inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));	res = sendto(s, msg, len, 0, (struct sockaddr *) &addr, sizeof(addr));	if (res < 0) {		DEBUG(DEBUG_IPAY, "\tsendto - %s\n", strerror(errno));	} else if (res != len) {		DEBUG(DEBUG_IPAY, "\tsend only %i/%i bytes\n", res, len);	}}static void handle_please_pay_more(int s, char *msg, int len){	struct ipay_please_pay_more *pay;	struct sockaddr_in addr;	int res;	DEBUG(DEBUG_IPAY, "\tplease pay more message\n");	if (ipay_check_len(len, sizeof(struct ipay_please_pay_more)))		return;	pay = (struct ipay_please_pay_more *) msg;	show_ipay_char("mnIdentifier", pay->mnIdentifier);	DEBUG(DEBUG_IPAY, "\t  usedTime: %u\n", ntohl(pay->usedTime));	DEBUG(DEBUG_IPAY, "\t  usedByte: %u\n", ntohl(pay->usedByte));	show_ipay_char("sessionKey", pay->sessionKey);	show_ipay_char("signature", pay->signature);	if (get_dest_mn_nai(pay->mnIdentifier, &addr) < 0) {		DEBUG(DEBUG_IPAY, "\tno matching binding for MN NAI found\n");		return;	}	DEBUG(DEBUG_IPAY, "\tsending %i bytes to %s:%i\n", len,	      inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));	res = sendto(s, msg, len, 0, (struct sockaddr *) &addr, sizeof(addr));	if (res < 0) {		DEBUG(DEBUG_IPAY, "\tsendto - %s\n", strerror(errno));	} else if (res != len) {		DEBUG(DEBUG_IPAY, "\tsend only %i/%i bytes\n", res, len);	}}static void handle_micro_payment(int s, char *msg, int len){	struct ipay_micro_payment *pay;	struct sockaddr_in addr;	int res;	DEBUG(DEBUG_IPAY, "\tmicro payment message\n");	if (ipay_check_len(len, sizeof(struct ipay_micro_payment)) < 0)		return;	pay = (struct ipay_micro_payment *) msg;	show_ipay_char("mnIdentifier", pay->mnIdentifier);	show_ipay_char("nextPayment", pay->nextPayment);	addr.sin_family = AF_INET;	if (config->highest_FA) {		DEBUG(DEBUG_IPAY, "\tforwarding message to AAAF\n");		addr.sin_addr = config->aaaf_addr;		addr.sin_port = htons(config->aaaf_port);	} else {		DEBUG(DEBUG_IPAY, "\tforwarding message to upper FA\n");		addr.sin_addr = config->upper_fa_addr;		addr.sin_port = htons(config->ipay_port);	}	DEBUG(DEBUG_IPAY, "\tsending %i bytes to %s:%i\n", len,	      inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));	res = sendto(s, msg, len, 0, (struct sockaddr *) &addr, sizeof(addr));	if (res < 0) {		DEBUG(DEBUG_IPAY, "\tsendto - %s\n", strerror(errno));	} else if (res != len) {		DEBUG(DEBUG_IPAY, "\tsend only %i/%i bytes\n", res, len);	}}void handle_ipay(int s){	char msg[MAXMSG];	struct sockaddr_in from;	int fromlen, len;	IPAY_TYPE *type;	DEBUG(DEBUG_IPAY, "Ipay message from socket %i\n", s);	fromlen = sizeof(from);	len = recvfrom(s, msg, MAXMSG, 0, (struct sockaddr *) &from, &fromlen);	if (len < 0) {		DEBUG(DEBUG_IPAY, "\trecvfrom failed - %s\n", strerror(errno));		return;	}	DEBUG(DEBUG_IPAY, "\t%i bytes from %s:%i\n", len,	      inet_ntoa(from.sin_addr), ntohs(from.sin_port));	if (len < sizeof(IPAY_TYPE)) {		DEBUG(DEBUG_IPAY, "\ttoo short message - ignoring it\n");		return;	}	type = (IPAY_TYPE *) msg;	DEBUG(DEBUG_IPAY, "\ttype=%i\n", ntohl(*type));	switch (ntohl(*type)) {	case IPAY_MSG_PURCHASE:		handle_purchase(s, msg, len);		break;	case IPAY_MSG_ALLOWANCE:		handle_allowance(s, msg, len);		break;	case IPAY_MSG_PLEASE_PAY_MORE:		handle_please_pay_more(s, msg, len);		break;	case IPAY_MSG_MICRO_PAYMENT:		handle_micro_payment(s, msg, len);		break;	default:		DEBUG(DEBUG_IPAY, "\tunknown message type - ignoring "		      "message\n");		break;	}}static intsend_stats_iter(struct node *node, void *data){	struct ipay_capacity_used capa;	struct bindingentry *binding;	struct tunnel_data *t_data;	struct sockaddr_in addr;	int s, res;	time_t now;	time(&now);	binding = (struct bindingentry *) node;	t_data = (struct tunnel_data *) binding->data;	assert(t_data != NULL);	s = *((int *) data);	if (!t_data->ipay_send_stats || !t_data->confirmed)		return 1;	/* send statistics */	memset(&capa, 0, sizeof(capa));	capa.type = htonl(IPAY_MSG_CAPACITY_USED);	memcpy(capa.mnIdentifier, t_data->mn_nai.nai,	       t_data->mn_nai.len > IPAY_CHAR_LEN ?	       IPAY_CHAR_LEN : t_data->mn_nai.len);	capa.timePrice = htonl(config->timePrice);	capa.usedTime = htonl(now - t_data->ipay_last_stats);	addr.sin_addr = config->aaaf_addr;	addr.sin_port = htons(config->aaaf_port);	DEBUG(DEBUG_IPAY, "sending capacity used to AAAF (%s:%i)\n",	      inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));	show_ipay_char("for MN", capa.mnIdentifier);	res = sendto(s, &capa, sizeof(capa), 0, (struct sockaddr *) &addr,		     sizeof(addr));	if (res < 0) {		DEBUG(DEBUG_IPAY, "\tsendto - %s\n", strerror(errno));	} else if (res != sizeof(capa)) {		DEBUG(DEBUG_IPAY, "\tsend only %i/%i bytes\n", res,		      sizeof(capa));	}	return 1;}/* do not send statistics more often than every 60 seconds */#define IPAY_STATS_INTERVAL 60void ipay_send_statistics(int s){	static time_t prev = 0;	time_t now;	if (!config->highest_FA)		return;	time(&now);	if (prev > 0 && prev <= now && now < prev + IPAY_STATS_INTERVAL)		return;	prev = now;	/* send statistics for every registered MN using Ipay */	hashtable_iterator(bindings_hash->hashtable, send_stats_iter, &s);}#endif

⌨️ 快捷键说明

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