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

📄 lan_ip_jf-cgi.h

📁 计费部分源程序。我认为该软件极好
💻 H
📖 第 1 页 / 共 3 页
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

#include <sys/param.h>
#include <sys/types.h>
/*#incldue <sys/time.h>*/
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>

#include <signal.h>

#include "jf-message.h"  /*进程之间通讯的消息定义*/
#include "myfunction.h"

#ifdef SET_WAIT_TIMEOUT
#define WAIT_TIMEOUT 120
#endif

#define MAX_GROUPID 200

#define UserIDFile "system/userID.sys"      /*用户ID文件,记录还未使用的用户ID数*/
#define LOGIN_INIT_FILE "login.init" /*记录各中数据文件的路径,供CGI程序使用*/
char UserFile[20] = "system/user.file";     /*用户的帐户文件*/

#define LIMIT_LOGIN_LOCATION 0x0001/*限制用户在某些地址登陆*/
#define LIMIT_LOGIN_NUM 0x0002/*限制用户的同时登录次数*/
#define MIN_LOGIN_DATA 500  /*允许限制使用量用户剩余字节的最小值,当剩余字节小于该值,则发干扰包*/
#define HOST_TYPE 1   /*地址为主机地址*/
#define NET_TYPE 0    /*地址为网络地址*/
#define NORMAL_USER 0 /*用户级别,普通级,相当于level=0,限制用户数据使用量*/
#define SUPPER_USER 1 /*用户级别,超级,相当于level=1,不限制用户数据使用量*/
#define DATE_LEN 15

#define USER_HASH_LEN 250
/*地址列表定义,该地址为主机地址或网络地址*/
typedef struct _AddressTYPE
	{
		int type;/*0---主机地址,1---网络地址*/
		struct in_addr addr;/*主机或网络地址*/
		struct in_addr netMask;/*网络屏蔽码*/
		struct _AddressTYPE* next;
		struct _AddressTYPE* prev;
	}AddressType;
#define USER_NAME_LEN 11
#define USER_PASS_LEN 11
/*用户列表定义*/
typedef struct _UserTYPE
	{
		int userID; /*用户的标识号,对于每个用户来说,该值唯一*/
		char userName[USER_NAME_LEN];/*用户名称*/
		char userPassword[USER_PASS_LEN];/*用户密码*/
		int level;/*用户的级别,0--进行使用量限制,1---不进行使用量限制*/
		int groupID;/*该用户的组ID*/
		long remainData;/*该用户剩余的数据量*/
		float remainMoney;/*该用户剩余的钱数*/
		int refrenceNum;/*该用户目前被引用数*/
		int state;/*该用户当前状态,0---未上网,1---上网*/
		int flag;/*该用户的表示,如flag&LIMIT_LOGIN_LOCATION=true,则进行检查它的登陆位置*/
		long addUserDate;/*用户被加入的时间*/
		AddressType* loginAddressList;/*当前用户已经从几处登陆*/
		AddressType* allowLoginAddressList;/*若限制用户登陆地点,则用本地址列表进行判断*/
		struct _UserTYPE* nextInHash;
		struct _UserTYPE* prevInHash;
		struct _UserTYPE* nextInList;
		struct _UserTYPE* prevInList;
	}UserType;
/*组的定义*/
#define GROUP_NAME_LEN 30
typedef struct _GroupType
	{
		int groupID;/*组的ID号*/
		char groupName[GROUP_NAME_LEN];/*组的名字*/
		int memberNum;/*组中成员的个数*/
		struct _GroupType* next;/*下一个组的指针*/
		struct _GroupType* prev;/*上一个组的指针*/
	}GroupType;
GroupType *GroupListHead,*GroupListTail;

char* GroupFile = "system/group.sys"; /*组文件*/

/************************************************************
following is for massege comunication
以下程序和数据结构用于进行消息通讯             
************************************************************/
/*输入输出消息*/
#define SCS_CGIINMSGKEY 460/*与CGI进程进行通讯*/
#define SCS_CGIOUTMSGKEY 450
/*
用户统计数据结构
*/
typedef struct _MonthSumDataType
	{
		long inPackets;
		long inPacketsBytes;
		long outPackets;
		long outPacketsBytes;
		long connectTime;/*连接时间*/
	}MonthSumDataType;
#define NET_PART_NUM  1/*网络分为几个段落,如国内段,国外段,免费段等*/
#define NET_PART_1 0   /*确省段落,一般应为国外网段*/
#define NET_PART_2 1
#define NET_PART_3 2
#define TIME_STAGE_NUM 1 /*每天分为多少个时间段*/
#define TIME_STAGE_1   0 /*时间段1*/
#define TIME_STAGE_2   1 /*时间段2*/
#define TIME_STAGE_3   2 /*时间段3*/
/*
统计数据结构
进入的数据包个数包括:在时间段n内,有网段m进入的包个数
*/
typedef struct _SumDataType
	{
		long inPackets[TIME_STAGE_NUM][NET_PART_NUM];/*进入的数据包个数*/
		long inPacketsBytes[TIME_STAGE_NUM][NET_PART_NUM];/*进入的数据包字节数*/
		long outPackets[TIME_STAGE_NUM][NET_PART_NUM];/*出去的数据包个数*/
		long outPacketsBytes[TIME_STAGE_NUM][NET_PART_NUM];/*出去的数据包字节数*/
		long connectTime;/*连接时间*/
	} SumDataType;
int SumDataSize=sizeof(SumDataType);

struct msg_scs CGIInMessage;/*用于CGI进程输入消息*/
struct msg_scs CGIOutMessage;/*用于CGI进程输出消息*/

int CGIInMessageID;/*与CGI进程进行通讯的输入消息标识*/
int CGIOutMessageID;/*与CGI进程进行通讯的输出消息标识*/

char *cgiDebug;
int pid;/*本进程的ID号,将使用本进程的PID值作为发给用户管理进程的信息的mtype值*/

int SearchMonth;/*查询的月份*/
char *SumSuffix = ".sum";/*每个用户月统计文件后缀*/
char PATH[100];/*用户帐户信息所在的文件*/
char HOSTIP[20];/*本机的节点地址*/

char *NetPartFile = "system/netpart.sys";/*网段文件*/
/*
网络或主机地址
*/
typedef struct _InternalNetTYPE
	{
		struct in_addr netAddress;/*内部网的网络地址*/
		struct in_addr netMask; /*内部网络的网络屏蔽码*/
		int type;/*标识本地址是网络地址,还是IP地址,0--net address,1--ip address*/
		int flag;/* 该内部网络的标识*/
		struct _InternalNetTYPE* next;
	}InternalNetType;

InternalNetType* NetPartList[NET_PART_NUM];/*各个网段链表的头指针*/
char NetPartName[NET_PART_NUM][50];/*各个网段的名字,如国内网段,国外网段,免费网段等*/

/*
时间段结构定义
*/
typedef struct _TimeStageType
	{
		int startTime,endTime;/*起始时间*/
		int timeStageNo;/*对应的时间段*/
		struct _TimeStageType* next;    
	}TimeStageType;                                                                                                         
TimeStageType * TimeStageHead=NULL,*TimeStageTail=NULL;
char* TimeStageNameFile = "system/timastagename.sys";/*时间段名字文件*/
char TimeStageName[TIME_STAGE_NUM][50];/*各个时间段段的名字,如下午5:00--早8:00,早8:00--下午5:00等*/

#define DEFAULT_CONST_RATIO 0.12 /*缺省的费率值,每1千字节为0.12元*/
char* ConstRatioFile = "system/constratio.sys";/*费率文件*/
float ConstRatio[TIME_STAGE_NUM][NET_PART_NUM][2];/*费率变量*/

char* ManagerAccountFile="system/manager.file";
typedef struct _ManagerAccountType
	{
		char managerName[USER_NAME_LEN];/*管理员名称*/
		char managerPass[USER_PASS_LEN];/*管理员密码*/
		int level;/*管理员级别*/
		struct _ManagerAccountType* next;
	}ManagerAccountType;
ManagerAccountType *ManagerListHead = NULL;

#ifdef ZOOM-OP
/*进行用户数据的缩放操作*/
char * ZoomRatioFile = "system/zoomratio.sys";
float ZoomRatio[2] = {1.0,1.0};
#endif

/*用于实现中文和英文两个版本*/
int language = 0;/*0---chinese,1---english*/

/*用于统计一组或全部用户的总体使用量*/
SumDataType totalSumData;
float totalValue = 0.0;


void ErrorInfo(int no);
int GetGroupIDByName(char* groupName);
char* GetGroupNameByID(int groupID);

void PrintError(char* str,...)
{
}

void cgiPrintf(char* str,...)
{
}

/*
转换以太网地址,从字符串到ether_addr结构,或相反
flag = 0, from string to struct
flag = 1, from struct to string
*/
void TransEtherAddress(int flag ,char* str,struct ether_addr *ether)
{
	int tmp[6],i;

	if (flag == 0)
	{
		sscanf(str,"%2x:%2x:%2x:%2x:%2x:%2x",
					&tmp[0],
					&tmp[1],
					&tmp[2],
					&tmp[3],
					&tmp[4],
					&tmp[5]);
		for (i = 0; i < 6; i++)
			ether->ether_addr_octet[i] = tmp[i];

	}
	else
	{
		sprintf(str,"%2x:%2x:%2x:%2x:%2x:%2x",
					ether->ether_addr_octet[0],
					ether->ether_addr_octet[1],
					ether->ether_addr_octet[2],
					ether->ether_addr_octet[3],
					ether->ether_addr_octet[4],
					ether->ether_addr_octet[5]);
	}
}

/*
转换IP地址,从字符串到in_addr结构,或相反
flag = 0, from string to struct
flag = 1, from struct to string
*/
void TransIpAddress(int flag ,char* str,struct in_addr *ip)
{
	int tmp[4];

	if (flag == 0)
	{
		sscanf(str,"%d.%d.%d.%d",&tmp[0],&tmp[1],&tmp[2],&tmp[3]);
		(ip->s_net) = tmp[0];
		(ip->s_host) = tmp[1];
		(ip->s_lh) = tmp[2];
		(ip->s_impno) = tmp[3];
	}
	else
	{
		sprintf(str,"%d.%d.%d.%d",
					ip->s_net,
					ip->s_host,
					ip->s_lh,
					ip->s_impno);
	}
}
/*
从一个字符串中得到第一个域,该域不含空白字符
返回值:为输入字符串中第一个域后的第一个字符的指针
*/
char* GetOneField(char* str,char* result)
{
	char* ch1,*ch2,*ch3;
	ch1 = str;
	while (*ch1 == ' ' || *ch1 =='\t')
		ch1++;
	ch2 = ch1;
	ch3 = result;
	while ((*ch2 != '|') &&(*ch2 != '#') && (*ch2 != ' ') && (*ch2 != '\t') && (*ch2 != '\n') && (*ch2 != '\r') && (*ch2 != 0))
	{
		*ch3 = *ch2;
		ch2++;
		ch3++;
	}
	*ch3 = 0;
	while ((*ch2 != '|') && (*ch2 != '\0'))
		ch2++;
	ch2++;
	return ch2;
}

/*
初始化2个消息队列
本程序中有2个消息队列:
一个消息对列用于得到CGI进程的输入消息,CGIInMessageID
一个消息队列用于处理CGI进程的输出消息,CGIOutMessageID,
*/
void InitMessage()
{
	CGIInMessageID = msgget(SCS_CGIINMSGKEY, 0777|IPC_CREAT);
	if (CGIInMessageID == -1)
	{
		PrintError(" in msgget failed!CGI In Message\n ");
		ErrorInfo(ERROR_CANNT_CREAT_MESSAGE);/*返回不能创建消息结构的CGI错误信息*/
		exit(1);
	}
	CGIOutMessageID = msgget(SCS_CGIOUTMSGKEY, 0777|IPC_CREAT);                
	if (CGIOutMessageID == -1)
	{
		PrintError(" out msgget failed!CGI OUT MESSGAE\n ");
		ErrorInfo(ERROR_CANNT_CREAT_MESSAGE);/*返回不能创建消息结构的CGI错误信息*/
		exit(1);
	}
}
/*
检查字符串是否为空或为空白串
返回值:0---不合法,1---合法
*/
int CheckString(char* str)
{
	int i;

	if (str == NULL)
		return 0;
	else
	{
		for (i = 0;i < strlen(str);i++)
			if ((str[i] != ' ') && (str[i] != '\n') && (str[i] != '\t') && (str[i] != '\0'))
				return 1;/*不空*/
	}
	return 0;
}
/*
判断IP地址是否合法
返回值:0---不合法,1---合法
*/
int CheckIp(char* adddr)
{
	return 0;
}
/*
从一个字符串中得到一个用户结构指针,若成功返回指针,否则返回NULL
若falg ==0,则字符串格式:userID|userName|userPassword|groupID|remanData|level|flag
若falg ==1,则字符串格式:userID|userName|userPassword|groupID|remainData|level|addUserDate|flag|address Num|Address Type|Ip or Net Address|Net Mask|....
address num:为后面有几个地址,每次地址列表增加个数不能大于5,因此Address Num <= 5
若falg ==2,则字符串格式:userID|userName|userPassword|groupID|remanData|level|addUserDate|flag
*/
UserType* GetOneUserFromStr(char* str,int flag)
{
	static UserType tempUser;
	static UserType* tempUserPtr = &tempUser;
	char result[50];
	char* fieldStart;
	AddressType* addr;
	int addrNum,addrType;
	struct in_addr ipAddr,netMask;
	long addUserDate;

	/*1.得到userID*/
	fieldStart = GetOneField(str,result);
	tempUser.userID = atoi(result);
	/*2.得到userName*/
	fieldStart = GetOneField(fieldStart,result);
	TangStrncpy(tempUser.userName,result,USER_NAME_LEN);
	/*3.得到userPassword*/
	fieldStart = GetOneField(fieldStart,result);
	TangStrncpy(tempUser.userPassword,result,USER_PASS_LEN);
	/*4.得到groupID*/
	fieldStart = GetOneField(fieldStart,result);
	tempUser.groupID = atoi(result);
	/*5.得到remainData*/
	fieldStart = GetOneField(fieldStart,result);
	tempUser.remainData = atol(result);
	/*6.得到level*/
	fieldStart = GetOneField(fieldStart,result);
	tempUser.level = atoi(result);
	/*得到addUserDate*/
	fieldStart = GetOneField(fieldStart,result);
	tempUser.addUserDate = atol(result);

	/*7.得到flag*/
	if (flag == 3)
	{/*从字符串中得到用户被加入的时间*/
		fieldStart = GetOneField(fieldStart,result);
		tempUser.addUserDate = atol(result);
	}
	else
	{/*当前时间为用户被加入的时间*/
		time(&tempUser.addUserDate);
	}

	/*8.得到flag*/
	fieldStart = GetOneField(fieldStart,result);
	tempUser.flag = atoi(result);
	if (flag == 1)
	{
		/*5.若flag&LIMIT_LOGIN_LOCATION==TRUE,则读取地址列表*/
		if (flag & LIMIT_LOGIN_LOCATION)
		{
			fieldStart = GetOneField(fieldStart,result);
			addrNum = atoi(result);
			if (addrNum >5)/*每次地址列表增加个数不能大于5*/
				addrNum = 5;
			while (addrNum > 0)
			{
				/*得到地址类型*/
				fieldStart = GetOneField(fieldStart,result);
				addrType = atoi(result);
				/*得到IP or Net地址*/
				fieldStart = GetOneField(fieldStart,result);
				TransIpAddress(0,result,&ipAddr);
				if (addrType != HOST_TYPE)
				{/*得到Net Mask*/
					fieldStart = GetOneField(fieldStart,result);
					TransIpAddress(0,result,&netMask);
				}
				/*生成地址列表*/
				addr = (AddressType*)malloc(sizeof(AddressType));
				if (addr)
				{
					addr->type = addrType;
					addr->addr.s_addr = ipAddr.s_addr;
					addr->netMask.s_addr = netMask.s_addr;
					addr->prev = NULL;
					addr->next = tempUserPtr->allowLoginAddressList;
					if (tempUserPtr->allowLoginAddressList)
						tempUserPtr->allowLoginAddressList->prev = addr;
					tempUserPtr->allowLoginAddressList = addr;
				}
				else
				{
					PrintError("Not enough memory!ModifyFlag()");
					break;
				}
				addrNum--;
			}       
		}

	}
	return tempUserPtr;
}
/*
显示一行用户数据
flag:0----计算一个月的费用,1----计算一年的费用

⌨️ 快捷键说明

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