📄 flt_rule.c
字号:
// $Id: flt_rule.c,v 1.2 2002/11/12 10:49:11 dev Exp $
#include <stdlib.h>
#include "flt_rule.h"
#include "ipc.h"
#include "tdi_fw_svc.h"
struct str_value {
const char *str;
int value;
};
static int str_value(const struct str_value *sv, const char *str);
static int get_amp(char *str, u_long *addr, u_long *mask, u_short *port, u_short *port2);
static struct str_value filter_sv[] = {
{"ALLOW", FILTER_ALLOW},
{"DENY", FILTER_DENY},
{NULL, 0}
};
static struct str_value proto_sv[] = {
{"TCP", IPPROTO_TCP},
{"UDP", IPPROTO_UDP},
{"RawIP", IPPROTO_IP},
{NULL, 0}
};
static struct str_value direction_sv[] = {
{"IN", DIRECTION_IN},
{"OUT", DIRECTION_OUT},
{NULL, 0}
};
/*
* rule is like this:
*
* ALLOW|DENY TCP|UDP|RawIP IN|OUT FROM <addr> TO <addr> [NOLOG]|[CLIENT|SERVER <proto>]
*/
int
parse_rule(char *str, struct flt_rule *rule)
{
static char delim[] = " \t";
char *p = str, *p2;
int v;
memset(rule, 0, sizeof(*rule));
// by default log using of all rules!
rule->log = 1;
/* ALLOW|DENY */
if (*p == '\0') {
error("PARSE\tparse_rule: filter ALLOW or DENY is missing");
return 0;
}
p2 = strpbrk(p, delim);
if (p2 != NULL)
*(p2++) = '\0';
v = str_value(filter_sv, p);
if (v == -1) {
error("PARSE\tparse_rule: \"%s\" is not ALLOW or DENY filter", p);
return 0;
}
rule->result = v;
p = p2;
/* TCP|UDP|RawIP */
if (p == NULL) {
error("PARSE\tparse_rule: protocol TCP, UDP or RawIP is missing");
return 0;
}
p2 = strpbrk(p, delim);
if (p2 != NULL)
*(p2++) = '\0';
v = str_value(proto_sv, p);
if (v == -1) {
error("PARSE\tparse_rule: \"%s\" is not TCP, UDP or RawIP protocol", p);
return 0;
}
rule->proto = v;
p = p2;
/* IN|OUT */
if (p == NULL) {
error("PARSE\tparse_rule: direction IN or OUT is missing");
return 0;
}
p2 = strpbrk(p, delim);
if (p2 != NULL)
*(p2++) = '\0';
v = str_value(direction_sv, p);
if (v == -1) {
error("PARSE\tparse_rule: \"%s\" is not IN or OUT direction", p);
return 0;
}
rule->direction = v;
p = p2;
/* FROM */
if (p == NULL) {
error("PARSE\tparse_rule: keyword FROM is missing");
return 0;
}
p2 = strpbrk(p, delim);
if (p2 != NULL)
*(p2++) = '\0';
if (strcmp(p, "FROM") != 0) {
error("PARSE\tparse_rule: \"%s\" is not FROM keyword", p);
return 0;
}
p = p2;
/* <addr-from> */
if (p == NULL) {
error("PARSE\tparse_rule: from address is missing");
return 0;
}
p2 = strpbrk(p, delim);
if (p2 != NULL)
*(p2++) = '\0';
if (!get_amp(p, &rule->addr_from, &rule->mask_from, &rule->port_from, &rule->port2_from)) {
error("PARSE\tparse_rule: invalid from address \"%s\"", p);
return 0;
}
p = p2;
/* TO */
if (p == NULL) {
error("PARSE\tparse_rule: keyword TO is missing");
return 0;
}
p2 = strpbrk(p, delim);
if (p2 != NULL)
*(p2++) = '\0';
if (strcmp(p, "TO") != 0) {
error("PARSE\tparse_rule: \"%s\" is not TO keyword");
return 0;
}
p = p2;
/* <addr-to> */
if (p == NULL) {
error("PARSE\tparse_rule: to address is missing");
return 0;
}
p2 = strpbrk(p, delim);
if (p2 != NULL)
*(p2++) = '\0';
if (!get_amp(p, &rule->addr_to, &rule->mask_to, &rule->port_to, &rule->port2_to)) {
error("PARSE\tparse_rule: invalid to address \"%s\"", p);
return 0;
}
p = p2;
/* NOLOG */
if (p != NULL) {
if (strcmp(p, "NOLOG") == 0)
rule->log = 0;
else {
error("PARSE\tparse_rule: invalid to address \"%s\"", p);
return 0;
}
}
return 1;
}
int
str_value(const struct str_value *sv, const char *str)
{
while (sv->str != NULL) {
if (strcmp(sv->str, str) == 0)
return sv->value;
sv++;
}
return -1;
}
int
get_amp(char *string, u_long *addr, u_long *mask, u_short *port, u_short *port2)
{
char *p, *addr_str = NULL, *mask_str = NULL, *port_str = NULL,
*port2_str = NULL;
int result = 0;
addr_str = string;
// "/mask"
p = strchr(string, '/');
if (p != NULL) {
*(p++) = '\0';
mask_str = p;
}
// ":port"
p = strchr(mask_str ? mask_str : string, ':');
if (p != NULL) {
*(p++) = '\0';
port_str = p;
// "-port2"
p = strchr(port_str, '-');
if (p != NULL) {
*(p++) = '\0';
port2_str = p;
}
}
// is it ANY?
if (strcmp(addr_str, "ANY") == 0) {
// 0.0.0.0/0
*addr = INADDR_ANY;
*mask = INADDR_ANY;
} else {
// <address>[/<mask>]
*addr = inet_addr(addr_str);
if (*addr == INADDR_NONE && strcmp(addr_str, "255.255.255.255") != 0) {
if (g_rules_resolve_addr) {
// try to resolve addr
struct hostent *he = gethostbyname(addr_str);
if (he == NULL) {
error("PARSE\tUnable to resolve: %s", addr_str);
return 0;
}
*addr = *(u_long *)he->h_addr;
// ??? do we need to log it ???
} else {
error("PARSE\tInvalid address: %s", addr_str);
return 0;
}
}
if (mask_str != NULL) {
// <mask>
int n = atoi(mask_str);
if ((n == 0 && strcmp(mask_str, "0") != 0) || n < 0 || n > 32) {
error("PARSE\tInvalid mask: %s", mask_str);
return 0;
}
if (n == 0)
*mask = 0;
else {
int i;
for (i = 1, *mask = 1; i < n; i++)
*mask |= *mask << 1;
}
} else
*mask = INADDR_NONE; // default mask 255.255.255.255
}
if (port_str) {
int n = atoi(port_str);
if ((n == 0 && strcmp(port_str, "0") != 0) || n < 0 || n > 0xffff) {
error("PARSE\tInvalid port: %s", port_str);
return 0;
}
*port = (USHORT)n;
} else
*port = 0;
if (port2_str) {
int n = atoi(port2_str);
if ((n == 0 && strcmp(port2_str, "0") != 0) || n < 0 || n > 0xffff) {
error("PARSE\tInvalid port2: %s", port2_str);
return 0;
}
*port2 = (USHORT)n;
} else
*port2 = 0;
// make network order
*port = htons(*port);
*port2 = htons(*port2);
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -