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