📄 ipa_ctl.c
字号:
#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 + -