X-Git-Url: http://git.onelab.eu/?p=ipfw.git;a=blobdiff_plain;f=dummynet%2Fip_fw2.c;h=50e870146ba7232fb54431da245a9e1ce7825f8c;hp=19d4d94a1751f161ddb8cda765e174cf09e8a762;hb=5ad9fec40da13c449d50def12f9cea6e24b6a708;hpb=f1a44f1ebacf274e0f35970bfc8ee5aa07aa9aca diff --git a/dummynet/ip_fw2.c b/dummynet/ip_fw2.c index 19d4d94..50e8701 100644 --- a/dummynet/ip_fw2.c +++ b/dummynet/ip_fw2.c @@ -44,10 +44,11 @@ __FBSDID("$FreeBSD: src/sys/netinet/ip_fw2.c,v 1.175.2.13 2008/10/30 16:29:04 bz #endif #include "opt_inet6.h" #include "opt_ipsec.h" -#include "opt_mac.h" #include #include +#include +#include #include #include #include @@ -56,6 +57,7 @@ __FBSDID("$FreeBSD: src/sys/netinet/ip_fw2.c,v 1.175.2.13 2008/10/30 16:29:04 bz #include #include #include +#include #include #include #include @@ -68,6 +70,11 @@ __FBSDID("$FreeBSD: src/sys/netinet/ip_fw2.c,v 1.175.2.13 2008/10/30 16:29:04 bz #include #include +#ifdef linux +#define INP_LOCK_ASSERT /* define before missing.h otherwise ? */ +#include "missing.h" +#endif + #define IPFW_INTERNAL /* Access to protected data structures in ip_fw.h. */ #include @@ -92,6 +99,7 @@ __FBSDID("$FreeBSD: src/sys/netinet/ip_fw2.c,v 1.175.2.13 2008/10/30 16:29:04 bz #include #ifdef INET6 #include +#include #endif #include /* XXX for in_cksum */ @@ -100,14 +108,6 @@ __FBSDID("$FreeBSD: src/sys/netinet/ip_fw2.c,v 1.175.2.13 2008/10/30 16:29:04 bz #include #endif -#ifdef linux -//#include /* XXX dev_net() is used in linux 2.6.30.5 */ -#define INP_LOCK_ASSERT /* define before missing.h otherwise ? */ -#include "missing.h" -#define _IPV6_H /* prevent ipv6 inclusion from hashtables and udp.h */ -#include /* linux - struct sock and sock_put() */ -#endif - static VNET_DEFINE(int, ipfw_vnet_ready) = 0; #define V_ipfw_vnet_ready VNET(ipfw_vnet_ready) /* @@ -218,6 +218,9 @@ SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, deny_unknown_exthdrs, #endif /* SYSCTL_NODE */ +#ifndef IPFW_NEWTABLES_MAX +#define IPFW_NEWTABLES_MAX 256 +#endif /* * Description of dynamic rules. * @@ -1912,7 +1915,7 @@ lookup_next_rule(struct ip_fw *me, u_int32_t tablearg) struct ip_fw *rule = NULL; ipfw_insn *cmd; u_int16_t rulenum; - +printf("%s called\n", __FUNCTION__); /* look for action, in case it is a skipto */ cmd = ACTION_PTR(me); if (cmd->opcode == O_LOG) @@ -1939,6 +1942,37 @@ lookup_next_rule(struct ip_fw *me, u_int32_t tablearg) return rule; } +#ifdef IPFW_HAVE_SKIPTO_TABLE +struct ip_fw *lookup_skipto_table(struct ip_fw_chain *chain, uint16_t num); + +struct ip_fw * +lookup_skipto_table(struct ip_fw_chain *chain, uint16_t num) +{ + struct ip_fw *f; + + printf("--%s called\n", __FUNCTION__); + if (1) + return NULL; + if (chain->skipto_pointers[num].id == chain->id) { + printf("-- %s pointer ok, return it\n", __FUNCTION__); + return chain->skipto_pointers[num].rule; + } + printf("-- %s search pointer\n", __FUNCTION__); + + for (f = chain->rules; f ; f = f->next) { + if (f->rulenum == num) { + chain->skipto_pointers[num].id = chain->id; + chain->skipto_pointers[num].rule = f; + printf("-- %s found, set and return\n", __FUNCTION__); + return f; + } + } + printf("-- %s NOT found return NULL\n", __FUNCTION__); + + return NULL; +} +#endif /* IPFW_HAVE_SKIPTO_TABLE */ + #ifdef radix static int add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr, @@ -2029,6 +2063,9 @@ extern int del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, extern int flush_table(struct ip_fw_chain *ch, uint16_t tbl); extern int count_table(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt); extern int dump_table(struct ip_fw_chain *ch, ipfw_table *tbl); +extern int lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr, + uint32_t *val); +extern int init_tables(struct ip_fw_chain *ch); #endif static void @@ -2038,14 +2075,14 @@ flush_tables(struct ip_fw_chain *ch) IPFW_WLOCK_ASSERT(ch); - for (tbl = 0; tbl < IPFW_TABLES_MAX; tbl++) + for (tbl = IPFW_TABLES_MAX -1; tbl < IPFW_NEWTABLES_MAX; tbl++) flush_table(ch, tbl); } +#ifdef radix static int init_tables(struct ip_fw_chain *ch) { -#ifdef radix int i; uint16_t j; @@ -2057,7 +2094,6 @@ init_tables(struct ip_fw_chain *ch) return (ENOMEM); } } -#endif return (0); } @@ -2065,7 +2101,6 @@ static int lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr, uint32_t *val) { -#ifdef radix struct radix_node_head *rnh; struct table_entry *ent; struct sockaddr_in sa; @@ -2080,9 +2115,9 @@ lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr, *val = ent->value; return (1); } -#endif return (0); } +#endif #ifdef radix static int @@ -2909,6 +2944,37 @@ do { \ dst_ip.s_addr : src_ip.s_addr; uint32_t v = 0; + if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) { + v = ((ipfw_insn_u32 *)cmd)->d[1]; + if (v == 0) + a = dst_ip.s_addr; + else if (v == 1) + a = src_ip.s_addr; + else if (offset != 0) + break; + else if (proto != IPPROTO_TCP && + proto != IPPROTO_UDP) + break; + else if (v == 2) + a = dst_port; + else if (v == 3) + a = src_port; + else if (v >= 4 && v <= 6) { + check_uidgid( + (ipfw_insn_u32 *)cmd, + proto, oif, + dst_ip, dst_port, + src_ip, src_port, &fw_ugid_cache, + &ugid_lookup, (struct inpcb *)args->m); + if (v ==4 /* O_UID */) + a = fw_ugid_cache.fw_uid; + else if (v == 5 /* O_GID */) + a = fw_ugid_cache.fw_groups[0]; + else if (v == 6 /* O_JAIL */) + a = fw_ugid_cache.fw_groups[1]; + } else + break; + } match = lookup_table(chain, cmd->arg1, a, &v); if (!match) @@ -3489,6 +3555,29 @@ do { \ break; } /* handle skipto */ +#ifdef IPFW_HAVE_SKIPTO_TABLE + /* NOTE: lookup_skipto_table can return NULL + * if the rule isn't found, so the + * standard lookup function must be + * called XXX + */ + if (cmd->arg1 == IP_FW_TABLEARG) { + f = lookup_skipto_table(chain, + tablearg); + if (f == NULL) + f = lookup_next_rule(f, tablearg); + } + else { + f = lookup_skipto_table(chain, + cmd->arg1); + if (f == NULL) { + if (f->next_rule == NULL) + lookup_next_rule(f, 0); + f = f->next_rule; + } + } + +#else if (cmd->arg1 == IP_FW_TABLEARG) { f = lookup_next_rule(f, tablearg); } else { @@ -3496,6 +3585,7 @@ do { \ lookup_next_rule(f, 0); f = f->next_rule; } +#endif /* * Skip disabled rules, and * re-enter the inner loop @@ -4262,10 +4352,11 @@ check_ipfw_struct(struct ip_fw *rule, int size) case O_IP_DST_LOOKUP: if (cmd->arg1 >= IPFW_TABLES_MAX) { printf("ipfw: invalid table number %d\n", - cmd->arg1); + cmd->arg1); return (EINVAL); } if (cmdlen != F_INSN_SIZE(ipfw_insn) && + cmdlen != F_INSN_SIZE(ipfw_insn_u32) + 1 && cmdlen != F_INSN_SIZE(ipfw_insn_u32)) goto bad_size; break; @@ -4821,7 +4912,7 @@ ipfw_ctl(struct sockopt *sopt) * NULL pointer, but this way we do not need to check for the special * case, plus here he have info on the default behaviour). */ -struct ip_fw *ip_fw_default_rule; +//struct ip_fw *ip_fw_default_rule; /* * This procedure is only used to handle keepalives. It is invoked @@ -5041,6 +5132,12 @@ vnet_ipfw_init(const void *unused) if (error) { panic("init_tables"); /* XXX Marko fix this ! */ } + +#ifdef IPFW_HAVE_SKIPTO_TABLE +// for (error = 0; error < 64*1024; error++) +// V_layer3_chain.skipto_pointers[error].id = -1; +#endif /* IPFW_HAVE_SKIPTO_TABLE */ + #ifdef IPFIREWALL_NAT LIST_INIT(&V_layer3_chain.nat); #endif