Grab the lock before reading uid/gid related structure, this will
[ipfw.git] / dummynet / new_glue.c
diff --git a/dummynet/new_glue.c b/dummynet/new_glue.c
new file mode 100644 (file)
index 0000000..52a1a7f
--- /dev/null
@@ -0,0 +1,263 @@
+#include "missing.h"
+//#include <sys/param.h>
+//#include <sys/systm.h>
+//#include <sys/malloc.h>
+// #include <sys/mbuf.h>
+//#include <sys/kernel.h>
+//#include <sys/lock.h>
+//#include <sys/jail.h>
+//#include <sys/module.h>
+//#include <sys/priv.h>
+//#include <sys/proc.h>
+//#include <sys/socket.h>
+//#include <sys/socketvar.h>
+//#include <sys/sysctl.h>
+//#include <sys/syslog.h>
+//#include <sys/ucred.h>
+//#include <net/ethernet.h> /* for ETHERTYPE_IP */
+//#include <net/if.h>
+//#include <net/radix.h>
+//#include <net/route.h>
+//#include <net/pf_mtag.h>
+
+#define IPFW_INTERNAL
+#include <netinet/ip_fw.h>
+
+#include "hashtable.h"
+#define IPFW_NEWTABLES_MAX     256
+
+struct t_o {
+       /* Object stored in the hash table */
+       uint32_t addr;
+       uint32_t value;
+       uint8_t mask;
+};
+
+MALLOC_DEFINE(M_IPFW_HTBL, "ipfw_tbl", "IpFw tables");
+
+static struct new_hash_table *global_tables[128];
+int add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
+                       uint8_t mlen, uint32_t value);
+int new_del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr);
+int del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
+                    uint8_t mlen);
+int new_flush_table(uint16_t tbl);
+int flush_table(struct ip_fw_chain *ch, uint16_t tbl);
+int lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr, 
+                uint32_t *val);
+int new_count_table_entry(uint32_t tbl, uint32_t *cnt);
+int count_table(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt);
+int new_dump_table_entry(ipfw_table *tbl);
+int dump_table(struct ip_fw_chain *ch, ipfw_table *tbl);
+int init_tables(struct ip_fw_chain *ch);
+
+/* hash and compare functions for 32-bit entries */
+static uint32_t
+simple_hash32(const void *key, uint32_t size)
+{
+       uint32_t ret = *(const uint32_t *)key % size;
+       printf("%s called\n", __FUNCTION__);
+       printf("Hash returns %d\n", ret);
+
+       return ret;
+}
+
+static int
+cmp_func32(const void *key1, const void *key2)
+{
+       int k1 = *(const int *)key1;
+       int k2 = *(const int *)key2;
+       int ret;
+       printf("(%s) k1=%d, k2=%d\n", __FUNCTION__, k1, k2);
+       if (k1 < k2)
+               ret = -1;
+       else if (k1 > k2)
+               ret = 1;
+       else
+               ret = 0;
+
+       printf("compare returns %d\n", ret);
+
+       return ret;
+}
+
+int
+add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
+    uint8_t mlen, uint32_t value)
+{
+       /* TODO:
+        * - Search the correct hash table (tbl - IPFW_TABLES_MAX)
+        * - Search if the entry already exists
+        * - Insert the new entry in the table
+        * - Possibly reallocate the table if it is too small
+        */
+
+       struct t_o obj;
+       int ret;
+       int i = tbl - IPFW_TABLES_MAX;
+       int size = 128;
+       int obj_size = sizeof(struct t_o);
+
+       printf("%s called\n", __FUNCTION__);
+       if (i < 0 || i > size-1) /* wrong table number */
+               return 1;
+       if (global_tables[i] == NULL) {
+               printf("Creating table n %d\n", tbl);
+               global_tables[i] = new_table_init(size, obj_size,
+                               simple_hash32, cmp_func32, M_IPFW_HTBL);
+       }
+
+       obj.addr = addr;
+       obj.value = value;
+       obj.mask = mlen;
+
+       /* Insert the object in the table */
+       ret = new_table_insert_obj(global_tables[i], &obj);
+       return ret;
+}
+
+int
+new_del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr)
+{
+       int ret;
+       int nr = tbl - IPFW_TABLES_MAX;
+
+       printf("%s called\n", __FUNCTION__);
+
+       ret = new_table_delete_obj(global_tables[nr], &addr);
+
+       return ret;
+}
+
+int
+del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
+    uint8_t mlen)
+{
+       printf("%s called\n", __FUNCTION__);
+       if (tbl >= IPFW_TABLES_MAX && tbl < IPFW_NEWTABLES_MAX) {
+               new_del_table_entry(ch, tbl, addr);
+               return 0;
+       }
+       return (EINVAL);
+}
+
+int
+new_flush_table(uint16_t tbl)
+{
+       printf("%s called\n", __FUNCTION__);
+       new_table_destroy(global_tables[tbl - IPFW_TABLES_MAX]);
+       return 0;
+}
+
+int
+flush_table(struct ip_fw_chain *ch, uint16_t tbl)
+{
+       printf("%s called\n", __FUNCTION__);
+       if (tbl >= IPFW_TABLES_MAX && tbl < IPFW_NEWTABLES_MAX)
+               return new_flush_table(tbl);
+       
+       return (EINVAL);
+}
+
+int
+lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
+    uint32_t *val)
+{
+       printf("%s called\n", __FUNCTION__);
+       if (tbl >= IPFW_TABLES_MAX && tbl < IPFW_NEWTABLES_MAX) {
+               struct new_hash_table *h;
+               struct t_o *obj;
+
+               h = global_tables[tbl - IPFW_NEWTABLES_MAX];
+               printf("Search %d in table number %d\n", addr, tbl);
+
+               obj = (struct t_o *)new_table_extract_obj(h, (void *)&addr);
+               if (obj == NULL)
+                       return 0;
+
+               *val = obj->value;
+
+               return 1;
+       }
+
+       return 1;
+}
+
+int
+new_count_table_entry(uint32_t tbl, uint32_t *cnt)
+{
+       printf("%s called\n", __FUNCTION__);
+       *cnt = new_table_get_element(global_tables[tbl - IPFW_TABLES_MAX]);
+       return 0;
+}
+
+int
+count_table(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt)
+{
+       printf("%s called\n", __FUNCTION__);
+       if (tbl >= IPFW_TABLES_MAX && tbl < IPFW_NEWTABLES_MAX) {
+               new_count_table_entry(tbl, cnt);
+               return (0);
+       }
+       return (EINVAL);
+}
+
+int
+new_dump_table_entry(ipfw_table *tbl)
+{
+       /* fill the tbl with all entryes */
+       ipfw_table_entry *ent;
+       const struct t_o *obj;
+       int i;
+       int n_el;
+       int nr = tbl->tbl - IPFW_TABLES_MAX;
+       struct new_hash_table *t = global_tables[nr];
+
+       printf("%s called\n", __FUNCTION__);
+
+       i = 0;
+       tbl->cnt = 0;
+
+       /* XXX determine tbl->size */
+       n_el = new_table_get_element(t);
+       obj = NULL;
+       for (; n_el > 0; n_el--) {
+               obj = table_next(t, obj);
+               if (obj == NULL)
+                       break;
+               printf("Found \n");
+               ent = &tbl->ent[tbl->cnt];
+
+               ent->addr = obj->addr;
+               ent->value = obj->value;
+               ent->masklen = obj->mask;
+               tbl->cnt++;
+       }
+       printf("\n");
+       return 0;
+}
+
+int
+dump_table(struct ip_fw_chain *ch, ipfw_table *tbl)
+{
+       printf("%s called\n", __FUNCTION__);
+       if (tbl->tbl >= IPFW_TABLES_MAX && tbl->tbl < IPFW_NEWTABLES_MAX) {
+               new_dump_table_entry(tbl);
+               return (0);
+       }
+       return (EINVAL);
+}
+
+int
+init_tables(struct ip_fw_chain *ch)
+{
+
+       int i;
+       printf("%s called\n", __FUNCTION__);
+       /* Initialize new tables XXXMPD */
+       for (i = 0; i < IPFW_NEWTABLES_MAX - IPFW_TABLES_MAX; i++) {
+               memset(&global_tables[i], sizeof(struct new_hash_table*), 0);
+       }
+
+       return (0);
+}