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