#endif
#include "opt_inet6.h"
#include "opt_ipsec.h"
-#include "opt_mac.h"
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/condvar.h>
+#include <sys/eventhandler.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/priv.h>
#include <sys/proc.h>
+#include <sys/rwlock.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sysctl.h>
#include <net/pf_mtag.h>
#include <net/vnet.h>
+#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 <netinet/in.h>
#include <netinet/icmp6.h>
#ifdef INET6
#include <netinet6/scope6_var.h>
+#include <netinet6/ip6_var.h>
#endif
#include <machine/in_cksum.h> /* XXX for in_cksum */
#include <security/mac/mac_framework.h>
#endif
-#ifdef linux
-//#include <linux/netdevice.h> /* 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 <net/sock.h> /* linux - struct sock and sock_put() */
-#endif
-
static VNET_DEFINE(int, ipfw_vnet_ready) = 0;
#define V_ipfw_vnet_ready VNET(ipfw_vnet_ready)
/*
#endif /* SYSCTL_NODE */
+#ifndef IPFW_NEWTABLES_MAX
+#define IPFW_NEWTABLES_MAX 256
+#endif
/*
* Description of dynamic rules.
*
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)
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,
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
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;
return (ENOMEM);
}
}
-#endif
return (0);
}
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;
*val = ent->value;
return (1);
}
-#endif
return (0);
}
+#endif
#ifdef radix
static int
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)
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 {
lookup_next_rule(f, 0);
f = f->next_rule;
}
+#endif
/*
* Skip disabled rules, and
* re-enter the inner loop
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;
* 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
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