2 * Copyright (c) 2009 Luigi Rizzo, Marta Carbone, Universita` di Pisa
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $Id: glue.h 12501 2014-01-10 01:09:14Z luigi $
28 * glue code to adapt the FreeBSD version to linux and windows,
29 * userland and kernel.
30 * This is included before any other headers, so we do not have
31 * a chance to override any #define that should appear in other
33 * First handle headers for userland and kernel. Then common code
34 * (including headers that require a specific order of inclusion),
35 * then the user- and kernel- specific parts.
38 #if defined __FreeBSD__
40 #endif /* __FreeBSD__ */
46 * common definitions to allow portability
52 #ifndef KERNEL_MODULE /* Userland headers */
54 #if defined(__CYGWIN32__) || defined(__CYGWIN__)
60 #if defined(TCC) && defined(_WIN32)
64 #include <stdint.h> /* linux needs it in addition to sys/types.h */
65 #include <sys/types.h> /* for size_t */
66 #include <sys/ioctl.h>
70 #include <netinet/ether.h> /* linux only 20111031 */
73 #else /* KERNEL_MODULE, kernel headers */
75 #define INET # want inet support
78 #include <linux/version.h>
80 #define ifnet net_device /* remap */
81 #define _KERNEL # make kernel structure visible
82 #define KLD_MODULE # add the module glue
84 #include <linux/stddef.h> /* linux kernel */
85 #include <linux/types.h> /* linux kernel */
87 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17) // or 2.4.x
88 #include <linux/linkage.h> /* linux/msg.h require this */
89 #include <linux/netdevice.h> /* just MAX_ADDR_LEN 8 on 2.4 32 on 2.6, also brings in byteorder */
92 /* on 2.6.22, msg.h requires spinlock_types.h */
93 /* XXX spinlock_type.h was introduced in 2.6.14 */
94 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) && \
95 LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
96 #include <linux/spinlock_types.h>
98 /* XXX m_type define conflict with include/sys/mbuf.h,
99 * so early include msg.h (to be solved)
101 #include <linux/msg.h>
103 #include <linux/list.h>
104 #include <linux/in.h> /* struct in_addr */
105 #include <linux/in6.h> /* struct in6_addr */
106 #include <linux/icmp.h>
108 * LIST_HEAD in queue.h conflict with linux/list.h
109 * some previous linux include need list.h definition
113 #define IF_NAMESIZE (16)
114 typedef uint32_t in_addr_t;
116 #define printf(fmt, arg...) printk(KERN_ERR fmt, ##arg)
117 #endif /* __linux__ */
119 #endif /* KERNEL_MODULE end of kernel headers */
123 * Part 2: common userland and kernel definitions
126 #ifndef ETHER_ADDR_LEN
127 #define ETHER_ADDR_LEN (6+0) /* length of an Ethernet address */
130 #define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */
131 #define ICMP6_DST_UNREACH_ADMIN 1 /* administratively prohibited */
132 #define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */
133 #define ICMP6_DST_UNREACH_NOPORT 4 /* port unreachable */
136 * linux: sysctl are mapped into /sys/module/ipfw_mod parameters
137 * windows: they are emulated via get/setsockopt
140 #define CTLFLAG_RDTUN 1
142 #define CTLFLAG_SECURE3 0 // unsupported
143 #define CTLFLAG_VNET 0 /* unsupported */
145 /* if needed, queue.h must be included here after list.h */
148 * struct thread is used in linux and windows kernel.
149 * In windows, we need to emulate the sockopt interface
150 * so also the userland needs to have the struct sockopt defined.
151 * In order to achieve 64 bit compatibility, padding has been inserted.
158 enum sopt_dir { SOPT_GET, SOPT_SET };
161 enum sopt_dir sopt_dir; /* is this a get or a set? */
162 int sopt_level; /* second arg of [gs]etsockopt */
163 int sopt_name; /* third arg of [gs]etsockopt */
168 void *sopt_val; /* fourth arg of [gs]etsockopt */
169 size_t sopt_valsize; /* (almost) fifth arg of [gs]etsockopt */
174 struct thread *sopt_td; /* calling thread or null if kernel */
178 #define INET_ADDRSTRLEN (16) /* missing in netinet/in.h */
181 * List of values used for set/getsockopt options.
182 * The base value on FreeBSD is defined as a macro,
183 * if not available we will use our own enum.
184 * The TABLE_BASE value is used in the kernel.
186 #ifndef IP_FW_TABLE_ADD
187 #define _IPFW_SOCKOPT_BASE 100 /* 40 on freebsd */
189 IP_FW_TABLE_ADD = _IPFW_SOCKOPT_BASE,
194 IP_FW_DYN_GET, /* new addition */
196 /* IP_FW3 and IP_DUMMYNET3 are the new API */
197 IP_FW3 = _IPFW_SOCKOPT_BASE + 8,
200 IP_FW_ADD = _IPFW_SOCKOPT_BASE + 10,
209 IP_FW_NAT_GET_CONFIG,
212 IP_DUMMYNET_CONFIGURE,
216 IP_DUMMYNET_GET = _IPFW_SOCKOPT_BASE + 24,
219 #endif /* IP_FW_TABLE_ADD */
222 * Part 3: userland stuff
225 #ifndef KERNEL_MODULE
228 * internal names in struct in6_addr (netinet/in6.h) differ,
229 * so we remap the FreeBSD names to the platform-specific ones.
232 #define __u6_addr in6_u
233 #define __u6_addr32 u6_addr32
234 #define in6_u __in6_u /* missing type for ipv6 (linux 2.6.28) */
235 #else /* _WIN32 uses different naming */
236 #define __u6_addr __u6
237 #define __u6_addr32 __s6_addr32
240 /* missing in linux netinet/ip.h */
241 #define IPTOS_ECN_ECT0 0x02 /* ECN-capable transport (0) */
242 #define IPTOS_ECN_CE 0x03 /* congestion experienced */
244 /* defined in freebsd netinet/icmp6.h */
245 #define ICMP6_MAXTYPE 201
247 /* on freebsd sys/socket.h pf specific */
248 #define NET_RT_IFLIST 3 /* survey interface list */
250 #if defined(__linux__) || defined(__CYGWIN32__) || defined(__CYGWIN__)
251 /* on freebsd net/if.h XXX used */
254 u_long ifi_mtu; /* maximum transmission unit */
258 * Message format for use in obtaining information about interfaces
259 * from getkerninfo and the routing socket.
260 * This is used in nat.c
263 u_short ifm_msglen; /* to skip over unknown messages */
264 u_char ifm_version; /* future binary compatibility */
265 u_char ifm_type; /* message type */
266 int ifm_addrs; /* like rtm_addrs */
267 int ifm_flags; /* value of if_flags */
268 u_short ifm_index; /* index for associated ifp */
269 struct if_data ifm_data;/* stats and other ifdata */
273 * Message format for use in obtaining information about interface
274 * addresses from getkerninfo and the routing socket
277 u_short ifam_msglen; /* to skip over unknown messages */
278 u_char ifam_version; /* future binary compatibility */
279 u_char ifam_type; /* message type */
280 int ifam_addrs; /* like rtm_addrs */
281 int ifam_flags; /* value of ifa_flags */
282 u_short ifam_index; /* index for associated ifp */
283 int ifam_metric; /* value of ifa_metric */
286 #ifndef NO_RTM /* conflicting with netlink */
287 /* missing in net/route.h */
288 #define RTM_VERSION 5 /* Up the ante and ignore older versions */
289 #define RTM_IFINFO 0xe /* iface going up/down etc. */
290 #define RTM_NEWADDR 0xc /* address being added to iface */
291 #define RTA_IFA 0x20 /* interface addr sockaddr present */
294 /* SA_SIZE is used in the userland nat.c modified */
295 #define SA_SIZE(sa) \
298 1 + ( (sizeof(struct sockaddr) - 1) | (sizeof(long) - 1) ) )
302 * Getkerninfo clock information structure
305 int hz; /* clock frequency */
306 int tick; /* micro-seconds per hz tick */
308 int stathz; /* statistics clock frequency */
309 int profhz; /* profiling clock frequency */
312 /* no sin_len in sockaddr, we only remap in userland */
313 #define sin_len sin_zero[0]
315 #endif /* Linux/Win */
318 * linux does not have a reentrant version of qsort,
319 * so we the FreeBSD stdlib version.
321 void qsort_r(void *a, size_t n, size_t es, void *thunk,
322 int cmp_t(void *, const void *, const void *));
324 /* prototypes from libutil */
325 /* humanize_number(3) */
326 #define HN_DECIMAL 0x01
327 #define HN_NOSPACE 0x02
329 #define HN_DIVISOR_1000 0x08
331 #define HN_GETSCALE 0x10
332 #define HN_AUTOSCALE 0x20
334 int humanize_number(char *_buf, size_t _len, int64_t _number,
335 const char *_suffix, int _scale, int _flags);
336 int expand_number(const char *_buf, int64_t *_num);
338 #define setprogname(x) /* not present in linux */
340 extern int optreset; /* not present in linux */
342 size_t strlcpy(char * dst, const char * src, size_t siz);
343 long long int strtonum(const char *nptr, long long minval,
344 long long maxval, const char **errstr);
346 int sysctlbyname(const char *name, void *oldp, size_t *oldlenp,
347 void *newp, size_t newlen);
350 #else /* KERNEL_MODULE */
353 * Part 4: kernel stuff
356 /* linux and windows kernel do not have bcopy ? */
357 #define bcopy(_s, _d, _l) memcpy(_d, _s, _l)
358 /* definitions useful for the kernel side */
365 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17) // or 2.4.x
366 #include <linux/in6.h>
369 /* skb_dst() and skb_dst_set() was introduced from linux 2.6.31 */
370 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
371 void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst);
372 struct dst_entry *skb_dst(const struct sk_buff *skb);
375 /* The struct flowi changed */
376 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38) // check boundaries
377 #define flow_daddr fl.u.ip4
379 #define flow_daddr fl.nl_u.ip4_u
382 #endif /* __linux__ */
385 * Do not load prio_heap.h header because of conflicting names
386 * with our heap functions defined in include/netinet/ipfw/dn_heap.h
387 * However do define struct ptr_heap used in linux 3.12.7 etc.
389 #define _LINUX_PRIO_HEAP_H
393 * The following define prevent the ipv6.h header to be loaded.
394 * Starting from the 2.6.38 kernel the ipv6.h file, which is included
395 * by include/net/inetpeer.h in turn included by net/route.h
396 * include the system tcp.h file while we want to include
397 * our include/net/tcp.h instead.
401 static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2)
403 memcpy(a1, a2, sizeof(struct in6_addr));
405 #endif /* _NET_IPV6_H */
407 #endif /* KERNEL_MODULE */
410 * Part 5: windows specific stuff
414 #ifndef KERNEL_MODULE
415 #define CTL_CODE( DeviceType, Function, Method, Access ) ( \
416 ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
419 #define METHOD_BUFFERED 0
420 #define METHOD_IN_DIRECT 1
421 #define METHOD_OUT_DIRECT 2
422 #define METHOD_NEITHER 3
423 #define FILE_ANY_ACCESS 0
424 #define FILE_READ_DATA ( 0x0001 ) // file & pipe
425 #define FILE_WRITE_DATA ( 0x0002 ) // file & pipe
426 #endif /* !KERNEL_MODULE */
428 #define FILE_DEVICE_IPFW 0x00654324
429 #define IP_FW_BASE_CTL 0x840
430 #define IP_FW_SETSOCKOPT \
431 CTL_CODE(FILE_DEVICE_IPFW, IP_FW_BASE_CTL + 1, METHOD_BUFFERED, FILE_WRITE_DATA)
432 #define IP_FW_GETSOCKOPT \
433 CTL_CODE(FILE_DEVICE_IPFW, IP_FW_BASE_CTL + 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
435 /*********************************
436 * missing declarations in altq.c *
437 **********************************/
439 #define _IOWR(x,y,t) _IOW(x,y,t)
441 /**********************************
442 * missing declarations in ipfw2.c *
443 ***********************************/
445 #define ICMP_UNREACH_NET 0 /* bad net */
446 #define ICMP_UNREACH_HOST 1 /* bad host */
447 #define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */
448 #define ICMP_UNREACH_PORT 3 /* bad port */
449 #define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */
450 #define ICMP_UNREACH_SRCFAIL 5 /* src route failed */
451 #define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */
452 #define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */
453 #define ICMP_UNREACH_ISOLATED 8 /* src host isolated */
454 #define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */
455 #define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */
456 #define ICMP_UNREACH_TOSNET 11 /* bad tos for net */
457 #define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */
458 #define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohib */
459 #define ICMP_UNREACH_HOST_PRECEDENCE 14 /* host prec vio. */
460 #define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* prec cutoff */
464 struct ether_addr * ether_aton(const char *a);
466 /*********************************
467 * missing declarations in ipv6.c *
468 **********************************/
470 struct hostent* gethostbyname2(const char *name, int af);
472 #define strcasecmp strcmp // windows XXX ip_dummynet.c
474 /********************
475 * windows wrappings *
476 *********************/
478 int my_socket(int domain, int ty, int proto);
479 #define socket(_a, _b, _c) my_socket(_a, _b, _c)
484 ********************/
485 #if defined (_WIN32) || defined (EMULATE_SYSCTL)
486 #define STRINGIFY(x) #x
488 /* flag is set with the last 2 bits for access, as defined in glue.h
489 * and the rest for type
502 uint32_t blocklen; //total size of the entry
503 uint32_t namelen; //strlen(name) + '\0'
504 uint32_t flags; //type and access
513 #define SYSCTL_NODE(a,b,c,d,e,f)
514 #define SYSCTL_DECL(a)
515 #define SYSCTL_VNET_PROC(a,b,c,d,e,f,g,h,i)
517 #define GST_HARD_LIMIT 100
519 /* In the module, GST is implemented as an array of
520 * sysctlentry, but while passing data to the userland
521 * pointers are useless, the buffer is actually made of:
522 * - sysctlhead (fixed size, containing lengths)
523 * - data (typically 32 bit)
524 * - name (zero-terminated and padded to mod4)
528 struct sysctlhead head;
534 int count; //number of valid tables
535 int totalsize; //total size of valid entries of al the valid tables
536 void* namebuffer; //a buffer for all chained names
537 struct sysctlentry entry[GST_HARD_LIMIT];
543 #define SYSBEGIN(x) void sysctl_addgroup_##x() {
549 /* XXX remove duplication */
550 #define SYSCTL_INT(a,b,c,d,e,f,g) \
551 sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1, \
552 (d) | (SYSCTLTYPE_INT << 2), sizeof(*e), e)
554 #define SYSCTL_VNET_INT(a,b,c,d,e,f,g) \
555 sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1, \
556 (d) | (SYSCTLTYPE_INT << 2), sizeof(*e), e)
558 #define SYSCTL_UINT(a,b,c,d,e,f,g) \
559 sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1, \
560 (d) | (SYSCTLTYPE_UINT << 2), sizeof(*e), e)
562 #define SYSCTL_VNET_UINT(a,b,c,d,e,f,g) \
563 sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1, \
564 (d) | (SYSCTLTYPE_UINT << 2), sizeof(*e), e)
566 #define SYSCTL_LONG(a,b,c,d,e,f,g) \
567 sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1, \
568 (d) | (SYSCTLTYPE_LONG << 2), sizeof(*e), e)
570 #define SYSCTL_ULONG(a,b,c,d,e,f,g) \
571 sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1, \
572 (d) | (SYSCTLTYPE_ULONG << 2), sizeof(*e), e)
573 #define TUNABLE_INT(a,b)
575 void keinit_GST(void);
576 void keexit_GST(void);
577 int kesysctl_emu_set(void* p, int l);
578 int kesysctl_emu_get(struct sockopt* sopt);
579 void sysctl_pushback(char* name, int flags, int datalen, void* data);
583 int sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp,
585 #endif /* _WIN32" || EMULATE_SYSCTL */
587 int do_cmd(int optname, void *optval, uintptr_t optlen);
591 #define __PAST_END(v, idx) v[idx]
592 #endif /* !_GLUE_H */