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

📄 snot_parse_rules.c

📁 IPv4和IPv6下发任意包的程序
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "snot.h"

/*
 * parse_ip - take a string of ip address information and convert it to a linked list
 * 
 * Input:
 *
 *  ip: ip address string begin with '[' and end with ']'
 *  addr_list: pointer to an address list structure to receive the addresses
 *  num: pointer to an int that receives the total number of converted addresses
 *  line: line number
 *
 * Returns:
 *
 *  0: Success
 *  1: Failure
 *
 */

int parse_ip(char *ip, struct addr_list **al, int *num, int line)
{
	char *tempstr,*temp, *temp2, *ipstring;
	char *tok;
	struct hostent *host;		// modified
	struct in6_addr *ina;		// modified
	struct in6_addr inatemp;	// modified
#ifdef DEBUG
	struct in6_addr pina;		// modified
	char szAddr[100];		// modified
#endif
	unsigned long mask;
	struct addr_list *alcurr;
	int i = 0;
	
	*num = 0;

	
	tempstr = strdup(ip);
	temp=tempstr;
	
	/* Clear list */
	*al = NULL;

	if(*temp == (char)'[')
	{
		temp++;
	}
	
	do{
		if (*temp == ',')                        //  ',' is the mark between ip strings
		{
			temp++;
		}
		while(isspace(*temp))
		{
			temp++;
		}
		if((temp2 = strpbrk(temp, ",]")) != NULL)
		{
			// now temp2 point to one ip string
			if((ipstring = malloc(temp2-temp+1)) == NULL)
			{
				printf("parse_ip: malloc failed..\n");
				return(1);
			}
			memset(ipstring,0,(temp2-temp+1));
			ipstring = strncpy(ipstring, temp, (temp2-temp));
			
		}
		else
		{
			ipstring = strdup(temp);
		}
		temp2 = ipstring;

		/* Give us something to work with */
		if((alcurr = malloc(sizeof(struct addr_list))) == NULL)
		{
			printf("parse_ip: malloc failed..\n");
			return(1);
		}

		if(*temp2 == (char)'!')
		{
#ifdef DEBUG
			printf("found NOT\n");
#endif
			alcurr->addrnot = 1;
			temp2++;
		}
		else
		{
			alcurr->addrnot = 0;
		}
		
		if(*temp2 == (char)'$')
		{
			/* Chances are this person hasn't set their variables properly */
			printf("parse_ip: [line %d]: Did you set your variables correctly? (parsing %s)\n",line,ip);
			return(1);
		}
		
		if (!(STRCASECMP(temp2,"any")))
		{
		 	for ( i = 0; i< 16; i++)
			{
				alcurr->addrmask.__u6_addr.__u6_addr8[i] = netmask[i];	// need to modify
				alcurr->addr.__u6_addr.__u6_addr8[i] = 0;				// modified
			}
		}
		else
		{
			if((tok = strchr(temp2, '/'))!= NULL)
			{
				/* We have a netmask */
				*tok = (char)NULL;
				tok++;
				mask = atoi(tok);
				if(mask<=32)			// need to modify
				{
					for ( i = 0; i < 16; i++ )
					{
						alcurr->addrmask.__u6_addr.__u6_addr8[i] = netmask[mask*16+i];		// modified
					}	
#ifdef DEBUG
					for ( i = 0; i < 16; i++ )
					{
						pina.s6_addr[i] = alcurr->addrmask.__u6_addr.__u6_addr8[i];	// modified
					}
					printf("parse_ip: Address mask is %s\n", inet_ntop(AF_INET6,pina,szAddr,100));	// modified
#endif
				}
				else
				{
					printf("parse_ip: Netmask too phat.\n");
					return(1);
				}
			}
			else
			{
#ifdef DEBUG
				printf("parse_ip: Host address\n");
#endif
				/* No '/' ? Then its a host address */
				//alcurr->addrmask = 0xFFFFFFFF;		// modified
				for( i = 0; i < 8; i++)			// modified
				{
					alcurr->addrmask.__u6_addr.__u6_addr8[i] = 0xFF;
					alcurr->addrmask.__u6_addr.__u6_addr8[i+8] = 0x0;
				}
				
			}
			/* Now lookup the IP address */
			//if (inet_addr6 (temp2) == -1)	// modified
			if (inet_pton( AF_INET6, temp2, &inatemp))	// modified
			{
				/* Try Resolving it */
#ifdef DEBUG
				printf("temp2 = %s\n",temp2);
#endif
				if ((host = gethostbyname2 ( temp2, AF_INET6 )) == NULL)		// modified
				{
					printf("parse_ip: [line %d]: Couldn't resolve address %s\n",line,temp2);
					return(1);
				}
				else
				{
					ina = (struct in6_addr *) host->h_addr_list[0];		// modified
#ifdef DEBUG		
					inet_ntop( AF_INET6, ina, szAddr, 100 );
					printf ( "DNS IP : %s\n", szAddr );		// modified
#endif
					for ( i = 0; i < 16; i++ )
					{
						alcurr->addr.__u6_addr.__u6_addr8[i] = ina->s6_addr[i];		// modified
					}
#ifdef DEBUG
					printf ("DNS Hostname : %s\n", ipstring);
#endif
				}
			}
			else
			{
				// alcurr->addr = inet_addr6 (temp2);		// modified
				inet_pton( AF_INET6, temp2, &alcurr->addr);	// modified
			}
		}			
		alcurr->next = *al;
		*al = alcurr;
		free(ipstring);
		*num = *num + 1;
	}
	while((temp = strpbrk(temp,",")) != NULL);
		
	free(tempstr);
	return(0);
}

/* end parse_ip */


/*
 * expand_vars - expand a rule line with applicable variables
 * 
 * Input:
 *
 *  rule: a snort rule string
 *  line: current line number
 *
 * Returns:
 *
 *  0: Success
 *  1: Failure
 *
 */

// sentence begin with "var" is similar to #define in c language...
int expand_vars(char **rule,int line)
{
	char *temp,*temp2,*temp3;
	int length = 0;
	struct var_list *vtemp;

	if((temp = malloc(RULE_MAX)) == NULL)
	{
		printf("expand_vars: [line %d] Couldnt malloc..\n",line);
		return(1);
	}
	
	memset(temp, 0, RULE_MAX);

	temp2 = *rule;
	temp3 = temp;
	while ((*temp2) != (char)NULL)
	{
		/* Have we got a variable? */
		if(*temp2 == '$')
		{
			/* Skip the $ */
			temp2++;
			if ((*temp2) == (char)NULL)
			{
				/* The $ is right at the end of the string.. paste it and move on */
				*temp3 = '$';
				free(*rule);
				*rule = temp;
				return(0);
			}
			else
			{
				/* check all vars */
				vtemp = vhead;
				while((vtemp != NULL) && (strncmp(vtemp->varname, temp2, strlen(vtemp->varname))))
				{
					vtemp = vtemp->next;
				}
				/* Check if we matched or just reached the end of the rules list */
				if(vtemp == NULL)
				{
					*temp3 = '$';
					temp3++;
				}
				else
				{
					if(strlen(vtemp->value)+(temp3-temp) >= RULE_MAX)
					{
						printf("expand_vars: [line %d] Variable expansion creates string > %d, ignoring..\n",line, RULE_MAX);
						free(temp);
						return(1);
					}
					strcat(temp3, vtemp->value);
					temp3 = temp3 + strlen(vtemp->value);
					temp2 = temp2 + strlen(vtemp->varname);
				}
			}
		}
		else
		{
			/* Check if we are going to blow the end of the malloced string */
			if((temp3 - temp) == RULE_MAX)
			{
				printf("expand_vars: [line %d] Variable expansion creates string > %d, ignoring..\n",line, RULE_MAX);
				free(temp);
				return(1);
			}
			/* Just a normal character */
			*temp3 = *temp2;
			temp2++;
			temp3++;
		}
	}
	free(*rule);
	*rule = temp;
	return(0);
}
/* end expand_vars */


/*
 * parse_rules: parse a snort rules file
 * 
 * Input:
 *
 *  globsrc: pointer to global overridden source ip address string
 *  globdst: pointer to global overridden destination ip address string
 *
 * Returns:
 *
 *  0: Success
 *  1: Failure
 *
 */

int parse_rules(char *globsrc, char *globdst, char *rulefile)
{
	char *token, *tok2;
	char *rs, *rulestring, *ruletemp;
	char *optstring;
	FILE *f;
	int line,i,j,found,found2;
	int pmin, pmax, offset, depth, contsize;
	char *arg, *temp, *temp2;
	int *flags;
	int hex1,hex2;
	unsigned char *uc;
	char *ia;
	char *ds;
	unsigned short *us;
	unsigned long *ul;
	int *mi;

	struct var_list *vtemp,*vcurrent,*vprev;
	struct rule *r;
	
	struct option_list
	{
		char *option_string;
		struct option_list *next;
	};
	
	struct option_list *olhead, *olcur, *oltemp;
	
	/* Set up the netmask table */
/*	netmask[0]=inet_addr("0.0.0.0");		// need to modify
	netmask[1]=inet_addr("128.0.0.0");
	netmask[2]=inet_addr("192.0.0.0");
	netmask[3]=inet_addr("224.0.0.0");
	netmask[4]=inet_addr("240.0.0.0");
	netmask[5]=inet_addr("248.0.0.0");
	netmask[6]=inet_addr("252.0.0.0");
	netmask[7]=inet_addr("254.0.0.0");
	netmask[8]=inet_addr("255.0.0.0");
	netmask[9]=inet_addr("255.128.0.0");
	netmask[10]=inet_addr("255.192.0.0");
	netmask[11]=inet_addr("255.224.0.0");
	netmask[12]=inet_addr("255.240.0.0");
	netmask[13]=inet_addr("255.248.0.0");
	netmask[14]=inet_addr("255.252.0.0");
	netmask[15]=inet_addr("255.254.0.0");
	netmask[16]=inet_addr("255.255.0.0");
	netmask[17]=inet_addr("255.255.128.0");
	netmask[18]=inet_addr("255.255.192.0");
	netmask[19]=inet_addr("255.255.224.0");
	netmask[20]=inet_addr("255.255.240.0");
	netmask[21]=inet_addr("255.255.248.0");
	netmask[22]=inet_addr("255.255.252.0");
	netmask[23]=inet_addr("255.255.254.0");
	netmask[24]=inet_addr("255.255.255.0");
	netmask[25]=inet_addr("255.255.255.128");
	netmask[26]=inet_addr("255.255.255.192");
	netmask[27]=inet_addr("255.255.255.224");
	netmask[28]=inet_addr("255.255.255.240");
	netmask[29]=inet_addr("255.255.255.248");
	netmask[30]=inet_addr("255.255.255.252");
	netmask[31]=inet_addr("255.255.255.254");
	netmask[32]=inet_addr("255.255.255.255");	
*/
	inet_pton(AF_INET6, "::", &netmask[0]);
	for ( i = 1; i < 33; i++ )
	{
		inet_pton(AF_INET6, "FFFF:FFFF:FFFF:FFFF:0000:0000:0000:0000", &netmask[i*16]);
	}
	line = total_rules = 0;
	
	/* Arbitrarily large number for size of the rule line */
	if ((rs = malloc(RULE_MAX)) == NULL)
	{
		printf("parse_rules: [line %d] : malloc failed..\n",line);
		return(1);
	}
#ifdef DEBUG
	printf("rule file is %s\n",rulefile);
#endif
	if((f = fopen(rulefile,"r"))!=NULL)
	{
				
		/* Clear out our linked lists */
		rulehead = NULL;	
		vhead = NULL;

		while((fgets(rs, RULE_MAX-1, f)) != NULL)
		{
			line++;
			/* check for dos chars in the rulestring */
			if((ruletemp = strchr(rs, 0x0d))||(ruletemp = strchr(rs, 0x0a)))
			{
				*ruletemp = 0;
			}
			rulestring = strdup(rs);
			ruletemp = rulestring;

			/* is it a comment or a blank line? */
			if ((rulestring) && (*rulestring) && (isalnum(*rulestring)))
			{
				rulestring = ruletemp;
				if(expand_vars(&rulestring,line))
				{
					return(1);
				}
				/* rulestring has been freed and malloced in expand vars */
				ruletemp = rulestring;
				
				optstring = strdup(rulestring);
#ifdef DEBUG
				printf("rulestring = %s\n", rulestring);
#endif
				while(isspace(*rulestring))
				{
					rulestring++;
				}
				/* variable line? */
				if(!(STRNICMP(rulestring, "var", 3)))
				{
					if ((token = strtok(rulestring, " ")) != NULL)
					{
						if ((token = strtok(NULL, " ")) != NULL)
						{
							if((vtemp = malloc(sizeof(struct var_list))) == NULL)
							{
								printf("parse_rules: [line %d] : malloc failed.\n",line);
								return(1);
							}
							vtemp->varname = strdup(token);
							arg = token;
							while(((*arg) != (char)NULL) &&(!isspace(*arg)))
							{
								arg++;
							}
							arg++;
							if(strlen(arg) == 0)
							{
								printf("parse_rules: [line %d]: Invalid Variable Value, ignoring\n",line);
								free(vtemp);
								goto ignore;
							}
							vtemp->value = strdup(arg);

							/* Put the variable in the linked list in alphabetical order */
							vprev = NULL;
							vcurrent = vhead;
							while((vcurrent != NULL) && (vcurrent->value != NULL) && (strncmp(vtemp->varname, vcurrent->varname, strlen(vcurrent->varname)) >= 0))
							{
								vprev = vcurrent;
								vcurrent = vcurrent->next;
							}
							if (vprev != NULL)
							{
								vtemp->next = vprev->next;
								vprev->next = vtemp;
							}
							else
							{
								vtemp->next = vhead;
								vhead = vtemp;
							}

#ifdef DEBUG
								
							print_var(vtemp);
#endif
						}
						else
						{
							printf("parse_rules: [line %d]: Invalid Variable Name, ignoring\n",line);
							goto ignore;
						}
					}
					else
					{
						printf("parse_rules: [line %d]: Invalid Variable Name, ignoring\n",line);
						goto ignore;
					}
				}
				// end of judgement of var line			
				else if ((token = strtok(rulestring, " ")) != NULL)
				{
					
					/* Give us a new rule to work with */

					if((r = malloc(sizeof(struct rule))) == NULL)
					{
						printf("parse_rules: [line %d] : malloc failed.\n",line);
						return(1);
					}

					/* log or alert rule? */
					if((!(STRCASECMP(token, "alert")))||(!(STRCASECMP(token, "log"))))
					{
						/* get the protocol type */
						if ((token = strtok(NULL, " ")) != NULL)
						{
							if(!(STRCASECMP(token, "tcp")))
							{
								r->proto = TCP;
							}
							else if(!(STRCASECMP(token, "udp")))
							{
								r->proto = UDP;
							}
							else if(!(STRCASECMP(token, "icmp")))
							{
								r->proto = ICMP;
							}

⌨️ 快捷键说明

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