Coverage Report

Created: 2025-07-11 06:39

/src/usrsctp/usrsctplib/netinet/sctp_bsd_addr.c
Line
Count
Source (jump to first uncovered line)
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
0
{
81
0
  struct sctp_iterator *it, *nit;
82
83
0
  TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) {
84
0
    if (it->function_atend != NULL) {
85
0
      (*it->function_atend) (it->pointer, it->val);
86
0
    }
87
0
    TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
88
0
    SCTP_FREE(it, SCTP_M_ITER);
89
0
  }
90
0
}
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
0
{
104
0
#if defined(SCTP_PROCESS_LEVEL_LOCKS)
105
#if defined(_WIN32)
106
  WakeAllConditionVariable(&sctp_it_ctl.iterator_wakeup);
107
#else
108
0
  pthread_cond_broadcast(&sctp_it_ctl.iterator_wakeup);
109
0
#endif
110
#else
111
  wakeup(&sctp_it_ctl.iterator_running);
112
#endif
113
0
}
114
115
#if defined(__Userspace__)
116
static void *
117
#else
118
static void
119
#endif
120
sctp_iterator_thread(void *v SCTP_UNUSED)
121
3
{
122
3
#if defined(__Userspace__)
123
3
  sctp_userspace_set_threadname("SCTP iterator");
124
3
#endif
125
3
  SCTP_IPI_ITERATOR_WQ_LOCK();
126
  /* In FreeBSD this thread never terminates. */
127
#if defined(__FreeBSD__) && !defined(__Userspace__)
128
  for (;;) {
129
#else
130
6
  while ((sctp_it_ctl.iterator_flags & SCTP_ITERATOR_MUST_EXIT) == 0) {
131
3
#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
3
    pthread_cond_wait(&sctp_it_ctl.iterator_wakeup, &sctp_it_ctl.ipi_iterator_wq_mtx);
145
3
#endif
146
3
#endif
147
3
#if !(defined(__FreeBSD__) && !defined(__Userspace__))
148
3
    if (sctp_it_ctl.iterator_flags & SCTP_ITERATOR_MUST_EXIT) {
149
0
      break;
150
0
    }
151
3
#endif
152
3
    sctp_iterator_worker();
153
3
  }
154
3
#if !(defined(__FreeBSD__) && !defined(__Userspace__))
155
  /* Now this thread needs to be terminated */
156
3
  sctp_cleanup_itqueue();
157
3
  sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_EXITED;
158
3
  SCTP_IPI_ITERATOR_WQ_UNLOCK();
159
3
#if defined(__Userspace__)
160
3
  sctp_wakeup_iterator();
161
3
  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
3
#endif
170
3
}
171
172
void
173
sctp_startup_iterator(void)
174
3
{
175
3
  if (sctp_it_ctl.thread_proc) {
176
    /* You only get one */
177
0
    return;
178
0
  }
179
  /* Initialize global locks here, thus only once. */
180
3
  SCTP_ITERATOR_LOCK_INIT();
181
3
  SCTP_IPI_ITERATOR_WQ_INIT();
182
3
  TAILQ_INIT(&sctp_it_ctl.iteratorhead);
183
3
#if defined(__Userspace__)
184
3
  if (sctp_userspace_thread_create(&sctp_it_ctl.thread_proc, &sctp_iterator_thread)) {
185
0
    SCTP_PRINTF("ERROR: Creating sctp_iterator_thread failed.\n");
186
3
  } else {
187
3
    SCTP_BASE_VAR(iterator_thread_started) = 1;
188
3
  }
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
3
}
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
0
{
210
0
    return; /* stub */
211
0
}
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
3
{
413
3
#if defined(INET) || defined(INET6)
414
3
  int rc;
415
3
  struct ifaddrs *ifa, *ifas;
416
3
  struct sctp_ifa *sctp_ifa;
417
3
  uint32_t ifa_flags;
418
419
3
  rc = getifaddrs(&ifas);
420
3
  if (rc != 0) {
421
0
    return;
422
0
  }
423
15
  for (ifa = ifas; ifa; ifa = ifa->ifa_next) {
424
12
    if (ifa->ifa_addr == NULL) {
425
0
      continue;
426
0
    }
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
12
    if ((ifa->ifa_addr->sa_family != AF_INET) && (ifa->ifa_addr->sa_family != AF_INET6)) {
439
      /* non inet/inet6 skip */
440
6
      continue;
441
6
    }
442
6
#endif
443
6
#if defined(INET6)
444
6
    if ((ifa->ifa_addr->sa_family == AF_INET6) &&
445
6
        IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
446
      /* skip unspecified addresses */
447
0
      continue;
448
0
    }
449
6
#endif
450
6
#if defined(INET)
451
6
    if (ifa->ifa_addr->sa_family == AF_INET &&
452
6
        ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) {
453
0
      continue;
454
0
    }
455
6
#endif
456
6
    ifa_flags = 0;
457
6
    sctp_ifa = sctp_add_addr_to_vrf(vrfid,
458
6
                                    NULL,
459
6
                                    if_nametoindex(ifa->ifa_name),
460
6
                                    0,
461
6
                                    ifa->ifa_name,
462
6
                                    NULL,
463
6
                                    ifa->ifa_addr,
464
6
                                    ifa_flags,
465
6
                                    0);
466
6
    if (sctp_ifa) {
467
6
      sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
468
6
    }
469
6
  }
470
3
  freeifaddrs(ifas);
471
3
#endif
472
3
}
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
3
{
638
3
  if (vrfid > SCTP_MAX_VRF_ID)
639
    /* can't do that */
640
0
    return;
641
642
  /* Don't care about return here */
643
3
  (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
3
  sctp_init_ifns_for_vrf(vrfid);
649
3
}
650
651
void
652
sctp_addr_change(struct ifaddr *ifa, int cmd)
653
0
{
654
0
#if defined(__Userspace__)
655
0
        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
                           (void *)ifa->ifa_ifp,
717
#if defined(__APPLE__) && !defined(__Userspace__)
718
                           ifnet_index(ifa->ifa_ifp));
719
#else
720
                           ifa->ifa_ifp->if_index);
721
#endif
722
723
    /* We don't bump refcount here so when it completes
724
     * the final delete will happen.
725
     */
726
  }
727
#endif
728
0
}
729
730
#if defined(__FreeBSD__) && !defined(__Userspace__)
731
void
732
sctp_addr_change_event_handler(void *arg __unused, struct ifaddr *ifa, int cmd) {
733
  sctp_addr_change(ifa, cmd);
734
}
735
#endif
736
#if defined(__APPLE__) && !defined(__Userspace__)
737
void
738
sctp_add_or_del_interfaces(int (*pred)(struct ifnet *), int add)
739
{
740
  struct ifnet **ifnetlist;
741
  struct ifaddr **ifaddrlist;
742
  uint32_t i, j, count;
743
744
  if (ifnet_list_get(IFNET_FAMILY_ANY, &ifnetlist, &count) != 0) {
745
    return;
746
  }
747
  for (i = 0; i < count; i++) {
748
    if (!(*pred)(ifnetlist[i])) {
749
      continue;
750
    }
751
    if (ifnet_get_address_list(ifnetlist[i], &ifaddrlist) != 0) {
752
      continue;
753
    }
754
    for (j = 0; ifaddrlist[j] != NULL; j++) {
755
      sctp_addr_change(ifaddrlist[j], add ? RTM_ADD : RTM_DELETE);
756
    }
757
    ifnet_free_address_list(ifaddrlist);
758
  }
759
  ifnet_list_free(ifnetlist);
760
  return;
761
}
762
#endif
763
764
struct mbuf *
765
sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
766
          int how, int allonebuf, int type)
767
10.1M
{
768
10.1M
  struct mbuf *m = NULL;
769
10.1M
#if defined(__FreeBSD__) || defined(__Userspace__)
770
10.1M
#if defined(__Userspace__)
771
10.1M
  m = m_getm2(NULL, space_needed, how, type, want_header ? M_PKTHDR : 0, allonebuf);
772
#else
773
  m = m_getm2(NULL, space_needed, how, type, want_header ? M_PKTHDR : 0);
774
#endif
775
10.1M
  if (m == NULL) {
776
    /* bad, no memory */
777
0
    return (m);
778
0
  }
779
#if !defined(__Userspace__)
780
  if (allonebuf) {
781
    if (SCTP_BUF_SIZE(m) < space_needed) {
782
      m_freem(m);
783
      return (NULL);
784
    }
785
    KASSERT(SCTP_BUF_NEXT(m) == NULL, ("%s: no chain allowed", __func__));
786
  }
787
#endif
788
#ifdef SCTP_MBUF_LOGGING
789
  if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
790
    sctp_log_mb(m, SCTP_MBUF_IALLOC);
791
  }
792
#endif
793
#else
794
  int mbuf_threshold;
795
  unsigned int size;
796
797
  if (want_header) {
798
    MGETHDR(m, how, type);
799
    size = MHLEN;
800
  } else {
801
    MGET(m, how, type);
802
    size = MLEN;
803
  }
804
  if (m == NULL) {
805
    return (NULL);
806
  }
807
  if (allonebuf == 0) {
808
    mbuf_threshold = SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count);
809
  } else {
810
    mbuf_threshold = 1;
811
  }
812
813
  if (space_needed > (unsigned int)(((mbuf_threshold - 1) * MLEN) + MHLEN)) {
814
    MCLGET(m, how);
815
    if (m == NULL) {
816
      return (NULL);
817
    }
818
    if (SCTP_BUF_IS_EXTENDED(m) == 0) {
819
      sctp_m_freem(m);
820
      return (NULL);
821
    }
822
    size = SCTP_BUF_EXTEND_SIZE(m);
823
  }
824
  if (allonebuf != 0 && size < space_needed) {
825
    m_freem(m);
826
    return (NULL);
827
  }
828
  SCTP_BUF_LEN(m) = 0;
829
  SCTP_BUF_NEXT(m) = SCTP_BUF_NEXT_PKT(m) = NULL;
830
#ifdef SCTP_MBUF_LOGGING
831
  if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
832
    sctp_log_mb(m, SCTP_MBUF_IALLOC);
833
  }
834
#endif
835
#endif
836
10.1M
  return (m);
837
10.1M
}
838
839
#ifdef SCTP_PACKET_LOGGING
840
void
841
sctp_packet_log(struct mbuf *m)
842
{
843
  int *lenat, thisone;
844
  void *copyto;
845
  uint32_t *tick_tock;
846
  int length;
847
  int total_len;
848
  int grabbed_lock = 0;
849
  int value, newval, thisend, thisbegin;
850
  /*
851
   * Buffer layout.
852
   * -sizeof this entry (total_len)
853
   * -previous end      (value)
854
   * -ticks of log      (ticks)
855
   * o -ip packet
856
   * o -as logged
857
   * - where this started (thisbegin)
858
   * x <--end points here
859
   */
860
  length = SCTP_HEADER_LEN(m);
861
  total_len = SCTP_SIZE32((length + (4 * sizeof(int))));
862
  /* Log a packet to the buffer. */
863
  if (total_len> SCTP_PACKET_LOG_SIZE) {
864
    /* Can't log this packet I have not a buffer big enough */
865
    return;
866
  }
867
  if (length < (int)(SCTP_MIN_V4_OVERHEAD + sizeof(struct sctp_cookie_ack_chunk))) {
868
    return;
869
  }
870
  atomic_add_int(&SCTP_BASE_VAR(packet_log_writers), 1);
871
 try_again:
872
  if (SCTP_BASE_VAR(packet_log_writers) > SCTP_PKTLOG_WRITERS_NEED_LOCK) {
873
    SCTP_IP_PKTLOG_LOCK();
874
    grabbed_lock = 1;
875
  again_locked:
876
    value = SCTP_BASE_VAR(packet_log_end);
877
    newval = SCTP_BASE_VAR(packet_log_end) + total_len;
878
    if (newval >= SCTP_PACKET_LOG_SIZE) {
879
      /* we wrapped */
880
      thisbegin = 0;
881
      thisend = total_len;
882
    } else {
883
      thisbegin = SCTP_BASE_VAR(packet_log_end);
884
      thisend = newval;
885
    }
886
    if (!(atomic_cmpset_int(&SCTP_BASE_VAR(packet_log_end), value, thisend))) {
887
      goto again_locked;
888
    }
889
  } else {
890
    value = SCTP_BASE_VAR(packet_log_end);
891
    newval = SCTP_BASE_VAR(packet_log_end) + total_len;
892
    if (newval >= SCTP_PACKET_LOG_SIZE) {
893
      /* we wrapped */
894
      thisbegin = 0;
895
      thisend = total_len;
896
    } else {
897
      thisbegin = SCTP_BASE_VAR(packet_log_end);
898
      thisend = newval;
899
    }
900
    if (!(atomic_cmpset_int(&SCTP_BASE_VAR(packet_log_end), value, thisend))) {
901
      goto try_again;
902
    }
903
  }
904
  /* Sanity check */
905
  if (thisend >= SCTP_PACKET_LOG_SIZE) {
906
    SCTP_PRINTF("Insanity stops a log thisbegin:%d thisend:%d writers:%d lock:%d end:%d\n",
907
                thisbegin,
908
                thisend,
909
                SCTP_BASE_VAR(packet_log_writers),
910
                grabbed_lock,
911
                SCTP_BASE_VAR(packet_log_end));
912
    SCTP_BASE_VAR(packet_log_end) = 0;
913
    goto no_log;
914
  }
915
  lenat = (int *)&SCTP_BASE_VAR(packet_log_buffer)[thisbegin];
916
  *lenat = total_len;
917
  lenat++;
918
  *lenat = value;
919
  lenat++;
920
  tick_tock = (uint32_t *)lenat;
921
  lenat++;
922
  *tick_tock = sctp_get_tick_count();
923
  copyto = (void *)lenat;
924
  thisone = thisend - sizeof(int);
925
  lenat = (int *)&SCTP_BASE_VAR(packet_log_buffer)[thisone];
926
  *lenat = thisbegin;
927
  if (grabbed_lock) {
928
    SCTP_IP_PKTLOG_UNLOCK();
929
    grabbed_lock = 0;
930
  }
931
  m_copydata(m, 0, length, (caddr_t)copyto);
932
 no_log:
933
  if (grabbed_lock) {
934
    SCTP_IP_PKTLOG_UNLOCK();
935
  }
936
  atomic_subtract_int(&SCTP_BASE_VAR(packet_log_writers), 1);
937
}
938
939
int
940
sctp_copy_out_packet_log(uint8_t *target, int length)
941
{
942
  /* We wind through the packet log starting at
943
   * start copying up to length bytes out.
944
   * We return the number of bytes copied.
945
   */
946
  int this_copy;
947
  int *lenat;
948
  int did_delay = 0;
949
950
  if (length < (int)(2 * sizeof(int))) {
951
    /* not enough room */
952
    return (0);
953
  }
954
  if (SCTP_PKTLOG_WRITERS_NEED_LOCK) {
955
    atomic_add_int(&SCTP_BASE_VAR(packet_log_writers), SCTP_PKTLOG_WRITERS_NEED_LOCK);
956
  again:
957
    if ((did_delay == 0) && (SCTP_BASE_VAR(packet_log_writers) != SCTP_PKTLOG_WRITERS_NEED_LOCK)) {
958
      /* we delay here for just a moment hoping the writer(s) that were
959
       * present when we entered will have left and we only have
960
       * locking ones that will contend with us for the lock. This
961
       * does not assure 100% access, but its good enough for
962
       * a logging facility like this.
963
       */
964
      did_delay = 1;
965
      DELAY(10);
966
      goto again;
967
    }
968
  }
969
  SCTP_IP_PKTLOG_LOCK();
970
  lenat = (int *)target;
971
  *lenat = SCTP_BASE_VAR(packet_log_end);
972
  lenat++;
973
  this_copy = min((length - sizeof(int)), SCTP_PACKET_LOG_SIZE);
974
  memcpy((void *)lenat, (void *)SCTP_BASE_VAR(packet_log_buffer), this_copy);
975
  if (SCTP_PKTLOG_WRITERS_NEED_LOCK) {
976
    atomic_subtract_int(&SCTP_BASE_VAR(packet_log_writers),
977
                        SCTP_PKTLOG_WRITERS_NEED_LOCK);
978
  }
979
  SCTP_IP_PKTLOG_UNLOCK();
980
  return (this_copy + sizeof(int));
981
}
982
983
#endif