Import source code for dummynet innode emulation.
[ipfw.git] / dummynet / bsd_compat.c
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 /*
27  * $Id$
28  *
29  * kernel variables and functions that are not available in linux.
30  */
31
32 #include <sys/cdefs.h>
33 #include <asm/div64.h>  /* do_div on 2.4 */
34 #include <linux/random.h>       /* get_random_bytes on 2.4 */
35 #include "missing.h"
36
37 /*
38  * gettimeofday would be in sys/time.h but it is not
39  * visible if _KERNEL is defined
40  */
41 int gettimeofday(struct timeval *, struct timezone *);
42
43 int ticks;              /* kernel ticks counter */
44 int hz = 1000;          /* default clock time */
45 long tick = 1000;       /* XXX is this 100000/hz ? */
46 int bootverbose = 0;
47 time_t time_uptime = 0;
48 struct timeval boottime;
49
50 int     ip_defttl;
51 int fw_one_pass = 1;
52 u_long  in_ifaddrhmask;                         /* mask for hash table */
53 struct  in_ifaddrhashhead *in_ifaddrhashtbl;    /* inet addr hash table  */
54
55 u_int rt_numfibs = RT_NUMFIBS;
56
57 /*
58  * pfil hook support.
59  * We make pfil_head_get return a non-null pointer, which is then ignored
60  * in our 'add-hook' routines.
61  */
62 struct pfil_head;
63 typedef int (pfil_hook_t)
64         (void *, struct mbuf **, struct ifnet *, int, struct inpcb *);
65
66 struct pfil_head *
67 pfil_head_get(int proto, u_long flags)
68 {
69         static int dummy;
70         return (struct pfil_head *)&dummy;
71 }
72  
73 int
74 pfil_add_hook(pfil_hook_t *func, void *arg, int dir, struct pfil_head *h)
75 {
76         return 0;
77 }
78
79 int
80 pfil_remove_hook(pfil_hook_t *func, void *arg, int dir, struct pfil_head *h)
81 {
82         return 0;
83 }
84
85 /* define empty body for kernel function */
86 int
87 priv_check(struct thread *td, int priv)
88 {
89         return 0;
90 }
91
92 int
93 securelevel_ge(struct ucred *cr, int level)
94 {
95         return 0;
96 }
97
98 int
99 sysctl_handle_int(SYSCTL_HANDLER_ARGS)
100 {
101         return 0;
102 }
103
104 int
105 sysctl_handle_long(SYSCTL_HANDLER_ARGS)
106 {
107         return 0;
108 }
109
110 void
111 ether_demux(struct ifnet *ifp, struct mbuf *m)
112 {
113         return;
114 }
115
116 int
117 ether_output_frame(struct ifnet *ifp, struct mbuf *m)
118 {
119         return 0;
120 }
121
122 void
123 in_rtalloc_ign(struct route *ro, u_long ignflags, u_int fibnum)
124 {
125         return;
126 }
127
128 void
129 icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu)
130 {
131         return;
132 }
133
134 u_short
135 in_cksum_skip(struct mbuf *m, int len, int skip)
136 {
137         return 0;
138 }
139
140 u_short
141 in_cksum_hdr(struct ip *ip)
142 {
143         return 0;
144 }
145
146 struct mbuf *
147 ip_reass(struct mbuf *clone)
148 {
149         return clone;
150 }
151 #ifdef INP_LOCK_ASSERT
152 #undef INP_LOCK_ASSERT
153 #define INP_LOCK_ASSERT(a)
154 #endif
155
156 int
157 jailed(struct ucred *cred)
158 {
159         return 0;
160 }
161
162 /*
163 * Return 1 if an internet address is for a ``local'' host
164 * (one to which we have a connection).  If subnetsarelocal
165 * is true, this includes other subnets of the local net.
166 * Otherwise, it includes only the directly-connected (sub)nets.
167 */
168 int
169 in_localaddr(struct in_addr in)
170 {
171         return 1;
172 }
173
174 int
175 sooptcopyout(struct sockopt *sopt, const void *buf, size_t len)
176 {
177         size_t valsize = sopt->sopt_valsize;
178
179         if (len < valsize)
180                 sopt->sopt_valsize = valsize = len;
181         bcopy(buf, sopt->sopt_val, valsize);
182         return 0;
183 }
184
185 /*
186  * copy data from userland to kernel
187  */
188 int
189 sooptcopyin(struct sockopt *sopt, void *buf, size_t len, size_t minlen)
190 {
191         size_t valsize = sopt->sopt_valsize;
192
193         if (valsize < minlen)
194                 return EINVAL;
195         if (valsize > len)
196                 sopt->sopt_valsize = valsize = len;
197         bcopy(sopt->sopt_val, buf, valsize);
198         return 0;
199 }
200
201 void
202 getmicrouptime(struct timeval *tv)
203 {
204 #ifdef _WIN32
205 #else
206         do_gettimeofday(tv);
207 #endif
208 }
209
210
211 #include <arpa/inet.h>
212
213 char *
214 inet_ntoa_r(struct in_addr ina, char *buf)
215 {
216 #ifdef _WIN32
217 #else
218         unsigned char *ucp = (unsigned char *)&ina;
219
220         sprintf(buf, "%d.%d.%d.%d",
221         ucp[0] & 0xff,
222         ucp[1] & 0xff,
223         ucp[2] & 0xff,
224         ucp[3] & 0xff);
225 #endif
226         return buf;
227 }
228
229 char *
230 inet_ntoa(struct in_addr ina)
231 {
232         static char buf[16];
233         return inet_ntoa_r(ina, buf);
234 }
235
236 int
237 random(void)
238 {
239 #ifdef _WIN32
240         return 0x123456;
241 #else
242         int r;
243         get_random_bytes(&r, sizeof(r));
244         return r & 0x7fffffff; 
245 #endif
246 }
247
248
249 /*
250  * do_div really does a u64 / u32 bit division.
251  * we save the sign and convert to uint befor calling.
252  * We are safe just because we always call it with small operands.
253  */
254 int64_t
255 div64(int64_t a, int64_t b)
256 {
257 #ifdef _WIN32
258         int a1 = a, b1 = b;
259         return a1/b1;
260 #else
261         uint64_t ua, ub;
262         int sign = ((a>0)?1:-1) * ((b>0)?1:-1);
263
264         ua = ((a>0)?a:-a);
265         ub = ((b>0)?b:-b);
266         do_div(ua, ub);
267         return sign*ua;
268 #endif
269 }
270
271 /*
272  * compact version of fnmatch.
273  */
274 int
275 fnmatch(const char *pattern, const char *string, int flags)
276 {
277         char s;
278
279         if (!string || !pattern)
280                 return 1;       /* no match */
281         while ( (s = *string++) ) {
282                 char p = *pattern++;
283                 if (p == '\0')          /* pattern is over, no match */
284                         return 1;
285                 if (p == '*')           /* wildcard, match */
286                         return 0;
287                 if (p == '.' || p == s) /* char match, continue */
288                         continue;
289                 return 1;               /* no match */
290         }
291         /* end of string, make sure the pattern is over too */
292         if (*pattern == '\0' || *pattern == '*')
293                 return 0;
294         return 1;       /* no match */
295 }
296
297 #ifdef _WIN32
298 /*
299  * as good as anywhere, place here the missing calls
300  */
301
302 void *
303 my_alloc(int size)
304 {
305         void *_ret = ExAllocatePoolWithTag(0, size, 'wfpi');
306         if (_ret)
307                 memset(_ret, 0, size);
308         return _ret;
309 }
310
311 void
312 panic(const char *fmt, ...)
313 {
314         printf("%s", fmt);
315         for (;;);
316 }
317
318 #include <stdarg.h>
319
320 extern int _vsnprintf(char *buf, int buf_size, char * fmt, va_list ap);
321
322 /*
323  * Windows' _snprintf doesn't terminate buffer with zero if size > buf_size
324  */
325 int
326 snprintf(char *buf, int buf_size, char *fmt, ...)
327 {
328     va_list ap;
329     va_start(ap, fmt);
330     if (_vsnprintf(buf, buf_size, fmt, ap) < 0)
331         buf[buf_size - 1] = '\0';
332     va_end(ap);
333
334     return 0;
335 }
336 #endif