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