Line data Source code
1 : /*-
2 : * Copyright (c) 2006-2007, by Cisco Systems, Inc. All rights reserved.
3 : * Copyright (c) 2008-2011, by Randall Stewart. All rights reserved.
4 : * Copyright (c) 2008-2011, by Michael Tuexen. All rights reserved.
5 : * Copyright (c) 2008-2011, by Brad Penoff. All rights reserved.
6 : *
7 : * Redistribution and use in source and binary forms, with or without
8 : * modification, are permitted provided that the following conditions are met:
9 : *
10 : * a) Redistributions of source code must retain the above copyright notice,
11 : * this list of conditions and the following disclaimer.
12 : *
13 : * b) Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in
15 : * the documentation and/or other materials provided with the distribution.
16 : *
17 : * c) Neither the name of Cisco Systems, Inc. nor the names of its
18 : * contributors may be used to endorse or promote products derived
19 : * from this software without specific prior written permission.
20 : *
21 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 : * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 : * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 : * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 : * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 : * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 : * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 : * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 : * THE POSSIBILITY OF SUCH DAMAGE.
32 : */
33 :
34 : #ifndef __sctp_os_userspace_h__
35 : #define __sctp_os_userspace_h__
36 : /*
37 : * Userspace includes
38 : * All the opt_xxx.h files are placed in the kernel build directory.
39 : * We will place them in userspace stack build directory.
40 : */
41 :
42 : #include <errno.h>
43 :
44 : #if defined(__Userspace_os_Windows)
45 : #include <winsock2.h>
46 : #include <ws2tcpip.h>
47 : #include <iphlpapi.h>
48 : #include <Mswsock.h>
49 : #include <Windows.h>
50 : #include "user_environment.h"
51 : typedef CRITICAL_SECTION userland_mutex_t;
52 : #if WINVER < 0x0600
53 : enum {
54 : C_SIGNAL = 0,
55 : C_BROADCAST = 1,
56 : C_MAX_EVENTS = 2
57 : };
58 : typedef struct
59 : {
60 : u_int waiters_count;
61 : CRITICAL_SECTION waiters_count_lock;
62 : HANDLE events_[C_MAX_EVENTS];
63 : } userland_cond_t;
64 : void InitializeXPConditionVariable(userland_cond_t *);
65 : void DeleteXPConditionVariable(userland_cond_t *);
66 : int SleepXPConditionVariable(userland_cond_t *, userland_mutex_t *);
67 : void WakeAllXPConditionVariable(userland_cond_t *);
68 : #define InitializeConditionVariable(cond) InitializeXPConditionVariable(cond)
69 : #define DeleteConditionVariable(cond) DeleteXPConditionVariable(cond)
70 : #define SleepConditionVariableCS(cond, mtx, time) SleepXPConditionVariable(cond, mtx)
71 : #define WakeAllConditionVariable(cond) WakeAllXPConditionVariable(cond)
72 : #else
73 : #define DeleteConditionVariable(cond)
74 : typedef CONDITION_VARIABLE userland_cond_t;
75 : #endif
76 : typedef HANDLE userland_thread_t;
77 : #define ADDRESS_FAMILY unsigned __int8
78 : #define IPVERSION 4
79 : #define MAXTTL 255
80 : /* VS2010 comes with stdint.h */
81 : #if _MSC_VER >= 1600
82 : #include <stdint.h>
83 : #else
84 : #define uint64_t unsigned __int64
85 : #define uint32_t unsigned __int32
86 : #define int32_t __int32
87 : #define uint16_t unsigned __int16
88 : #define int16_t __int16
89 : #define uint8_t unsigned __int8
90 : #define int8_t __int8
91 : #endif
92 : #ifndef _SIZE_T_DEFINED
93 : #define size_t __int32
94 : #endif
95 : #define u_long unsigned __int64
96 : #define u_int unsigned __int32
97 : #define u_int32_t unsigned __int32
98 : #define u_int16_t unsigned __int16
99 : #define u_int8_t unsigned __int8
100 : #define u_char unsigned char
101 : #define n_short unsigned __int16
102 : #define u_short unsigned __int16
103 : #define n_time unsigned __int32
104 : #define sa_family_t unsigned __int8
105 : #define ssize_t __int64
106 : #define __func__ __FUNCTION__
107 :
108 : #ifndef EWOULDBLOCK
109 : #define EWOULDBLOCK WSAEWOULDBLOCK
110 : #endif
111 : #ifndef EINPROGRESS
112 : #define EINPROGRESS WSAEINPROGRESS
113 : #endif
114 : #ifndef EALREADY
115 : #define EALREADY WSAEALREADY
116 : #endif
117 : #ifndef ENOTSOCK
118 : #define ENOTSOCK WSAENOTSOCK
119 : #endif
120 : #ifndef EDESTADDRREQ
121 : #define EDESTADDRREQ WSAEDESTADDRREQ
122 : #endif
123 : #ifndef EMSGSIZE
124 : #define EMSGSIZE WSAEMSGSIZE
125 : #endif
126 : #ifndef EPROTOTYPE
127 : #define EPROTOTYPE WSAEPROTOTYPE
128 : #endif
129 : #ifndef ENOPROTOOPT
130 : #define ENOPROTOOPT WSAENOPROTOOPT
131 : #endif
132 : #ifndef EPROTONOSUPPORT
133 : #define EPROTONOSUPPORT WSAEPROTONOSUPPORT
134 : #endif
135 : #ifndef ESOCKTNOSUPPORT
136 : #define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
137 : #endif
138 : #ifndef EOPNOTSUPP
139 : #define EOPNOTSUPP WSAEOPNOTSUPP
140 : #endif
141 : #ifndef ENOTSUP
142 : #define ENOTSUP WSAEOPNOTSUPP
143 : #endif
144 : #ifndef EPFNOSUPPORT
145 : #define EPFNOSUPPORT WSAEPFNOSUPPORT
146 : #endif
147 : #ifndef EAFNOSUPPORT
148 : #define EAFNOSUPPORT WSAEAFNOSUPPORT
149 : #endif
150 : #ifndef EADDRINUSE
151 : #define EADDRINUSE WSAEADDRINUSE
152 : #endif
153 : #ifndef EADDRNOTAVAIL
154 : #define EADDRNOTAVAIL WSAEADDRNOTAVAIL
155 : #endif
156 : #ifndef ENETDOWN
157 : #define ENETDOWN WSAENETDOWN
158 : #endif
159 : #ifndef ENETUNREACH
160 : #define ENETUNREACH WSAENETUNREACH
161 : #endif
162 : #ifndef ENETRESET
163 : #define ENETRESET WSAENETRESET
164 : #endif
165 : #ifndef ECONNABORTED
166 : #define ECONNABORTED WSAECONNABORTED
167 : #endif
168 : #ifndef ECONNRESET
169 : #define ECONNRESET WSAECONNRESET
170 : #endif
171 : #ifndef ENOBUFS
172 : #define ENOBUFS WSAENOBUFS
173 : #endif
174 : #ifndef EISCONN
175 : #define EISCONN WSAEISCONN
176 : #endif
177 : #ifndef ENOTCONN
178 : #define ENOTCONN WSAENOTCONN
179 : #endif
180 : #ifndef ESHUTDOWN
181 : #define ESHUTDOWN WSAESHUTDOWN
182 : #endif
183 : #ifndef ETOOMANYREFS
184 : #define ETOOMANYREFS WSAETOOMANYREFS
185 : #endif
186 : #ifndef ETIMEDOUT
187 : #define ETIMEDOUT WSAETIMEDOUT
188 : #endif
189 : #ifndef ECONNREFUSED
190 : #define ECONNREFUSED WSAECONNREFUSED
191 : #endif
192 : #ifndef ELOOP
193 : #define ELOOP WSAELOOP
194 : #endif
195 : #ifndef EHOSTDOWN
196 : #define EHOSTDOWN WSAEHOSTDOWN
197 : #endif
198 : #ifndef EHOSTUNREACH
199 : #define EHOSTUNREACH WSAEHOSTUNREACH
200 : #endif
201 : #ifndef EPROCLIM
202 : #define EPROCLIM WSAEPROCLIM
203 : #endif
204 : #ifndef EUSERS
205 : #define EUSERS WSAEUSERS
206 : #endif
207 : #ifndef EDQUOT
208 : #define EDQUOT WSAEDQUOT
209 : #endif
210 : #ifndef ESTALE
211 : #define ESTALE WSAESTALE
212 : #endif
213 : #ifndef EREMOTE
214 : #define EREMOTE WSAEREMOTE
215 : #endif
216 :
217 : typedef char* caddr_t;
218 :
219 : #define bzero(buf, len) memset(buf, 0, len)
220 : #define bcopy(srcKey, dstKey, len) memcpy(dstKey, srcKey, len)
221 : #if _MSC_VER < 1900
222 : #define snprintf(data, size, format, ...) _snprintf_s(data, size, _TRUNCATE, format, __VA_ARGS__)
223 : #endif
224 : #define inline __inline
225 : #define __inline__ __inline
226 : #define MSG_EOR 0x8 /* data completes record */
227 : #define MSG_DONTWAIT 0x80 /* this message should be nonblocking */
228 :
229 : #ifdef CMSG_DATA
230 : #undef CMSG_DATA
231 : #endif
232 : /*
233 : * The following definitions should apply iff WINVER < 0x0600
234 : * but that check doesn't work in all cases. So be more pedantic...
235 : */
236 : #define CMSG_DATA(x) WSA_CMSG_DATA(x)
237 : #define CMSG_ALIGN(x) WSA_CMSGDATA_ALIGN(x)
238 : #ifndef CMSG_FIRSTHDR
239 : #define CMSG_FIRSTHDR(x) WSA_CMSG_FIRSTHDR(x)
240 : #endif
241 : #ifndef CMSG_NXTHDR
242 : #define CMSG_NXTHDR(x, y) WSA_CMSG_NXTHDR(x, y)
243 : #endif
244 : #ifndef CMSG_SPACE
245 : #define CMSG_SPACE(x) WSA_CMSG_SPACE(x)
246 : #endif
247 : #ifndef CMSG_LEN
248 : #define CMSG_LEN(x) WSA_CMSG_LEN(x)
249 : #endif
250 :
251 : /**** from sctp_os_windows.h ***************/
252 : #define SCTP_IFN_IS_IFT_LOOP(ifn) ((ifn)->ifn_type == IFT_LOOP)
253 : #define SCTP_ROUTE_IS_REAL_LOOP(ro) ((ro)->ro_rt && (ro)->ro_rt->rt_ifa && (ro)->ro_rt->rt_ifa->ifa_ifp && (ro)->ro_rt->rt_ifa->ifa_ifp->if_type == IFT_LOOP)
254 :
255 : /*
256 : * Access to IFN's to help with src-addr-selection
257 : */
258 : /* This could return VOID if the index works but for BSD we provide both. */
259 : #define SCTP_GET_IFN_VOID_FROM_ROUTE(ro) \
260 : ((ro)->ro_rt != NULL ? (ro)->ro_rt->rt_ifp : NULL)
261 : #define SCTP_ROUTE_HAS_VALID_IFN(ro) \
262 : ((ro)->ro_rt && (ro)->ro_rt->rt_ifp)
263 : /******************************************/
264 :
265 : #define SCTP_GET_IF_INDEX_FROM_ROUTE(ro) 1 /* compiles... TODO use routing socket to determine */
266 :
267 : #define BIG_ENDIAN 1
268 : #define LITTLE_ENDIAN 0
269 : #ifdef WORDS_BIGENDIAN
270 : #define BYTE_ORDER BIG_ENDIAN
271 : #else
272 : #define BYTE_ORDER LITTLE_ENDIAN
273 : #endif
274 :
275 : #else /* !defined(Userspace_os_Windows) */
276 : #include <sys/socket.h>
277 : #if defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Linux) || defined(__Userspace_os_NetBSD) || defined(__Userspace_os_OpenBSD) || defined(__Userspace_os_NaCl)
278 : #include <pthread.h>
279 : #endif
280 : typedef pthread_mutex_t userland_mutex_t;
281 : typedef pthread_cond_t userland_cond_t;
282 : typedef pthread_t userland_thread_t;
283 : #endif
284 :
285 : #if defined(__Userspace_os_Windows) || defined(__Userspace_os_NaCl)
286 :
287 : #define IFNAMSIZ 64
288 :
289 : #define random() rand()
290 : #define srandom(s) srand(s)
291 :
292 : #define timeradd(tvp, uvp, vvp) \
293 : do { \
294 : (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
295 : (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
296 : if ((vvp)->tv_usec >= 1000000) { \
297 : (vvp)->tv_sec++; \
298 : (vvp)->tv_usec -= 1000000; \
299 : } \
300 : } while (0)
301 :
302 : #define timersub(tvp, uvp, vvp) \
303 : do { \
304 : (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
305 : (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
306 : if ((vvp)->tv_usec < 0) { \
307 : (vvp)->tv_sec--; \
308 : (vvp)->tv_usec += 1000000; \
309 : } \
310 : } while (0)
311 :
312 : /*#include <packon.h>
313 : #pragma pack(push, 1)*/
314 : struct ip {
315 : u_char ip_hl:4, ip_v:4;
316 : u_char ip_tos;
317 : u_short ip_len;
318 : u_short ip_id;
319 : u_short ip_off;
320 : #define IP_RP 0x8000
321 : #define IP_DF 0x4000
322 : #define IP_MF 0x2000
323 : #define IP_OFFMASK 0x1fff
324 : u_char ip_ttl;
325 : u_char ip_p;
326 : u_short ip_sum;
327 : struct in_addr ip_src, ip_dst;
328 : };
329 :
330 : struct ifaddrs {
331 : struct ifaddrs *ifa_next;
332 : char *ifa_name;
333 : unsigned int ifa_flags;
334 : struct sockaddr *ifa_addr;
335 : struct sockaddr *ifa_netmask;
336 : struct sockaddr *ifa_dstaddr;
337 : void *ifa_data;
338 : };
339 :
340 : struct udphdr {
341 : uint16_t uh_sport;
342 : uint16_t uh_dport;
343 : uint16_t uh_ulen;
344 : uint16_t uh_sum;
345 : };
346 :
347 : struct iovec {
348 : unsigned long len;
349 : char *buf;
350 : };
351 :
352 : #define iov_base buf
353 : #define iov_len len
354 :
355 : struct ifa_msghdr {
356 : uint16_t ifam_msglen;
357 : unsigned char ifam_version;
358 : unsigned char ifam_type;
359 : uint32_t ifam_addrs;
360 : uint32_t ifam_flags;
361 : uint16_t ifam_index;
362 : uint32_t ifam_metric;
363 : };
364 :
365 : struct ifdevmtu {
366 : int ifdm_current;
367 : int ifdm_min;
368 : int ifdm_max;
369 : };
370 :
371 : struct ifkpi {
372 : unsigned int ifk_module_id;
373 : unsigned int ifk_type;
374 : union {
375 : void *ifk_ptr;
376 : int ifk_value;
377 : } ifk_data;
378 : };
379 :
380 : struct ifreq {
381 : char ifr_name[16];
382 : union {
383 : struct sockaddr ifru_addr;
384 : struct sockaddr ifru_dstaddr;
385 : struct sockaddr ifru_broadaddr;
386 : short ifru_flags;
387 : int ifru_metric;
388 : int ifru_mtu;
389 : int ifru_phys;
390 : int ifru_media;
391 : int ifru_intval;
392 : char* ifru_data;
393 : struct ifdevmtu ifru_devmtu;
394 : struct ifkpi ifru_kpi;
395 : uint32_t ifru_wake_flags;
396 : } ifr_ifru;
397 : #define ifr_addr ifr_ifru.ifru_addr
398 : #define ifr_dstaddr ifr_ifru.ifru_dstaddr
399 : #define ifr_broadaddr ifr_ifru.ifru_broadaddr
400 : #define ifr_flags ifr_ifru.ifru_flags[0]
401 : #define ifr_prevflags ifr_ifru.ifru_flags[1]
402 : #define ifr_metric ifr_ifru.ifru_metric
403 : #define ifr_mtu ifr_ifru.ifru_mtu
404 : #define ifr_phys ifr_ifru.ifru_phys
405 : #define ifr_media ifr_ifru.ifru_media
406 : #define ifr_data ifr_ifru.ifru_data
407 : #define ifr_devmtu ifr_ifru.ifru_devmtu
408 : #define ifr_intval ifr_ifru.ifru_intval
409 : #define ifr_kpi ifr_ifru.ifru_kpi
410 : #define ifr_wake_flags ifr_ifru.ifru_wake_flags
411 : };
412 :
413 : #endif
414 :
415 : #if defined(__Userspace_os_Windows)
416 : int Win_getifaddrs(struct ifaddrs**);
417 : #define getifaddrs(interfaces) (int)Win_getifaddrs(interfaces)
418 : int win_if_nametoindex(const char *);
419 : #define if_nametoindex(x) win_if_nametoindex(x)
420 : #endif
421 :
422 : #define mtx_lock(arg1)
423 : #define mtx_unlock(arg1)
424 : #define mtx_assert(arg1,arg2)
425 : #define MA_OWNED 7 /* sys/mutex.h typically on FreeBSD */
426 : #if !defined(__Userspace_os_FreeBSD)
427 : struct mtx {int dummy;};
428 : #if !defined(__Userspace_os_NetBSD)
429 : struct selinfo {int dummy;};
430 : #endif
431 : struct sx {int dummy;};
432 : #endif
433 :
434 : #include <stdio.h>
435 : #include <string.h>
436 : /* #include <sys/param.h> in FreeBSD defines MSIZE */
437 : /* #include <sys/ktr.h> */
438 : /* #include <sys/systm.h> */
439 : #if defined(HAVE_SYS_QUEUE_H)
440 : #include <sys/queue.h>
441 : #else
442 : #include <user_queue.h>
443 : #endif
444 : #include <user_malloc.h>
445 : /* #include <sys/kernel.h> */
446 : /* #include <sys/sysctl.h> */
447 : /* #include <sys/protosw.h> */
448 : /* on FreeBSD, this results in a redefintion of SOCK(BUF)_(UN)LOCK and
449 : * uknown type of struct mtx for sb_mtx in struct sockbuf */
450 : #include "user_socketvar.h" /* MALLOC_DECLARE's M_PCB. Replacement for sys/socketvar.h */
451 : /* #include <sys/jail.h> */
452 : /* #include <sys/sysctl.h> */
453 : #include <user_environment.h>
454 : #include <user_atomic.h>
455 : #include <user_mbuf.h>
456 : /* #include <sys/uio.h> */
457 : /* #include <sys/lock.h> */
458 : #if defined(__FreeBSD__) && __FreeBSD_version > 602000
459 : #include <sys/rwlock.h>
460 : #endif
461 : /* #include <sys/kthread.h> */
462 : #if defined(__FreeBSD__) && __FreeBSD_version > 602000
463 : #include <sys/priv.h>
464 : #endif
465 : /* #include <sys/random.h> */
466 : /* #include <sys/limits.h> */
467 : /* #include <machine/cpu.h> */
468 :
469 : #if defined(__Userspace_os_Darwin)
470 : /* was a 0 byte file. needed for structs if_data(64) and net_event_data */
471 : #include <net/if_var.h>
472 : #endif
473 : #if defined(__Userspace_os_FreeBSD)
474 : #include <net/if_types.h>
475 : /* #include <net/if_var.h> was a 0 byte file. causes struct mtx redefinition */
476 : #endif
477 : /* OOTB only - dummy route used at the moment. should we port route to
478 : * userspace as well? */
479 : /* on FreeBSD, this results in a redefintion of struct route */
480 : /* #include <net/route.h> */
481 : #if !defined(__Userspace_os_Windows) && !defined(__Userspace_os_NaCl)
482 : #include <net/if.h>
483 : #include <netinet/in.h>
484 : #include <netinet/in_systm.h>
485 : #include <netinet/ip.h>
486 : #endif
487 : #if defined(HAVE_NETINET_IP_ICMP_H)
488 : #include <netinet/ip_icmp.h>
489 : #else
490 : #include <user_ip_icmp.h>
491 : #endif
492 : /* #include <netinet/in_pcb.h> ported to userspace */
493 : #include <user_inpcb.h>
494 :
495 : /* for getifaddrs */
496 : #include <sys/types.h>
497 : #if !defined(__Userspace_os_Windows)
498 : #if !defined(ANDROID) && (defined(INET) || defined(INET6))
499 : #include <ifaddrs.h>
500 : #endif
501 :
502 : /* for ioctl */
503 : #include <sys/ioctl.h>
504 :
505 : /* for close, etc. */
506 : #include <unistd.h>
507 : #endif
508 :
509 : /* lots of errno's used and needed in userspace */
510 :
511 : /* for offsetof */
512 : #include <stddef.h>
513 :
514 : #if defined(SCTP_PROCESS_LEVEL_LOCKS) && !defined(__Userspace_os_Windows)
515 : /* for pthread_mutex_lock, pthread_mutex_unlock, etc. */
516 : #include <pthread.h>
517 : #endif
518 :
519 : #ifdef IPSEC
520 : #include <netipsec/ipsec.h>
521 : #include <netipsec/key.h>
522 : #endif /* IPSEC */
523 :
524 : #ifdef INET6
525 : #if defined(__Userspace_os_FreeBSD)
526 : #include <sys/domain.h>
527 : #endif
528 : #ifdef IPSEC
529 : #include <netipsec/ipsec6.h>
530 : #endif
531 : #if !defined(__Userspace_os_Windows)
532 : #include <netinet/ip6.h>
533 : #include <netinet/icmp6.h>
534 : #endif
535 : #if defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Linux) || defined(__Userspace_os_NetBSD) || defined(__Userspace_os_OpenBSD) || defined(__Userspace_os_Windows)
536 : #include "user_ip6_var.h"
537 : #else
538 : #include <netinet6/ip6_var.h>
539 : #endif
540 : #if defined(__Userspace_os_FreeBSD)
541 : #include <netinet6/in6_pcb.h>
542 : #include <netinet6/ip6protosw.h>
543 : /* #include <netinet6/nd6.h> was a 0 byte file */
544 : #include <netinet6/scope6_var.h>
545 : #endif
546 : #endif /* INET6 */
547 :
548 : #if defined(HAVE_SCTP_PEELOFF_SOCKOPT)
549 : #include <sys/file.h>
550 : #include <sys/filedesc.h>
551 : #endif
552 :
553 : #include "netinet/sctp_sha1.h"
554 :
555 : #if __FreeBSD_version >= 700000
556 : #include <netinet/ip_options.h>
557 : #endif
558 :
559 : #define SCTP_PRINTF(...) \
560 : if (SCTP_BASE_VAR(debug_printf)) { \
561 : SCTP_BASE_VAR(debug_printf)(__VA_ARGS__); \
562 : }
563 :
564 : #if defined(__FreeBSD__)
565 : #ifndef in6pcb
566 : #define in6pcb inpcb
567 : #endif
568 : #endif
569 : /* Declare all the malloc names for all the various mallocs */
570 : MALLOC_DECLARE(SCTP_M_MAP);
571 : MALLOC_DECLARE(SCTP_M_STRMI);
572 : MALLOC_DECLARE(SCTP_M_STRMO);
573 : MALLOC_DECLARE(SCTP_M_ASC_ADDR);
574 : MALLOC_DECLARE(SCTP_M_ASC_IT);
575 : MALLOC_DECLARE(SCTP_M_AUTH_CL);
576 : MALLOC_DECLARE(SCTP_M_AUTH_KY);
577 : MALLOC_DECLARE(SCTP_M_AUTH_HL);
578 : MALLOC_DECLARE(SCTP_M_AUTH_IF);
579 : MALLOC_DECLARE(SCTP_M_STRESET);
580 : MALLOC_DECLARE(SCTP_M_CMSG);
581 : MALLOC_DECLARE(SCTP_M_COPYAL);
582 : MALLOC_DECLARE(SCTP_M_VRF);
583 : MALLOC_DECLARE(SCTP_M_IFA);
584 : MALLOC_DECLARE(SCTP_M_IFN);
585 : MALLOC_DECLARE(SCTP_M_TIMW);
586 : MALLOC_DECLARE(SCTP_M_MVRF);
587 : MALLOC_DECLARE(SCTP_M_ITER);
588 : MALLOC_DECLARE(SCTP_M_SOCKOPT);
589 :
590 : #if defined(SCTP_LOCAL_TRACE_BUF)
591 :
592 : #define SCTP_GET_CYCLECOUNT get_cyclecount()
593 : #define SCTP_CTR6 sctp_log_trace
594 :
595 : #else
596 : #define SCTP_CTR6 CTR6
597 : #endif
598 :
599 : /* Empty ktr statement for _Userspace__ (similar to what is done for mac) */
600 : #define CTR6(m, d, p1, p2, p3, p4, p5, p6)
601 :
602 :
603 :
604 : #define SCTP_BASE_INFO(__m) system_base_info.sctppcbinfo.__m
605 : #define SCTP_BASE_STATS system_base_info.sctpstat
606 : #define SCTP_BASE_STAT(__m) system_base_info.sctpstat.__m
607 : #define SCTP_BASE_SYSCTL(__m) system_base_info.sctpsysctl.__m
608 : #define SCTP_BASE_VAR(__m) system_base_info.__m
609 :
610 : /*
611 : *
612 : */
613 : #if !defined(__Userspace_os_Darwin)
614 : #define USER_ADDR_NULL (NULL) /* FIX ME: temp */
615 : #endif
616 :
617 : #if defined(SCTP_DEBUG)
618 : #include <netinet/sctp_constants.h>
619 : #define SCTPDBG(level, ...) \
620 : { \
621 : do { \
622 : if (SCTP_BASE_SYSCTL(sctp_debug_on) & level) { \
623 : SCTP_PRINTF(__VA_ARGS__); \
624 : } \
625 : } while (0); \
626 : }
627 : #define SCTPDBG_ADDR(level, addr) \
628 : { \
629 : do { \
630 : if (SCTP_BASE_SYSCTL(sctp_debug_on) & level ) { \
631 : sctp_print_address(addr); \
632 : } \
633 : } while (0); \
634 : }
635 : #else
636 : #define SCTPDBG(level, ...)
637 : #define SCTPDBG_ADDR(level, addr)
638 : #endif
639 :
640 : #ifdef SCTP_LTRACE_CHUNKS
641 : #define SCTP_LTRACE_CHK(a, b, c, d) if(sctp_logging_level & SCTP_LTRACE_CHUNK_ENABLE) CTR6(KTR_SUBSYS, "SCTP:%d[%d]:%x-%x-%x-%x", SCTP_LOG_CHUNK_PROC, 0, a, b, c, d)
642 : #else
643 : #define SCTP_LTRACE_CHK(a, b, c, d)
644 : #endif
645 :
646 : #ifdef SCTP_LTRACE_ERRORS
647 : #define SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, file, err) \
648 : if (sctp_logging_level & SCTP_LTRACE_ERROR_ENABLE) \
649 : SCTP_PRINTF("mbuf:%p inp:%p stcb:%p net:%p file:%x line:%d error:%d\n", \
650 : (void *)m, (void *)inp, (void *)stcb, (void *)net, file, __LINE__, err);
651 : #define SCTP_LTRACE_ERR_RET(inp, stcb, net, file, err) \
652 : if (sctp_logging_level & SCTP_LTRACE_ERROR_ENABLE) \
653 : SCTP_PRINTF("inp:%p stcb:%p net:%p file:%x line:%d error:%d\n", \
654 : (void *)inp, (void *)stcb, (void *)net, file, __LINE__, err);
655 : #else
656 : #define SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, file, err)
657 : #define SCTP_LTRACE_ERR_RET(inp, stcb, net, file, err)
658 : #endif
659 :
660 :
661 : /*
662 : * Local address and interface list handling
663 : */
664 : #define SCTP_MAX_VRF_ID 0
665 : #define SCTP_SIZE_OF_VRF_HASH 3
666 : #define SCTP_IFNAMSIZ IFNAMSIZ
667 : #define SCTP_DEFAULT_VRFID 0
668 : #define SCTP_VRF_ADDR_HASH_SIZE 16
669 : #define SCTP_VRF_IFN_HASH_SIZE 3
670 : #define SCTP_INIT_VRF_TABLEID(vrf)
671 :
672 : #if !defined(__Userspace_os_Windows)
673 : #define SCTP_IFN_IS_IFT_LOOP(ifn) (strncmp((ifn)->ifn_name, "lo", 2) == 0)
674 : /* BSD definition */
675 : /* #define SCTP_ROUTE_IS_REAL_LOOP(ro) ((ro)->ro_rt && (ro)->ro_rt->rt_ifa && (ro)->ro_rt->rt_ifa->ifa_ifp && (ro)->ro_rt->rt_ifa->ifa_ifp->if_type == IFT_LOOP) */
676 : /* only used in IPv6 scenario, which isn't supported yet */
677 : #define SCTP_ROUTE_IS_REAL_LOOP(ro) 0
678 :
679 : /*
680 : * Access to IFN's to help with src-addr-selection
681 : */
682 : /* This could return VOID if the index works but for BSD we provide both. */
683 : #define SCTP_GET_IFN_VOID_FROM_ROUTE(ro) (void *)ro->ro_rt->rt_ifp
684 : #define SCTP_GET_IF_INDEX_FROM_ROUTE(ro) 1 /* compiles... TODO use routing socket to determine */
685 : #define SCTP_ROUTE_HAS_VALID_IFN(ro) ((ro)->ro_rt && (ro)->ro_rt->rt_ifp)
686 : #endif
687 :
688 : /*
689 : * general memory allocation
690 : */
691 : #define SCTP_MALLOC(var, type, size, name) \
692 : do { \
693 : MALLOC(var, type, size, name, M_NOWAIT); \
694 : } while (0)
695 :
696 : #define SCTP_FREE(var, type) FREE(var, type)
697 :
698 : #define SCTP_MALLOC_SONAME(var, type, size) \
699 : do { \
700 : MALLOC(var, type, size, M_SONAME, (M_WAITOK | M_ZERO)); \
701 : } while (0)
702 :
703 : #define SCTP_FREE_SONAME(var) FREE(var, M_SONAME)
704 :
705 : #define SCTP_PROCESS_STRUCT struct proc *
706 :
707 : /*
708 : * zone allocation functions
709 : */
710 :
711 :
712 : #if defined(SCTP_SIMPLE_ALLOCATOR)
713 : /*typedef size_t sctp_zone_t;*/
714 : #define SCTP_ZONE_INIT(zone, name, size, number) { \
715 : zone = size; \
716 : }
717 :
718 : /* __Userspace__ SCTP_ZONE_GET: allocate element from the zone */
719 : #define SCTP_ZONE_GET(zone, type) \
720 : (type *)malloc(zone);
721 :
722 :
723 : /* __Userspace__ SCTP_ZONE_FREE: free element from the zone */
724 : #define SCTP_ZONE_FREE(zone, element) { \
725 : free(element); \
726 : }
727 :
728 : #define SCTP_ZONE_DESTROY(zone)
729 : #else
730 : /*__Userspace__
731 : Compiling & linking notes: Needs libumem, which has been placed in ./user_lib
732 : All userspace header files are in ./user_include. Makefile will need the
733 : following.
734 : CFLAGS = -I./ -Wall
735 : LDFLAGS = -L./user_lib -R./user_lib -lumem
736 : */
737 : #include "user_include/umem.h"
738 :
739 : /* __Userspace__ SCTP_ZONE_INIT: initialize the zone */
740 : /*
741 : __Userspace__
742 : No equivalent function to uma_zone_set_max added yet. (See SCTP_ZONE_INIT in sctp_os_bsd.h
743 : for reference). It may not be required as mentioned in
744 : http://nixdoc.net/man-pages/FreeBSD/uma_zalloc.9.html that
745 : max limits may not enforced on systems with more than one CPU.
746 : */
747 : #define SCTP_ZONE_INIT(zone, name, size, number) { \
748 : zone = umem_cache_create(name, size, 0, NULL, NULL, NULL, NULL, NULL, 0); \
749 : }
750 :
751 : /* __Userspace__ SCTP_ZONE_GET: allocate element from the zone */
752 : #define SCTP_ZONE_GET(zone, type) \
753 : (type *)umem_cache_alloc(zone, UMEM_DEFAULT);
754 :
755 :
756 : /* __Userspace__ SCTP_ZONE_FREE: free element from the zone */
757 : #define SCTP_ZONE_FREE(zone, element) \
758 : umem_cache_free(zone, element);
759 :
760 :
761 : /* __Userspace__ SCTP_ZONE_DESTROY: destroy the zone */
762 : #define SCTP_ZONE_DESTROY(zone) \
763 : umem_cache_destroy(zone);
764 : #endif
765 :
766 : /* global struct ifaddrs used in sctp_init_ifns_for_vrf getifaddrs call
767 : * but references to fields are needed to persist as the vrf is queried.
768 : * getifaddrs allocates memory that needs to be freed with a freeifaddrs
769 : * call; this global is used to call freeifaddrs upon in sctp_pcb_finish
770 : */
771 : extern struct ifaddrs *g_interfaces;
772 :
773 :
774 : /*
775 : * __Userspace__ Defining sctp_hashinit_flags() and sctp_hashdestroy() for userland.
776 : */
777 : void *sctp_hashinit_flags(int elements, struct malloc_type *type,
778 : u_long *hashmask, int flags);
779 : void
780 : sctp_hashdestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask);
781 :
782 : void
783 : sctp_hashfreedestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask);
784 :
785 :
786 : #define HASH_NOWAIT 0x00000001
787 : #define HASH_WAITOK 0x00000002
788 :
789 : /* M_PCB is MALLOC_DECLARE'd in sys/socketvar.h */
790 : #define SCTP_HASH_INIT(size, hashmark) sctp_hashinit_flags(size, M_PCB, hashmark, HASH_NOWAIT)
791 :
792 : #define SCTP_HASH_FREE(table, hashmark) sctp_hashdestroy(table, M_PCB, hashmark)
793 :
794 : #define SCTP_HASH_FREE_DESTROY(table, hashmark) sctp_hashfreedestroy(table, M_PCB, hashmark)
795 : #define SCTP_M_COPYM m_copym
796 :
797 : /*
798 : * timers
799 : */
800 : /* __Userspace__
801 : * user_sctp_callout.h has typedef struct sctp_callout sctp_os_timer_t;
802 : * which is used in the timer related functions such as
803 : * SCTP_OS_TIMER_INIT etc.
804 : */
805 : #include <netinet/sctp_callout.h>
806 :
807 : /* __Userspace__ Creating a receive thread */
808 : #include <user_recv_thread.h>
809 :
810 : /*__Userspace__ defining KTR_SUBSYS 1 as done in sctp_os_macosx.h */
811 : #define KTR_SUBSYS 1
812 :
813 : #define sctp_get_tick_count() (ticks)
814 :
815 : /* The packed define for 64 bit platforms */
816 : #if !defined(__Userspace_os_Windows)
817 : #define SCTP_PACKED __attribute__((packed))
818 : #define SCTP_UNUSED __attribute__((unused))
819 : #else
820 : #define SCTP_PACKED
821 : #define SCTP_UNUSED
822 : #endif
823 :
824 : /*
825 : * Functions
826 : */
827 : /* Mbuf manipulation and access macros */
828 : #define SCTP_BUF_LEN(m) (m->m_len)
829 : #define SCTP_BUF_NEXT(m) (m->m_next)
830 : #define SCTP_BUF_NEXT_PKT(m) (m->m_nextpkt)
831 : #define SCTP_BUF_RESV_UF(m, size) m->m_data += size
832 : #define SCTP_BUF_AT(m, size) m->m_data + size
833 : #define SCTP_BUF_IS_EXTENDED(m) (m->m_flags & M_EXT)
834 : #define SCTP_BUF_EXTEND_SIZE(m) (m->m_ext.ext_size)
835 : #define SCTP_BUF_TYPE(m) (m->m_type)
836 : #define SCTP_BUF_RECVIF(m) (m->m_pkthdr.rcvif)
837 : #define SCTP_BUF_PREPEND M_PREPEND
838 :
839 : #define SCTP_ALIGN_TO_END(m, len) if(m->m_flags & M_PKTHDR) { \
840 : MH_ALIGN(m, len); \
841 : } else if ((m->m_flags & M_EXT) == 0) { \
842 : M_ALIGN(m, len); \
843 : }
844 :
845 : /* We make it so if you have up to 4 threads
846 : * writting based on the default size of
847 : * the packet log 65 k, that would be
848 : * 4 16k packets before we would hit
849 : * a problem.
850 : */
851 : #define SCTP_PKTLOG_WRITERS_NEED_LOCK 3
852 :
853 :
854 : /*
855 : * routes, output, etc.
856 : */
857 :
858 : typedef struct sctp_route sctp_route_t;
859 : typedef struct sctp_rtentry sctp_rtentry_t;
860 :
861 0 : static inline void sctp_userspace_rtalloc(sctp_route_t *ro)
862 : {
863 0 : if (ro->ro_rt != NULL) {
864 0 : ro->ro_rt->rt_refcnt++;
865 0 : return;
866 : }
867 :
868 0 : ro->ro_rt = (sctp_rtentry_t *) malloc(sizeof(sctp_rtentry_t));
869 0 : if (ro->ro_rt == NULL)
870 0 : return;
871 :
872 : /* initialize */
873 0 : memset(ro->ro_rt, 0, sizeof(sctp_rtentry_t));
874 0 : ro->ro_rt->rt_refcnt = 1;
875 :
876 : /* set MTU */
877 : /* TODO set this based on the ro->ro_dst, looking up MTU with routing socket */
878 : #if 0
879 : if (userspace_rawroute == -1) {
880 : userspace_rawroute = socket(AF_ROUTE, SOCK_RAW, 0);
881 : if (userspace_rawroute == -1)
882 : return;
883 : }
884 : #endif
885 0 : ro->ro_rt->rt_rmx.rmx_mtu = 1500; /* FIXME temporary solution */
886 :
887 : /* TODO enable the ability to obtain interface index of route for
888 : * SCTP_GET_IF_INDEX_FROM_ROUTE macro.
889 : */
890 : }
891 : #define SCTP_RTALLOC(ro, vrf_id) sctp_userspace_rtalloc((sctp_route_t *)ro)
892 :
893 : /* dummy rtfree needed once user_route.h is included */
894 0 : static inline void sctp_userspace_rtfree(sctp_rtentry_t *rt)
895 : {
896 0 : if(rt == NULL) {
897 0 : return;
898 : }
899 0 : if(--rt->rt_refcnt > 0) {
900 0 : return;
901 : }
902 0 : free(rt);
903 0 : rt = NULL;
904 : }
905 : #define rtfree(arg1) sctp_userspace_rtfree(arg1)
906 :
907 :
908 : /*************************/
909 : /* MTU */
910 : /*************************/
911 : int sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af);
912 :
913 : #define SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index, af) sctp_userspace_get_mtu_from_ifn(ifn_index, af)
914 :
915 : #define SCTP_GATHER_MTU_FROM_ROUTE(sctp_ifa, sa, rt) ((rt != NULL) ? rt->rt_rmx.rmx_mtu : 0)
916 :
917 : #define SCTP_GATHER_MTU_FROM_INTFC(sctp_ifn) sctp_userspace_get_mtu_from_ifn(if_nametoindex(((struct ifaddrs *) (sctp_ifn))->ifa_name), AF_INET)
918 :
919 : #define SCTP_SET_MTU_OF_ROUTE(sa, rt, mtu) do { \
920 : if (rt != NULL) \
921 : rt->rt_rmx.rmx_mtu = mtu; \
922 : } while(0)
923 :
924 : /* (de-)register interface event notifications */
925 : #define SCTP_REGISTER_INTERFACE(ifhandle, af)
926 : #define SCTP_DEREGISTER_INTERFACE(ifhandle, af)
927 :
928 :
929 : /*************************/
930 : /* These are for logging */
931 : /*************************/
932 : /* return the base ext data pointer */
933 : #define SCTP_BUF_EXTEND_BASE(m) (m->m_ext.ext_buf)
934 : /* return the refcnt of the data pointer */
935 : #define SCTP_BUF_EXTEND_REFCNT(m) (*m->m_ext.ref_cnt)
936 : /* return any buffer related flags, this is
937 : * used beyond logging for apple only.
938 : */
939 : #define SCTP_BUF_GET_FLAGS(m) (m->m_flags)
940 :
941 : /* For BSD this just accesses the M_PKTHDR length
942 : * so it operates on an mbuf with hdr flag. Other
943 : * O/S's may have seperate packet header and mbuf
944 : * chain pointers.. thus the macro.
945 : */
946 : #define SCTP_HEADER_TO_CHAIN(m) (m)
947 : #define SCTP_DETACH_HEADER_FROM_CHAIN(m)
948 : #define SCTP_HEADER_LEN(m) ((m)->m_pkthdr.len)
949 : #define SCTP_GET_HEADER_FOR_OUTPUT(o_pak) 0
950 : #define SCTP_RELEASE_HEADER(m)
951 : #define SCTP_RELEASE_PKT(m) sctp_m_freem(m)
952 : /* UDP __Userspace__ - dummy definition */
953 : #define SCTP_ENABLE_UDP_CSUM(m) m=m
954 : /* BSD definition */
955 : /* #define SCTP_ENABLE_UDP_CSUM(m) do { \ */
956 : /* m->m_pkthdr.csum_flags = CSUM_UDP; \ */
957 : /* m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); \ */
958 : /* } while (0) */
959 :
960 : #define SCTP_GET_PKT_VRFID(m, vrf_id) ((vrf_id = SCTP_DEFAULT_VRFID) != SCTP_DEFAULT_VRFID)
961 :
962 :
963 :
964 : /* Attach the chain of data into the sendable packet. */
965 : #define SCTP_ATTACH_CHAIN(pak, m, packet_length) do { \
966 : pak = m; \
967 : pak->m_pkthdr.len = packet_length; \
968 : } while(0)
969 :
970 : /* Other m_pkthdr type things */
971 : /* FIXME need real definitions */
972 : #define SCTP_IS_IT_BROADCAST(dst, m) 0
973 : /* OOTB only #define SCTP_IS_IT_BROADCAST(dst, m) ((m->m_flags & M_PKTHDR) ? in_broadcast(dst, m->m_pkthdr.rcvif) : 0) BSD def */
974 : #define SCTP_IS_IT_LOOPBACK(m) 0
975 : /* OOTB ONLY #define SCTP_IS_IT_LOOPBACK(m) ((m->m_flags & M_PKTHDR) && ((m->m_pkthdr.rcvif == NULL) || (m->m_pkthdr.rcvif->if_type == IFT_LOOP))) BSD def */
976 :
977 :
978 : /* This converts any input packet header
979 : * into the chain of data holders, for BSD
980 : * its a NOP.
981 : */
982 :
983 : /* get the v6 hop limit */
984 : #define SCTP_GET_HLIM(inp, ro) 128 /* As done for __Windows__ */
985 : #define IPv6_HOP_LIMIT 128
986 :
987 : /* is the endpoint v6only? */
988 : #define SCTP_IPV6_V6ONLY(inp) (((struct inpcb *)inp)->inp_flags & IN6P_IPV6_V6ONLY)
989 : /* is the socket non-blocking? */
990 : #define SCTP_SO_IS_NBIO(so) ((so)->so_state & SS_NBIO)
991 : #define SCTP_SET_SO_NBIO(so) ((so)->so_state |= SS_NBIO)
992 : #define SCTP_CLEAR_SO_NBIO(so) ((so)->so_state &= ~SS_NBIO)
993 : /* get the socket type */
994 : #define SCTP_SO_TYPE(so) ((so)->so_type)
995 :
996 : /* reserve sb space for a socket */
997 : #define SCTP_SORESERVE(so, send, recv) soreserve(so, send, recv)
998 :
999 : /* wakeup a socket */
1000 : #define SCTP_SOWAKEUP(so) wakeup(&(so)->so_timeo, so)
1001 : /* clear the socket buffer state */
1002 : #define SCTP_SB_CLEAR(sb) \
1003 : (sb).sb_cc = 0; \
1004 : (sb).sb_mb = NULL; \
1005 : (sb).sb_mbcnt = 0;
1006 :
1007 : #define SCTP_SB_LIMIT_RCV(so) so->so_rcv.sb_hiwat
1008 : #define SCTP_SB_LIMIT_SND(so) so->so_snd.sb_hiwat
1009 :
1010 : /* Future zero copy wakeup/send function */
1011 : #define SCTP_ZERO_COPY_EVENT(inp, so)
1012 : /* This is re-pulse ourselves for sendbuf */
1013 : #define SCTP_ZERO_COPY_SENDQ_EVENT(inp, so)
1014 :
1015 : #define SCTP_READ_RANDOM(buf, len) read_random(buf, len)
1016 :
1017 : #define SCTP_SHA1_CTX struct sctp_sha1_context
1018 : #define SCTP_SHA1_INIT sctp_sha1_init
1019 : #define SCTP_SHA1_UPDATE sctp_sha1_update
1020 : #define SCTP_SHA1_FINAL(x,y) sctp_sha1_final((unsigned char *)x, y)
1021 :
1022 : /* start OOTB only stuff */
1023 : /* TODO IFT_LOOP is in net/if_types.h on Linux */
1024 : #define IFT_LOOP 0x18
1025 :
1026 : /* sctp_pcb.h */
1027 :
1028 : #if defined(__Userspace_os_Windows)
1029 : #define SHUT_RD 1
1030 : #define SHUT_WR 2
1031 : #define SHUT_RDWR 3
1032 : #endif
1033 : #define PRU_FLUSH_RD SHUT_RD
1034 : #define PRU_FLUSH_WR SHUT_WR
1035 : #define PRU_FLUSH_RDWR SHUT_RDWR
1036 :
1037 : /* netinet/ip_var.h defintions are behind an if defined for _KERNEL on FreeBSD */
1038 : #define IP_RAWOUTPUT 0x2
1039 :
1040 :
1041 : /* end OOTB only stuff */
1042 :
1043 : #define AF_CONN 123
1044 : struct sockaddr_conn {
1045 : #ifdef HAVE_SCONN_LEN
1046 : uint8_t sconn_len;
1047 : #endif
1048 : uint8_t sconn_family;
1049 : uint16_t sconn_port;
1050 : void *sconn_addr;
1051 : };
1052 :
1053 : /*
1054 : * SCTP protocol specific mbuf flags.
1055 : */
1056 : #define M_NOTIFICATION M_PROTO5 /* SCTP notification */
1057 :
1058 : /*
1059 : * IP output routines
1060 : */
1061 :
1062 : /* Defining SCTP_IP_ID macro.
1063 : In netinet/ip_output.c, we have u_short ip_id;
1064 : In netinet/ip_var.h, we have extern u_short ip_id; (enclosed within _KERNEL_)
1065 : See static __inline uint16_t ip_newid(void) in netinet/ip_var.h
1066 : */
1067 : #define SCTP_IP_ID(inp) (ip_id)
1068 :
1069 : /* need sctphdr to get port in SCTP_IP_OUTPUT. sctphdr defined in sctp.h */
1070 : #include <netinet/sctp.h>
1071 : extern void sctp_userspace_ip_output(int *result, struct mbuf *o_pak,
1072 : sctp_route_t *ro, void *stcb,
1073 : uint32_t vrf_id);
1074 :
1075 : #define SCTP_IP_OUTPUT(result, o_pak, ro, stcb, vrf_id) sctp_userspace_ip_output(&result, o_pak, ro, stcb, vrf_id);
1076 :
1077 : #if defined(INET6)
1078 : extern void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak,
1079 : struct route_in6 *ro, void *stcb,
1080 : uint32_t vrf_id);
1081 : #define SCTP_IP6_OUTPUT(result, o_pak, ro, ifp, stcb, vrf_id) sctp_userspace_ip6_output(&result, o_pak, ro, stcb, vrf_id);
1082 : #endif
1083 :
1084 :
1085 :
1086 : #if 0
1087 : #define SCTP_IP6_OUTPUT(result, o_pak, ro, ifp, stcb, vrf_id) \
1088 : { \
1089 : if (stcb && stcb->sctp_ep) \
1090 : result = ip6_output(o_pak, \
1091 : ((struct in6pcb *)(stcb->sctp_ep))->in6p_outputopts, \
1092 : (ro), 0, 0, ifp, NULL); \
1093 : else \
1094 : result = ip6_output(o_pak, NULL, (ro), 0, 0, ifp, NULL); \
1095 : }
1096 : #endif
1097 :
1098 : struct mbuf *
1099 : sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int allonebuf, int type);
1100 :
1101 :
1102 : /* with the current included files, this is defined in Linux but
1103 : * in FreeBSD, it is behind a _KERNEL in sys/socket.h ...
1104 : */
1105 : #if defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) || defined(__Userspace_os_NaCl)
1106 : /* stolen from /usr/include/sys/socket.h */
1107 : #define CMSG_ALIGN(n) _ALIGN(n)
1108 : #elif defined(__Userspace_os_NetBSD)
1109 : #define CMSG_ALIGN(n) (((n) + __ALIGNBYTES) & ~__ALIGNBYTES)
1110 : #elif defined(__Userspace_os_Darwin)
1111 : #if !defined(__DARWIN_ALIGNBYTES)
1112 : #define __DARWIN_ALIGNBYTES (sizeof(__darwin_size_t) - 1)
1113 : #endif
1114 :
1115 : #if !defined(__DARWIN_ALIGN)
1116 : #define __DARWIN_ALIGN(p) ((__darwin_size_t)((char *)(uintptr_t)(p) + __DARWIN_ALIGNBYTES) &~ __DARWIN_ALIGNBYTES)
1117 : #endif
1118 :
1119 : #if !defined(__DARWIN_ALIGNBYTES32)
1120 : #define __DARWIN_ALIGNBYTES32 (sizeof(__uint32_t) - 1)
1121 : #endif
1122 :
1123 : #if !defined(__DARWIN_ALIGN32)
1124 : #define __DARWIN_ALIGN32(p) ((__darwin_size_t)((char *)(uintptr_t)(p) + __DARWIN_ALIGNBYTES32) &~ __DARWIN_ALIGNBYTES32)
1125 : #endif
1126 : #define CMSG_ALIGN(n) __DARWIN_ALIGN32(n)
1127 : #endif
1128 : #define I_AM_HERE \
1129 : do { \
1130 : SCTP_PRINTF("%s:%d at %s\n", __FILE__, __LINE__ , __FUNCTION__); \
1131 : } while (0)
1132 :
1133 : #ifndef timevalsub
1134 : #define timevalsub(tp1, tp2) \
1135 : do { \
1136 : (tp1)->tv_sec -= (tp2)->tv_sec; \
1137 : (tp1)->tv_usec -= (tp2)->tv_usec; \
1138 : if ((tp1)->tv_usec < 0) { \
1139 : (tp1)->tv_sec--; \
1140 : (tp1)->tv_usec += 1000000; \
1141 : } \
1142 : } while (0)
1143 : #endif
1144 :
1145 : #if defined(__Userspace_os_Linux)
1146 : #if !defined(TAILQ_FOREACH_SAFE)
1147 : #define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
1148 : for ((var) = ((head)->tqh_first); \
1149 : (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
1150 : (var) = (tvar))
1151 : #endif
1152 : #if !defined(LIST_FOREACH_SAFE)
1153 : #define LIST_FOREACH_SAFE(var, head, field, tvar) \
1154 : for ((var) = ((head)->lh_first); \
1155 : (var) && ((tvar) = LIST_NEXT((var), field), 1); \
1156 : (var) = (tvar))
1157 : #endif
1158 : #endif
1159 : #if defined(__Userspace_os_DragonFly)
1160 : #define TAILQ_FOREACH_SAFE TAILQ_FOREACH_MUTABLE
1161 : #define LIST_FOREACH_SAFE LIST_FOREACH_MUTABLE
1162 : #endif
1163 :
1164 : #if defined(__Userspace_os_NaCl)
1165 : #define timercmp(tvp, uvp, cmp) \
1166 : (((tvp)->tv_sec == (uvp)->tv_sec) ? \
1167 : ((tvp)->tv_usec cmp (uvp)->tv_usec) : \
1168 : ((tvp)->tv_sec cmp (uvp)->tv_sec))
1169 : #endif
1170 :
1171 : #endif
|