tweak for building in fedora20
[ipfw-google.git] / glue.h
1 /*
2  * Copyright (c) 2009 Luigi Rizzo, Marta Carbone, Universita` di Pisa
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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
23  * SUCH DAMAGE.
24  */
25 /*
26  * $Id: glue.h 12501 2014-01-10 01:09:14Z luigi $
27  *
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
32  * headers.
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.
36  */
37  
38 #if defined __FreeBSD__
39 #define _GLUE_H
40 #endif /* __FreeBSD__ */
41 #ifndef _GLUE_H
42 #define _GLUE_H
43
44
45 /*
46  * common definitions to allow portability
47  */
48 #ifndef __FBSDID
49 #define __FBSDID(x)
50 #endif  /* FBSDID */
51
52 #ifndef KERNEL_MODULE   /* Userland headers */
53
54 #if defined(__CYGWIN32__) || defined(__CYGWIN__)
55 #if !defined(_WIN32)                                   
56 #define _WIN32                                                                  
57 #endif                                                                          
58 #endif                                                                          
59
60 #if defined(TCC) && defined(_WIN32)
61 #include <tcc_glue.h>
62 #endif /* TCC */
63
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>
67 #include <time.h>
68 #include <errno.h>
69 #ifdef __linux__
70 #include <netinet/ether.h>      /* linux only 20111031 */
71 #endif
72
73 #else /* KERNEL_MODULE, kernel headers */
74
75 #define INET            # want inet support
76 #ifdef __linux__
77
78 #include <linux/version.h>
79
80 #define ifnet           net_device      /* remap */
81 #define _KERNEL         # make kernel structure visible
82 #define KLD_MODULE      # add the module glue
83
84 #include <linux/stddef.h>       /* linux kernel */
85 #include <linux/types.h>        /* linux kernel */
86
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 */
90 #endif
91
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>
97 #endif
98 /* XXX m_type define conflict with include/sys/mbuf.h,
99  * so early include msg.h (to be solved)
100 */
101 #include <linux/msg.h>  
102
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>
107 /*
108  * LIST_HEAD in queue.h conflict with linux/list.h
109  * some previous linux include need list.h definition
110  */
111 #undef LIST_HEAD
112
113 #define IF_NAMESIZE     (16)
114 typedef uint32_t        in_addr_t;
115
116 #define printf(fmt, arg...) printk(KERN_ERR fmt, ##arg)
117 #endif  /* __linux__ */
118
119 #endif /* KERNEL_MODULE end of kernel headers */
120
121
122 /*
123  * Part 2: common userland and kernel definitions
124  */
125
126 #ifndef ETHER_ADDR_LEN
127 #define ETHER_ADDR_LEN (6+0)       /* length of an Ethernet address */
128 #endif
129
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 */
134
135 /*
136  * linux: sysctl are mapped into /sys/module/ipfw_mod parameters
137  * windows: they are emulated via get/setsockopt
138  */
139 #define CTLFLAG_RD              1
140 #define CTLFLAG_RDTUN   1
141 #define CTLFLAG_RW              2
142 #define CTLFLAG_SECURE3 0 // unsupported
143 #define CTLFLAG_VNET    0       /* unsupported */
144
145 /* if needed, queue.h must be included here after list.h */
146
147 /*
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.
152  */
153 struct thread {
154         void *sopt_td;
155         void *td_ucred;
156 };
157
158 enum sopt_dir { SOPT_GET, SOPT_SET };
159
160 struct  sockopt {
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 */
164 #ifdef _X64EMU
165                 void* pad1;
166                 void* pad2;
167 #endif
168                 void   *sopt_val;       /* fourth arg of [gs]etsockopt */
169                 size_t  sopt_valsize;   /* (almost) fifth arg of [gs]etsockopt */
170 #ifdef _X64EMU
171                 void* pad3;
172                 void* pad4;
173 #endif
174                 struct  thread *sopt_td; /* calling thread or null if kernel */
175 };
176
177
178 #define INET_ADDRSTRLEN         (16)    /* missing in netinet/in.h */
179
180 /*
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.
185  */
186 #ifndef IP_FW_TABLE_ADD
187 #define _IPFW_SOCKOPT_BASE      100     /* 40 on freebsd */
188 enum ipfw_msg_type {
189         IP_FW_TABLE_ADD         = _IPFW_SOCKOPT_BASE,
190         IP_FW_TABLE_DEL,
191         IP_FW_TABLE_FLUSH,
192         IP_FW_TABLE_GETSIZE,
193         IP_FW_TABLE_LIST,
194         IP_FW_DYN_GET,          /* new addition */
195
196         /* IP_FW3 and IP_DUMMYNET3 are the new API */
197         IP_FW3                  = _IPFW_SOCKOPT_BASE + 8,
198         IP_DUMMYNET3,
199
200         IP_FW_ADD               = _IPFW_SOCKOPT_BASE + 10,
201         IP_FW_DEL,
202         IP_FW_FLUSH,
203         IP_FW_ZERO,
204         IP_FW_GET,
205         IP_FW_RESETLOG,
206
207         IP_FW_NAT_CFG,
208         IP_FW_NAT_DEL,
209         IP_FW_NAT_GET_CONFIG,
210         IP_FW_NAT_GET_LOG,
211
212         IP_DUMMYNET_CONFIGURE,
213         IP_DUMMYNET_DEL ,
214         IP_DUMMYNET_FLUSH,
215         /* 63 is missing */
216         IP_DUMMYNET_GET         = _IPFW_SOCKOPT_BASE + 24,
217         _IPFW_SOCKOPT_END
218 };
219 #endif /* IP_FW_TABLE_ADD */
220
221 /*
222  * Part 3: userland stuff
223  */
224
225 #ifndef KERNEL_MODULE
226
227 /*
228  * internal names in struct in6_addr (netinet/in6.h) differ,
229  * so we remap the FreeBSD names to the platform-specific ones.
230  */
231 #ifndef _WIN32
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
238 #endif  /* _WIN32 */
239
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 */
243
244 /* defined in freebsd netinet/icmp6.h */
245 #define ICMP6_MAXTYPE   201
246
247 /* on freebsd sys/socket.h pf specific */
248 #define NET_RT_IFLIST   3               /* survey interface list */
249
250 #if defined(__linux__) || defined(__CYGWIN32__) || defined(__CYGWIN__)
251 /* on freebsd net/if.h XXX used */
252 struct if_data {
253         /* ... */
254         u_long ifi_mtu; /* maximum transmission unit */
255 };
256
257 /*
258  * Message format for use in obtaining information about interfaces
259  * from getkerninfo and the routing socket.
260  * This is used in nat.c
261  */
262 struct if_msghdr {
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 */
270 };
271
272 /*
273  * Message format for use in obtaining information about interface
274  * addresses from getkerninfo and the routing socket
275  */
276 struct ifa_msghdr {
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 */
284 };
285
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 */
292 #endif  /* NO_RTM */
293
294 /* SA_SIZE is used in the userland nat.c modified */
295 #define SA_SIZE(sa)                                             \
296     (  (!(sa) ) ?      \
297         sizeof(long)            :                               \
298         1 + ( (sizeof(struct sockaddr) - 1) | (sizeof(long) - 1) ) )
299
300 /* sys/time.h */
301 /*
302  * Getkerninfo clock information structure
303  */
304 struct clockinfo {
305         int     hz;             /* clock frequency */
306         int     tick;           /* micro-seconds per hz tick */
307         int     spare;
308         int     stathz;         /* statistics clock frequency */
309         int     profhz;         /* profiling clock frequency */
310 };
311
312 /* no sin_len in sockaddr, we only remap in userland */
313 #define sin_len sin_zero[0]
314
315 #endif /* Linux/Win */
316
317 /*
318  * linux does not have a reentrant version of qsort,
319  * so we the FreeBSD stdlib version.
320  */
321 void qsort_r(void *a, size_t n, size_t es, void *thunk,
322         int cmp_t(void *, const void *, const void *));
323
324 /* prototypes from libutil */
325 /* humanize_number(3) */
326 #define HN_DECIMAL              0x01
327 #define HN_NOSPACE              0x02
328 #define HN_B                    0x04
329 #define HN_DIVISOR_1000         0x08
330
331 #define HN_GETSCALE             0x10
332 #define HN_AUTOSCALE            0x20
333
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);
337
338 #define setprogname(x)  /* not present in linux */
339
340 extern int optreset;    /* not present in linux */
341
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);
345  
346 int sysctlbyname(const char *name, void *oldp, size_t *oldlenp,
347         void *newp, size_t newlen);
348  
349
350 #else /* KERNEL_MODULE */
351
352 /*
353  * Part 4: kernel stuff
354  */
355
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 */
359 struct route_in6 {
360         int dummy;
361 };
362
363 #ifdef __linux__
364
365 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17) // or 2.4.x
366 #include <linux/in6.h>
367 #endif
368
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);
373 #endif
374
375 /* The struct flowi changed */
376 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38) // check boundaries
377 #define flow_daddr fl.u.ip4
378 #else
379 #define flow_daddr fl.nl_u.ip4_u
380 #endif
381
382 #endif /* __linux__ */
383
384 /* 
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.
388  */
389 #define _LINUX_PRIO_HEAP_H
390 struct ptr_heap;
391
392 /* 
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.
398  */
399 #ifndef _NET_IPV6_H
400 #define _NET_IPV6_H
401 static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2)
402 {
403         memcpy(a1, a2, sizeof(struct in6_addr));
404 }
405 #endif /* _NET_IPV6_H */
406
407 #endif  /* KERNEL_MODULE */
408
409 /*
410  * Part 5: windows specific stuff
411  */
412
413 #ifdef _WIN32
414 #ifndef KERNEL_MODULE
415 #define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
416     ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
417 )
418
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 */
427
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)
434
435 /*********************************
436 * missing declarations in altq.c *
437 **********************************/
438
439 #define _IOWR(x,y,t) _IOW(x,y,t)
440
441 /**********************************
442 * missing declarations in ipfw2.c *
443 ***********************************/
444
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 */
461
462
463 struct ether_addr;
464 struct ether_addr * ether_aton(const char *a);
465
466 /*********************************
467 * missing declarations in ipv6.c *
468 **********************************/
469
470 struct hostent* gethostbyname2(const char *name, int af);
471
472 #define strcasecmp strcmp // windows XXX ip_dummynet.c
473
474 /********************
475 * windows wrappings *
476 *********************/
477
478 int my_socket(int domain, int ty, int proto);
479 #define socket(_a, _b, _c)      my_socket(_a, _b, _c)
480
481 #endif /* _WIN32 */
482 /*******************
483 * SYSCTL emulation *
484 ********************/
485 #if defined (_WIN32) || defined (EMULATE_SYSCTL)
486 #define STRINGIFY(x) #x
487
488 /* flag is set with the last 2 bits for access, as defined in glue.h
489  * and the rest for type
490  */
491 enum {
492         SYSCTLTYPE_INT = 0,
493         SYSCTLTYPE_UINT,
494         SYSCTLTYPE_SHORT,
495         SYSCTLTYPE_USHORT,
496         SYSCTLTYPE_LONG,
497         SYSCTLTYPE_ULONG,
498         SYSCTLTYPE_STRING,
499 };
500
501 struct sysctlhead {
502         uint32_t blocklen; //total size of the entry
503         uint32_t namelen; //strlen(name) + '\0'
504         uint32_t flags; //type and access
505         uint32_t datalen;
506 };
507
508 #ifdef _KERNEL
509
510 #ifdef SYSCTL_NODE
511 #undef SYSCTL_NODE
512 #endif
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)
516
517 #define GST_HARD_LIMIT 100
518
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)
525  */
526
527 struct sysctlentry {
528         struct sysctlhead head;
529         char* name;
530         void* data;
531 };
532
533 struct sysctltable {
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];
538 };
539
540 #ifdef SYSBEGIN
541 #undef SYSBEGIN
542 #endif
543 #define SYSBEGIN(x) void sysctl_addgroup_##x() {
544 #ifdef SYSEND
545 #undef SYSEND
546 #endif
547 #define SYSEND }
548
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)
553
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)
557
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)
561
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)
565
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)
569
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)
574
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);
580
581 #endif /* _KERNEL */
582
583 int sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp,
584          size_t newlen);
585 #endif /* _WIN32" || EMULATE_SYSCTL */
586 #ifdef _WIN32
587 int do_cmd(int optname, void *optval, uintptr_t optlen);
588
589 #endif /* _WIN32 */
590
591 #define __PAST_END(v, idx)      v[idx]
592 #endif /* !_GLUE_H */