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

📄 ipa_ctl.c

📁 监控局域网上网
💻 C
📖 第 1 页 / 共 4 页
字号:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pcap.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netinet/if_ether.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <sys/socket.h>
#include <stdarg.h>

#include <sys/errno.h>
#include <sys/signal.h>
#include <sys/ioctl.h>

#include <sys/wait.h>
#include <sys/signal.h>
#include <sys/time.h>
#include <time.h>
#include <netdb.h>
#include <ctype.h>
#include <stdarg.h>
#include <fcntl.h>
#include <stdio.h>
#include <dirent.h>

#include "ipa_fun.h"

//全局日志文件名称
char gd_SYS_LOG_FILE[128];

//ipa_ctl子进程号数组,一共三个子进程
int gd_ipaworksvrchildpidarr[16];
//ipa_ctl子进程数,等于3
int gd_ipaworksvrchildpidarrdim;

//白名单暂存地
char  gd_WHITE_LIST_file[64];
//IP list存放地
char  gd_IP_LIST_file[64];

//信号锁文件描述符
int   gd_semfd = -1;
//ipa_ctl监听sockfd
int   gd_msock = -1;

//pcap handle
pcap_t *gd_adhandle;

//进程间通讯的TCP sockfd
int    gd_sockToKill;

//发送TCP reset的PACKET sockfd
int    gd_PACKET_sockfd;
//发送TCP reset的网卡设备名称
char   gd_PACKET_dev[8];


char   gd_SNIFFER_dev[8];

//系统中网卡设备列表
m_dev_t  *gd_devname;
//系统中网卡设备数量
int    gd_devnum;

//被监控的TCP端口列表
unsigned short *gd_portsList;
//被监控的TCP端口数量
short gd_portnum;

//gd_winupdateip的IP地址,只取前2个字节
char gd_winupdateip[16];

//white list的内存映像
IP_MAC_t *gd_white_ip_mac;
//white list地址数量
int  gd_white_list_len = 0;

//ip list的内存映像
IP_MAC_t *gd_ip_mac;
//ip list地址数量
int  gd_ip_list_len = 0;

//本网段网络地址部分
char gd_self_net_addr[12];

//上次刷新white list内存映像的时间
unsigned int gd_last_time = 0;
//上次刷新ip list内存映像的时间
unsigned int gd_last_ip_time = 0;

char  gd_log_level = 1;
ipa_conf_t gd_ipa_conf;

int into_ipa_cap();
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
int is_in_ip_list(u_int sipaddr, char *mac);
int is_in_white_list(u_int sipaddr, char *mac);
int is_in_reset_port_list(unsigned short dport);
int is_win_update(u_int saddr, u_int daddr);
int is_for_myself(u_int saddr, u_int daddr);
void send_reset( mac_address_t *srcmac, ip_address_t *srcip, u_short sport, mac_address_t *destmac, 
                 ip_address_t *destip, u_short dport, u_int seqnum, u_int win );
int init_PACKET_sock();
int get_all_dev();


int read_ipa_conf(char *filename, ipa_conf_t *pipa_conf, unsigned short **ports, short *portnum);
int read_RESET_PORTS_LIST_part(char *filename, FILE *fp, unsigned short **ports, short *portnum);

int getWinUpdateip(char *url, char *winupdateip);

int is_in_inner_net_or_in(u_int saddr , u_int daddr);
void onquitCap(int sig);
int into_ipa_kill(int msock);
int InnerService(int sock);
int DealRequest(char *reqBuf, int requestlen, char *resp, int *resplen);
int deal_add_white_list(char *reqBuf, int requestlen, char *resp, int *resplen);
int deal_delete_white_list(char *reqBuf, int requestlen, char *resp, int *resplen);
int deal_add_ip_list(char *reqBuf, int requestlen, char *resp, int *resplen);
int deal_print_ip_list(char *reqBuf, int requestlen, char *resp, int *resplen);
int deal_print_white_list(char *reqBuf, int requestlen, char *resp, int *resplen);
int deal_reset_ip_list(char *reqBuf, int requestlen, char *resp, int *resplen);
int deal_reset_white_list(char *reqBuf, int requestlen, char *resp, int *resplen);
int deal_check_if_ip_mac_name_in_the_white_list(char *reqBuf, int requestlen, char *resp, int *resplen);
int deal_check_if_ip_mac_name_in_the_ip_list(char *reqBuf, int requestlen, char *resp, int *resplen);

void deal_reset_tcp(char *reqBuf, int requestlen, char *resp, int *resplen);
void onquitIPA(int sig);


int main(int argc, char *argv[])
{
	int  msock;
	int  ret;
	int  i;
	int  pid, pid1;
	int  aint;
	char service[16];
	struct stat buf;
	
	ret = read_ipa_conf("ipa.conf", &gd_ipa_conf, &gd_portsList, &gd_portnum);
	if (ret < 0)
	{
		exit(1);	
	}
	gd_log_level = gd_ipa_conf.IPA_LOG_LEVEL;
	
	strcpy(gd_IP_LIST_file, "IP_LIST.bin");
	strcpy(gd_WHITE_LIST_file, "WHITE_LIST.bin");
	
	ret = comMkShfn(gd_WHITE_LIST_file, 4,  1);
	if (ret < 0)
	{
		printf("Fail on create file[%s] error[%s]\n", gd_WHITE_LIST_file, strerror(errno));
		exit(1);
	}
	aint = 0;	
	ret = comWriteShfn(gd_WHITE_LIST_file, 0, (char *)&aint, 4) ;
	if (ret < 0)
	{
		printf("Fail on comWriteShfn file[%s] error[%s]\n", gd_WHITE_LIST_file, strerror(errno));
		exit(1);
	}

	ret = stat(gd_IP_LIST_file, &buf);
	if (ret < 0) 
	{
		ret = comMkShfn(gd_IP_LIST_file, 4,  1);
		if (ret < 0)
		{
			printf("Fail on create file[%s] error[%s]\n", gd_IP_LIST_file, strerror(errno));
			exit(1);
		}
		aint = 0;	
		ret = comWriteShfn(gd_IP_LIST_file, 0, (char *)&aint, 4) ;
		if (ret < 0)
		{
			printf("Fail on comWriteShfn file[%s] error[%s]\n", gd_IP_LIST_file, strerror(errno));
			exit(1);
		}
	}

	gd_semfd = mkfSemSet("SEM_AWAY_ME.bin", 10, 1);
	if (gd_semfd < 0)	
	{	
		printf("mkfSemSet(SEM_AWAY_ME.bin, 9, 1) ret[%d] errno[%d:%s]\n",  gd_semfd, errno, strerror(errno));
		exit(1);
	}
		
	strcpy(gd_SYS_LOG_FILE, "ipa.log");
	gd_ipaworksvrchildpidarrdim = 3;

	if (getenv("IPA_SERVICE_PORT") == NULL)
	{
		putenv("IPA_SERVICE_PORT=9876");
		printf("The \"IPA_SERVICE_PORT\" env varible is set to 9876, you can select another one in .bash_profile!\n");
	}
	if(fork() != 0)	exit(0);

	//setsid();
	umask(0100);
	for (i=2; i<64; i++)	close(i);

	safe_signal(SIGINT, (void *)SIG_IGN);
	safe_signal(SIGHUP, (void *)SIG_IGN);
	safe_signal(SIGTERM, (void *)onquitIPA);


	if ( init_PACKET_sock() < 0)  return -1;

	ret = get_all_dev();
	if (ret < 0)
	{
		printf("in main(), get_all_dev() error[%d:%s] \n", errno, strerror(errno));
		logit(gd_SYS_LOG_FILE, "in main(), get_all_dev() error[%d:%s] \n", errno, strerror(errno));
		exit(1);
	}

	strcpy(service, getenv("IPA_SERVICE_PORT"));
	msock = passivesock(service, "tcp", 5);
	if(msock < 0)	return(1);
	
	for (i=0; i<gd_ipaworksvrchildpidarrdim; i++)
	{
		pid = fork();
		if (pid == 0)
		{
	               	printf("child  process %d is started.\n", getpid());
	                if (i == 0)
	                {
			        close(msock);
				ret = into_ipa_cap();
	                }
			else
			{
	               	//printf("child  into_ipa_kill %d is started.\n", getpid());
	                	ret = into_ipa_kill(msock);
			}
			exit(ret);
		}
		else if (pid > 0)
		{
			gd_ipaworksvrchildpidarr[i] = pid;
		}
		else
		{
			printf( "in main(), fork() errno[%d] \n", errno);
			logit(gd_SYS_LOG_FILE, "in main(), fork() errno[%d] \n", errno);
			onquitIPA(15);
		}
	}
	printf("parent process %d is started.\n", getpid());

	
	i = 0;
	for (;;)
	{
		ret = 0;
		pid = wait(&ret);
		ret >>= 8;
		if (pid < 0) 
		{
			logit(gd_SYS_LOG_FILE, "in main(), wait() error[%d:%s] \n", errno, strerror(errno));
			continue;
		}
                if (ret == 9) onquitIPA(SIGTERM);

		pid1 = fork();
		if (pid1 == 0)
		{
			if (pid == gd_ipaworksvrchildpidarr[0])
			{
			        close(msock);
				ret = into_ipa_cap();
			}
			else
				ret = into_ipa_kill(msock);
			exit(ret);
		}
		else if (pid1 < 0)
		{
			logit(gd_SYS_LOG_FILE, "in main(), fork() errno[%d] \n", errno);
			onquitIPA(15);
		}
		else
		{
			for (i=0; i<gd_ipaworksvrchildpidarrdim; i++)
			{
				if (gd_ipaworksvrchildpidarr[i] == pid)
					gd_ipaworksvrchildpidarr[i] = pid1;
			}
		}
	}

	return 0;

}


int into_ipa_cap()
{
	int  ret;
	
	safe_signal(SIGTERM, (void *)onquitCap);
	ret = init_m_pcap();
	return ret;
}

void onquitCap(int sig)
{
	close(gd_sockToKill);
	comSleep(100);
	exit(0);	
}

void onquitIpa_kill(int sig)
{
	close(gd_msock);
	comSleep(100);
	exit(0);
}


int into_ipa_kill(int msock)
{
	int  ret;
	
	gd_msock = msock;
	safe_signal(SIGTERM, (void *)onquitIpa_kill);
	ret = start_tcp_serv(msock, InnerService);

	return ret;
}


int InnerService(int sock)
{
	int  ret;
	char reqBuf[512];
	char respbuf[512];
	int  requestlen;
	int  resplen;
	
	for (;;)
	{
		ret = readStream(sock, reqBuf, &requestlen);
		if(ret != 0)	return ret;

		ret = DealRequest(reqBuf, requestlen, respbuf, &resplen);
		if (ret < 0)  return ret;
		//写应答
		if (resplen < 1) continue;
 		ret = writesock(sock, respbuf, resplen);
		if (ret != 0)	return ret;		
	}
	return(ret);
}


int DealRequest(char *reqBuf, int requestlen, char *resp, int *resplen)
{
	int    ret;
	Header_t  RequestHeader;
	
	memcpy(&RequestHeader, reqBuf, sizeof(Header_t));
	RequestHeader.buflen  = ntohl(RequestHeader.buflen );
	RequestHeader.code = ntohl(RequestHeader.code);
	
	switch (RequestHeader.code)
	{
		case RESET_TCP:	//Reset a tcp connection
			*resplen = 0;
			deal_reset_tcp(reqBuf, requestlen, resp, resplen);
			break;
		case ADD_IP_LIST:
			ret = deal_add_ip_list(reqBuf, requestlen, resp, resplen);
			break;
		case DELETE_IP_LIST:
			ret = deal_delete_ip_list(reqBuf, requestlen, resp, resplen);
			break;
		case ADD_WHITE_LIST:
			ret = deal_add_white_list(reqBuf, requestlen, resp, resplen);
			break;
		case DELETE_WHITE_LIST:
			ret = deal_delete_white_list(reqBuf, requestlen, resp, resplen);
			break;
		case PRINT_IP_LIST:
			ret = deal_print_ip_list(reqBuf, requestlen, resp, resplen);
			break;
		case PRINT_WHITE_LIST:
			ret = deal_print_white_list(reqBuf, requestlen, resp, resplen);
			break;
		case RESET_IP_LIST:
			ret = deal_reset_ip_list(reqBuf, requestlen, resp, resplen);
			break;
		case RESET_WHITE_LIST:
			ret = deal_reset_white_list(reqBuf, requestlen, resp, resplen);
			break;
		case CHECK_IF_IP_MAC_NAME_IN_THE_WHITE_LIST:
			ret = deal_check_if_ip_mac_name_in_the_white_list(reqBuf, requestlen, resp, resplen);
			break;
		case CHECK_IF_IP_MAC_NAME_IN_THE_IP_LIST:
			ret = deal_check_if_ip_mac_name_in_the_ip_list(reqBuf, requestlen, resp, resplen);
			break;

		default:
			return -1;
	}
	
	return ret;
}


int deal_check_if_ip_mac_name_in_the_ip_list(char *reqBuf, int requestlen, char *resp, int *resplen)
{
	Header_t  *pheader;
	IP_MAC_NAME_t *plist, *pnode;
	int       i;
	int       pos;
	char      *buf;
	int       ret;
	int       ipListLen;
	
	pheader = (Header_t *)resp;
	pheader->buflen = htonl(sizeof(Header_t));
	*resplen = sizeof(Header_t);
	pnode = (IP_MAC_NAME_t *)(reqBuf+sizeof(Header_t));

	ret = comReadShfn(gd_IP_LIST_file, 0, 4, (char *)&ipListLen) ;
	if (ret < 0)	
	{
		pheader->code = htonl(1);
		pos = sizeof(Header_t);
		buf = resp + pos;
		sprintf(buf, "comReadShfn() fail [%s]!\n", strerror(errno));
		pos += strlen(buf);
		pos ++;
		pheader->buflen = htonl(pos);
		*resplen = pos;
		return 1;
	}

	if (ipListLen < 1)
	{
		pheader->code = htonl(1);
		pos = sizeof(Header_t);
		buf = resp + pos;
		sprintf(buf, "The ip list is empty!\n");
		pos += strlen(buf);
		pos ++;
		pheader->buflen = htonl(pos);
		*resplen = pos;
		return 1;
	}


	plist = (IP_MAC_NAME_t *)calloc(sizeof(IP_MAC_NAME_t), ipListLen);
	if (plist == NULL)
	{
		pheader->code = htonl(1);
		pos = sizeof(Header_t);
		buf = resp + pos;
		sprintf(buf, "calloc() fail [%s]!\n", strerror(errno));
		pos += strlen(buf);
		pos ++;
		pheader->buflen = htonl(pos);
		*resplen = pos;
		return -1;
	}
	ret = comReadShfn(gd_IP_LIST_file, 4, ipListLen*sizeof(IP_MAC_NAME_t), (char *)plist);
	if (ret < 0)	
	{
		free(plist);
		pheader->code = htonl(1);
		pos = sizeof(Header_t);
		buf = resp + pos;
		sprintf(buf, "comReadShfn() fail [%s]!\n", strerror(errno));
		pos += strlen(buf);
		pos ++;
		pheader->buflen = htonl(pos);
		*resplen = pos;
		return -1;
	}
	
	for (i=0; i<ipListLen; i++)
	{
		if (  (strcmp(plist[i].ip, pnode->ip) == 0) &&
		      (strcmp(plist[i].mac, pnode->mac) == 0) &&
		      (strcmp(plist[i].name, pnode->name) == 0)  )
		{
			free(plist);
			pheader->code = htonl(0);
			return 0;
		}
	}
	free(plist);

	pheader->code = htonl(4);
	pos = sizeof(Header_t);
	buf = resp + pos;
	sprintf(buf, "What you input is not in the ip list!\n", strerror(errno));
	pos += strlen(buf);
	pos ++;
	pheader->buflen = htonl(pos);
	*resplen = pos;

	return 0;
}


int deal_check_if_ip_mac_name_in_the_white_list(char *reqBuf, int requestlen, char *resp, int *resplen)
{
	Header_t  *pheader;
	IP_MAC_NAME_t *plist, *pnode;
	int       i;
	int       pos;
	char      *buf;
	int       ret;
	int       whileListLen;
	
	pheader = (Header_t *)resp;
	pheader->buflen = htonl(sizeof(Header_t));
	*resplen = sizeof(Header_t);
	pnode = (IP_MAC_NAME_t *)(reqBuf+sizeof(Header_t));

	ret = comReadShfn(gd_WHITE_LIST_file, 0, 4, (char *)&whileListLen) ;
	if (ret < 0)	
	{
		pheader->code = htonl(1);
		pos = sizeof(Header_t);
		buf = resp + pos;
		sprintf(buf, "comReadShfn() fail [%s]!\n", strerror(errno));
		pos += strlen(buf);
		pos ++;
		pheader->buflen = htonl(pos);
		*resplen = pos;
		return 1;
	}

	if (whileListLen < 1)
	{
		pheader->code = htonl(1);

⌨️ 快捷键说明

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