Import source code for dummynet innode emulation.
[ipfw.git] / glue.h
diff --git a/glue.h b/glue.h
new file mode 100644 (file)
index 0000000..8a6a014
--- /dev/null
+++ b/glue.h
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2009 Luigi Rizzo, Marta Carbone, Universita` di Pisa
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ *
+ * $Id$
+ *
+ * glue code to adapt the FreeBSD version to linux and windows,
+ * userland and kernel.
+ * This is included before any other headers, so we do not have
+ * a chance to override any #define that should appear in other
+ * headers.
+ */
+#ifndef _GLUE_H
+#define        _GLUE_H
+
+/*
+ * common definitions to allow portability
+ */
+#ifndef __FBSDID
+#define __FBSDID(x)
+#endif  /* FBSDID */
+
+/*
+ * emulation of FreeBSD's sockopt and thread
+ * This was in sockopt.h
+ */
+enum sopt_dir { SOPT_GET, SOPT_SET };
+
+#ifndef KERNEL_MODULE  /* Userland part */
+
+#include <stdint.h>            /* linux needs this in addition to sys/types.h */
+
+#include <sys/types.h>         /* for size_t */
+#include <sys/ioctl.h>
+#include <time.h>
+
+#include <netinet/ether.h>
+
+#else /* KERNEL_MODULE, kernel part */
+
+#ifndef _WIN32
+#include <linux/version.h>
+
+#define ifnet          net_device      /* remap */
+#define        _KERNEL         # make kernel structure visible
+#define        KLD_MODULE      # add the module glue
+#define        INET            # want inet support
+
+#include <linux/stddef.h>      /* linux kernel */
+#include <linux/types.h>       /* linux kernel */
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)        // or 2.4.x
+#include <linux/linkage.h>     /* linux/msg.h require this */
+#include <linux/netdevice.h>   /* just MAX_ADDR_LEN 8 on 2.4 32 on 2.6, also brings in byteorder */
+#endif
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) && \
+               LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)     // under 2.6.22 compilation is required by msg.h
+#include <linux/spinlock_types.h>
+#endif
+#include <linux/msg.h>         /* XXX m_type define conflict with include/sys/mbuf.h,
+                                * so early include this file (to be solved) */
+#include <linux/list.h>
+#include <linux/in.h>          /* struct in_addr */
+#include <linux/icmp.h>
+/*
+ * LIST_HEAD in queue.h conflict with linux/list.h
+ * some previous linux include need list.h definition
+ */
+#undef LIST_HEAD
+
+#define         IF_NAMESIZE     16
+typedef uint32_t      in_addr_t;
+
+#define printf(fmt, arg...) printk(KERN_ERR fmt, ##arg)
+
+#endif /* !_WIN32 */
+#endif /* KERNEL_MODULE */
+
+/*
+ * In windows, we need to emulate the sockopt interface
+ * so also the userland needs to have the struct sockopt defined.
+ * No need to declare struct thread on linux, but we need on windows.
+ */
+
+struct thread {
+        void *sopt_td;
+        void *td_ucred;
+};
+
+struct  sockopt {
+        enum    sopt_dir sopt_dir; /* is this a get or a set? */
+        int     sopt_level;     /* second arg of [gs]etsockopt */
+        int     sopt_name;      /* third arg of [gs]etsockopt */
+        void   *sopt_val;       /* fourth arg of [gs]etsockopt */
+        size_t  sopt_valsize;   /* (almost) fifth arg of [gs]etsockopt */
+        struct  thread *sopt_td; /* calling thread or null if kernel */
+};
+
+
+/* This must be included here after list.h */
+#include <sys/queue.h>         /* both the kernel side and nat.c needs this */
+
+#ifndef KERNEL_MODULE
+
+/* define internals for struct in6_addr netinet/in6.h on FreeBSD */
+#define __u6_addr in6_u
+#define __u6_addr32 u6_addr32
+/* define missing type for ipv6 (linux 2.6.28) */
+#define in6_u __in6_u
+
+/* missing in linux netinet/ip.h */
+#define IPTOS_ECN_ECT0          0x02    /* ECN-capable transport (0) */
+#define IPTOS_ECN_CE            0x03    /* congestion experienced */
+
+/* defined in freebsd netinet/icmp6.h */
+#define ICMP6_MAXTYPE                   201
+
+/* on freebsd sys/socket.h pf specific */
+#define NET_RT_IFLIST   3               /* survey interface list */
+
+/* on freebsd net/if.h XXX used */
+struct if_data {
+
+       /* ... */
+        u_long ifi_mtu;                /* maximum transmission unit */   
+};
+
+/*
+ * Message format for use in obtaining information about interfaces
+ * from getkerninfo and the routing socket.
+ * This is used in nat.c
+ */
+struct if_msghdr {
+        u_short ifm_msglen;     /* to skip over non-understood messages */
+        u_char  ifm_version;    /* future binary compatibility */
+        u_char  ifm_type;       /* message type */
+        int     ifm_addrs;      /* like rtm_addrs */
+        int     ifm_flags;      /* value of if_flags */
+        u_short ifm_index;      /* index for associated ifp */
+        struct  if_data ifm_data;/* statistics and other data about if */
+};
+
+/*
+ * Message format for use in obtaining information about interface addresses
+ * from getkerninfo and the routing socket
+ */
+struct ifa_msghdr {
+        u_short ifam_msglen;    /* to skip over non-understood messages */
+        u_char  ifam_version;   /* future binary compatibility */
+        u_char  ifam_type;      /* message type */
+        int     ifam_addrs;     /* like rtm_addrs */
+        int     ifam_flags;     /* value of ifa_flags */
+        u_short ifam_index;     /* index for associated ifp */
+        int     ifam_metric;    /* value of ifa_metric */
+};
+
+#ifndef NO_RTM /* conflicting with netlink */
+/* missing in net/route.h */
+#define RTM_VERSION     5       /* Up the ante and ignore older versions */
+#define RTM_IFINFO      0xe     /* iface going up/down etc. */
+#define RTM_NEWADDR     0xc     /* address being added to iface */
+#define RTA_IFA         0x20    /* interface addr sockaddr present */
+#endif /* NO_RTM */
+
+/* SA_SIZE is used in the userland nat.c modified */
+#define SA_SIZE(sa)                                             \
+    (  (!(sa) ) ?      \
+        sizeof(long)            :                               \
+        1 + ( (sizeof(struct sockaddr) - 1) | (sizeof(long) - 1) ) )
+
+/* sys/time.h */
+/*
+ * Getkerninfo clock information structure
+ */
+struct clockinfo {
+        int     hz;             /* clock frequency */
+        int     tick;           /* micro-seconds per hz tick */
+        int     spare;
+        int     stathz;         /* statistics clock frequency */
+        int     profhz;         /* profiling clock frequency */
+};
+
+
+/*
+ * linux does not have heapsort
+ */
+#define heapsort(_a, _b, _c, _d)       qsort(_a, _b, _c, _d)
+
+#define setprogname(x) /* not present in linux */
+
+extern int optreset;   /* not present in linux */
+
+size_t strlcpy(char * dst, const char * src, size_t siz);
+long long int
+strtonum(const char *nptr, long long minval, long long maxval,
+         const char **errstr);
+int
+sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp,
+         size_t newlen);
+#else /* KERNEL_MODULE */
+
+/* linux and windows kernel do not have bcopy ? */
+#define bcopy(_s, _d, _l)      memcpy(_d, _s, _l)
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)        // or 2.4.x
+#include <linux/in6.h>
+#endif
+
+/* definitions useful for the kernel side */
+
+struct route_in6 { };
+
+#endif /* KERNEL_MODULE */
+
+/*
+ * List of values used for set/getsockopt options.
+ * The base value on FreeBSD is defined as a macro,
+ * if not available we will use our own enum.
+ * The TABLE_BASE value is used in the kernel.
+ */
+#ifndef IP_FW_TABLE_ADD
+#define _IPFW_SOCKOPT_BASE     100     /* 40 on freebsd */
+enum ipfw_msg_type {
+       IP_FW_TABLE_ADD         = _IPFW_SOCKOPT_BASE,
+       IP_FW_TABLE_DEL,
+       IP_FW_TABLE_FLUSH,
+       IP_FW_TABLE_GETSIZE,
+       IP_FW_TABLE_LIST,
+
+       IP_FW_ADD               = _IPFW_SOCKOPT_BASE + 10,
+       IP_FW_DEL,
+       IP_FW_FLUSH,
+       IP_FW_ZERO,
+       IP_FW_GET,
+       IP_FW_RESETLOG,
+
+       IP_FW_NAT_CFG,
+       IP_FW_NAT_DEL,
+       IP_FW_NAT_GET_CONFIG,
+       IP_FW_NAT_GET_LOG,
+
+       IP_DUMMYNET_CONFIGURE,
+       IP_DUMMYNET_DEL ,
+       IP_DUMMYNET_FLUSH,
+       /* 63 is missing */
+       IP_DUMMYNET_GET         = _IPFW_SOCKOPT_BASE + 24,
+       _IPFW_SOCKOPT_END
+};
+#endif /* IP_FW_TABLE_ADD */
+
+#endif /* !_GLUE_H */