70268bb8ab0e6fdefe8e238044aaebb93c51fc21
[ipfw.git] / dummynet2 / 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 4665 2010-01-04 12:35:39Z 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 /*
146  * we don't really reassemble, just return whatever we had.
147  */
148 struct mbuf *
149 ip_reass(struct mbuf *clone)
150 {
151         return clone;
152 }
153 #ifdef INP_LOCK_ASSERT
154 #undef INP_LOCK_ASSERT
155 #define INP_LOCK_ASSERT(a)
156 #endif
157
158 /* credentials check */
159 #include <netinet/ip_fw.h>
160 int
161 cred_check(void *_insn,  int proto, struct ifnet *oif,
162     struct in_addr dst_ip, u_int16_t dst_port, struct in_addr src_ip,
163     u_int16_t src_port, struct bsd_ucred *u, int *ugid_lookupp,
164     struct sk_buff *skb)
165 {
166         int match = 0;
167         ipfw_insn_u32 *insn = (ipfw_insn_u32 *)_insn;
168
169         if (*ugid_lookupp == 0) {        /* actively lookup and copy in cache */
170                 /* returns null if any element of the chain up to file is null.
171                  * if sk != NULL then we also have a reference
172                  */
173                 *ugid_lookupp = linux_lookup(proto,
174                         src_ip.s_addr, htons(src_port),
175                         dst_ip.s_addr, htons(dst_port),
176                         skb, oif ? 1 : 0, u);
177         }
178         if (*ugid_lookupp < 0)
179                 return 0;
180
181         if (insn->o.opcode == O_UID)
182                 match = (u->uid == (uid_t)insn->d[0]);
183         else if (insn->o.opcode == O_JAIL)
184                 match = (u->xid == (uid_t)insn->d[0]);
185         else if (insn->o.opcode == O_GID)
186                 match = (u->gid == (uid_t)insn->d[0]);
187         return match;
188 }
189
190 int
191 jailed(struct ucred *cred)
192 {
193         return 0;
194 }
195
196 /*
197 * Return 1 if an internet address is for a ``local'' host
198 * (one to which we have a connection).  If subnetsarelocal
199 * is true, this includes other subnets of the local net.
200 * Otherwise, it includes only the directly-connected (sub)nets.
201 */
202 int
203 in_localaddr(struct in_addr in)
204 {
205         return 1;
206 }
207
208 int
209 sooptcopyout(struct sockopt *sopt, const void *buf, size_t len)
210 {
211         size_t valsize = sopt->sopt_valsize;
212
213         if (len < valsize)
214                 sopt->sopt_valsize = valsize = len;
215         bcopy(buf, sopt->sopt_val, valsize);
216         return 0;
217 }
218
219 /*
220  * copy data from userland to kernel
221  */
222 int
223 sooptcopyin(struct sockopt *sopt, void *buf, size_t len, size_t minlen)
224 {
225         size_t valsize = sopt->sopt_valsize;
226
227         if (valsize < minlen)
228                 return EINVAL;
229         if (valsize > len)
230                 sopt->sopt_valsize = valsize = len;
231         bcopy(sopt->sopt_val, buf, valsize);
232         return 0;
233 }
234
235 void
236 getmicrouptime(struct timeval *tv)
237 {
238 #ifdef _WIN32
239 #else
240         do_gettimeofday(tv);
241 #endif
242 }
243
244
245 #include <arpa/inet.h>
246
247 char *
248 inet_ntoa_r(struct in_addr ina, char *buf)
249 {
250 #ifdef _WIN32
251 #else
252         unsigned char *ucp = (unsigned char *)&ina;
253
254         sprintf(buf, "%d.%d.%d.%d",
255         ucp[0] & 0xff,
256         ucp[1] & 0xff,
257         ucp[2] & 0xff,
258         ucp[3] & 0xff);
259 #endif
260         return buf;
261 }
262
263 char *
264 inet_ntoa(struct in_addr ina)
265 {
266         static char buf[16];
267         return inet_ntoa_r(ina, buf);
268 }
269
270 int
271 random(void)
272 {
273 #ifdef _WIN32
274         return 0x123456;
275 #else
276         int r;
277         get_random_bytes(&r, sizeof(r));
278         return r & 0x7fffffff; 
279 #endif
280 }
281
282
283 /*
284  * do_div really does a u64 / u32 bit division.
285  * we save the sign and convert to uint befor calling.
286  * We are safe just because we always call it with small operands.
287  */
288 int64_t
289 div64(int64_t a, int64_t b)
290 {
291 #ifdef _WIN32
292         int a1 = a, b1 = b;
293         return a1/b1;
294 #else
295         uint64_t ua, ub;
296         int sign = ((a>0)?1:-1) * ((b>0)?1:-1);
297
298         ua = ((a>0)?a:-a);
299         ub = ((b>0)?b:-b);
300         do_div(ua, ub);
301         return sign*ua;
302 #endif
303 }
304
305 /*
306  * compact version of fnmatch.
307  */
308 int
309 fnmatch(const char *pattern, const char *string, int flags)
310 {
311         char s;
312
313         if (!string || !pattern)
314                 return 1;       /* no match */
315         while ( (s = *string++) ) {
316                 char p = *pattern++;
317                 if (p == '\0')          /* pattern is over, no match */
318                         return 1;
319                 if (p == '*')           /* wildcard, match */
320                         return 0;
321                 if (p == '.' || p == s) /* char match, continue */
322                         continue;
323                 return 1;               /* no match */
324         }
325         /* end of string, make sure the pattern is over too */
326         if (*pattern == '\0' || *pattern == '*')
327                 return 0;
328         return 1;       /* no match */
329 }
330
331 #ifdef _WIN32
332 /*
333  * as good as anywhere, place here the missing calls
334  */
335
336 void *
337 my_alloc(int size)
338 {
339         void *_ret = ExAllocatePoolWithTag(0, size, 'wfpi');
340         if (_ret)
341                 memset(_ret, 0, size);
342         return _ret;
343 }
344
345 void
346 panic(const char *fmt, ...)
347 {
348         printf("%s", fmt);
349         for (;;);
350 }
351
352 #include <stdarg.h>
353
354 extern int _vsnprintf(char *buf, int buf_size, char * fmt, va_list ap);
355
356 /*
357  * Windows' _snprintf doesn't terminate buffer with zero if size > buf_size
358  */
359 int
360 snprintf(char *buf, int buf_size, char *fmt, ...)
361 {
362     va_list ap;
363     va_start(ap, fmt);
364     if (_vsnprintf(buf, buf_size, fmt, ap) < 0)
365         buf[buf_size - 1] = '\0';
366     va_end(ap);
367
368     return 0;
369 }
370 #endif