1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/sctp/src/netinet/sctp_os_userspace.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1152 @@ 1.4 +/*- 1.5 + * Copyright (c) 2006-2007, by Cisco Systems, Inc. All rights reserved. 1.6 + * Copyright (c) 2008-2011, by Randall Stewart. All rights reserved. 1.7 + * Copyright (c) 2008-2011, by Michael Tuexen. All rights reserved. 1.8 + * Copyright (c) 2008-2011, by Brad Penoff. All rights reserved. 1.9 + * 1.10 + * Redistribution and use in source and binary forms, with or without 1.11 + * modification, are permitted provided that the following conditions are met: 1.12 + * 1.13 + * a) Redistributions of source code must retain the above copyright notice, 1.14 + * this list of conditions and the following disclaimer. 1.15 + * 1.16 + * b) Redistributions in binary form must reproduce the above copyright 1.17 + * notice, this list of conditions and the following disclaimer in 1.18 + * the documentation and/or other materials provided with the distribution. 1.19 + * 1.20 + * c) Neither the name of Cisco Systems, Inc. nor the names of its 1.21 + * contributors may be used to endorse or promote products derived 1.22 + * from this software without specific prior written permission. 1.23 + * 1.24 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.25 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 1.26 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.27 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 1.28 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1.29 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1.30 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1.31 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1.32 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.33 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 1.34 + * THE POSSIBILITY OF SUCH DAMAGE. 1.35 + */ 1.36 + 1.37 +#ifndef __sctp_os_userspace_h__ 1.38 +#define __sctp_os_userspace_h__ 1.39 +/* 1.40 + * Userspace includes 1.41 + * All the opt_xxx.h files are placed in the kernel build directory. 1.42 + * We will place them in userspace stack build directory. 1.43 + */ 1.44 + 1.45 +#include <errno.h> 1.46 + 1.47 +#if defined(__Userspace_os_Windows) 1.48 +#include <winsock2.h> 1.49 +#include <ws2tcpip.h> 1.50 +#include <iphlpapi.h> 1.51 +#include <Mswsock.h> 1.52 +#include <Windows.h> 1.53 +#include "user_environment.h" 1.54 +typedef CRITICAL_SECTION userland_mutex_t; 1.55 +#if WINVER < 0x0600 1.56 +enum { 1.57 + C_SIGNAL = 0, 1.58 + C_BROADCAST = 1, 1.59 + C_MAX_EVENTS = 2 1.60 +}; 1.61 +typedef struct 1.62 +{ 1.63 + u_int waiters_count; 1.64 + CRITICAL_SECTION waiters_count_lock; 1.65 + HANDLE events_[C_MAX_EVENTS]; 1.66 +} userland_cond_t; 1.67 +void InitializeXPConditionVariable(userland_cond_t *); 1.68 +void DeleteXPConditionVariable(userland_cond_t *); 1.69 +int SleepXPConditionVariable(userland_cond_t *, userland_mutex_t *); 1.70 +void WakeAllXPConditionVariable(userland_cond_t *); 1.71 +#define InitializeConditionVariable(cond) InitializeXPConditionVariable(cond) 1.72 +#define DeleteConditionVariable(cond) DeleteXPConditionVariable(cond) 1.73 +#define SleepConditionVariableCS(cond, mtx, time) SleepXPConditionVariable(cond, mtx) 1.74 +#define WakeAllConditionVariable(cond) WakeAllXPConditionVariable(cond) 1.75 +#else 1.76 +#define DeleteConditionVariable(cond) 1.77 +typedef CONDITION_VARIABLE userland_cond_t; 1.78 +#endif 1.79 +typedef HANDLE userland_thread_t; 1.80 +#define ADDRESS_FAMILY unsigned __int8 1.81 +#define IPVERSION 4 1.82 +#define MAXTTL 255 1.83 +/* VS2010 comes with stdint.h */ 1.84 +#if _MSC_VER >= 1600 1.85 +#include <stdint.h> 1.86 +#else 1.87 +#define uint64_t unsigned __int64 1.88 +#define uint32_t unsigned __int32 1.89 +#define int32_t __int32 1.90 +#define uint16_t unsigned __int16 1.91 +#define int16_t __int16 1.92 +#define uint8_t unsigned __int8 1.93 +#define int8_t __int8 1.94 +#endif 1.95 +#ifndef _SIZE_T_DEFINED 1.96 +#define size_t __int32 1.97 +#endif 1.98 +#define u_long unsigned __int64 1.99 +#define u_int unsigned __int32 1.100 +#define u_int32_t unsigned __int32 1.101 +#define u_int16_t unsigned __int16 1.102 +#define u_int8_t unsigned __int8 1.103 +#define u_char unsigned char 1.104 +#define n_short unsigned __int16 1.105 +#define u_short unsigned __int16 1.106 +#define n_time unsigned __int32 1.107 +#define sa_family_t unsigned __int8 1.108 +#define ssize_t __int64 1.109 +#define IFNAMSIZ 64 1.110 +#define __func__ __FUNCTION__ 1.111 + 1.112 +#ifndef EWOULDBLOCK 1.113 +#define EWOULDBLOCK WSAEWOULDBLOCK 1.114 +#endif 1.115 +#ifndef EINPROGRESS 1.116 +#define EINPROGRESS WSAEINPROGRESS 1.117 +#endif 1.118 +#ifndef EALREADY 1.119 +#define EALREADY WSAEALREADY 1.120 +#endif 1.121 +#ifndef ENOTSOCK 1.122 +#define ENOTSOCK WSAENOTSOCK 1.123 +#endif 1.124 +#ifndef EDESTADDRREQ 1.125 +#define EDESTADDRREQ WSAEDESTADDRREQ 1.126 +#endif 1.127 +#ifndef EMSGSIZE 1.128 +#define EMSGSIZE WSAEMSGSIZE 1.129 +#endif 1.130 +#ifndef EPROTOTYPE 1.131 +#define EPROTOTYPE WSAEPROTOTYPE 1.132 +#endif 1.133 +#ifndef ENOPROTOOPT 1.134 +#define ENOPROTOOPT WSAENOPROTOOPT 1.135 +#endif 1.136 +#ifndef EPROTONOSUPPORT 1.137 +#define EPROTONOSUPPORT WSAEPROTONOSUPPORT 1.138 +#endif 1.139 +#ifndef ESOCKTNOSUPPORT 1.140 +#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT 1.141 +#endif 1.142 +#ifndef EOPNOTSUPP 1.143 +#define EOPNOTSUPP WSAEOPNOTSUPP 1.144 +#endif 1.145 +#ifndef ENOTSUP 1.146 +#define ENOTSUP WSAEOPNOTSUPP 1.147 +#endif 1.148 +#ifndef EPFNOSUPPORT 1.149 +#define EPFNOSUPPORT WSAEPFNOSUPPORT 1.150 +#endif 1.151 +#ifndef EAFNOSUPPORT 1.152 +#define EAFNOSUPPORT WSAEAFNOSUPPORT 1.153 +#endif 1.154 +#ifndef EADDRINUSE 1.155 +#define EADDRINUSE WSAEADDRINUSE 1.156 +#endif 1.157 +#ifndef EADDRNOTAVAIL 1.158 +#define EADDRNOTAVAIL WSAEADDRNOTAVAIL 1.159 +#endif 1.160 +#ifndef ENETDOWN 1.161 +#define ENETDOWN WSAENETDOWN 1.162 +#endif 1.163 +#ifndef ENETUNREACH 1.164 +#define ENETUNREACH WSAENETUNREACH 1.165 +#endif 1.166 +#ifndef ENETRESET 1.167 +#define ENETRESET WSAENETRESET 1.168 +#endif 1.169 +#ifndef ECONNABORTED 1.170 +#define ECONNABORTED WSAECONNABORTED 1.171 +#endif 1.172 +#ifndef ECONNRESET 1.173 +#define ECONNRESET WSAECONNRESET 1.174 +#endif 1.175 +#ifndef ENOBUFS 1.176 +#define ENOBUFS WSAENOBUFS 1.177 +#endif 1.178 +#ifndef EISCONN 1.179 +#define EISCONN WSAEISCONN 1.180 +#endif 1.181 +#ifndef ENOTCONN 1.182 +#define ENOTCONN WSAENOTCONN 1.183 +#endif 1.184 +#ifndef ESHUTDOWN 1.185 +#define ESHUTDOWN WSAESHUTDOWN 1.186 +#endif 1.187 +#ifndef ETOOMANYREFS 1.188 +#define ETOOMANYREFS WSAETOOMANYREFS 1.189 +#endif 1.190 +#ifndef ETIMEDOUT 1.191 +#define ETIMEDOUT WSAETIMEDOUT 1.192 +#endif 1.193 +#ifndef ECONNREFUSED 1.194 +#define ECONNREFUSED WSAECONNREFUSED 1.195 +#endif 1.196 +#ifndef ELOOP 1.197 +#define ELOOP WSAELOOP 1.198 +#endif 1.199 +#ifndef EHOSTDOWN 1.200 +#define EHOSTDOWN WSAEHOSTDOWN 1.201 +#endif 1.202 +#ifndef EHOSTUNREACH 1.203 +#define EHOSTUNREACH WSAEHOSTUNREACH 1.204 +#endif 1.205 +#ifndef EPROCLIM 1.206 +#define EPROCLIM WSAEPROCLIM 1.207 +#endif 1.208 +#ifndef EUSERS 1.209 +#define EUSERS WSAEUSERS 1.210 +#endif 1.211 +#ifndef EDQUOT 1.212 +#define EDQUOT WSAEDQUOT 1.213 +#endif 1.214 +#ifndef ESTALE 1.215 +#define ESTALE WSAESTALE 1.216 +#endif 1.217 +#ifndef EREMOTE 1.218 +#define EREMOTE WSAEREMOTE 1.219 +#endif 1.220 + 1.221 +typedef char* caddr_t; 1.222 + 1.223 +int Win_getifaddrs(struct ifaddrs**); 1.224 +#define getifaddrs(interfaces) (int)Win_getifaddrs(interfaces) 1.225 +int win_if_nametoindex(const char *); 1.226 +#define if_nametoindex(x) win_if_nametoindex(x) 1.227 + 1.228 +#define bzero(buf, len) memset(buf, 0, len) 1.229 +#define bcopy(srcKey, dstKey, len) memcpy(dstKey, srcKey, len) 1.230 +#define snprintf(data, size, format, name) _snprintf_s(data, size, _TRUNCATE, format, name) 1.231 +#define inline __inline 1.232 +#define __inline__ __inline 1.233 +#define random() rand() 1.234 +#define srandom(s) srand(s) 1.235 +#define MSG_EOR 0x8 /* data completes record */ 1.236 +#define MSG_DONTWAIT 0x80 /* this message should be nonblocking */ 1.237 + 1.238 +#ifdef CMSG_DATA 1.239 +#undef CMSG_DATA 1.240 +#endif 1.241 +/* 1.242 + * The following definitions should apply iff WINVER < 0x0600 1.243 + * but that check doesn't work in all cases. So be more pedantic... 1.244 + */ 1.245 +#define CMSG_DATA(x) WSA_CMSG_DATA(x) 1.246 +#define CMSG_ALIGN(x) WSA_CMSGDATA_ALIGN(x) 1.247 +#ifndef CMSG_FIRSTHDR 1.248 +#define CMSG_FIRSTHDR(x) WSA_CMSG_FIRSTHDR(x) 1.249 +#endif 1.250 +#ifndef CMSG_NXTHDR 1.251 +#define CMSG_NXTHDR(x, y) WSA_CMSG_NXTHDR(x, y) 1.252 +#endif 1.253 +#ifndef CMSG_SPACE 1.254 +#define CMSG_SPACE(x) WSA_CMSG_SPACE(x) 1.255 +#endif 1.256 +#ifndef CMSG_LEN 1.257 +#define CMSG_LEN(x) WSA_CMSG_LEN(x) 1.258 +#endif 1.259 + 1.260 +/**** from sctp_os_windows.h ***************/ 1.261 +#define SCTP_IFN_IS_IFT_LOOP(ifn) ((ifn)->ifn_type == IFT_LOOP) 1.262 +#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) 1.263 + 1.264 +/* 1.265 + * Access to IFN's to help with src-addr-selection 1.266 + */ 1.267 +/* This could return VOID if the index works but for BSD we provide both. */ 1.268 +#define SCTP_GET_IFN_VOID_FROM_ROUTE(ro) \ 1.269 + ((ro)->ro_rt != NULL ? (ro)->ro_rt->rt_ifp : NULL) 1.270 +#define SCTP_ROUTE_HAS_VALID_IFN(ro) \ 1.271 + ((ro)->ro_rt && (ro)->ro_rt->rt_ifp) 1.272 +/******************************************/ 1.273 + 1.274 +#define SCTP_GET_IF_INDEX_FROM_ROUTE(ro) 1 /* compiles... TODO use routing socket to determine */ 1.275 + 1.276 +#define timeradd(tvp, uvp, vvp) \ 1.277 + do { \ 1.278 + (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ 1.279 + (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ 1.280 + if ((vvp)->tv_usec >= 1000000) { \ 1.281 + (vvp)->tv_sec++; \ 1.282 + (vvp)->tv_usec -= 1000000; \ 1.283 + } \ 1.284 + } while (0) 1.285 + 1.286 +#define timersub(tvp, uvp, vvp) \ 1.287 + do { \ 1.288 + (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ 1.289 + (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ 1.290 + if ((vvp)->tv_usec < 0) { \ 1.291 + (vvp)->tv_sec--; \ 1.292 + (vvp)->tv_usec += 1000000; \ 1.293 + } \ 1.294 + } while (0) 1.295 + 1.296 +#define BIG_ENDIAN 1 1.297 +#define LITTLE_ENDIAN 0 1.298 +#ifdef WORDS_BIGENDIAN 1.299 +#define BYTE_ORDER BIG_ENDIAN 1.300 +#else 1.301 +#define BYTE_ORDER LITTLE_ENDIAN 1.302 +#endif 1.303 + 1.304 +struct iovec { 1.305 + ULONG len; 1.306 + CHAR FAR *buf; 1.307 +}; 1.308 + 1.309 +#define iov_base buf 1.310 +#define iov_len len 1.311 + 1.312 +struct ifa_msghdr { 1.313 + unsigned __int16 ifam_msglen; 1.314 + unsigned char ifam_version; 1.315 + unsigned char ifam_type; 1.316 + __int32 ifam_addrs; 1.317 + __int32 ifam_flags; 1.318 + unsigned __int16 ifam_index; 1.319 + __int32 ifam_metric; 1.320 +}; 1.321 + 1.322 +struct ifdevmtu { 1.323 + int ifdm_current; 1.324 + int ifdm_min; 1.325 + int ifdm_max; 1.326 +}; 1.327 + 1.328 +struct ifkpi { 1.329 + unsigned int ifk_module_id; 1.330 + unsigned int ifk_type; 1.331 + union { 1.332 + void *ifk_ptr; 1.333 + int ifk_value; 1.334 + } ifk_data; 1.335 +}; 1.336 + 1.337 +struct ifreq { 1.338 + char ifr_name[16]; 1.339 + union { 1.340 + struct sockaddr ifru_addr; 1.341 + struct sockaddr ifru_dstaddr; 1.342 + struct sockaddr ifru_broadaddr; 1.343 + short ifru_flags; 1.344 + int ifru_metric; 1.345 + int ifru_mtu; 1.346 + int ifru_phys; 1.347 + int ifru_media; 1.348 + int ifru_intval; 1.349 + char* ifru_data; 1.350 + struct ifdevmtu ifru_devmtu; 1.351 + struct ifkpi ifru_kpi; 1.352 + unsigned __int32 ifru_wake_flags; 1.353 + } ifr_ifru; 1.354 +#define ifr_addr ifr_ifru.ifru_addr 1.355 +#define ifr_dstaddr ifr_ifru.ifru_dstaddr 1.356 +#define ifr_broadaddr ifr_ifru.ifru_broadaddr 1.357 +#define ifr_flags ifr_ifru.ifru_flags[0] 1.358 +#define ifr_prevflags ifr_ifru.ifru_flags[1] 1.359 +#define ifr_metric ifr_ifru.ifru_metric 1.360 +#define ifr_mtu ifr_ifru.ifru_mtu 1.361 +#define ifr_phys ifr_ifru.ifru_phys 1.362 +#define ifr_media ifr_ifru.ifru_media 1.363 +#define ifr_data ifr_ifru.ifru_data 1.364 +#define ifr_devmtu ifr_ifru.ifru_devmtu 1.365 +#define ifr_intval ifr_ifru.ifru_intval 1.366 +#define ifr_kpi ifr_ifru.ifru_kpi 1.367 +#define ifr_wake_flags ifr_ifru.ifru_wake_flags 1.368 +}; 1.369 + 1.370 +/*#include <packon.h> 1.371 +#pragma pack(push, 1)*/ 1.372 +struct ip { 1.373 + u_char ip_hl:4, ip_v:4; 1.374 + u_char ip_tos; 1.375 + u_short ip_len; 1.376 + u_short ip_id; 1.377 + u_short ip_off; 1.378 +#define IP_RP 0x8000 1.379 +#define IP_DF 0x4000 1.380 +#define IP_MF 0x2000 1.381 +#define IP_OFFMASK 0x1fff 1.382 + u_char ip_ttl; 1.383 + u_char ip_p; 1.384 + u_short ip_sum; 1.385 + struct in_addr ip_src, ip_dst; 1.386 +}; 1.387 + 1.388 +struct ifaddrs { 1.389 + struct ifaddrs *ifa_next; 1.390 + char *ifa_name; 1.391 + unsigned int ifa_flags; 1.392 + struct sockaddr *ifa_addr; 1.393 + struct sockaddr *ifa_netmask; 1.394 + struct sockaddr *ifa_dstaddr; 1.395 + void *ifa_data; 1.396 +}; 1.397 + 1.398 +struct udphdr { 1.399 + unsigned __int16 uh_sport; 1.400 + unsigned __int16 uh_dport; 1.401 + unsigned __int16 uh_ulen; 1.402 + unsigned __int16 uh_sum; 1.403 +}; 1.404 + 1.405 +#else /* !defined(Userspace_os_Windows) */ 1.406 +#include <sys/cdefs.h> /* needed? added from old __FreeBSD__ */ 1.407 +#include <sys/socket.h> 1.408 +#if defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Linux) || defined(__Userspace_os_NetBSD) || defined(__Userspace_os_OpenBSD) || defined(ANDROID) 1.409 +#include <pthread.h> 1.410 +#endif 1.411 +typedef pthread_mutex_t userland_mutex_t; 1.412 +typedef pthread_cond_t userland_cond_t; 1.413 +typedef pthread_t userland_thread_t; 1.414 +#endif 1.415 + 1.416 +#define mtx_lock(arg1) 1.417 +#define mtx_unlock(arg1) 1.418 +#define mtx_assert(arg1,arg2) 1.419 +#define MA_OWNED 7 /* sys/mutex.h typically on FreeBSD */ 1.420 +#if !defined(__Userspace_os_FreeBSD) 1.421 +struct mtx {int dummy;}; 1.422 +#if !defined(__Userspace_os_NetBSD) 1.423 +struct selinfo {int dummy;}; 1.424 +#endif 1.425 +struct sx {int dummy;}; 1.426 +#endif 1.427 + 1.428 +#include <stdio.h> 1.429 +#include <string.h> 1.430 +/* #include <sys/param.h> in FreeBSD defines MSIZE */ 1.431 +/* #include <sys/ktr.h> */ 1.432 +/* #include <sys/systm.h> */ 1.433 +#if defined(__Userspace_os_Windows) 1.434 +#include <user_queue.h> 1.435 +#else 1.436 +#include <sys/queue.h> 1.437 +#endif 1.438 +#include <user_malloc.h> 1.439 +/* #include <sys/kernel.h> */ 1.440 +/* #include <sys/sysctl.h> */ 1.441 +/* #include <sys/protosw.h> */ 1.442 +/* on FreeBSD, this results in a redefintion of SOCK(BUF)_(UN)LOCK and 1.443 + * uknown type of struct mtx for sb_mtx in struct sockbuf */ 1.444 +#include "user_socketvar.h" /* MALLOC_DECLARE's M_PCB. Replacement for sys/socketvar.h */ 1.445 +/* #include <sys/jail.h> */ 1.446 +/* #include <sys/sysctl.h> */ 1.447 +#include <user_environment.h> 1.448 +#include <user_atomic.h> 1.449 +#include <user_mbuf.h> 1.450 +/* #include <sys/uio.h> */ 1.451 +/* #include <sys/lock.h> */ 1.452 +#if defined(__FreeBSD__) && __FreeBSD_version > 602000 1.453 +#include <sys/rwlock.h> 1.454 +#endif 1.455 +/* #include <sys/kthread.h> */ 1.456 +#if defined(__FreeBSD__) && __FreeBSD_version > 602000 1.457 +#include <sys/priv.h> 1.458 +#endif 1.459 +/* #include <sys/random.h> */ 1.460 +/* #include <sys/limits.h> */ 1.461 +/* #include <machine/cpu.h> */ 1.462 + 1.463 +#if defined(__Userspace_os_Darwin) 1.464 +/* was a 0 byte file. needed for structs if_data(64) and net_event_data */ 1.465 +#include <net/if_var.h> 1.466 +#endif 1.467 +#if defined(__Userspace_os_FreeBSD) 1.468 +#include <net/if_types.h> 1.469 +/* #include <net/if_var.h> was a 0 byte file. causes struct mtx redefinition */ 1.470 +#endif 1.471 +/* OOTB only - dummy route used at the moment. should we port route to 1.472 + * userspace as well? */ 1.473 +/* on FreeBSD, this results in a redefintion of struct route */ 1.474 +/* #include <net/route.h> */ 1.475 +#if !defined(__Userspace_os_Windows) 1.476 +#include <net/if.h> 1.477 +#include <netinet/in.h> 1.478 +#include <netinet/in_systm.h> 1.479 +#include <netinet/ip.h> 1.480 +#include <netinet/ip_icmp.h> 1.481 +#else 1.482 +#include <user_ip_icmp.h> 1.483 +#endif 1.484 +/* #include <netinet/in_pcb.h> ported to userspace */ 1.485 +#include <user_inpcb.h> 1.486 + 1.487 +/* for getifaddrs */ 1.488 +#include <sys/types.h> 1.489 +#if !defined(__Userspace_os_Windows) 1.490 +#if !defined(ANDROID) && (defined(INET) || defined(INET6)) 1.491 +#include <ifaddrs.h> 1.492 +#endif 1.493 + 1.494 +/* for ioctl */ 1.495 +#include <sys/ioctl.h> 1.496 + 1.497 +/* for close, etc. */ 1.498 +#include <unistd.h> 1.499 +#endif 1.500 + 1.501 +/* lots of errno's used and needed in userspace */ 1.502 + 1.503 +/* for offsetof */ 1.504 +#include <stddef.h> 1.505 + 1.506 +#if defined(SCTP_PROCESS_LEVEL_LOCKS) && !defined(__Userspace_os_Windows) 1.507 +/* for pthread_mutex_lock, pthread_mutex_unlock, etc. */ 1.508 +#include <pthread.h> 1.509 +#endif 1.510 + 1.511 +#ifdef IPSEC 1.512 +#include <netipsec/ipsec.h> 1.513 +#include <netipsec/key.h> 1.514 +#endif /* IPSEC */ 1.515 + 1.516 +#ifdef INET6 1.517 +#if defined(__Userspace_os_FreeBSD) 1.518 +#include <sys/domain.h> 1.519 +#endif 1.520 +#ifdef IPSEC 1.521 +#include <netipsec/ipsec6.h> 1.522 +#endif 1.523 +#if !defined(__Userspace_os_Windows) 1.524 +#include <netinet/ip6.h> 1.525 +#include <netinet/icmp6.h> 1.526 +#endif 1.527 +#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) 1.528 +#include "user_ip6_var.h" 1.529 +#else 1.530 +#include <netinet6/ip6_var.h> 1.531 +#endif 1.532 +#if defined(__Userspace_os_FreeBSD) 1.533 +#include <netinet6/in6_pcb.h> 1.534 +#include <netinet6/ip6protosw.h> 1.535 +/* #include <netinet6/nd6.h> was a 0 byte file */ 1.536 +#include <netinet6/scope6_var.h> 1.537 +#endif 1.538 +#endif /* INET6 */ 1.539 + 1.540 +#if defined(HAVE_SCTP_PEELOFF_SOCKOPT) 1.541 +#include <sys/file.h> 1.542 +#include <sys/filedesc.h> 1.543 +#endif 1.544 + 1.545 +#include "netinet/sctp_sha1.h" 1.546 + 1.547 +#if __FreeBSD_version >= 700000 1.548 +#include <netinet/ip_options.h> 1.549 +#endif 1.550 + 1.551 +#define SCTP_PRINTF(...) \ 1.552 + if (SCTP_BASE_VAR(debug_printf)) { \ 1.553 + SCTP_BASE_VAR(debug_printf)(__VA_ARGS__); \ 1.554 + } 1.555 + 1.556 +#if defined(__FreeBSD__) 1.557 +#ifndef in6pcb 1.558 +#define in6pcb inpcb 1.559 +#endif 1.560 +#endif 1.561 +/* Declare all the malloc names for all the various mallocs */ 1.562 +MALLOC_DECLARE(SCTP_M_MAP); 1.563 +MALLOC_DECLARE(SCTP_M_STRMI); 1.564 +MALLOC_DECLARE(SCTP_M_STRMO); 1.565 +MALLOC_DECLARE(SCTP_M_ASC_ADDR); 1.566 +MALLOC_DECLARE(SCTP_M_ASC_IT); 1.567 +MALLOC_DECLARE(SCTP_M_AUTH_CL); 1.568 +MALLOC_DECLARE(SCTP_M_AUTH_KY); 1.569 +MALLOC_DECLARE(SCTP_M_AUTH_HL); 1.570 +MALLOC_DECLARE(SCTP_M_AUTH_IF); 1.571 +MALLOC_DECLARE(SCTP_M_STRESET); 1.572 +MALLOC_DECLARE(SCTP_M_CMSG); 1.573 +MALLOC_DECLARE(SCTP_M_COPYAL); 1.574 +MALLOC_DECLARE(SCTP_M_VRF); 1.575 +MALLOC_DECLARE(SCTP_M_IFA); 1.576 +MALLOC_DECLARE(SCTP_M_IFN); 1.577 +MALLOC_DECLARE(SCTP_M_TIMW); 1.578 +MALLOC_DECLARE(SCTP_M_MVRF); 1.579 +MALLOC_DECLARE(SCTP_M_ITER); 1.580 +MALLOC_DECLARE(SCTP_M_SOCKOPT); 1.581 + 1.582 +#if defined(SCTP_LOCAL_TRACE_BUF) 1.583 + 1.584 +#define SCTP_GET_CYCLECOUNT get_cyclecount() 1.585 +#define SCTP_CTR6 sctp_log_trace 1.586 + 1.587 +#else 1.588 +#define SCTP_CTR6 CTR6 1.589 +#endif 1.590 + 1.591 +/* Empty ktr statement for _Userspace__ (similar to what is done for mac) */ 1.592 +#define CTR6(m, d, p1, p2, p3, p4, p5, p6) 1.593 + 1.594 + 1.595 + 1.596 +#define SCTP_BASE_INFO(__m) system_base_info.sctppcbinfo.__m 1.597 +#define SCTP_BASE_STATS system_base_info.sctpstat 1.598 +#define SCTP_BASE_STAT(__m) system_base_info.sctpstat.__m 1.599 +#define SCTP_BASE_SYSCTL(__m) system_base_info.sctpsysctl.__m 1.600 +#define SCTP_BASE_VAR(__m) system_base_info.__m 1.601 + 1.602 +/* 1.603 + * 1.604 + */ 1.605 +#if !defined(__Userspace_os_Darwin) 1.606 +#define USER_ADDR_NULL (NULL) /* FIX ME: temp */ 1.607 +#endif 1.608 + 1.609 +#if defined(SCTP_DEBUG) 1.610 +#include <netinet/sctp_constants.h> 1.611 +#define SCTPDBG(level, ...) \ 1.612 +{ \ 1.613 + do { \ 1.614 + if (SCTP_BASE_SYSCTL(sctp_debug_on) & level) { \ 1.615 + SCTP_PRINTF(__VA_ARGS__); \ 1.616 + } \ 1.617 + } while (0); \ 1.618 +} 1.619 +#define SCTPDBG_ADDR(level, addr) \ 1.620 +{ \ 1.621 + do { \ 1.622 + if (SCTP_BASE_SYSCTL(sctp_debug_on) & level ) { \ 1.623 + sctp_print_address(addr); \ 1.624 + } \ 1.625 + } while (0); \ 1.626 +} 1.627 +#else 1.628 +#define SCTPDBG(level, ...) 1.629 +#define SCTPDBG_ADDR(level, addr) 1.630 +#endif 1.631 + 1.632 +#ifdef SCTP_LTRACE_CHUNKS 1.633 +#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) 1.634 +#else 1.635 +#define SCTP_LTRACE_CHK(a, b, c, d) 1.636 +#endif 1.637 + 1.638 +#ifdef SCTP_LTRACE_ERRORS 1.639 +#define SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, file, err) \ 1.640 + if (sctp_logging_level & SCTP_LTRACE_ERROR_ENABLE) \ 1.641 + SCTP_PRINTF("mbuf:%p inp:%p stcb:%p net:%p file:%x line:%d error:%d\n", \ 1.642 + (void *)m, (void *)inp, (void *)stcb, (void *)net, file, __LINE__, err); 1.643 +#define SCTP_LTRACE_ERR_RET(inp, stcb, net, file, err) \ 1.644 + if (sctp_logging_level & SCTP_LTRACE_ERROR_ENABLE) \ 1.645 + SCTP_PRINTF("inp:%p stcb:%p net:%p file:%x line:%d error:%d\n", \ 1.646 + (void *)inp, (void *)stcb, (void *)net, file, __LINE__, err); 1.647 +#else 1.648 +#define SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, file, err) 1.649 +#define SCTP_LTRACE_ERR_RET(inp, stcb, net, file, err) 1.650 +#endif 1.651 + 1.652 + 1.653 +/* 1.654 + * Local address and interface list handling 1.655 + */ 1.656 +#define SCTP_MAX_VRF_ID 0 1.657 +#define SCTP_SIZE_OF_VRF_HASH 3 1.658 +#define SCTP_IFNAMSIZ IFNAMSIZ 1.659 +#define SCTP_DEFAULT_VRFID 0 1.660 +#define SCTP_VRF_ADDR_HASH_SIZE 16 1.661 +#define SCTP_VRF_IFN_HASH_SIZE 3 1.662 +#define SCTP_INIT_VRF_TABLEID(vrf) 1.663 + 1.664 +#if !defined(__Userspace_os_Windows) 1.665 +#define SCTP_IFN_IS_IFT_LOOP(ifn) (strncmp((ifn)->ifn_name, "lo", 2) == 0) 1.666 +/* BSD definition */ 1.667 +/* #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) */ 1.668 +/* only used in IPv6 scenario, which isn't supported yet */ 1.669 +#define SCTP_ROUTE_IS_REAL_LOOP(ro) 0 1.670 + 1.671 +/* 1.672 + * Access to IFN's to help with src-addr-selection 1.673 + */ 1.674 +/* This could return VOID if the index works but for BSD we provide both. */ 1.675 +#define SCTP_GET_IFN_VOID_FROM_ROUTE(ro) (void *)ro->ro_rt->rt_ifp 1.676 +#define SCTP_GET_IF_INDEX_FROM_ROUTE(ro) 1 /* compiles... TODO use routing socket to determine */ 1.677 +#define SCTP_ROUTE_HAS_VALID_IFN(ro) ((ro)->ro_rt && (ro)->ro_rt->rt_ifp) 1.678 +#endif 1.679 + 1.680 +/* 1.681 + * general memory allocation 1.682 + */ 1.683 +#define SCTP_MALLOC(var, type, size, name) \ 1.684 + do { \ 1.685 + MALLOC(var, type, size, name, M_NOWAIT); \ 1.686 + } while (0) 1.687 + 1.688 +#define SCTP_FREE(var, type) FREE(var, type) 1.689 + 1.690 +#define SCTP_MALLOC_SONAME(var, type, size) \ 1.691 + do { \ 1.692 + MALLOC(var, type, size, M_SONAME, (M_WAITOK | M_ZERO)); \ 1.693 + } while (0) 1.694 + 1.695 +#define SCTP_FREE_SONAME(var) FREE(var, M_SONAME) 1.696 + 1.697 +#define SCTP_PROCESS_STRUCT struct proc * 1.698 + 1.699 +/* 1.700 + * zone allocation functions 1.701 + */ 1.702 + 1.703 + 1.704 +#if defined(SCTP_SIMPLE_ALLOCATOR) 1.705 +/*typedef size_t sctp_zone_t;*/ 1.706 +#define SCTP_ZONE_INIT(zone, name, size, number) { \ 1.707 + zone = size; \ 1.708 +} 1.709 + 1.710 +/* __Userspace__ SCTP_ZONE_GET: allocate element from the zone */ 1.711 +#define SCTP_ZONE_GET(zone, type) \ 1.712 + (type *)malloc(zone); 1.713 + 1.714 + 1.715 +/* __Userspace__ SCTP_ZONE_FREE: free element from the zone */ 1.716 +#define SCTP_ZONE_FREE(zone, element) { \ 1.717 + free(element); \ 1.718 +} 1.719 + 1.720 +#define SCTP_ZONE_DESTROY(zone) 1.721 +#else 1.722 +/*__Userspace__ 1.723 + Compiling & linking notes: Needs libumem, which has been placed in ./user_lib 1.724 + All userspace header files are in ./user_include. Makefile will need the 1.725 + following. 1.726 + CFLAGS = -I./ -Wall 1.727 + LDFLAGS = -L./user_lib -R./user_lib -lumem 1.728 +*/ 1.729 +#include "user_include/umem.h" 1.730 + 1.731 +/* __Userspace__ SCTP_ZONE_INIT: initialize the zone */ 1.732 +/* 1.733 + __Userspace__ 1.734 + No equivalent function to uma_zone_set_max added yet. (See SCTP_ZONE_INIT in sctp_os_bsd.h 1.735 + for reference). It may not be required as mentioned in 1.736 + http://nixdoc.net/man-pages/FreeBSD/uma_zalloc.9.html that 1.737 + max limits may not enforced on systems with more than one CPU. 1.738 +*/ 1.739 +#define SCTP_ZONE_INIT(zone, name, size, number) { \ 1.740 + zone = umem_cache_create(name, size, 0, NULL, NULL, NULL, NULL, NULL, 0); \ 1.741 + } 1.742 + 1.743 +/* __Userspace__ SCTP_ZONE_GET: allocate element from the zone */ 1.744 +#define SCTP_ZONE_GET(zone, type) \ 1.745 + (type *)umem_cache_alloc(zone, UMEM_DEFAULT); 1.746 + 1.747 + 1.748 +/* __Userspace__ SCTP_ZONE_FREE: free element from the zone */ 1.749 +#define SCTP_ZONE_FREE(zone, element) \ 1.750 + umem_cache_free(zone, element); 1.751 + 1.752 + 1.753 +/* __Userspace__ SCTP_ZONE_DESTROY: destroy the zone */ 1.754 +#define SCTP_ZONE_DESTROY(zone) \ 1.755 + umem_cache_destroy(zone); 1.756 +#endif 1.757 + 1.758 +/* global struct ifaddrs used in sctp_init_ifns_for_vrf getifaddrs call 1.759 + * but references to fields are needed to persist as the vrf is queried. 1.760 + * getifaddrs allocates memory that needs to be freed with a freeifaddrs 1.761 + * call; this global is used to call freeifaddrs upon in sctp_pcb_finish 1.762 + */ 1.763 +extern struct ifaddrs *g_interfaces; 1.764 + 1.765 + 1.766 +/* 1.767 + * __Userspace__ Defining sctp_hashinit_flags() and sctp_hashdestroy() for userland. 1.768 + */ 1.769 +void *sctp_hashinit_flags(int elements, struct malloc_type *type, 1.770 + u_long *hashmask, int flags); 1.771 +void 1.772 +sctp_hashdestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask); 1.773 + 1.774 +void 1.775 +sctp_hashfreedestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask); 1.776 + 1.777 + 1.778 +#define HASH_NOWAIT 0x00000001 1.779 +#define HASH_WAITOK 0x00000002 1.780 + 1.781 +/* M_PCB is MALLOC_DECLARE'd in sys/socketvar.h */ 1.782 +#define SCTP_HASH_INIT(size, hashmark) sctp_hashinit_flags(size, M_PCB, hashmark, HASH_NOWAIT) 1.783 + 1.784 +#define SCTP_HASH_FREE(table, hashmark) sctp_hashdestroy(table, M_PCB, hashmark) 1.785 + 1.786 +#define SCTP_HASH_FREE_DESTROY(table, hashmark) sctp_hashfreedestroy(table, M_PCB, hashmark) 1.787 +#define SCTP_M_COPYM m_copym 1.788 + 1.789 +/* 1.790 + * timers 1.791 + */ 1.792 +/* __Userspace__ 1.793 + * user_sctp_callout.h has typedef struct sctp_callout sctp_os_timer_t; 1.794 + * which is used in the timer related functions such as 1.795 + * SCTP_OS_TIMER_INIT etc. 1.796 +*/ 1.797 +#include <netinet/sctp_callout.h> 1.798 + 1.799 +/* __Userspace__ Creating a receive thread */ 1.800 +#include <user_recv_thread.h> 1.801 + 1.802 +/*__Userspace__ defining KTR_SUBSYS 1 as done in sctp_os_macosx.h */ 1.803 +#define KTR_SUBSYS 1 1.804 + 1.805 +#define sctp_get_tick_count() (ticks) 1.806 + 1.807 +/* The packed define for 64 bit platforms */ 1.808 +#if !defined(__Userspace_os_Windows) 1.809 +#define SCTP_PACKED __attribute__((packed)) 1.810 +#define SCTP_UNUSED __attribute__((unused)) 1.811 +#else 1.812 +#define SCTP_PACKED 1.813 +#define SCTP_UNUSED 1.814 +#endif 1.815 + 1.816 +/* 1.817 + * Functions 1.818 + */ 1.819 +/* Mbuf manipulation and access macros */ 1.820 +#define SCTP_BUF_LEN(m) (m->m_len) 1.821 +#define SCTP_BUF_NEXT(m) (m->m_next) 1.822 +#define SCTP_BUF_NEXT_PKT(m) (m->m_nextpkt) 1.823 +#define SCTP_BUF_RESV_UF(m, size) m->m_data += size 1.824 +#define SCTP_BUF_AT(m, size) m->m_data + size 1.825 +#define SCTP_BUF_IS_EXTENDED(m) (m->m_flags & M_EXT) 1.826 +#define SCTP_BUF_EXTEND_SIZE(m) (m->m_ext.ext_size) 1.827 +#define SCTP_BUF_TYPE(m) (m->m_type) 1.828 +#define SCTP_BUF_RECVIF(m) (m->m_pkthdr.rcvif) 1.829 +#define SCTP_BUF_PREPEND M_PREPEND 1.830 + 1.831 +#define SCTP_ALIGN_TO_END(m, len) if(m->m_flags & M_PKTHDR) { \ 1.832 + MH_ALIGN(m, len); \ 1.833 + } else if ((m->m_flags & M_EXT) == 0) { \ 1.834 + M_ALIGN(m, len); \ 1.835 + } 1.836 + 1.837 +/* We make it so if you have up to 4 threads 1.838 + * writting based on the default size of 1.839 + * the packet log 65 k, that would be 1.840 + * 4 16k packets before we would hit 1.841 + * a problem. 1.842 + */ 1.843 +#define SCTP_PKTLOG_WRITERS_NEED_LOCK 3 1.844 + 1.845 + 1.846 +/* 1.847 + * routes, output, etc. 1.848 + */ 1.849 + 1.850 +typedef struct sctp_route sctp_route_t; 1.851 +typedef struct sctp_rtentry sctp_rtentry_t; 1.852 + 1.853 +static inline void sctp_userspace_rtalloc(sctp_route_t *ro) 1.854 +{ 1.855 + if (ro->ro_rt != NULL) { 1.856 + ro->ro_rt->rt_refcnt++; 1.857 + return; 1.858 + } 1.859 + 1.860 + ro->ro_rt = (sctp_rtentry_t *) malloc(sizeof(sctp_rtentry_t)); 1.861 + if (ro->ro_rt == NULL) 1.862 + return; 1.863 + 1.864 + /* initialize */ 1.865 + memset(ro->ro_rt, 0, sizeof(sctp_rtentry_t)); 1.866 + ro->ro_rt->rt_refcnt = 1; 1.867 + 1.868 + /* set MTU */ 1.869 + /* TODO set this based on the ro->ro_dst, looking up MTU with routing socket */ 1.870 +#if 0 1.871 + if (userspace_rawroute == -1) { 1.872 + userspace_rawroute = socket(AF_ROUTE, SOCK_RAW, 0); 1.873 + if (userspace_rawroute == -1) 1.874 + return; 1.875 + } 1.876 +#endif 1.877 + ro->ro_rt->rt_rmx.rmx_mtu = 1500; /* FIXME temporary solution */ 1.878 + 1.879 + /* TODO enable the ability to obtain interface index of route for 1.880 + * SCTP_GET_IF_INDEX_FROM_ROUTE macro. 1.881 + */ 1.882 +} 1.883 +#define SCTP_RTALLOC(ro, vrf_id) sctp_userspace_rtalloc((sctp_route_t *)ro) 1.884 + 1.885 +/* dummy rtfree needed once user_route.h is included */ 1.886 +static inline void sctp_userspace_rtfree(sctp_rtentry_t *rt) 1.887 +{ 1.888 + if(rt == NULL) { 1.889 + return; 1.890 + } 1.891 + if(--rt->rt_refcnt > 0) { 1.892 + return; 1.893 + } 1.894 + free(rt); 1.895 + rt = NULL; 1.896 +} 1.897 +#define rtfree(arg1) sctp_userspace_rtfree(arg1) 1.898 + 1.899 + 1.900 +/*************************/ 1.901 +/* MTU */ 1.902 +/*************************/ 1.903 +int sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af); 1.904 + 1.905 +#define SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index, af) sctp_userspace_get_mtu_from_ifn(ifn_index, af) 1.906 + 1.907 +#define SCTP_GATHER_MTU_FROM_ROUTE(sctp_ifa, sa, rt) ((rt != NULL) ? rt->rt_rmx.rmx_mtu : 0) 1.908 + 1.909 +#define SCTP_GATHER_MTU_FROM_INTFC(sctp_ifn) sctp_userspace_get_mtu_from_ifn(if_nametoindex(((struct ifaddrs *) (sctp_ifn))->ifa_name), AF_INET) 1.910 + 1.911 +#define SCTP_SET_MTU_OF_ROUTE(sa, rt, mtu) do { \ 1.912 + if (rt != NULL) \ 1.913 + rt->rt_rmx.rmx_mtu = mtu; \ 1.914 + } while(0) 1.915 + 1.916 +/* (de-)register interface event notifications */ 1.917 +#define SCTP_REGISTER_INTERFACE(ifhandle, af) 1.918 +#define SCTP_DEREGISTER_INTERFACE(ifhandle, af) 1.919 + 1.920 + 1.921 +/*************************/ 1.922 +/* These are for logging */ 1.923 +/*************************/ 1.924 +/* return the base ext data pointer */ 1.925 +#define SCTP_BUF_EXTEND_BASE(m) (m->m_ext.ext_buf) 1.926 + /* return the refcnt of the data pointer */ 1.927 +#define SCTP_BUF_EXTEND_REFCNT(m) (*m->m_ext.ref_cnt) 1.928 +/* return any buffer related flags, this is 1.929 + * used beyond logging for apple only. 1.930 + */ 1.931 +#define SCTP_BUF_GET_FLAGS(m) (m->m_flags) 1.932 + 1.933 +/* For BSD this just accesses the M_PKTHDR length 1.934 + * so it operates on an mbuf with hdr flag. Other 1.935 + * O/S's may have seperate packet header and mbuf 1.936 + * chain pointers.. thus the macro. 1.937 + */ 1.938 +#define SCTP_HEADER_TO_CHAIN(m) (m) 1.939 +#define SCTP_DETACH_HEADER_FROM_CHAIN(m) 1.940 +#define SCTP_HEADER_LEN(m) ((m)->m_pkthdr.len) 1.941 +#define SCTP_GET_HEADER_FOR_OUTPUT(o_pak) 0 1.942 +#define SCTP_RELEASE_HEADER(m) 1.943 +#define SCTP_RELEASE_PKT(m) sctp_m_freem(m) 1.944 +/* UDP __Userspace__ - dummy definition */ 1.945 +#define SCTP_ENABLE_UDP_CSUM(m) m=m 1.946 +/* BSD definition */ 1.947 +/* #define SCTP_ENABLE_UDP_CSUM(m) do { \ */ 1.948 +/* m->m_pkthdr.csum_flags = CSUM_UDP; \ */ 1.949 +/* m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); \ */ 1.950 +/* } while (0) */ 1.951 + 1.952 +#define SCTP_GET_PKT_VRFID(m, vrf_id) ((vrf_id = SCTP_DEFAULT_VRFID) != SCTP_DEFAULT_VRFID) 1.953 + 1.954 + 1.955 + 1.956 +/* Attach the chain of data into the sendable packet. */ 1.957 +#define SCTP_ATTACH_CHAIN(pak, m, packet_length) do { \ 1.958 + pak = m; \ 1.959 + pak->m_pkthdr.len = packet_length; \ 1.960 + } while(0) 1.961 + 1.962 +/* Other m_pkthdr type things */ 1.963 +/* FIXME need real definitions */ 1.964 +#define SCTP_IS_IT_BROADCAST(dst, m) 0 1.965 +/* OOTB only #define SCTP_IS_IT_BROADCAST(dst, m) ((m->m_flags & M_PKTHDR) ? in_broadcast(dst, m->m_pkthdr.rcvif) : 0) BSD def */ 1.966 +#define SCTP_IS_IT_LOOPBACK(m) 0 1.967 +/* 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 */ 1.968 + 1.969 + 1.970 +/* This converts any input packet header 1.971 + * into the chain of data holders, for BSD 1.972 + * its a NOP. 1.973 + */ 1.974 + 1.975 +/* get the v6 hop limit */ 1.976 +#define SCTP_GET_HLIM(inp, ro) 128 /* As done for __Windows__ */ 1.977 +#define IPv6_HOP_LIMIT 128 1.978 + 1.979 +/* is the endpoint v6only? */ 1.980 +#define SCTP_IPV6_V6ONLY(inp) (((struct inpcb *)inp)->inp_flags & IN6P_IPV6_V6ONLY) 1.981 +/* is the socket non-blocking? */ 1.982 +#define SCTP_SO_IS_NBIO(so) ((so)->so_state & SS_NBIO) 1.983 +#define SCTP_SET_SO_NBIO(so) ((so)->so_state |= SS_NBIO) 1.984 +#define SCTP_CLEAR_SO_NBIO(so) ((so)->so_state &= ~SS_NBIO) 1.985 +/* get the socket type */ 1.986 +#define SCTP_SO_TYPE(so) ((so)->so_type) 1.987 + 1.988 +/* reserve sb space for a socket */ 1.989 +#define SCTP_SORESERVE(so, send, recv) soreserve(so, send, recv) 1.990 + 1.991 +/* wakeup a socket */ 1.992 +#define SCTP_SOWAKEUP(so) wakeup(&(so)->so_timeo, so) 1.993 +/* clear the socket buffer state */ 1.994 +#define SCTP_SB_CLEAR(sb) \ 1.995 + (sb).sb_cc = 0; \ 1.996 + (sb).sb_mb = NULL; \ 1.997 + (sb).sb_mbcnt = 0; 1.998 + 1.999 +#define SCTP_SB_LIMIT_RCV(so) so->so_rcv.sb_hiwat 1.1000 +#define SCTP_SB_LIMIT_SND(so) so->so_snd.sb_hiwat 1.1001 + 1.1002 +/* Future zero copy wakeup/send function */ 1.1003 +#define SCTP_ZERO_COPY_EVENT(inp, so) 1.1004 +/* This is re-pulse ourselves for sendbuf */ 1.1005 +#define SCTP_ZERO_COPY_SENDQ_EVENT(inp, so) 1.1006 + 1.1007 +#define SCTP_READ_RANDOM(buf, len) read_random(buf, len) 1.1008 + 1.1009 +#define SCTP_SHA1_CTX struct sctp_sha1_context 1.1010 +#define SCTP_SHA1_INIT sctp_sha1_init 1.1011 +#define SCTP_SHA1_UPDATE sctp_sha1_update 1.1012 +#define SCTP_SHA1_FINAL(x,y) sctp_sha1_final((unsigned char *)x, y) 1.1013 + 1.1014 +/* start OOTB only stuff */ 1.1015 +/* TODO IFT_LOOP is in net/if_types.h on Linux */ 1.1016 +#define IFT_LOOP 0x18 1.1017 + 1.1018 +/* sctp_pcb.h */ 1.1019 + 1.1020 +#if defined(__Userspace_os_Windows) 1.1021 +#define SHUT_RD 1 1.1022 +#define SHUT_WR 2 1.1023 +#define SHUT_RDWR 3 1.1024 +#endif 1.1025 +#define PRU_FLUSH_RD SHUT_RD 1.1026 +#define PRU_FLUSH_WR SHUT_WR 1.1027 +#define PRU_FLUSH_RDWR SHUT_RDWR 1.1028 + 1.1029 +/* netinet/ip_var.h defintions are behind an if defined for _KERNEL on FreeBSD */ 1.1030 +#define IP_RAWOUTPUT 0x2 1.1031 + 1.1032 + 1.1033 +/* end OOTB only stuff */ 1.1034 + 1.1035 +#define AF_CONN 123 1.1036 +struct sockaddr_conn { 1.1037 +#ifdef HAVE_SCONN_LEN 1.1038 + uint8_t sconn_len; 1.1039 +#endif 1.1040 + uint8_t sconn_family; 1.1041 + uint16_t sconn_port; 1.1042 + void *sconn_addr; 1.1043 +}; 1.1044 + 1.1045 +/* 1.1046 + * SCTP protocol specific mbuf flags. 1.1047 + */ 1.1048 +#define M_NOTIFICATION M_PROTO5 /* SCTP notification */ 1.1049 + 1.1050 +/* 1.1051 + * IP output routines 1.1052 + */ 1.1053 + 1.1054 +/* Defining SCTP_IP_ID macro. 1.1055 + In netinet/ip_output.c, we have u_short ip_id; 1.1056 + In netinet/ip_var.h, we have extern u_short ip_id; (enclosed within _KERNEL_) 1.1057 + See static __inline uint16_t ip_newid(void) in netinet/ip_var.h 1.1058 + */ 1.1059 +#define SCTP_IP_ID(inp) (ip_id) 1.1060 + 1.1061 +/* need sctphdr to get port in SCTP_IP_OUTPUT. sctphdr defined in sctp.h */ 1.1062 +#include <netinet/sctp.h> 1.1063 +extern void sctp_userspace_ip_output(int *result, struct mbuf *o_pak, 1.1064 + sctp_route_t *ro, void *stcb, 1.1065 + uint32_t vrf_id); 1.1066 + 1.1067 +#define SCTP_IP_OUTPUT(result, o_pak, ro, stcb, vrf_id) sctp_userspace_ip_output(&result, o_pak, ro, stcb, vrf_id); 1.1068 + 1.1069 +#if defined(INET6) 1.1070 +extern void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak, 1.1071 + struct route_in6 *ro, void *stcb, 1.1072 + uint32_t vrf_id); 1.1073 +#define SCTP_IP6_OUTPUT(result, o_pak, ro, ifp, stcb, vrf_id) sctp_userspace_ip6_output(&result, o_pak, ro, stcb, vrf_id); 1.1074 +#endif 1.1075 + 1.1076 + 1.1077 + 1.1078 +#if 0 1.1079 +#define SCTP_IP6_OUTPUT(result, o_pak, ro, ifp, stcb, vrf_id) \ 1.1080 +{ \ 1.1081 + if (stcb && stcb->sctp_ep) \ 1.1082 + result = ip6_output(o_pak, \ 1.1083 + ((struct in6pcb *)(stcb->sctp_ep))->in6p_outputopts, \ 1.1084 + (ro), 0, 0, ifp, NULL); \ 1.1085 + else \ 1.1086 + result = ip6_output(o_pak, NULL, (ro), 0, 0, ifp, NULL); \ 1.1087 +} 1.1088 +#endif 1.1089 + 1.1090 +struct mbuf * 1.1091 +sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int allonebuf, int type); 1.1092 + 1.1093 + 1.1094 +/* with the current included files, this is defined in Linux but 1.1095 + * in FreeBSD, it is behind a _KERNEL in sys/socket.h ... 1.1096 + */ 1.1097 +#if defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) 1.1098 +/* stolen from /usr/include/sys/socket.h */ 1.1099 +#define CMSG_ALIGN(n) _ALIGN(n) 1.1100 +#elif defined(__Userspace_os_NetBSD) 1.1101 +#define CMSG_ALIGN(n) (((n) + __ALIGNBYTES) & ~__ALIGNBYTES) 1.1102 +#elif defined(__Userspace_os_Darwin) 1.1103 +#if !defined(__DARWIN_ALIGNBYTES) 1.1104 +#define __DARWIN_ALIGNBYTES (sizeof(__darwin_size_t) - 1) 1.1105 +#endif 1.1106 + 1.1107 +#if !defined(__DARWIN_ALIGN) 1.1108 +#define __DARWIN_ALIGN(p) ((__darwin_size_t)((char *)(uintptr_t)(p) + __DARWIN_ALIGNBYTES) &~ __DARWIN_ALIGNBYTES) 1.1109 +#endif 1.1110 + 1.1111 +#if !defined(__DARWIN_ALIGNBYTES32) 1.1112 +#define __DARWIN_ALIGNBYTES32 (sizeof(__uint32_t) - 1) 1.1113 +#endif 1.1114 + 1.1115 +#if !defined(__DARWIN_ALIGN32) 1.1116 +#define __DARWIN_ALIGN32(p) ((__darwin_size_t)((char *)(uintptr_t)(p) + __DARWIN_ALIGNBYTES32) &~ __DARWIN_ALIGNBYTES32) 1.1117 +#endif 1.1118 +#define CMSG_ALIGN(n) __DARWIN_ALIGN32(n) 1.1119 +#endif 1.1120 +#define I_AM_HERE \ 1.1121 + do { \ 1.1122 + SCTP_PRINTF("%s:%d at %s\n", __FILE__, __LINE__ , __FUNCTION__); \ 1.1123 + } while (0) 1.1124 + 1.1125 +#ifndef timevalsub 1.1126 +#define timevalsub(tp1, tp2) \ 1.1127 + do { \ 1.1128 + (tp1)->tv_sec -= (tp2)->tv_sec; \ 1.1129 + (tp1)->tv_usec -= (tp2)->tv_usec; \ 1.1130 + if ((tp1)->tv_usec < 0) { \ 1.1131 + (tp1)->tv_sec--; \ 1.1132 + (tp1)->tv_usec += 1000000; \ 1.1133 + } \ 1.1134 + } while (0) 1.1135 +#endif 1.1136 + 1.1137 +#if defined(__Userspace_os_Linux) 1.1138 +#if !defined(TAILQ_FOREACH_SAFE) 1.1139 +#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ 1.1140 + for ((var) = ((head)->tqh_first); \ 1.1141 + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ 1.1142 + (var) = (tvar)) 1.1143 +#endif 1.1144 +#if !defined(LIST_FOREACH_SAFE) 1.1145 +#define LIST_FOREACH_SAFE(var, head, field, tvar) \ 1.1146 + for ((var) = ((head)->lh_first); \ 1.1147 + (var) && ((tvar) = LIST_NEXT((var), field), 1); \ 1.1148 + (var) = (tvar)) 1.1149 +#endif 1.1150 +#endif 1.1151 +#if defined(__Userspace_os_DragonFly) 1.1152 +#define TAILQ_FOREACH_SAFE TAILQ_FOREACH_MUTABLE 1.1153 +#define LIST_FOREACH_SAFE LIST_FOREACH_MUTABLE 1.1154 +#endif 1.1155 +#endif