netwerk/sctp/src/netinet/sctp_os_userspace.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rwxr-xr-x

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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

mercurial