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

📄 flt_rule.c

📁 基于TDI驱动编写的个人防火墙程序。包括驱动模块、应用层规则配置及加载模块。
💻 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 + -