tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

sctp_bsd_addr.c (28078B)


      1 /*-
      2 * SPDX-License-Identifier: BSD-3-Clause
      3 *
      4 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
      5 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
      6 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
      7 *
      8 * Redistribution and use in source and binary forms, with or without
      9 * modification, are permitted provided that the following conditions are met:
     10 *
     11 * a) Redistributions of source code must retain the above copyright notice,
     12 *    this list of conditions and the following disclaimer.
     13 *
     14 * b) Redistributions in binary form must reproduce the above copyright
     15 *    notice, this list of conditions and the following disclaimer in
     16 *    the documentation and/or other materials provided with the distribution.
     17 *
     18 * c) Neither the name of Cisco Systems, Inc. nor the names of its
     19 *    contributors may be used to endorse or promote products derived
     20 *    from this software without specific prior written permission.
     21 *
     22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     24 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     32 * THE POSSIBILITY OF SUCH DAMAGE.
     33 */
     34 
     35 #include <netinet/sctp_os.h>
     36 #include <netinet/sctp_var.h>
     37 #include <netinet/sctp_pcb.h>
     38 #include <netinet/sctp_header.h>
     39 #include <netinet/sctputil.h>
     40 #include <netinet/sctp_output.h>
     41 #include <netinet/sctp_bsd_addr.h>
     42 #include <netinet/sctp_uio.h>
     43 #include <netinet/sctputil.h>
     44 #include <netinet/sctp_timer.h>
     45 #include <netinet/sctp_asconf.h>
     46 #include <netinet/sctp_sysctl.h>
     47 #include <netinet/sctp_indata.h>
     48 #if defined(__FreeBSD__) && !defined(__Userspace__)
     49 #include <sys/unistd.h>
     50 #endif
     51 
     52 /* Declare all of our malloc named types */
     53 MALLOC_DEFINE(SCTP_M_MAP, "sctp_map", "sctp asoc map descriptor");
     54 MALLOC_DEFINE(SCTP_M_STRMI, "sctp_stri", "sctp stream in array");
     55 MALLOC_DEFINE(SCTP_M_STRMO, "sctp_stro", "sctp stream out array");
     56 MALLOC_DEFINE(SCTP_M_ASC_ADDR, "sctp_aadr", "sctp asconf address");
     57 MALLOC_DEFINE(SCTP_M_ASC_IT, "sctp_a_it", "sctp asconf iterator");
     58 MALLOC_DEFINE(SCTP_M_AUTH_CL, "sctp_atcl", "sctp auth chunklist");
     59 MALLOC_DEFINE(SCTP_M_AUTH_KY, "sctp_atky", "sctp auth key");
     60 MALLOC_DEFINE(SCTP_M_AUTH_HL, "sctp_athm", "sctp auth hmac list");
     61 MALLOC_DEFINE(SCTP_M_AUTH_IF, "sctp_athi", "sctp auth info");
     62 MALLOC_DEFINE(SCTP_M_STRESET, "sctp_stre", "sctp stream reset");
     63 MALLOC_DEFINE(SCTP_M_CMSG, "sctp_cmsg", "sctp CMSG buffer");
     64 MALLOC_DEFINE(SCTP_M_COPYAL, "sctp_cpal", "sctp copy all");
     65 MALLOC_DEFINE(SCTP_M_VRF, "sctp_vrf", "sctp vrf struct");
     66 MALLOC_DEFINE(SCTP_M_IFA, "sctp_ifa", "sctp ifa struct");
     67 MALLOC_DEFINE(SCTP_M_IFN, "sctp_ifn", "sctp ifn struct");
     68 MALLOC_DEFINE(SCTP_M_TIMW, "sctp_timw", "sctp time block");
     69 MALLOC_DEFINE(SCTP_M_MVRF, "sctp_mvrf", "sctp mvrf pcb list");
     70 MALLOC_DEFINE(SCTP_M_ITER, "sctp_iter", "sctp iterator control");
     71 MALLOC_DEFINE(SCTP_M_SOCKOPT, "sctp_socko", "sctp socket option");
     72 MALLOC_DEFINE(SCTP_M_MCORE, "sctp_mcore", "sctp mcore queue");
     73 
     74 /* Global NON-VNET structure that controls the iterator */
     75 struct iterator_control sctp_it_ctl;
     76 #if !(defined(__FreeBSD__) && !defined(__Userspace__))
     77 
     78 static void
     79 sctp_cleanup_itqueue(void)
     80 {
     81 struct sctp_iterator *it, *nit;
     82 
     83 TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) {
     84 	if (it->function_atend != NULL) {
     85 		(*it->function_atend) (it->pointer, it->val);
     86 	}
     87 	TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
     88 	SCTP_FREE(it, SCTP_M_ITER);
     89 }
     90 }
     91 #endif
     92 #if defined(__Userspace__)
     93 /*__Userspace__ TODO if we use thread based iterator
     94 * then the implementation of wakeup will need to change.
     95 * Currently we are using timeo_cond for ident so_timeo
     96 * but that is not sufficient if we need to use another ident
     97 * like wakeup(&sctppcbinfo.iterator_running);
     98 */
     99 #endif
    100 
    101 void
    102 sctp_wakeup_iterator(void)
    103 {
    104 #if defined(SCTP_PROCESS_LEVEL_LOCKS)
    105 #if defined(_WIN32)
    106 WakeAllConditionVariable(&sctp_it_ctl.iterator_wakeup);
    107 #else
    108 pthread_cond_broadcast(&sctp_it_ctl.iterator_wakeup);
    109 #endif
    110 #else
    111 wakeup(&sctp_it_ctl.iterator_running);
    112 #endif
    113 }
    114 
    115 #if defined(__Userspace__)
    116 static void *
    117 #else
    118 static void
    119 #endif
    120 sctp_iterator_thread(void *v SCTP_UNUSED)
    121 {
    122 #if defined(__Userspace__)
    123 sctp_userspace_set_threadname("SCTP iterator");
    124 #endif
    125 SCTP_IPI_ITERATOR_WQ_LOCK();
    126 /* In FreeBSD this thread never terminates. */
    127 #if defined(__FreeBSD__) && !defined(__Userspace__)
    128 for (;;) {
    129 #else
    130 while ((sctp_it_ctl.iterator_flags & SCTP_ITERATOR_MUST_EXIT) == 0) {
    131 #endif
    132 #if !defined(__Userspace__)
    133 	msleep(&sctp_it_ctl.iterator_running,
    134 #if defined(__FreeBSD__)
    135 	       &sctp_it_ctl.ipi_iterator_wq_mtx,
    136 #elif defined(__APPLE__)
    137 	       sctp_it_ctl.ipi_iterator_wq_mtx,
    138 #endif
    139 	       0, "waiting_for_work", 0);
    140 #else
    141 #if defined(_WIN32)
    142 	SleepConditionVariableCS(&sctp_it_ctl.iterator_wakeup, &sctp_it_ctl.ipi_iterator_wq_mtx, INFINITE);
    143 #else
    144 	pthread_cond_wait(&sctp_it_ctl.iterator_wakeup, &sctp_it_ctl.ipi_iterator_wq_mtx);
    145 #endif
    146 #endif
    147 #if !(defined(__FreeBSD__) && !defined(__Userspace__))
    148 	if (sctp_it_ctl.iterator_flags & SCTP_ITERATOR_MUST_EXIT) {
    149 		break;
    150 	}
    151 #endif
    152 	sctp_iterator_worker();
    153 }
    154 #if !(defined(__FreeBSD__) && !defined(__Userspace__))
    155 /* Now this thread needs to be terminated */
    156 sctp_cleanup_itqueue();
    157 sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_EXITED;
    158 SCTP_IPI_ITERATOR_WQ_UNLOCK();
    159 #if defined(__Userspace__)
    160 sctp_wakeup_iterator();
    161 return (NULL);
    162 #else
    163 wakeup(&sctp_it_ctl.iterator_flags);
    164 thread_terminate(current_thread());
    165 #ifdef INVARIANTS
    166 panic("Hmm. thread_terminate() continues...");
    167 #endif
    168 #endif
    169 #endif
    170 }
    171 
    172 void
    173 sctp_startup_iterator(void)
    174 {
    175 if (sctp_it_ctl.thread_proc) {
    176 	/* You only get one */
    177 	return;
    178 }
    179 /* Initialize global locks here, thus only once. */
    180 SCTP_ITERATOR_LOCK_INIT();
    181 SCTP_IPI_ITERATOR_WQ_INIT();
    182 TAILQ_INIT(&sctp_it_ctl.iteratorhead);
    183 #if defined(__Userspace__)
    184 if (sctp_userspace_thread_create(&sctp_it_ctl.thread_proc, &sctp_iterator_thread)) {
    185 	SCTP_PRINTF("ERROR: Creating sctp_iterator_thread failed.\n");
    186 } else {
    187 	SCTP_BASE_VAR(iterator_thread_started) = 1;
    188 }
    189 #elif defined(__FreeBSD__)
    190 kproc_create(sctp_iterator_thread,
    191              (void *)NULL,
    192              &sctp_it_ctl.thread_proc,
    193              0,
    194              SCTP_KTHREAD_PAGES,
    195              SCTP_KTRHEAD_NAME);
    196 #elif defined(__APPLE__)
    197 kernel_thread_start((thread_continue_t)sctp_iterator_thread, NULL, &sctp_it_ctl.thread_proc);
    198 #endif
    199 }
    200 
    201 #ifdef INET6
    202 
    203 #if defined(__Userspace__)
    204 /* __Userspace__ TODO. struct in6_ifaddr is defined in sys/netinet6/in6_var.h
    205   ip6_use_deprecated is defined as  int ip6_use_deprecated = 1; in /src/sys/netinet6/in6_proto.c
    206 */
    207 void
    208 sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa)
    209 {
    210    return; /* stub */
    211 }
    212 #else
    213 void
    214 sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa)
    215 {
    216 struct in6_ifaddr *ifa6;
    217 
    218 ifa6 = (struct in6_ifaddr *)ifa->ifa;
    219 ifa->flags = ifa6->ia6_flags;
    220 if (!MODULE_GLOBAL(ip6_use_deprecated)) {
    221 	if (ifa->flags &
    222 	    IN6_IFF_DEPRECATED) {
    223 		ifa->localifa_flags |= SCTP_ADDR_IFA_UNUSEABLE;
    224 	} else {
    225 		ifa->localifa_flags &= ~SCTP_ADDR_IFA_UNUSEABLE;
    226 	}
    227 } else {
    228 	ifa->localifa_flags &= ~SCTP_ADDR_IFA_UNUSEABLE;
    229 }
    230 if (ifa->flags &
    231     (IN6_IFF_DETACHED |
    232      IN6_IFF_ANYCAST |
    233      IN6_IFF_NOTREADY)) {
    234 	ifa->localifa_flags |= SCTP_ADDR_IFA_UNUSEABLE;
    235 } else {
    236 	ifa->localifa_flags &= ~SCTP_ADDR_IFA_UNUSEABLE;
    237 }
    238 }
    239 #endif /* __Userspace__ */
    240 #endif /* INET6 */
    241 
    242 #if !defined(__Userspace__)
    243 static uint32_t
    244 sctp_is_desired_interface_type(struct ifnet *ifn)
    245 {
    246 int result;
    247 
    248 /* check the interface type to see if it's one we care about */
    249 #if defined(__APPLE__) && !defined(__Userspace__)
    250 switch(ifnet_type(ifn)) {
    251 #else
    252 switch (ifn->if_type) {
    253 #endif
    254 case IFT_ETHER:
    255 case IFT_ISO88023:
    256 case IFT_ISO88024:
    257 case IFT_ISO88025:
    258 case IFT_ISO88026:
    259 case IFT_STARLAN:
    260 case IFT_P10:
    261 case IFT_P80:
    262 case IFT_HY:
    263 case IFT_FDDI:
    264 case IFT_XETHER:
    265 case IFT_ISDNBASIC:
    266 case IFT_ISDNPRIMARY:
    267 case IFT_PTPSERIAL:
    268 case IFT_OTHER:
    269 case IFT_PPP:
    270 case IFT_LOOP:
    271 case IFT_SLIP:
    272 case IFT_GIF:
    273 case IFT_L2VLAN:
    274 case IFT_STF:
    275 #if !(defined(__APPLE__) && !defined(__Userspace__))
    276 case IFT_IP:
    277 case IFT_IPOVERCDLC:
    278 case IFT_IPOVERCLAW:
    279 case IFT_PROPVIRTUAL: /* NetGraph Virtual too */
    280 case IFT_VIRTUALIPADDRESS:
    281 #endif
    282 	result = 1;
    283 	break;
    284 default:
    285 	result = 0;
    286 }
    287 
    288 return (result);
    289 }
    290 #endif
    291 #if defined(__APPLE__) && !defined(__Userspace__)
    292 
    293 int
    294 sctp_is_vmware_interface(struct ifnet *ifn)
    295 {
    296 return (strncmp(ifnet_name(ifn), "vmnet", 5) == 0);
    297 }
    298 
    299 #endif
    300 
    301 #if defined(_WIN32) && defined(__Userspace__)
    302 #ifdef MALLOC
    303 #undef MALLOC
    304 #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
    305 #endif
    306 #ifdef FREE
    307 #undef FREE
    308 #define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
    309 #endif
    310 static void
    311 sctp_init_ifns_for_vrf(int vrfid)
    312 {
    313 #if defined(INET) || defined(INET6)
    314 struct sctp_ifa *sctp_ifa;
    315 DWORD Err, AdapterAddrsSize;
    316 PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt;
    317 PIP_ADAPTER_UNICAST_ADDRESS pUnicast;
    318 #endif
    319 
    320 #ifdef INET
    321 AdapterAddrsSize = 0;
    322 
    323 if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, NULL, &AdapterAddrsSize)) != 0) {
    324 	if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) {
    325 		SCTP_PRINTF("GetAdaptersV4Addresses() sizing failed with error code %d\n", Err);
    326 		SCTP_PRINTF("err = %d; AdapterAddrsSize = %d\n", Err, AdapterAddrsSize);
    327 		return;
    328 	}
    329 }
    330 
    331 /* Allocate memory from sizing information */
    332 if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) {
    333 	SCTP_PRINTF("Memory allocation error!\n");
    334 	return;
    335 }
    336 /* Get actual adapter information */
    337 if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) {
    338 	SCTP_PRINTF("GetAdaptersV4Addresses() failed with error code %d\n", Err);
    339 	FREE(pAdapterAddrs);
    340 	return;
    341 }
    342 /* Enumerate through each returned adapter and save its information */
    343 for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) {
    344 	if (pAdapt->IfType == IF_TYPE_IEEE80211 || pAdapt->IfType == IF_TYPE_ETHERNET_CSMACD) {
    345 		for (pUnicast = pAdapt->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
    346 			if (IN4_ISLINKLOCAL_ADDRESS(&(((struct sockaddr_in *)(pUnicast->Address.lpSockaddr))->sin_addr))) {
    347 				continue;
    348 			}
    349 			sctp_ifa = sctp_add_addr_to_vrf(0,
    350 			                                NULL,
    351 			                                pAdapt->IfIndex,
    352 			                                (pAdapt->IfType == IF_TYPE_IEEE80211)?MIB_IF_TYPE_ETHERNET:pAdapt->IfType,
    353 			                                pAdapt->AdapterName,
    354 			                                NULL,
    355 			                                pUnicast->Address.lpSockaddr,
    356 			                                pAdapt->Flags,
    357 			                                0);
    358 			if (sctp_ifa) {
    359 				sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
    360 			}
    361 		}
    362 	}
    363 }
    364 FREE(pAdapterAddrs);
    365 #endif
    366 #ifdef INET6
    367 AdapterAddrsSize = 0;
    368 
    369 if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, NULL, &AdapterAddrsSize)) != 0) {
    370 	if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) {
    371 		SCTP_PRINTF("GetAdaptersV6Addresses() sizing failed with error code %d\n", Err);
    372 		SCTP_PRINTF("err = %d; AdapterAddrsSize = %d\n", Err, AdapterAddrsSize);
    373 		return;
    374 	}
    375 }
    376 /* Allocate memory from sizing information */
    377 if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) {
    378 	SCTP_PRINTF("Memory allocation error!\n");
    379 	return;
    380 }
    381 /* Get actual adapter information */
    382 if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) {
    383 	SCTP_PRINTF("GetAdaptersV6Addresses() failed with error code %d\n", Err);
    384 	FREE(pAdapterAddrs);
    385 	return;
    386 }
    387 /* Enumerate through each returned adapter and save its information */
    388 for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) {
    389 	if (pAdapt->IfType == IF_TYPE_IEEE80211 || pAdapt->IfType == IF_TYPE_ETHERNET_CSMACD) {
    390 		for (pUnicast = pAdapt->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
    391 			sctp_ifa = sctp_add_addr_to_vrf(0,
    392 			                                NULL,
    393 			                                pAdapt->Ipv6IfIndex,
    394 			                                (pAdapt->IfType == IF_TYPE_IEEE80211)?MIB_IF_TYPE_ETHERNET:pAdapt->IfType,
    395 			                                pAdapt->AdapterName,
    396 			                                NULL,
    397 			                                pUnicast->Address.lpSockaddr,
    398 			                                pAdapt->Flags,
    399 			                                0);
    400 			if (sctp_ifa) {
    401 				sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
    402 			}
    403 		}
    404 	}
    405 }
    406 FREE(pAdapterAddrs);
    407 #endif
    408 }
    409 #elif defined(__Userspace__)
    410 static void
    411 sctp_init_ifns_for_vrf(int vrfid)
    412 {
    413 #if defined(INET) || defined(INET6)
    414 int rc;
    415 struct ifaddrs *ifa, *ifas;
    416 struct sctp_ifa *sctp_ifa;
    417 uint32_t ifa_flags;
    418 
    419 rc = getifaddrs(&ifas);
    420 if (rc != 0) {
    421 	return;
    422 }
    423 for (ifa = ifas; ifa; ifa = ifa->ifa_next) {
    424 	if (ifa->ifa_addr == NULL) {
    425 		continue;
    426 	}
    427 #if !defined(INET)
    428 	if (ifa->ifa_addr->sa_family != AF_INET6) {
    429 		/* non inet6 skip */
    430 		continue;
    431 	}
    432 #elif !defined(INET6)
    433 	if (ifa->ifa_addr->sa_family != AF_INET) {
    434 		/* non inet skip */
    435 		continue;
    436 	}
    437 #else
    438 	if ((ifa->ifa_addr->sa_family != AF_INET) && (ifa->ifa_addr->sa_family != AF_INET6)) {
    439 		/* non inet/inet6 skip */
    440 		continue;
    441 	}
    442 #endif
    443 #if defined(INET6)
    444 	if ((ifa->ifa_addr->sa_family == AF_INET6) &&
    445 	    IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
    446 		/* skip unspecified addresses */
    447 		continue;
    448 	}
    449 #endif
    450 #if defined(INET)
    451 	if (ifa->ifa_addr->sa_family == AF_INET &&
    452 	    ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) {
    453 		continue;
    454 	}
    455 #endif
    456 	ifa_flags = 0;
    457 	sctp_ifa = sctp_add_addr_to_vrf(vrfid,
    458 	                                NULL,
    459 	                                if_nametoindex(ifa->ifa_name),
    460 	                                0,
    461 	                                ifa->ifa_name,
    462 	                                NULL,
    463 	                                ifa->ifa_addr,
    464 	                                ifa_flags,
    465 	                                0);
    466 	if (sctp_ifa) {
    467 		sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
    468 	}
    469 }
    470 freeifaddrs(ifas);
    471 #endif
    472 }
    473 #endif
    474 #if defined(__APPLE__) && !defined(__Userspace__)
    475 static void
    476 sctp_init_ifns_for_vrf(int vrfid)
    477 {
    478 /* Here we must apply ANY locks needed by the
    479  * IFN we access and also make sure we lock
    480  * any IFA that exists as we float through the
    481  * list of IFA's
    482  */
    483 struct ifnet **ifnetlist;
    484 uint32_t i, j, count;
    485 char name[SCTP_IFNAMSIZ];
    486 struct ifnet *ifn;
    487 struct ifaddr **ifaddrlist;
    488 struct ifaddr *ifa;
    489 struct in6_ifaddr *ifa6;
    490 struct sctp_ifa *sctp_ifa;
    491 uint32_t ifa_flags;
    492 
    493 if (ifnet_list_get(IFNET_FAMILY_ANY, &ifnetlist, &count) != 0) {
    494 	return;
    495 }
    496 for (i = 0; i < count; i++) {
    497 	ifn = ifnetlist[i];
    498 	if (SCTP_BASE_SYSCTL(sctp_ignore_vmware_interfaces) && sctp_is_vmware_interface(ifn)) {
    499 		continue;
    500 	}
    501 	if (sctp_is_desired_interface_type(ifn) == 0) {
    502 		/* non desired type */
    503 		continue;
    504 	}
    505 	if (ifnet_get_address_list(ifn, &ifaddrlist) != 0) {
    506 		continue;
    507 	}
    508 	for (j = 0; ifaddrlist[j] != NULL; j++) {
    509 		ifa = ifaddrlist[j];
    510 		if (ifa->ifa_addr == NULL) {
    511 			continue;
    512 		}
    513 		if ((ifa->ifa_addr->sa_family != AF_INET) && (ifa->ifa_addr->sa_family != AF_INET6)) {
    514 			/* non inet/inet6 skip */
    515 			continue;
    516 		}
    517 		if (ifa->ifa_addr->sa_family == AF_INET6) {
    518 			if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
    519 				/* skip unspecified addresses */
    520 				continue;
    521 			}
    522 		} else {
    523 			if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == INADDR_ANY) {
    524 				continue;
    525 			}
    526 		}
    527 		if (ifa->ifa_addr->sa_family == AF_INET6) {
    528 			ifa6 = (struct in6_ifaddr *)ifa;
    529 			ifa_flags = ifa6->ia6_flags;
    530 		} else {
    531 			ifa_flags = 0;
    532 		}
    533 		SCTP_SNPRINTF(name, SCTP_IFNAMSIZ, "%s%d", ifnet_name(ifn), ifnet_unit(ifn));
    534 		sctp_ifa = sctp_add_addr_to_vrf(vrfid,
    535 		                                (void *)ifn, /* XXX */
    536 		                                ifnet_index(ifn),
    537 		                                ifnet_type(ifn),
    538 		                                name,
    539 		                                (void *)ifa, /* XXX */
    540 		                                ifa->ifa_addr,
    541 		                                ifa_flags,
    542 		                                0);
    543 		if (sctp_ifa) {
    544 			sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
    545 		}
    546 	}
    547 	ifnet_free_address_list(ifaddrlist);
    548 }
    549 ifnet_list_free(ifnetlist);
    550 }
    551 #endif
    552 #if defined(__FreeBSD__) && !defined(__Userspace__)
    553 static void
    554 sctp_init_ifns_for_vrf(int vrfid)
    555 {
    556 /* Here we must apply ANY locks needed by the
    557  * IFN we access and also make sure we lock
    558  * any IFA that exists as we float through the
    559  * list of IFA's
    560  */
    561 struct epoch_tracker et;
    562 struct ifnet *ifn;
    563 struct ifaddr *ifa;
    564 struct sctp_ifa *sctp_ifa;
    565 uint32_t ifa_flags;
    566 #ifdef INET6
    567 struct in6_ifaddr *ifa6;
    568 #endif
    569 
    570 IFNET_RLOCK();
    571 NET_EPOCH_ENTER(et);
    572 CK_STAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_link) {
    573 	if (sctp_is_desired_interface_type(ifn) == 0) {
    574 		/* non desired type */
    575 		continue;
    576 	}
    577 	CK_STAILQ_FOREACH(ifa, &ifn->if_addrhead, ifa_link) {
    578 		if (ifa->ifa_addr == NULL) {
    579 			continue;
    580 		}
    581 		switch (ifa->ifa_addr->sa_family) {
    582 #ifdef INET
    583 		case AF_INET:
    584 			if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) {
    585 				continue;
    586 			}
    587 			break;
    588 #endif
    589 #ifdef INET6
    590 		case AF_INET6:
    591 			if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
    592 				/* skip unspecified addresses */
    593 				continue;
    594 			}
    595 			break;
    596 #endif
    597 		default:
    598 			continue;
    599 		}
    600 		switch (ifa->ifa_addr->sa_family) {
    601 #ifdef INET
    602 		case AF_INET:
    603 			ifa_flags = 0;
    604 			break;
    605 #endif
    606 #ifdef INET6
    607 		case AF_INET6:
    608 			ifa6 = (struct in6_ifaddr *)ifa;
    609 			ifa_flags = ifa6->ia6_flags;
    610 			break;
    611 #endif
    612 		default:
    613 			ifa_flags = 0;
    614 			break;
    615 		}
    616 		sctp_ifa = sctp_add_addr_to_vrf(vrfid,
    617 		                                (void *)ifn,
    618 		                                ifn->if_index,
    619 		                                ifn->if_type,
    620 		                                ifn->if_xname,
    621 		                                (void *)ifa,
    622 		                                ifa->ifa_addr,
    623 		                                ifa_flags,
    624 		                                0);
    625 		if (sctp_ifa) {
    626 			sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
    627 		}
    628 	}
    629 }
    630 NET_EPOCH_EXIT(et);
    631 IFNET_RUNLOCK();
    632 }
    633 #endif
    634 
    635 void
    636 sctp_init_vrf_list(int vrfid)
    637 {
    638 if (vrfid > SCTP_MAX_VRF_ID)
    639 	/* can't do that */
    640 	return;
    641 
    642 /* Don't care about return here */
    643 (void)sctp_allocate_vrf(vrfid);
    644 
    645 /* Now we need to build all the ifn's
    646  * for this vrf and there addresses
    647  */
    648 sctp_init_ifns_for_vrf(vrfid);
    649 }
    650 
    651 void
    652 sctp_addr_change(struct ifaddr *ifa, int cmd)
    653 {
    654 #if defined(__Userspace__)
    655        return;
    656 #else
    657 uint32_t ifa_flags = 0;
    658 
    659 if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) {
    660 	return;
    661 }
    662 /* BSD only has one VRF, if this changes
    663  * we will need to hook in the right
    664  * things here to get the id to pass to
    665  * the address management routine.
    666  */
    667 if (SCTP_BASE_VAR(first_time) == 0) {
    668 	/* Special test to see if my ::1 will showup with this */
    669 	SCTP_BASE_VAR(first_time) = 1;
    670 	sctp_init_ifns_for_vrf(SCTP_DEFAULT_VRFID);
    671 }
    672 
    673 if ((cmd != RTM_ADD) && (cmd != RTM_DELETE)) {
    674 	/* don't know what to do with this */
    675 	return;
    676 }
    677 
    678 if (ifa->ifa_addr == NULL) {
    679 	return;
    680 }
    681 if (sctp_is_desired_interface_type(ifa->ifa_ifp) == 0) {
    682 	/* non desired type */
    683 	return;
    684 }
    685 switch (ifa->ifa_addr->sa_family) {
    686 #ifdef INET
    687 case AF_INET:
    688 	if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) {
    689 		return;
    690 	}
    691 	break;
    692 #endif
    693 #ifdef INET6
    694 case AF_INET6:
    695 	ifa_flags = ((struct in6_ifaddr *)ifa)->ia6_flags;
    696 	if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
    697 		/* skip unspecified addresses */
    698 		return;
    699 	}
    700 	break;
    701 #endif
    702 default:
    703 	/* non inet/inet6 skip */
    704 	return;
    705 }
    706 if (cmd == RTM_ADD) {
    707 	(void)sctp_add_addr_to_vrf(SCTP_DEFAULT_VRFID, (void *)ifa->ifa_ifp,
    708 #if defined(__APPLE__) && !defined(__Userspace__)
    709 	                           ifnet_index(ifa->ifa_ifp), ifnet_type(ifa->ifa_ifp), ifnet_name(ifa->ifa_ifp),
    710 #else
    711 	                           ifa->ifa_ifp->if_index, ifa->ifa_ifp->if_type, ifa->ifa_ifp->if_xname,
    712 #endif
    713 	                           (void *)ifa, ifa->ifa_addr, ifa_flags, 1);
    714 } else {
    715 	sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr,
    716 #if defined(__APPLE__) && !defined(__Userspace__)
    717 	                       ifnet_index(ifa->ifa_ifp),
    718 	                       ifnet_name(ifa->ifa_ifp));
    719 #else
    720 	                       ifa->ifa_ifp->if_index,
    721 	                       ifa->ifa_ifp->if_xname);
    722 #endif
    723 
    724 	/* We don't bump refcount here so when it completes
    725 	 * the final delete will happen.
    726 	 */
    727 }
    728 #endif
    729 }
    730 
    731 #if defined(__FreeBSD__) && !defined(__Userspace__)
    732 void
    733 sctp_addr_change_event_handler(void *arg __unused, struct ifaddr *ifa, int cmd) {
    734 sctp_addr_change(ifa, cmd);
    735 }
    736 #endif
    737 #if defined(__APPLE__) && !defined(__Userspace__)
    738 void
    739 sctp_add_or_del_interfaces(int (*pred)(struct ifnet *), int add)
    740 {
    741 struct ifnet **ifnetlist;
    742 struct ifaddr **ifaddrlist;
    743 uint32_t i, j, count;
    744 
    745 if (ifnet_list_get(IFNET_FAMILY_ANY, &ifnetlist, &count) != 0) {
    746 	return;
    747 }
    748 for (i = 0; i < count; i++) {
    749 	if (!(*pred)(ifnetlist[i])) {
    750 		continue;
    751 	}
    752 	if (ifnet_get_address_list(ifnetlist[i], &ifaddrlist) != 0) {
    753 		continue;
    754 	}
    755 	for (j = 0; ifaddrlist[j] != NULL; j++) {
    756 		sctp_addr_change(ifaddrlist[j], add ? RTM_ADD : RTM_DELETE);
    757 	}
    758 	ifnet_free_address_list(ifaddrlist);
    759 }
    760 ifnet_list_free(ifnetlist);
    761 return;
    762 }
    763 #endif
    764 
    765 struct mbuf *
    766 sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
    767 	      int how, int allonebuf, int type)
    768 {
    769 struct mbuf *m = NULL;
    770 #if defined(__FreeBSD__) || defined(__Userspace__)
    771 #if defined(__Userspace__)
    772 m = m_getm2(NULL, space_needed, how, type, want_header ? M_PKTHDR : 0, allonebuf);
    773 #else
    774 m = m_getm2(NULL, space_needed, how, type, want_header ? M_PKTHDR : 0);
    775 #endif
    776 if (m == NULL) {
    777 	/* bad, no memory */
    778 	return (m);
    779 }
    780 #if !defined(__Userspace__)
    781 if (allonebuf) {
    782 	if (SCTP_BUF_SIZE(m) < space_needed) {
    783 		m_freem(m);
    784 		return (NULL);
    785 	}
    786 	KASSERT(SCTP_BUF_NEXT(m) == NULL, ("%s: no chain allowed", __func__));
    787 }
    788 #endif
    789 #ifdef SCTP_MBUF_LOGGING
    790 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
    791 	sctp_log_mb(m, SCTP_MBUF_IALLOC);
    792 }
    793 #endif
    794 #else
    795 int mbuf_threshold;
    796 unsigned int size;
    797 
    798 if (want_header) {
    799 	MGETHDR(m, how, type);
    800 	size = MHLEN;
    801 } else {
    802 	MGET(m, how, type);
    803 	size = MLEN;
    804 }
    805 if (m == NULL) {
    806 	return (NULL);
    807 }
    808 if (allonebuf == 0) {
    809 	mbuf_threshold = SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count);
    810 } else {
    811 	mbuf_threshold = 1;
    812 }
    813 
    814 if (space_needed > (unsigned int)(((mbuf_threshold - 1) * MLEN) + MHLEN)) {
    815 	MCLGET(m, how);
    816 	if (m == NULL) {
    817 		return (NULL);
    818 	}
    819 	if (SCTP_BUF_IS_EXTENDED(m) == 0) {
    820 		sctp_m_freem(m);
    821 		return (NULL);
    822 	}
    823 	size = SCTP_BUF_EXTEND_SIZE(m);
    824 }
    825 if (allonebuf != 0 && size < space_needed) {
    826 	m_freem(m);
    827 	return (NULL);
    828 }
    829 SCTP_BUF_LEN(m) = 0;
    830 SCTP_BUF_NEXT(m) = SCTP_BUF_NEXT_PKT(m) = NULL;
    831 #ifdef SCTP_MBUF_LOGGING
    832 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
    833 	sctp_log_mb(m, SCTP_MBUF_IALLOC);
    834 }
    835 #endif
    836 #endif
    837 return (m);
    838 }
    839 
    840 #ifdef SCTP_PACKET_LOGGING
    841 void
    842 sctp_packet_log(struct mbuf *m)
    843 {
    844 int *lenat, thisone;
    845 void *copyto;
    846 uint32_t *tick_tock;
    847 int length;
    848 int total_len;
    849 int grabbed_lock = 0;
    850 int value, newval, thisend, thisbegin;
    851 /*
    852  * Buffer layout.
    853  * -sizeof this entry (total_len)
    854  * -previous end      (value)
    855  * -ticks of log      (ticks)
    856  * o -ip packet
    857  * o -as logged
    858  * - where this started (thisbegin)
    859  * x <--end points here
    860  */
    861 length = SCTP_HEADER_LEN(m);
    862 total_len = SCTP_SIZE32((length + (4 * sizeof(int))));
    863 /* Log a packet to the buffer. */
    864 if (total_len> SCTP_PACKET_LOG_SIZE) {
    865 	/* Can't log this packet I have not a buffer big enough */
    866 	return;
    867 }
    868 if (length < (int)(SCTP_MIN_V4_OVERHEAD + sizeof(struct sctp_cookie_ack_chunk))) {
    869 	return;
    870 }
    871 atomic_add_int(&SCTP_BASE_VAR(packet_log_writers), 1);
    872 try_again:
    873 if (SCTP_BASE_VAR(packet_log_writers) > SCTP_PKTLOG_WRITERS_NEED_LOCK) {
    874 	SCTP_IP_PKTLOG_LOCK();
    875 	grabbed_lock = 1;
    876 again_locked:
    877 	value = SCTP_BASE_VAR(packet_log_end);
    878 	newval = SCTP_BASE_VAR(packet_log_end) + total_len;
    879 	if (newval >= SCTP_PACKET_LOG_SIZE) {
    880 		/* we wrapped */
    881 		thisbegin = 0;
    882 		thisend = total_len;
    883 	} else {
    884 		thisbegin = SCTP_BASE_VAR(packet_log_end);
    885 		thisend = newval;
    886 	}
    887 	if (!(atomic_cmpset_int(&SCTP_BASE_VAR(packet_log_end), value, thisend))) {
    888 		goto again_locked;
    889 	}
    890 } else {
    891 	value = SCTP_BASE_VAR(packet_log_end);
    892 	newval = SCTP_BASE_VAR(packet_log_end) + total_len;
    893 	if (newval >= SCTP_PACKET_LOG_SIZE) {
    894 		/* we wrapped */
    895 		thisbegin = 0;
    896 		thisend = total_len;
    897 	} else {
    898 		thisbegin = SCTP_BASE_VAR(packet_log_end);
    899 		thisend = newval;
    900 	}
    901 	if (!(atomic_cmpset_int(&SCTP_BASE_VAR(packet_log_end), value, thisend))) {
    902 		goto try_again;
    903 	}
    904 }
    905 /* Sanity check */
    906 if (thisend >= SCTP_PACKET_LOG_SIZE) {
    907 	SCTP_PRINTF("Insanity stops a log thisbegin:%d thisend:%d writers:%d lock:%d end:%d\n",
    908 	            thisbegin,
    909 	            thisend,
    910 	            SCTP_BASE_VAR(packet_log_writers),
    911 	            grabbed_lock,
    912 	            SCTP_BASE_VAR(packet_log_end));
    913 	SCTP_BASE_VAR(packet_log_end) = 0;
    914 	goto no_log;
    915 }
    916 lenat = (int *)&SCTP_BASE_VAR(packet_log_buffer)[thisbegin];
    917 *lenat = total_len;
    918 lenat++;
    919 *lenat = value;
    920 lenat++;
    921 tick_tock = (uint32_t *)lenat;
    922 lenat++;
    923 *tick_tock = sctp_get_tick_count();
    924 copyto = (void *)lenat;
    925 thisone = thisend - sizeof(int);
    926 lenat = (int *)&SCTP_BASE_VAR(packet_log_buffer)[thisone];
    927 *lenat = thisbegin;
    928 if (grabbed_lock) {
    929 	SCTP_IP_PKTLOG_UNLOCK();
    930 	grabbed_lock = 0;
    931 }
    932 m_copydata(m, 0, length, (caddr_t)copyto);
    933 no_log:
    934 if (grabbed_lock) {
    935 	SCTP_IP_PKTLOG_UNLOCK();
    936 }
    937 atomic_subtract_int(&SCTP_BASE_VAR(packet_log_writers), 1);
    938 }
    939 
    940 int
    941 sctp_copy_out_packet_log(uint8_t *target, int length)
    942 {
    943 /* We wind through the packet log starting at
    944  * start copying up to length bytes out.
    945  * We return the number of bytes copied.
    946  */
    947 int this_copy;
    948 int *lenat;
    949 int did_delay = 0;
    950 
    951 if (length < (int)(2 * sizeof(int))) {
    952 	/* not enough room */
    953 	return (0);
    954 }
    955 if (SCTP_PKTLOG_WRITERS_NEED_LOCK) {
    956 	atomic_add_int(&SCTP_BASE_VAR(packet_log_writers), SCTP_PKTLOG_WRITERS_NEED_LOCK);
    957 again:
    958 	if ((did_delay == 0) && (SCTP_BASE_VAR(packet_log_writers) != SCTP_PKTLOG_WRITERS_NEED_LOCK)) {
    959 		/* we delay here for just a moment hoping the writer(s) that were
    960 		 * present when we entered will have left and we only have
    961 		 * locking ones that will contend with us for the lock. This
    962 		 * does not assure 100% access, but its good enough for
    963 		 * a logging facility like this.
    964 		 */
    965 		did_delay = 1;
    966 		DELAY(10);
    967 		goto again;
    968 	}
    969 }
    970 SCTP_IP_PKTLOG_LOCK();
    971 lenat = (int *)target;
    972 *lenat = SCTP_BASE_VAR(packet_log_end);
    973 lenat++;
    974 this_copy = min((length - sizeof(int)), SCTP_PACKET_LOG_SIZE);
    975 memcpy((void *)lenat, (void *)SCTP_BASE_VAR(packet_log_buffer), this_copy);
    976 if (SCTP_PKTLOG_WRITERS_NEED_LOCK) {
    977 	atomic_subtract_int(&SCTP_BASE_VAR(packet_log_writers),
    978 	                    SCTP_PKTLOG_WRITERS_NEED_LOCK);
    979 }
    980 SCTP_IP_PKTLOG_UNLOCK();
    981 return (this_copy + sizeof(int));
    982 }
    983 
    984 #endif