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