for Windows, remove \r from the files to patch
[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(_WIN32)                                   
55 #define _WIN32                                                                  
56 #endif                                                                          
57
58 #if defined(TCC) && defined(_WIN32)
59 #include <tcc_glue.h>
60 #endif /* TCC */
61
62 #include <stdint.h>     /* linux needs it in addition to sys/types.h */
63 #include <sys/types.h>  /* for size_t */
64 #include <sys/ioctl.h>
65 #include <time.h>
66 #include <errno.h>
67 #ifdef __linux__
68 #include <netinet/ether.h>      /* linux only 20111031 */
69 #endif
70
71 #else /* KERNEL_MODULE, kernel headers */
72
73 #define INET            # want inet support
74 #ifdef __linux__
75
76 #include <linux/version.h>
77
78 #define ifnet           net_device      /* remap */
79 #define _KERNEL         # make kernel structure visible
80 #define KLD_MODULE      # add the module glue
81
82 #include <linux/stddef.h>       /* linux kernel */
83 #include <linux/types.h>        /* linux kernel */
84
85 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17) // or 2.4.x
86 #include <linux/linkage.h>      /* linux/msg.h require this */
87 #include <linux/netdevice.h>    /* just MAX_ADDR_LEN 8 on 2.4 32 on 2.6, also brings in byteorder */
88 #endif
89
90 /* on 2.6.22, msg.h requires spinlock_types.h */
91 /* XXX spinlock_type.h was introduced in 2.6.14 */
92 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) && \
93         LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
94 #include <linux/spinlock_types.h>
95 #endif
96 /* XXX m_type define conflict with include/sys/mbuf.h,
97  * so early include msg.h (to be solved)
98 */
99 #include <linux/msg.h>  
100
101 #include <linux/list.h>
102 #include <linux/in.h>           /* struct in_addr */
103 #include <linux/in6.h>          /* struct in6_addr */
104 #include <linux/icmp.h>
105 /*
106  * LIST_HEAD in queue.h conflict with linux/list.h
107  * some previous linux include need list.h definition
108  */
109 #undef LIST_HEAD
110
111 #define IF_NAMESIZE     (16)
112 typedef uint32_t        in_addr_t;
113
114 #define printf(fmt, arg...) printk(KERN_ERR fmt, ##arg)
115 #endif  /* __linux__ */
116
117 #endif /* KERNEL_MODULE end of kernel headers */
118
119
120 /*
121  * Part 2: common userland and kernel definitions
122  */
123
124 #ifndef ETHER_ADDR_LEN
125 #define ETHER_ADDR_LEN (6+0)       /* length of an Ethernet address */
126 #endif
127
128 #define ICMP6_DST_UNREACH_NOROUTE       0       /* no route to destination */
129 #define ICMP6_DST_UNREACH_ADMIN         1       /* administratively prohibited */
130 #define ICMP6_DST_UNREACH_ADDR          3       /* address unreachable */
131 #define ICMP6_DST_UNREACH_NOPORT        4       /* port unreachable */
132
133 /*
134  * linux: sysctl are mapped into /sys/module/ipfw_mod parameters
135  * windows: they are emulated via get/setsockopt
136  */
137 #define CTLFLAG_RD              1
138 #define CTLFLAG_RDTUN   1
139 #define CTLFLAG_RW              2
140 #define CTLFLAG_SECURE3 0 // unsupported
141 #define CTLFLAG_VNET    0       /* unsupported */
142
143 /* if needed, queue.h must be included here after list.h */
144
145 /*
146  * struct thread is used in linux and windows kernel.
147  * In windows, we need to emulate the sockopt interface
148  * so also the userland needs to have the struct sockopt defined.
149  * In order to achieve 64 bit compatibility, padding has been inserted.
150  */
151 struct thread {
152         void *sopt_td;
153         void *td_ucred;
154 };
155
156 enum sopt_dir { SOPT_GET, SOPT_SET };
157
158 struct  sockopt {
159         enum    sopt_dir sopt_dir; /* is this a get or a set? */
160         int     sopt_level;     /* second arg of [gs]etsockopt */
161         int     sopt_name;      /* third arg of [gs]etsockopt */
162 #ifdef _X64EMU
163                 void* pad1;
164                 void* pad2;
165 #endif
166                 void   *sopt_val;       /* fourth arg of [gs]etsockopt */
167                 size_t  sopt_valsize;   /* (almost) fifth arg of [gs]etsockopt */
168 #ifdef _X64EMU
169                 void* pad3;
170                 void* pad4;
171 #endif
172                 struct  thread *sopt_td; /* calling thread or null if kernel */
173 };
174
175
176 #define INET_ADDRSTRLEN         (16)    /* missing in netinet/in.h */
177
178 /*
179  * List of values used for set/getsockopt options.
180  * The base value on FreeBSD is defined as a macro,
181  * if not available we will use our own enum.
182  * The TABLE_BASE value is used in the kernel.
183  */
184 #ifndef IP_FW_TABLE_ADD
185 #define _IPFW_SOCKOPT_BASE      100     /* 40 on freebsd */
186 enum ipfw_msg_type {
187         IP_FW_TABLE_ADD         = _IPFW_SOCKOPT_BASE,
188         IP_FW_TABLE_DEL,
189         IP_FW_TABLE_FLUSH,
190         IP_FW_TABLE_GETSIZE,
191         IP_FW_TABLE_LIST,
192         IP_FW_DYN_GET,          /* new addition */
193
194         /* IP_FW3 and IP_DUMMYNET3 are the new API */
195         IP_FW3                  = _IPFW_SOCKOPT_BASE + 8,
196         IP_DUMMYNET3,
197
198         IP_FW_ADD               = _IPFW_SOCKOPT_BASE + 10,
199         IP_FW_DEL,
200         IP_FW_FLUSH,
201         IP_FW_ZERO,
202         IP_FW_GET,
203         IP_FW_RESETLOG,
204
205         IP_FW_NAT_CFG,
206         IP_FW_NAT_DEL,
207         IP_FW_NAT_GET_CONFIG,
208         IP_FW_NAT_GET_LOG,
209
210         IP_DUMMYNET_CONFIGURE,
211         IP_DUMMYNET_DEL ,
212         IP_DUMMYNET_FLUSH,
213         /* 63 is missing */
214         IP_DUMMYNET_GET         = _IPFW_SOCKOPT_BASE + 24,
215         _IPFW_SOCKOPT_END
216 };
217 #endif /* IP_FW_TABLE_ADD */
218
219 /*
220  * Part 3: userland stuff
221  */
222
223 #ifndef KERNEL_MODULE
224
225 /*
226  * internal names in struct in6_addr (netinet/in6.h) differ,
227  * so we remap the FreeBSD names to the platform-specific ones.
228  */
229 #ifndef _WIN32
230 #define __u6_addr       in6_u
231 #define __u6_addr32     u6_addr32
232 #define in6_u __in6_u   /* missing type for ipv6 (linux 2.6.28) */
233 #else   /* _WIN32 uses different naming */
234 #define __u6_addr       __u6
235 #define __u6_addr32     __s6_addr32
236 #endif  /* _WIN32 */
237
238 /* missing in linux netinet/ip.h */
239 #define IPTOS_ECN_ECT0  0x02    /* ECN-capable transport (0) */
240 #define IPTOS_ECN_CE    0x03    /* congestion experienced */
241
242 /* defined in freebsd netinet/icmp6.h */
243 #define ICMP6_MAXTYPE   201
244
245 /* on freebsd sys/socket.h pf specific */
246 #define NET_RT_IFLIST   3               /* survey interface list */
247
248 #if defined(__linux__) || defined(__CYGWIN32__)
249 /* on freebsd net/if.h XXX used */
250 struct if_data {
251         /* ... */
252         u_long ifi_mtu; /* maximum transmission unit */
253 };
254
255 /*
256  * Message format for use in obtaining information about interfaces
257  * from getkerninfo and the routing socket.
258  * This is used in nat.c
259  */
260 struct if_msghdr {
261         u_short ifm_msglen;     /* to skip over unknown messages */
262         u_char  ifm_version;    /* future binary compatibility */
263         u_char  ifm_type;       /* message type */
264         int     ifm_addrs;      /* like rtm_addrs */
265         int     ifm_flags;      /* value of if_flags */
266         u_short ifm_index;      /* index for associated ifp */
267         struct  if_data ifm_data;/* stats and other ifdata */
268 };
269
270 /*
271  * Message format for use in obtaining information about interface
272  * addresses from getkerninfo and the routing socket
273  */
274 struct ifa_msghdr {
275         u_short ifam_msglen;    /* to skip over unknown messages */
276         u_char  ifam_version;   /* future binary compatibility */
277         u_char  ifam_type;      /* message type */
278         int     ifam_addrs;     /* like rtm_addrs */
279         int     ifam_flags;     /* value of ifa_flags */
280         u_short ifam_index;     /* index for associated ifp */
281         int     ifam_metric;    /* value of ifa_metric */
282 };
283
284 #ifndef NO_RTM  /* conflicting with netlink */
285 /* missing in net/route.h */
286 #define RTM_VERSION     5       /* Up the ante and ignore older versions */
287 #define RTM_IFINFO      0xe     /* iface going up/down etc. */
288 #define RTM_NEWADDR     0xc     /* address being added to iface */
289 #define RTA_IFA         0x20    /* interface addr sockaddr present */
290 #endif  /* NO_RTM */
291
292 /* SA_SIZE is used in the userland nat.c modified */
293 #define SA_SIZE(sa)                                             \
294     (  (!(sa) ) ?      \
295         sizeof(long)            :                               \
296         1 + ( (sizeof(struct sockaddr) - 1) | (sizeof(long) - 1) ) )
297
298 /* sys/time.h */
299 /*
300  * Getkerninfo clock information structure
301  */
302 struct clockinfo {
303         int     hz;             /* clock frequency */
304         int     tick;           /* micro-seconds per hz tick */
305         int     spare;
306         int     stathz;         /* statistics clock frequency */
307         int     profhz;         /* profiling clock frequency */
308 };
309
310 /* no sin_len in sockaddr, we only remap in userland */
311 #define sin_len sin_zero[0]
312
313 #endif /* Linux/Win */
314
315 /*
316  * linux does not have a reentrant version of qsort,
317  * so we the FreeBSD stdlib version.
318  */
319 void qsort_r(void *a, size_t n, size_t es, void *thunk,
320         int cmp_t(void *, const void *, const void *));
321
322 /* prototypes from libutil */
323 /* humanize_number(3) */
324 #define HN_DECIMAL              0x01
325 #define HN_NOSPACE              0x02
326 #define HN_B                    0x04
327 #define HN_DIVISOR_1000         0x08
328
329 #define HN_GETSCALE             0x10
330 #define HN_AUTOSCALE            0x20
331
332 int     humanize_number(char *_buf, size_t _len, int64_t _number,
333             const char *_suffix, int _scale, int _flags);
334 int     expand_number(const char *_buf, int64_t *_num);
335
336 #define setprogname(x)  /* not present in linux */
337
338 extern int optreset;    /* not present in linux */
339
340 size_t strlcpy(char * dst, const char * src, size_t siz);
341 long long int strtonum(const char *nptr, long long minval,
342         long long maxval, const char **errstr);
343  
344 int sysctlbyname(const char *name, void *oldp, size_t *oldlenp,
345         void *newp, size_t newlen);
346  
347
348 #else /* KERNEL_MODULE */
349
350 /*
351  * Part 4: kernel stuff
352  */
353
354 /* linux and windows kernel do not have bcopy ? */
355 #define bcopy(_s, _d, _l)       memcpy(_d, _s, _l)
356 /* definitions useful for the kernel side */
357 struct route_in6 {
358         int dummy;
359 };
360
361 #ifdef __linux__
362
363 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17) // or 2.4.x
364 #include <linux/in6.h>
365 #endif
366
367 /* skb_dst() and skb_dst_set() was introduced from linux 2.6.31 */
368 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
369 void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst);
370 struct dst_entry *skb_dst(const struct sk_buff *skb);
371 #endif
372
373 /* The struct flowi changed */
374 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38) // check boundaries
375 #define flow_daddr fl.u.ip4
376 #else
377 #define flow_daddr fl.nl_u.ip4_u
378 #endif
379
380 #endif /* __linux__ */
381
382 /* 
383  * Do not load prio_heap.h header because of conflicting names
384  * with our heap functions defined in include/netinet/ipfw/dn_heap.h
385  * However do define struct ptr_heap used in linux 3.12.7 etc.
386  */
387 #define _LINUX_PRIO_HEAP_H
388 struct ptr_heap;
389
390 /* 
391  * The following define prevent the ipv6.h header to be loaded.
392  * Starting from the 2.6.38 kernel the ipv6.h file, which is included
393  * by include/net/inetpeer.h in turn included by net/route.h
394  * include the system tcp.h file while we want to include 
395  * our include/net/tcp.h instead.
396  */
397 #ifndef _NET_IPV6_H
398 #define _NET_IPV6_H
399 static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2)
400 {
401         memcpy(a1, a2, sizeof(struct in6_addr));
402 }
403 #endif /* _NET_IPV6_H */
404
405 #endif  /* KERNEL_MODULE */
406
407 /*
408  * Part 5: windows specific stuff
409  */
410
411 #ifdef _WIN32
412 #ifndef KERNEL_MODULE
413 #define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
414     ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
415 )
416
417 #define METHOD_BUFFERED                 0
418 #define METHOD_IN_DIRECT                1
419 #define METHOD_OUT_DIRECT               2
420 #define METHOD_NEITHER                  3
421 #define FILE_ANY_ACCESS                 0
422 #define FILE_READ_DATA            ( 0x0001 )    // file & pipe
423 #define FILE_WRITE_DATA           ( 0x0002 )    // file & pipe
424 #endif /* !KERNEL_MODULE */
425
426 #define FILE_DEVICE_IPFW                0x00654324
427 #define IP_FW_BASE_CTL                  0x840
428 #define IP_FW_SETSOCKOPT \
429         CTL_CODE(FILE_DEVICE_IPFW, IP_FW_BASE_CTL + 1, METHOD_BUFFERED, FILE_WRITE_DATA)
430 #define IP_FW_GETSOCKOPT \
431         CTL_CODE(FILE_DEVICE_IPFW, IP_FW_BASE_CTL + 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
432
433 /*********************************
434 * missing declarations in altq.c *
435 **********************************/
436
437 #define _IOWR(x,y,t) _IOW(x,y,t)
438
439 /**********************************
440 * missing declarations in ipfw2.c *
441 ***********************************/
442
443 #define ICMP_UNREACH_NET                0       /* bad net */
444 #define ICMP_UNREACH_HOST               1       /* bad host */
445 #define ICMP_UNREACH_PROTOCOL           2       /* bad protocol */
446 #define ICMP_UNREACH_PORT               3       /* bad port */
447 #define ICMP_UNREACH_NEEDFRAG           4       /* IP_DF caused drop */
448 #define ICMP_UNREACH_SRCFAIL            5       /* src route failed */
449 #define ICMP_UNREACH_NET_UNKNOWN        6       /* unknown net */
450 #define ICMP_UNREACH_HOST_UNKNOWN       7       /* unknown host */
451 #define ICMP_UNREACH_ISOLATED           8       /* src host isolated */
452 #define ICMP_UNREACH_NET_PROHIB         9       /* prohibited access */
453 #define ICMP_UNREACH_HOST_PROHIB        10      /* ditto */
454 #define ICMP_UNREACH_TOSNET             11      /* bad tos for net */
455 #define ICMP_UNREACH_TOSHOST            12      /* bad tos for host */
456 #define ICMP_UNREACH_FILTER_PROHIB      13      /* admin prohib */
457 #define ICMP_UNREACH_HOST_PRECEDENCE    14      /* host prec vio. */
458 #define ICMP_UNREACH_PRECEDENCE_CUTOFF  15      /* prec cutoff */
459
460
461 struct ether_addr;
462 struct ether_addr * ether_aton(const char *a);
463
464 /*********************************
465 * missing declarations in ipv6.c *
466 **********************************/
467
468 struct hostent* gethostbyname2(const char *name, int af);
469
470
471 /********************
472 * windows wrappings *
473 *********************/
474
475 int my_socket(int domain, int ty, int proto);
476 #define socket(_a, _b, _c)      my_socket(_a, _b, _c)
477
478 #endif /* _WIN32 */
479 /*******************
480 * SYSCTL emulation *
481 ********************/
482 #if defined (_WIN32) || defined (EMULATE_SYSCTL)
483 #define STRINGIFY(x) #x
484
485 /* flag is set with the last 2 bits for access, as defined in glue.h
486  * and the rest for type
487  */
488 enum {
489         SYSCTLTYPE_INT = 0,
490         SYSCTLTYPE_UINT,
491         SYSCTLTYPE_SHORT,
492         SYSCTLTYPE_USHORT,
493         SYSCTLTYPE_LONG,
494         SYSCTLTYPE_ULONG,
495         SYSCTLTYPE_STRING,
496 };
497
498 struct sysctlhead {
499         uint32_t blocklen; //total size of the entry
500         uint32_t namelen; //strlen(name) + '\0'
501         uint32_t flags; //type and access
502         uint32_t datalen;
503 };
504
505 #ifdef _KERNEL
506
507 #ifdef SYSCTL_NODE
508 #undef SYSCTL_NODE
509 #endif
510 #define SYSCTL_NODE(a,b,c,d,e,f)
511 #define SYSCTL_DECL(a)
512 #define SYSCTL_VNET_PROC(a,b,c,d,e,f,g,h,i)
513
514 #define GST_HARD_LIMIT 100
515
516 /* In the module, GST is implemented as an array of
517  * sysctlentry, but while passing data to the userland
518  * pointers are useless, the buffer is actually made of:
519  * - sysctlhead (fixed size, containing lengths)
520  * - data (typically 32 bit)
521  * - name (zero-terminated and padded to mod4)
522  */
523
524 struct sysctlentry {
525         struct sysctlhead head;
526         char* name;
527         void* data;
528 };
529
530 struct sysctltable {
531         int count; //number of valid tables
532         int totalsize; //total size of valid entries of al the valid tables
533         void* namebuffer; //a buffer for all chained names
534         struct sysctlentry entry[GST_HARD_LIMIT];
535 };
536
537 #ifdef SYSBEGIN
538 #undef SYSBEGIN
539 #endif
540 #define SYSBEGIN(x) void sysctl_addgroup_##x() {
541 #ifdef SYSEND
542 #undef SYSEND
543 #endif
544 #define SYSEND }
545
546 /* XXX remove duplication */
547 #define SYSCTL_INT(a,b,c,d,e,f,g)                               \
548         sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1,      \
549                 (d) | (SYSCTLTYPE_INT << 2), sizeof(*e), e)
550
551 #define SYSCTL_VNET_INT(a,b,c,d,e,f,g)                          \
552         sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1,      \
553                 (d) | (SYSCTLTYPE_INT << 2), sizeof(*e), e)
554
555 #define SYSCTL_UINT(a,b,c,d,e,f,g)                              \
556         sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1,      \
557                 (d) | (SYSCTLTYPE_UINT << 2), sizeof(*e), e)
558
559 #define SYSCTL_VNET_UINT(a,b,c,d,e,f,g)                         \
560         sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1,      \
561                 (d) | (SYSCTLTYPE_UINT << 2), sizeof(*e), e)
562
563 #define SYSCTL_LONG(a,b,c,d,e,f,g)                              \
564         sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1,      \
565                 (d) | (SYSCTLTYPE_LONG << 2), sizeof(*e), e)
566
567 #define SYSCTL_ULONG(a,b,c,d,e,f,g)                             \
568         sysctl_pushback(STRINGIFY(a) "." STRINGIFY(c) + 1,      \
569                 (d) | (SYSCTLTYPE_ULONG << 2), sizeof(*e), e)
570 #define TUNABLE_INT(a,b)
571
572 void keinit_GST(void);
573 void keexit_GST(void);
574 int kesysctl_emu_set(void* p, int l);
575 int kesysctl_emu_get(struct sockopt* sopt);
576 void sysctl_pushback(char* name, int flags, int datalen, void* data);
577
578 #endif /* _KERNEL */
579
580 int sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp,
581          size_t newlen);
582 #endif /* _WIN32" || EMULATE_SYSCTL */
583 #ifdef _WIN32
584 int do_cmd(int optname, void *optval, uintptr_t optlen);
585
586 #endif /* _WIN32 */
587
588 #define __PAST_END(v, idx)      v[idx]
589 #endif /* !_GLUE_H */