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