📄 rules.c
字号:
i++;
}
#ifdef DEBUG
printf("OptListEnd\n");
#endif
AddOptFuncToList(OptListEnd, otn_tmp);
}
else
{
#ifdef DEBUG
printf("OptListEnd\n");
#endif
AddOptFuncToList(OptListEnd, otn_tmp);
}
free(toks);
}
/****************************************************************************
*
* Function: RuleType(char *)
*
* Purpose: Determine what type of rule is being processed and return its
* equivalent value
*
* Arguments: func => string containing the rule type
*
* Returns: The rule type designation
*
***************************************************************************/
int RuleType(char *func)
{
if (func == NULL)
{
FatalError("ERROR line %s (%d) => Unknown rule type (%s)\n", file_name, file_line, func);
}
if (!strncasecmp(func, "log",3))
return RULE_LOG;
if (!strncasecmp(func, "alert",5))
return RULE_ALERT;
if (!strncasecmp(func, "pass",4))
return RULE_PASS;
if (!strncasecmp(func, "var",3))
return RULE_VAR;
if (!strncasecmp(func, "include",7))
return RULE_INCLUDE;
if (!strncasecmp(func, "preprocessor",12))
return RULE_PREPROCESS;
if (!strncasecmp(func, "output",6))
return RULE_OUTPUT;
FatalError("ERROR line %s (%d) => Unknown rule type: %s\n", file_name, file_line, func);
return 0;
}
/****************************************************************************
*
* Function: WhichProto(char *)
*
* Purpose: Figure out which protocol the current rule is talking about
*
* Arguments: proto_str => the protocol string
*
* Returns: The integer value of the protocol
*
***************************************************************************/
int WhichProto(char *proto_str)
{
if (!strncasecmp(proto_str, "tcp", 3))
return IPPROTO_TCP;
if (!strncasecmp(proto_str, "udp", 3))
return IPPROTO_UDP;
if (!strncasecmp(proto_str, "icmp", 4))
return IPPROTO_ICMP;
/* if we've gotten here, we have a protocol string we din't recognize
and should exit */
FatalError( "ERROR %s (%d) => Bad protocol: %s\n", file_name, file_line, proto_str);
return 0;
}
/****************************************************************************
*
* Function: ParseIP(char *, u_long *, u_long *)
*
* Purpose: Convert a supplied IP address to it's network order 32-bit long
value. Also convert the CIDR block notation into a real
* netmask.
*
* Arguments: addr => address string to convert
* ip_addr => storage point for the converted ip address
* netmask => storage point for the converted netmask
*
* Returns: 0 for normal addresses, 1 for an "any" address
*
***************************************************************************/
int ParseIP(char *paddr, u_long *ip_addr, u_long *netmask)
{
char **toks; /* token dbl buffer */
int num_toks; /* number of tokens found by mSplit() */
int nmask; /* netmask temporary storage */
char *addr; /* string to parse, eventually a variable-contents */
struct hostent *host_info; /* various struct pointers for stuff */
struct sockaddr_in sin; /* addr struct */
/* check for variable */
if (! strncmp(paddr, "$", 1))
{
if ((addr = VarGet(paddr + 1)) == NULL)
{
FatalError( "ERROR %s (%d) => Undefined variable %s\n", file_name, file_line, paddr);
}
}
else
addr = paddr;
/* check for wildcards */
if (!strncasecmp(addr, "any", 3))
{
*ip_addr = 0;
*netmask = 0;
return 1;
}
/* break out the CIDR notation from the IP address */
toks = mSplit(addr,"/",2,&num_toks,0);
switch (num_toks)
{
case 1:
*netmask = netmasks[32];
break;
case 2:
/* convert the CIDR notation into a real live netmask */
nmask = atoi(toks[1]);
/* it's pain to differ whether toks[1] is correct if netmask is /0, so
* we deploy some sort of evil hack with isdigit */
if (!isdigit((int)toks[1][0])) nmask=-1;
if ((nmask > -1)&&(nmask < 33))
{
*netmask = netmasks[nmask];
}
else
{
FatalError("ERROR %s (%d) => Invalid CIDR block for IP addr %s\n", file_name, file_line, addr);
}
break;
default:
FatalError("ERROR %s (%d) => No netmask specified for IP address %s\n", file_name, file_line, addr);
break;
}
#ifndef WORDS_BIGENDIAN
/* since PC's store things the "wrong" way, shuffle the bytes into
the right order */
*netmask = htonl(*netmask);
#endif
/* convert names to IP addrs */
if (isalpha((int)toks[0][0]))
{
/* get the hostname and fill in the host_info struct */
if ((host_info = gethostbyname(toks[0])))
{
bcopy(host_info->h_addr, (char *)&sin.sin_addr, host_info->h_length);
}
else if ((sin.sin_addr.s_addr = inet_addr(toks[0])) == INADDR_NONE)
{
FatalError("ERROR %s (%d) => Couldn't resolve hostname %s\n",
file_name, file_line, toks[0]);
}
*ip_addr = ((u_long)(sin.sin_addr.s_addr) & (*netmask));
return 1;
}
/* convert the IP addr into its 32-bit value */
/* broadcast address fix from Steve Beaty <beaty@emess.mscd.edu> */
/*
** if the address is the (v4) broadcast address, inet_addr returns -1
** which usually signifies an error, but in the broadcast address case,
** is correct. we'd use inet_aton() here, but it's less portable.
*/
if (! strncmp (toks[0], "255.255.255.255", 15))
{
*ip_addr = INADDR_BROADCAST;
}
else if ((*ip_addr = inet_addr(toks[0])) == -1)
{
FatalError( "ERROR %s (%d) => Rule IP addr (%s) didn't x-late, WTF?\n", file_name, file_line, toks[0]);
}
else
{
/* set the final homenet address up */
*ip_addr = ((u_long)(*ip_addr) & (*netmask));
}
free(toks);
return 0;
}
/****************************************************************************
*
* Function: ParsePort(char *, u_short *)
*
* Purpose: Convert the port string over to an integer value
*
* Arguments: prule_port => port rule string
* port => converted integer value of the port
*
* Returns: 0 for a normal port number, 1 for an "any" port
*
***************************************************************************/
int ParsePort(char *prule_port, u_short *hi_port, u_short *lo_port, char *proto, int *not_flag)
{
char **toks; /* token dbl buffer */
int num_toks; /* number of tokens found by mSplit() */
char *rule_port; /* port string */
*not_flag = 0;
/* check for variable */
if (! strncmp(prule_port, "$", 1))
{
if ((rule_port = VarGet(prule_port + 1)) == NULL)
{
FatalError( "ERROR %s (%d) => Undefined variable %s\n", file_name, file_line, prule_port);
}
}
else
rule_port = prule_port;
/* check for wildcards */
if (!strncasecmp(rule_port, "any", 3))
{
*hi_port = 0;
*lo_port = 0;
return 1;
}
if (rule_port[0] == '!')
{
*not_flag = 1;
rule_port++;
}
if (rule_port[0] == ':')
{
*lo_port = 0;
}
toks = mSplit(rule_port, ":", 2, &num_toks,0);
switch (num_toks)
{
case 1:
*hi_port = ConvPort(toks[0], proto);
if (rule_port[0] == ':')
{
*lo_port = 0;
}
else
{
*lo_port = *hi_port;
if (index(rule_port, ':') != NULL)
{
*hi_port = 65535;
}
}
return 0;
case 2:
*lo_port = ConvPort(toks[0], proto);
if (toks[1][0] == 0)
*hi_port = 65535;
else
*hi_port = ConvPort(toks[1], proto);
return 0;
default:
FatalError("ERROR %s (%d) => port conversion failed on \"%s\"\n",
file_name, file_line, rule_port);
}
return 0;
}
/****************************************************************************
*
* Function: ConvPort(char *, char *)
*
* Purpose: Convert the port string over to an integer value
*
* Arguments: port => port string
* proto => converted integer value of the port
*
* Returns: the port number
*
***************************************************************************/
int ConvPort(char *port, char *proto)
{
int conv; /* storage for the converted number */
struct servent *service_info;
/* convert a "word port" (http, ftp, imap, whatever) to its
corresponding numeric port value */
if (isalpha((int)port[0]) != 0)
{
service_info = getservbyname(port, proto);
if (service_info != NULL)
{
conv = ntohs(service_info->s_port);
return conv;
}
else
{
FatalError( "ERROR %s (%d) => getservbyname() failed on \"%s\"\n",
file_name, file_line, port);
}
}
if (!isdigit((int)port[0]))
{
FatalError( "ERROR %s (%d) => Invalid port: %s\n", file_name,
file_line, port);
}
/* convert the value */
conv = atoi(port);
/* make sure it's in bounds */
if ((conv >= 0) && (conv < 65536))
{
return conv;
}
else
{
FatalError( "ERROR %s (%d) => bad port number: %s", file_name,
file_line, port);
}
return 0;
}
/****************************************************************************
*
* Function: ParseMessage(char *)
*
* Purpose: Stuff the alert message onto the rule
*
* Arguments: msg => the msg string
*
* Returns: void function
*
***************************************************************************/
void ParseMessage(char *msg)
{
char *ptr;
char *end;
int size;
/* figure out where the message starts */
ptr = index(msg,'"');
if (ptr == NULL)
{
ptr = msg;
}
else
ptr++;
end = index(ptr,'"');
if (end != NULL)
*end = 0;
while (isspace((int) *ptr)) ptr++;
/* find the end of the alert string */
size = strlen(msg)+1;
/* alloc space for the string and put it in the rule */
if (size > 0)
{
otn_tmp->message = (char *)calloc((sizeof(char)*size), sizeof(char));
strncpy(otn_tmp->message, ptr, size);
otn_tmp->message[size-1] = 0;
#ifdef DEBUG
printf("Rule message set to: %s\n", otn_tmp->message);
#endif
}
else
{
ErrorMessage( "ERROR %s (%d): bad alert message size %d\n", file_name, file_line, size);
}
}
/****************************************************************************
*
* Function: ParseLogto(char *)
*
* Purpose: stuff the special log filename onto the proper rule option
*
* Arguments: filename => the file name
*
* Returns: void function
*
***************************************************************************/
void ParseLogto(char *filename)
{
char *sptr;
char *eptr;
/* grab everything between the starting " and the end one */
sptr = index(filename, '"');
eptr = strrchr(filename, '"');
if (sptr != NULL && eptr != NULL)
{
/* increment past the first quote */
sptr++;
/* zero out the second one */
*eptr = 0;
}
else
{
sptr = filename;
}
/* malloc up a nice shiny clean buffer */
otn_tmp->logto = (char *) calloc(strlen(sptr) + 1, sizeof(char));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -