269
create_wildcards(u_short port) {
272
isc_boolean_t okipv4 = ISC_TRUE;
274
* create pseudo-interface with wildcard IPv4 address
277
if(isc_net_probeipv4() != ISC_R_SUCCESS)
281
if(okipv4 == ISC_TRUE) {
282
inter_list[idx].sin.ss_family = AF_INET;
283
((struct sockaddr_in*)&inter_list[idx].sin)->sin_addr.s_addr = htonl(INADDR_ANY);
284
((struct sockaddr_in*)&inter_list[idx].sin)->sin_port = port;
285
(void) strncpy(inter_list[idx].name, "wildcard", sizeof(inter_list[idx].name));
286
inter_list[idx].mask.ss_family = AF_INET;
287
((struct sockaddr_in*)&inter_list[idx].mask)->sin_addr.s_addr = htonl(~(u_int32)0);
288
inter_list[idx].bfd = INVALID_SOCKET;
289
inter_list[idx].num_mcast = 0;
290
inter_list[idx].received = 0;
291
inter_list[idx].sent = 0;
292
inter_list[idx].notsent = 0;
293
inter_list[idx].flags = INT_BROADCAST;
294
any_interface = &inter_list[idx];
297
* enable possible multicast reception on the broadcast socket
299
inter_list[idx].bcast.ss_family = AF_INET;
300
((struct sockaddr_in*)&inter_list[idx].bcast)->sin_port = port;
301
((struct sockaddr_in*)&inter_list[idx].bcast)->sin_addr.s_addr = htonl(INADDR_ANY);
307
#ifdef ISC_PLATFORM_HAVEIPV6
309
* create pseudo-interface with wildcard IPv6 address
311
if (isc_net_probeipv6() == ISC_R_SUCCESS) {
312
inter_list[idx].sin.ss_family = AF_INET6;
313
((struct sockaddr_in6*)&inter_list[idx].sin)->sin6_addr = in6addr_any;
314
((struct sockaddr_in6*)&inter_list[idx].sin)->sin6_port = port;
315
(void) strncpy(inter_list[idx].name, "wildcard", sizeof(inter_list[idx].name));
316
inter_list[idx].mask.ss_family = AF_INET6;
317
memset(&((struct sockaddr_in6*)&inter_list[idx].mask)->sin6_addr.s6_addr, 0xff, sizeof(struct in6_addr));
318
inter_list[idx].bfd = INVALID_SOCKET;
319
inter_list[idx].num_mcast = 0;
320
inter_list[idx].received = 0;
321
inter_list[idx].sent = 0;
322
inter_list[idx].notsent = 0;
323
inter_list[idx].flags = 0;
324
any6_interface = &inter_list[idx];
333
address_okay(isc_interface_t *isc_if) {
337
printf("address_okay: listen Virtual: %d, IF name: %s, Up Flag: %d\n",
338
listen_to_virtual_ips, isc_if->name, (isc_if->flags & INTERFACE_F_UP));
341
if (listen_to_virtual_ips == 0 && (strchr(isc_if->name, (int)':') != NULL))
344
/* XXXPDM This should be fixed later, but since we may not have set
345
* the UP flag, we at least get to use the interface.
346
* The UP flag is not always set so we don't do this right now.
348
/* if ((isc_if->flags & INTERFACE_F_UP) == 0)
354
convert_isc_if(isc_interface_t *isc_if, struct interface *itf, u_short port) {
356
if(isc_if->af == AF_INET) {
357
itf->sin.ss_family = (u_short) isc_if->af;
358
strcpy(itf->name, isc_if->name);
359
memcpy(&(((struct sockaddr_in*)&itf->sin)->sin_addr),
360
&(isc_if->address.type.in),
361
sizeof(struct in_addr));
362
((struct sockaddr_in*)&itf->sin)->sin_port = port;
364
if((isc_if->flags & INTERFACE_F_BROADCAST) != 0) {
365
itf->flags |= INT_BROADCAST;
366
itf->bcast.ss_family = itf->sin.ss_family;
367
memcpy(&(((struct sockaddr_in*)&itf->bcast)->sin_addr),
368
&(isc_if->broadcast.type.in),
369
sizeof(struct in_addr));
370
((struct sockaddr_in*)&itf->bcast)->sin_port = port;
373
itf->mask.ss_family = itf->sin.ss_family;
374
memcpy(&(((struct sockaddr_in*)&itf->mask)->sin_addr),
375
&(isc_if->netmask.type.in),
376
sizeof(struct in_addr));
377
((struct sockaddr_in*)&itf->mask)->sin_port = port;
379
if (((isc_if->flags & INTERFACE_F_LOOPBACK) != 0) && (loopback_interface == NULL))
381
loopback_interface = itf;
384
#ifdef ISC_PLATFORM_HAVEIPV6
385
else if (isc_if->af == AF_INET6) {
386
itf->sin.ss_family = (u_short) isc_if->af;
387
strcpy(itf->name, isc_if->name);
388
memcpy(&(((struct sockaddr_in6 *)&itf->sin)->sin6_addr),
389
&(isc_if->address.type.in6),
390
sizeof(struct in6_addr));
391
((struct sockaddr_in6 *)&itf->sin)->sin6_port = port;
393
itf->mask.ss_family = itf->sin.ss_family;
394
memcpy(&(((struct sockaddr_in6 *)&itf->mask)->sin6_addr),
395
&(isc_if->netmask.type.in6),
396
sizeof(struct in6_addr));
397
((struct sockaddr_in6 *)&itf->mask)->sin6_port = port;
399
if (((isc_if->flags & INTERFACE_F_LOOPBACK) != 0) && (loopback6_interface == NULL))
401
loopback6_interface = itf;
404
#endif /* ISC_PLATFORM_HAVEIPV6 */
406
/* Process the rest of the flags */
408
if((isc_if->flags & INTERFACE_F_UP) != 0)
409
itf->flags |= INT_UP;
410
if((isc_if->flags & INTERFACE_F_LOOPBACK) != 0)
411
itf->flags |= INT_LOOPBACK;
412
if((isc_if->flags & INTERFACE_F_POINTTOPOINT) != 0)
413
itf->flags |= INT_PPP;
415
/* Copy the scopeid and the interface index */
416
itf->ifindex = isc_if->ifindex;
417
itf->scopeid = isc_if->scopeid;
195
420
* create_sockets - create a socket for each interface plus a default
196
421
* socket for when we don't know where to send
203
#if _BSDI_VERSION >= 199510
205
struct ifaddrs *ifaddrs, *ifap;
206
struct sockaddr_in resmask;
207
#if _BSDI_VERSION < 199701
211
#else /* _BSDI_VERSION >= 199510 */
214
# endif /* STREAMS_TLI */
215
char buf[MAXINTERFACES*sizeof(struct ifreq)];
217
struct ifreq ifreq, *ifr;
218
int n, i, j, vs, size = 0;
219
struct sockaddr_in resmask;
220
#endif /* _BSDI_VERSION >= 199510 */
428
struct sockaddr_storage resmask;
430
isc_mem_t *mctx = NULL;
431
isc_interfaceiter_t *iter = NULL;
432
isc_boolean_t scan_ipv4 = ISC_FALSE;
433
isc_boolean_t scan_ipv6 = ISC_FALSE;
224
439
printf("create_sockets(%d)\n", ntohs( (u_short) port));
442
if (isc_net_probeipv6() == ISC_R_SUCCESS)
443
scan_ipv6 = ISC_TRUE;
444
#if defined(ISC_PLATFORM_HAVEIPV6) && defined(DEBUG)
447
netsyslog(LOG_ERR, "no IPv6 interfaces found");
450
if (isc_net_probeipv4() == ISC_R_SUCCESS)
451
scan_ipv4 = ISC_TRUE;
455
netsyslog(LOG_ERR, "no IPv4 interfaces found");
458
nwilds = create_wildcards(port);
461
result = isc_interfaceiter_create(mctx, &iter);
462
if (result != ISC_R_SUCCESS)
465
for (result = isc_interfaceiter_first(iter);
466
result == ISC_R_SUCCESS;
467
result = isc_interfaceiter_next(iter))
469
isc_interface_t isc_if;
472
result = isc_interfaceiter_current(iter, &isc_if);
473
if (result != ISC_R_SUCCESS)
476
/* See if we have a valid family to use */
477
family = isc_if.address.family;
478
if (family != AF_INET && family != AF_INET6)
480
if (scan_ipv4 == ISC_FALSE && family == AF_INET)
482
if (scan_ipv6 == ISC_FALSE && family == AF_INET6)
485
/* Check to see if we are going to use the interface */
486
if (address_okay(&isc_if) == ISC_TRUE) {
487
convert_isc_if(&isc_if, &inter_list[idx], port);
488
inter_list[idx].fd = INVALID_SOCKET;
489
inter_list[idx].bfd = INVALID_SOCKET;
490
inter_list[idx].num_mcast = 0;
491
inter_list[idx].received = 0;
492
inter_list[idx].sent = 0;
493
inter_list[idx].notsent = 0;
497
isc_interfaceiter_destroy(&iter);
228
* create pseudo-interface with wildcard address
501
* I/O Completion Ports don't care about the select and FD_SET
230
inter_list[0].sin.sin_family = AF_INET;
231
inter_list[0].sin.sin_port = port;
232
inter_list[0].sin.sin_addr.s_addr = htonl(INADDR_ANY);
233
(void) strncpy(inter_list[0].name, "wildcard",
234
sizeof(inter_list[0].name));
235
inter_list[0].mask.sin_addr.s_addr = htonl(~ (u_int32)0);
236
inter_list[0].received = 0;
237
inter_list[0].sent = 0;
238
inter_list[0].notsent = 0;
239
inter_list[0].flags = INT_BROADCAST;
240
any_interface = &inter_list[0];
242
#if _BSDI_VERSION >= 199510
243
#if _BSDI_VERSION >= 199701
244
if (getifaddrs(&ifaddrs) < 0)
246
msyslog(LOG_ERR, "getifaddrs: %m");
250
for (ifap = ifaddrs; ifap != NULL; ifap = ifap->ifa_next)
252
if (getifaddrs(&ifaddrs, &num_if) < 0)
254
msyslog(LOG_ERR, "create_sockets: getifaddrs() failed: %m");
260
for (ifap = ifaddrs, lp = ifap + num_if; ifap < lp; ifap++)
263
struct sockaddr_in *sin;
268
if (ifap->ifa_addr->sa_family != AF_INET)
271
if ((ifap->ifa_flags & IFF_UP) == 0)
274
if (ifap->ifa_flags & IFF_LOOPBACK) {
275
sin = (struct sockaddr_in *)ifap->ifa_addr;
276
if (ntohl(sin->sin_addr.s_addr) != 0x7f000001)
279
inter_list[i].flags = 0;
280
if (ifap->ifa_flags & IFF_BROADCAST)
281
inter_list[i].flags |= INT_BROADCAST;
282
strcpy(inter_list[i].name, ifap->ifa_name);
283
sin = (struct sockaddr_in *)ifap->ifa_addr;
284
inter_list[i].sin = *sin;
285
inter_list[i].sin.sin_port = port;
286
if (ifap->ifa_flags & IFF_LOOPBACK) {
287
inter_list[i].flags = INT_LOOPBACK;
288
if (loopback_interface == NULL
289
|| ntohl(sin->sin_addr.s_addr) != 0x7f000001)
290
loopback_interface = &inter_list[i];
292
if (inter_list[i].flags & INT_BROADCAST) {
293
sin = (struct sockaddr_in *)ifap->ifa_broadaddr;
294
inter_list[i].bcast = *sin;
295
inter_list[i].bcast.sin_port = port;
297
if (ifap->ifa_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) {
298
inter_list[i].mask.sin_addr.s_addr = 0xffffffff;
300
sin = (struct sockaddr_in *)ifap->ifa_netmask;
301
inter_list[i].mask = *sin;
303
inter_list[i].mask.sin_family = AF_INET;
304
inter_list[i].mask.sin_len = sizeof *sin;
307
* look for an already existing source interface address. If
308
* the machine has multiple point to point interfaces, then
309
* the local address may appear more than once.
311
* A second problem exists if we have two addresses on
312
* the same network (via "ifconfig alias ..."). Don't
313
* make two xntp interfaces for the two aliases on the
314
* one physical interface. -wsr
316
for (j=0; j < i; j++)
317
if (inter_list[j].sin.sin_addr.s_addr &
318
inter_list[j].mask.sin_addr.s_addr ==
319
inter_list[i].sin.sin_addr.s_addr &
320
inter_list[i].mask.sin_addr.s_addr)
322
if (inter_list[j].flags & INT_LOOPBACK)
323
inter_list[j] = inter_list[i];
328
if (i > MAXINTERFACES)
332
#else /* _BSDI_VERSION >= 199510 */
333
# ifdef USE_STREAMS_DEVICE_FOR_IF_CONFIG
334
if ((vs = open("/dev/ip", O_RDONLY)) < 0)
336
msyslog(LOG_ERR, "create_sockets: open(/dev/ip) failed: %m");
339
# else /* not USE_STREAMS_DEVICE_FOR_IF_CONFIG */
341
(vs = socket(AF_INET, SOCK_DGRAM, 0))
344
# else /* SYS_WINNT */
346
# endif /* SYS_WINNT */
348
msyslog(LOG_ERR, "create_sockets: socket(AF_INET, SOCK_DGRAM) failed: %m");
351
# endif /* not USE_STREAMS_DEVICE_FOR_IF_CONFIG */
354
# if !defined(SYS_WINNT)
355
ifc.ifc_len = sizeof(buf);
358
ioc.ic_cmd = SIOCGIFCONF;
360
ioc.ic_dp = (caddr_t)buf;
361
ioc.ic_len = sizeof(buf);
362
if(ioctl(vs, I_STR, &ioc) < 0 ||
363
ioc.ic_len < sizeof(struct ifreq))
365
msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFCONF) failed: %m - exiting");
368
# ifdef SIZE_RETURNED_IN_BUFFER
369
ifc.ifc_len = ioc.ic_len - sizeof(int);
370
ifc.ifc_buf = buf + sizeof(int);
371
# else /* not SIZE_RETURNED_IN_BUFFER */
372
ifc.ifc_len = ioc.ic_len;
374
# endif /* not SIZE_RETURNED_IN_BUFFER */
376
# else /* not STREAMS_TLI */
377
ifc.ifc_len = sizeof(buf);
380
if (ioctl(vs, SIOCGIFCONF, (char *)&ifc) < 0)
382
if (WSAIoctl(vs, SIO_GET_INTERFACE_LIST, 0, 0, ifc.ifc_buf, ifc.ifc_len, &ifc.ifc_len, 0, 0) == SOCKET_ERROR)
383
# endif /* SYS_WINNT */
385
msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFCONF) failed: %m - exiting");
389
# endif /* not STREAMS_TLI */
391
for(n = ifc.ifc_len, ifr = ifc.ifc_req; n > 0;
392
ifr = (struct ifreq *)((char *)ifr + size))
394
extern int listen_to_virtual_ips;
398
# ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
399
if (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_addr))
400
size += ifr->ifr_addr.sa_len - sizeof(struct sockaddr);
404
# if !defined(SYS_WINNT)
405
/* Exclude logical interfaces (indicated by ':' in the interface name) */
407
printf("interface <%s> ", ifr->ifr_name);
408
if ((listen_to_virtual_ips == 0)
409
&& (strchr(ifr->ifr_name, (int)':') != NULL)) {
418
# ifdef VMS /* VMS+UCX */
419
(((struct sockaddr *)&(ifr->ifr_addr))->sa_family != AF_INET)
421
(ifr->ifr_addr.sa_family != AF_INET)
422
# endif /* VMS+UCX */
425
printf("ignoring %s - not AF_INET\n",
429
# endif /* SYS_WINNT */
431
inter_list[i].flags = 0;
432
/* is it broadcast capable? */
435
ioc.ic_cmd = SIOCGIFFLAGS;
437
ioc.ic_dp = (caddr_t)&ifreq;
438
ioc.ic_len = sizeof(struct ifreq);
439
if(ioctl(vs, I_STR, &ioc)) {
440
msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFFLAGS) failed: %m");
443
# else /* not STREAMS_TLI */
444
if (ioctl(vs, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
446
msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFFLAGS) failed: %m");
449
# endif /* not STREAMS_TLI */
450
if ((ifreq.ifr_flags & IFF_UP) == 0) {
452
printf("ignoring %s - interface not UP\n",
456
inter_list[i].flags = 0;
457
if (ifreq.ifr_flags & IFF_BROADCAST)
458
inter_list[i].flags |= INT_BROADCAST;
459
# endif /* not SYS_WINNT */
460
# if !defined(SUN_3_3_STINKS)
462
# if defined(IFF_LOCAL_LOOPBACK) /* defined(SYS_HPUX) && (SYS_HPUX < 8) */
463
(ifreq.ifr_flags & IFF_LOCAL_LOOPBACK)
464
# elif defined(IFF_LOOPBACK)
465
(ifreq.ifr_flags & IFF_LOOPBACK)
466
# else /* not IFF_LOCAL_LOOPBACK and not IFF_LOOPBACK */
467
/* test against 127.0.0.1 (yuck!!) */
468
(inter_list[i].sin.sin_addr.s_addr == inet_addr("127.0.0.1"))
469
# endif /* not IFF_LOCAL_LOOPBACK and not IFF_LOOPBACK */
473
inter_list[i].flags |= INT_LOOPBACK;
474
# endif /* not SYS_WINNT */
475
if (loopback_interface == 0)
477
loopback_interface = &inter_list[i];
480
# endif /* not SUN_3_3_STINKS */
485
ioc.ic_cmd = SIOCGIFADDR;
487
ioc.ic_dp = (caddr_t)&ifreq;
488
ioc.ic_len = sizeof(struct ifreq);
489
if (ioctl(vs, I_STR, &ioc))
491
msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFADDR) failed: %m");
494
# else /* not STREAMS_TLI */
495
if (ioctl(vs, SIOCGIFADDR, (char *)&ifreq) < 0)
498
msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFADDR) failed: %m");
501
# endif /* not STREAMS_TLI */
502
# endif /* not SYS_WINNT */
504
# if defined(SYS_WINNT)
505
{int TODO_FillInTheNameWithSomeThingReasonble;}
507
(void)strncpy(inter_list[i].name, ifreq.ifr_name,
508
sizeof(inter_list[i].name));
510
inter_list[i].sin = *(struct sockaddr_in *)&ifr->ifr_addr;
511
inter_list[i].sin.sin_family = AF_INET;
512
inter_list[i].sin.sin_port = port;
514
# if defined(SUN_3_3_STINKS)
516
* Oh, barf! I'm too disgusted to even explain this
518
if (SRCADR(&inter_list[i].sin) == 0x7f000001)
520
inter_list[i].flags |= INT_LOOPBACK;
521
if (loopback_interface == 0)
522
loopback_interface = &inter_list[i];
524
# endif /* SUN_3_3_STINKS */
525
# if !defined SYS_WINNT && !defined SYS_CYGWIN32 /* no interface flags on NT */
526
if (inter_list[i].flags & INT_BROADCAST) {
528
ioc.ic_cmd = SIOCGIFBRDADDR;
530
ioc.ic_dp = (caddr_t)&ifreq;
531
ioc.ic_len = sizeof(struct ifreq);
532
if(ioctl(vs, I_STR, &ioc)) {
533
msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFBRDADDR) failed: %m");
536
# else /* not STREAMS_TLI */
537
if (ioctl(vs, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
538
msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFBRDADDR) failed: %m");
541
# endif /* not STREAMS_TLI */
543
# ifndef ifr_broadaddr
544
inter_list[i].bcast =
545
*(struct sockaddr_in *)&ifreq.ifr_addr;
547
inter_list[i].bcast =
548
*(struct sockaddr_in *)&ifreq.ifr_broadaddr;
549
# endif /* ifr_broadaddr */
550
inter_list[i].bcast.sin_family = AF_INET;
551
inter_list[i].bcast.sin_port = port;
555
ioc.ic_cmd = SIOCGIFNETMASK;
557
ioc.ic_dp = (caddr_t)&ifreq;
558
ioc.ic_len = sizeof(struct ifreq);
559
if(ioctl(vs, I_STR, &ioc)) {
560
msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFNETMASK) failed: %m");
563
# else /* not STREAMS_TLI */
564
if (ioctl(vs, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
565
msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFNETMASK) failed: %m");
568
# endif /* not STREAMS_TLI */
569
inter_list[i].mask = *(struct sockaddr_in *)&ifreq.ifr_addr;
572
inter_list[i].bcast = ifreq.ifr_broadaddr;
573
inter_list[i].bcast.sin_family = AF_INET;
574
inter_list[i].bcast.sin_port = port;
575
inter_list[i].mask = ifreq.ifr_mask;
576
# endif /* not SYS_WINNT */
579
* look for an already existing source interface address. If
580
* the machine has multiple point to point interfaces, then
581
* the local address may appear more than once.
583
for (j=0; j < i; j++)
584
if (inter_list[j].sin.sin_addr.s_addr ==
585
inter_list[i].sin.sin_addr.s_addr) {
590
if (i > MAXINTERFACES)
594
#endif /* _BSDI_VERSION >= 199510 */
503
#ifndef HAVE_IO_COMPLETION_PORT
598
505
FD_ZERO(&activefds);
599
507
for (i = 0; i < ninterfaces; i++) {
600
508
inter_list[i].fd = open_socket(&inter_list[i].sin,
601
509
inter_list[i].flags & INT_BROADCAST, 0);
605
* Now that we have opened all the sockets, turn off the reuse flag for
608
for (i = 0; i < ninterfaces; i++) {
612
* if inter_list[ n ].fd is -1, we might have a adapter
613
* configured but not present
615
if ( inter_list[ i ].fd != -1 ) {
616
if (setsockopt(inter_list[i].fd, SOL_SOCKET,
617
SO_REUSEADDR, (char *)&off,
619
msyslog(LOG_ERR, "create_sockets: setsockopt(SO_REUSEADDR,off) failed: %m");
510
if (inter_list[i].fd != INVALID_SOCKET)
511
msyslog(LOG_INFO, "Listening on interface %s, %s#%d",
513
stoa((&inter_list[i].sin)),
515
if ((inter_list[i].flags & INT_BROADCAST) &&
516
inter_list[i].bfd != INVALID_SOCKET)
517
msyslog(LOG_INFO, "Listening on broadcast address %s#%d",
518
stoa((&inter_list[i].bcast)),
520
#if defined (HAVE_IO_COMPLETION_PORT)
521
if (inter_list[i].fd != INVALID_SOCKET) {
522
io_completion_port_add_socket(inter_list[i].fd, &inter_list[i]);
626
* enable possible multicast reception on the broadcast socket
528
* Now that we have opened all the sockets, turn off the reuse
628
inter_list[0].bcast.sin_addr.s_addr = htonl(INADDR_ANY);
629
inter_list[0].bcast.sin_family = AF_INET;
630
inter_list[0].bcast.sin_port = port;
634
534
* Blacklist all bound interface addresses
535
* Wildcard interfaces are ignored.
636
resmask.sin_addr.s_addr = ~ (u_int32)0;
637
for (i = 1; i < ninterfaces; i++)
538
for (i = nwilds; i < ninterfaces; i++) {
539
SET_HOSTMASK(&resmask, inter_list[i].sin.ss_family);
638
540
hack_restrict(RESTRICT_FLAGS, &inter_list[i].sin, &resmask,
639
541
RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE);
545
* Calculate the address hash for each interface address.
547
for (i = 0; i < ninterfaces; i++) {
548
inter_list[i].addr_refid = addr2refid(&inter_list[i].sin);
642
554
printf("create_sockets: ninterfaces=%d\n", ninterfaces);
643
555
for (i = 0; i < ninterfaces; i++) {
644
printf("interface %d: fd=%d, bfd=%d, name=%.8s, flags=0x%x\n",
556
printf("interface %d: fd=%d, bfd=%d, name=%.8s, flags=0x%x, scope=%d\n",
646
558
inter_list[i].fd,
647
559
inter_list[i].bfd,
648
560
inter_list[i].name,
649
inter_list[i].flags);
562
inter_list[i].scopeid);
650
563
/* Leave these as three printf calls. */
651
564
printf(" sin=%s",
652
inet_ntoa((inter_list[i].sin.sin_addr)));
565
stoa((&inter_list[i].sin)));
653
566
if (inter_list[i].flags & INT_BROADCAST)
654
567
printf(" bcast=%s,",
655
inet_ntoa((inter_list[i].bcast.sin_addr)));
568
stoa((&inter_list[i].bcast)));
656
569
printf(" mask=%s\n",
657
inet_ntoa((inter_list[i].mask.sin_addr)));
570
stoa((&inter_list[i].mask)));
661
#if defined (HAVE_IO_COMPLETION_PORT)
662
for (i = 0; i < ninterfaces; i++) {
663
io_completion_port_add_socket(&inter_list[i]);
666
574
return ninterfaces;
700
664
io_multicast_add(
665
struct sockaddr_storage addr
705
669
struct ip_mreq mreq;
706
670
int i = ninterfaces; /* Use the next interface */
707
u_int32 haddr = ntohl(addr);
671
u_int32 haddr = ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr);
708
672
struct in_addr iaddr;
710
674
struct sockaddr_in *sinp;
713
if (!IN_CLASSD(haddr)) {
715
"multicast address %s not class D",
719
for (i = 0; i < ninterfaces; i++) {
720
/* Already have this address */
721
if (inter_list[i].sin.sin_addr.s_addr == addr)
723
/* found a free slot */
724
if (inter_list[i].sin.sin_addr.s_addr == 0 &&
725
inter_list[i].fd <= 0 && inter_list[i].bfd <= 0 &&
726
inter_list[i].flags == 0)
729
sinp = &(inter_list[i].sin);
730
memset((char *)&mreq, 0, sizeof(mreq));
731
memset((char *)&inter_list[i], 0, sizeof inter_list[0]);
732
sinp->sin_family = AF_INET;
733
sinp->sin_addr = iaddr;
734
sinp->sin_port = htons(123);
737
* Try opening a socket for the specified class D address. This
738
* works under SunOS 4.x, but not OSF1 .. :-(
740
s = open_socket(sinp, 0, 1);
742
memset((char *)&inter_list[i], 0, sizeof inter_list[0]);
744
/* HACK ! -- stuff in an address */
745
inter_list[i].bcast.sin_addr.s_addr = addr;
747
"...multicast address %s using wildcard socket",
750
inter_list[i].fd = s;
751
inter_list[i].bfd = -1;
752
(void) strncpy(inter_list[i].name, "multicast",
753
sizeof(inter_list[i].name));
754
inter_list[i].mask.sin_addr.s_addr = htonl(~(u_int32)0);
758
* enable reception of multicast packets
760
mreq.imr_multiaddr = iaddr;
761
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
762
if (setsockopt(inter_list[i].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
763
(char *)&mreq, sizeof(mreq)) == -1)
765
"setsockopt IP_ADD_MEMBERSHIP fails: %m for %x / %x (%s)",
766
mreq.imr_multiaddr.s_addr,
767
mreq.imr_interface.s_addr, inet_ntoa(iaddr));
768
inter_list[i].flags |= INT_MULTICAST;
769
if (i >= ninterfaces)
676
#ifdef ISC_PLATFORM_HAVEIPV6
677
struct ipv6_mreq mreq6;
678
struct in6_addr iaddr6;
679
struct sockaddr_in6 *sin6p;
680
#endif /* ISC_PLATFORM_HAVEIPV6 */
682
switch (addr.ss_family)
685
iaddr = (((struct sockaddr_in*)&addr)->sin_addr);
686
if (!IN_CLASSD(haddr)) {
688
"multicast address %s not class D",
692
for (i = nwilds; i < ninterfaces; i++) {
693
/* Be sure it's the correct family */
694
if (inter_list[i].sin.ss_family != AF_INET)
696
/* Already have this address */
697
if (SOCKCMP(&inter_list[i].sin, &addr))
699
/* found a free slot */
700
if (SOCKNUL(&inter_list[i].sin) &&
701
inter_list[i].fd <= 0 && inter_list[i].bfd <= 0 &&
702
inter_list[i].flags == 0)
705
sinp = (struct sockaddr_in*)&(inter_list[i].sin);
706
memset((char *)&mreq, 0, sizeof(mreq));
707
memset((char *)&inter_list[i], 0, sizeof(struct interface));
708
sinp->sin_family = AF_INET;
709
sinp->sin_addr = iaddr;
710
sinp->sin_port = htons(NTP_PORT);
713
* Try opening a socket for the specified class D address. This
714
* works under SunOS 4.x, but not OSF1 .. :-(
717
s = open_socket((struct sockaddr_storage*)sinp, 0, 1);
719
if (s == INVALID_SOCKET) {
720
memset((char *)&inter_list[i], 0, sizeof(struct interface));
723
/* HACK ! -- stuff in an address */
724
inter_list[i].bcast = addr;
726
"...multicast address %s using wildcard socket",
730
"No wildcard socket available to use for address %s",
735
inter_list[i].fd = s;
736
inter_list[i].bfd = INVALID_SOCKET;
737
(void) strncpy(inter_list[i].name, "multicast",
738
sizeof(inter_list[i].name));
739
((struct sockaddr_in*)&inter_list[i].mask)->sin_addr.s_addr = htonl(~(u_int32)0);
740
#if defined (HAVE_IO_COMPLETION_PORT)
741
io_completion_port_add_socket(inter_list[i].fd, &inter_list[i]);
746
* enable reception of multicast packets
748
mreq.imr_multiaddr = iaddr;
749
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
750
if (setsockopt(inter_list[i].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
751
(char *)&mreq, sizeof(mreq)) == -1)
753
"setsockopt IP_ADD_MEMBERSHIP fails: %m for %x / %x (%s)",
754
mreq.imr_multiaddr.s_addr,
755
mreq.imr_interface.s_addr, inet_ntoa(iaddr));
756
inter_list[i].flags |= INT_MULTICAST;
757
inter_list[i].num_mcast++;
758
if (i >= ninterfaces)
761
add_addr_to_list(&addr, i);
764
#ifdef ISC_PLATFORM_HAVEIPV6
767
iaddr6 = ((struct sockaddr_in6*)&addr)->sin6_addr;
768
if (!IN6_IS_ADDR_MULTICAST(&iaddr6)) {
770
"address %s not IPv6 multicast address",
774
for (i = nwilds; i < ninterfaces; i++) {
775
/* Be sure it's the correct family */
776
if(inter_list[i].sin.ss_family != AF_INET6)
778
/* Already have this address */
779
if (SOCKCMP(&inter_list[i].sin, &addr))
781
/* found a free slot */
782
if (SOCKNUL(&inter_list[i].sin) &&
783
inter_list[i].fd <= 0 && inter_list[i].bfd <= 0 &&
784
inter_list[i].flags == 0)
787
sin6p = (struct sockaddr_in6*)&inter_list[i].sin;
788
memset((char *)&mreq6, 0, sizeof(mreq6));
789
memset((char *)&inter_list[i], 0, sizeof(struct interface));
790
sin6p->sin6_family = AF_INET6;
791
sin6p->sin6_scope_id = inter_list[i].scopeid;
792
sin6p->sin6_addr = iaddr6;
793
sin6p->sin6_port = htons(NTP_PORT);
796
* Try opening a socket for the specified class D address. This
797
* works under SunOS 4.x, but not OSF1 .. :-(
800
s = open_socket((struct sockaddr_storage*)sin6p, 0, 1);
802
if(s == INVALID_SOCKET){
803
memset((char *)&inter_list[i], 0, sizeof(struct interface));
806
/* HACK ! -- stuff in an address */
807
inter_list[i].bcast = addr;
809
"...multicast address %s using wildcard socket",
813
"No wildcard socket available to use for address %s",
818
inter_list[i].fd = s;
819
inter_list[i].bfd = INVALID_SOCKET;
820
(void)strncpy(inter_list[i].name, "multicast",
821
sizeof(inter_list[i].name));
822
memset(&(((struct sockaddr_in6*)&inter_list[i].mask)->sin6_addr), 1, sizeof(struct in6_addr));
823
#if defined (HAVE_IO_COMPLETION_PORT)
824
io_completion_port_add_socket(inter_list[i].fd, &inter_list[i]);
829
* Enable reception of multicast packets
830
* If the address is link-local we can get the interface index
831
* from the scope id. Don't do this for other types of multicast
832
* addresses. For now let the kernel figure it out.
834
mreq6.ipv6mr_multiaddr = iaddr6;
835
if (IN6_IS_ADDR_MC_LINKLOCAL(&iaddr6))
836
mreq6.ipv6mr_interface = sin6p->sin6_scope_id;
838
mreq6.ipv6mr_interface = 0;
840
if(setsockopt(inter_list[i].fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
841
(char *)&mreq6, sizeof(mreq6)) == -1)
843
"setsockopt IPV6_JOIN_GROUP fails: %m on interface %d(%s)",
844
mreq6.ipv6mr_interface, stoa(&addr));
845
inter_list[i].flags |= INT_MULTICAST;
846
inter_list[i].num_mcast++;
850
add_addr_to_list(&addr, i);
852
#endif /* ISC_PLATFORM_HAVEIPV6 */
857
printf("io_multicast_add %s\n", stoa(&addr));
771
859
#else /* MCAST */
772
struct in_addr iaddr;
776
861
"cannot add multicast address %s as no MCAST support",
778
863
#endif /* MCAST */
804
889
io_multicast_del(
890
struct sockaddr_storage addr
810
895
struct ip_mreq mreq;
811
u_int32 haddr = ntohl(addr);
812
struct sockaddr_in sinaddr;
814
if (!IN_CLASSD(haddr))
816
sinaddr.sin_addr.s_addr = addr;
818
"invalid multicast address %s", ntoa(&sinaddr));
823
* Disable reception of multicast packets
825
mreq.imr_multiaddr.s_addr = addr;
826
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
827
for (i = 0; i < ninterfaces; i++)
829
if (!(inter_list[i].flags & INT_MULTICAST))
831
if (!(inter_list[i].fd < 0))
833
if (addr != inter_list[i].sin.sin_addr.s_addr)
837
/* we have an explicit fd, so we can close it */
838
close_socket(inter_list[i].fd);
839
memset((char *)&inter_list[i], 0, sizeof inter_list[0]);
840
inter_list[i].fd = -1;
841
inter_list[i].bfd = -1;
845
/* We are sharing "any address" port :-( Don't close it! */
846
if (setsockopt(inter_list[i].fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
847
(char *)&mreq, sizeof(mreq)) == -1)
848
msyslog(LOG_ERR, "setsockopt IP_DROP_MEMBERSHIP fails: %m");
849
/* This is **WRONG** -- there may be others ! */
850
/* There should be a count of users ... */
851
inter_list[i].flags &= ~INT_MULTICAST;
898
#ifdef ISC_PLATFORM_HAVEIPV6
899
struct ipv6_mreq mreq6;
900
struct in6_addr haddr6;
901
#endif /* ISC_PLATFORM_HAVEIPV6 */
903
switch (addr.ss_family)
907
haddr = ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr);
909
if (!IN_CLASSD(haddr))
912
"invalid multicast address %s", stoa(&addr));
917
* Disable reception of multicast packets
919
mreq.imr_multiaddr = ((struct sockaddr_in*)&addr)->sin_addr;
920
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
921
for (i = 0; i < ninterfaces; i++)
923
/* Be sure it's the correct family */
924
if (inter_list[i].sin.ss_family != AF_INET)
926
if (!(inter_list[i].flags & INT_MULTICAST))
928
if (!(inter_list[i].fd < 0))
930
if (!SOCKCMP(&addr, &inter_list[i].sin))
934
/* we have an explicit fd, so we can close it */
935
close_socket(inter_list[i].fd);
936
memset((char *)&inter_list[i], 0, sizeof(struct interface));
937
inter_list[i].fd = INVALID_SOCKET;
938
inter_list[i].bfd = INVALID_SOCKET;
942
/* We are sharing "any address" port :-( Don't close it! */
943
if (setsockopt(inter_list[i].fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
944
(char *)&mreq, sizeof(mreq)) == -1)
945
netsyslog(LOG_ERR, "setsockopt IP_DROP_MEMBERSHIP fails on address: %s %m",
947
inter_list[i].num_mcast--;
948
/* If there are none left negate the Multicast flag */
949
if(inter_list[i].num_mcast == 0)
950
inter_list[i].flags &= ~INT_MULTICAST;
955
#ifdef ISC_PLATFORM_HAVEIPV6
957
haddr6 = ((struct sockaddr_in6*)&addr)->sin6_addr;
959
if (!IN6_IS_ADDR_MULTICAST(&haddr6))
962
"invalid multicast address %s", stoa(&addr));
967
* Disable reception of multicast packets
969
mreq6.ipv6mr_multiaddr = ((struct sockaddr_in6*)&addr)->sin6_addr;
970
mreq6.ipv6mr_interface = 0;
971
for (i = 0; i < ninterfaces; i++)
973
/* Be sure it's the correct family */
974
if (inter_list[i].sin.ss_family != AF_INET6)
976
if (!(inter_list[i].flags & INT_MULTICAST))
978
if (!(inter_list[i].fd < 0))
980
if (!SOCKCMP(&addr, &inter_list[i].sin))
984
/* we have an explicit fd, so we can close it */
985
close_socket(inter_list[i].fd);
986
memset((char *)&inter_list[i], 0, sizeof(struct interface));
987
inter_list[i].fd = INVALID_SOCKET;
988
inter_list[i].bfd = INVALID_SOCKET;
992
/* We are sharing "any address" port :-( Don't close it! */
993
if (setsockopt(inter_list[i].fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
994
(char *)&mreq6, sizeof(mreq6)) == -1)
995
netsyslog(LOG_ERR, "setsockopt IP_DROP_MEMBERSHIP fails on address %s: %m",
997
/* If there are none left negate the Multicast flag */
998
if(inter_list[i].num_mcast == 0)
999
inter_list[i].flags &= ~INT_MULTICAST;
1003
#endif /* ISC_PLATFORM_HAVEIPV6 */
1005
delete_addr_from_list(&addr);
854
1007
#else /* not MCAST */
855
msyslog(LOG_ERR, "this function requires multicast kernel");
1008
netsyslog(LOG_ERR, "this function requires multicast kernel");
856
1009
#endif /* not MCAST */
861
1014
* open_socket - open a socket, returning the file descriptor
865
struct sockaddr_in *addr,
1019
struct sockaddr_storage *addr,
867
1021
int turn_off_reuse
871
1026
int on = 1, off = 0;
872
1027
#if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS)
874
1029
#endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */
1031
if ((addr->ss_family == AF_INET6) && (isc_net_probeipv6() != ISC_R_SUCCESS))
1032
return (INVALID_SOCKET);
876
1034
/* create a datagram (UDP) socket */
877
if ( (fd = socket(AF_INET, SOCK_DGRAM, 0))
878
1035
#ifndef SYS_WINNT
1036
if ( (fd = socket(addr->ss_family, SOCK_DGRAM, 0)) < 0) {
1038
if(addr->ss_family == AF_INET)
1039
netsyslog(LOG_ERR, "socket(AF_INET, SOCK_DGRAM, 0) failed on address %s: %m",
1041
else if(addr->ss_family == AF_INET6)
1042
netsyslog(LOG_ERR, "socket(AF_INET6, SOCK_DGRAM, 0) failed on address %s: %m",
1044
if (errval == EPROTONOSUPPORT || errval == EAFNOSUPPORT ||
1045
errval == EPFNOSUPPORT)
1046
return (INVALID_SOCKET);
1051
if ( (fd = socket(addr->ss_family, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
1052
errval = WSAGetLastError();
1053
if(addr->ss_family == AF_INET)
1054
netsyslog(LOG_ERR, "socket(AF_INET, SOCK_DGRAM, 0) failed on address %s: %m",
1056
else if(addr->ss_family == AF_INET6)
1057
netsyslog(LOG_ERR, "socket(AF_INET6, SOCK_DGRAM, 0) failed on address %s: %m",
1059
if (errval == WSAEPROTONOSUPPORT || errval == WSAEAFNOSUPPORT ||
1060
errval == WSAEPFNOSUPPORT)
1061
return (INVALID_SOCKET);
1065
if (connection_reset_fix(fd) != ISC_R_SUCCESS) {
1066
netsyslog(LOG_ERR, "connection_reset_fix(fd) failed on address %s: %m",
882
1070
#endif /* SYS_WINNT */
885
msyslog(LOG_ERR, "socket(AF_INET, SOCK_DGRAM, 0) failed: %m");
890
1072
/* set SO_REUSEADDR since we will be binding the same port
891
1073
number on each interface */
892
1074
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
893
1075
(char *)&on, sizeof(on)))
895
msyslog(LOG_ERR, "setsockopt SO_REUSEADDR on fails: %m");
1077
netsyslog(LOG_ERR, "setsockopt SO_REUSEADDR on fails on address %s: %m",
1082
* IPv4 specific options go here
1084
if (addr->ss_family == AF_INET) {
898
1085
#if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS)
899
1086
/* set IP_TOS to minimize packet delay */
900
tos = IPTOS_LOWDELAY;
901
if (setsockopt(fd, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(tos)) < 0)
903
msyslog(LOG_ERR, "setsockopt IPTOS_LOWDELAY on fails: %m");
1087
tos = IPTOS_LOWDELAY;
1088
if (setsockopt(fd, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(tos)) < 0)
1090
netsyslog(LOG_ERR, "setsockopt IPTOS_LOWDELAY on fails on address %s: %m",
905
1093
#endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */
1097
* IPv6 specific options go here
1099
if (addr->ss_family == AF_INET6) {
1100
#if defined(IPV6_V6ONLY)
1101
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
1102
(char*)&on, sizeof(on)))
1104
netsyslog(LOG_ERR, "setsockopt IPV6_V6ONLY on fails on address %s: %m",
1107
#else /* IPV6_V6ONLY */
1108
#if defined(IPV6_BINDV6ONLY)
1109
if (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDV6ONLY,
1110
(char*)&on, sizeof(on)))
1113
"setsockopt IPV6_BINDV6ONLY on fails on address %s: %m",
1116
#endif /* IPV6_BINDV6ONLY */
1117
#endif /* IPV6_V6ONLY */
908
1121
* bind the local address.
910
if (bind(fd, (struct sockaddr *)addr, sizeof(*addr)) < 0) {
1123
if (bind(fd, (struct sockaddr *)addr, SOCKLEN(addr)) < 0) {
913
"bind() fd %d, family %d, port %d, addr %s, in_classd=%d flags=%d fails: %%m",
914
fd, addr->sin_family, (int)ntohs(addr->sin_port),
916
IN_CLASSD(ntohl(addr->sin_addr.s_addr)), flags);
917
msyslog(LOG_ERR, buff);
1126
if(addr->ss_family == AF_INET)
1128
"bind() fd %d, family %d, port %d, addr %s, in_classd=%d flags=%d fails: %%m",
1129
fd, addr->ss_family, (int)ntohs(((struct sockaddr_in*)addr)->sin_port),
1131
IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)), flags);
1132
else if(addr->ss_family == AF_INET6)
1134
"bind() fd %d, family %d, port %d, addr %s, in6_is_addr_multicast=%d flags=%d fails: %%m",
1135
fd, addr->ss_family, (int)ntohs(((struct sockaddr_in6*)addr)->sin6_port),
1137
IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr), flags);
1138
else return INVALID_SOCKET;
1140
netsyslog(LOG_ERR, buff);
918
1141
closesocket(fd);
921
* soft fail if opening a class D address
1144
* soft fail if opening a multicast address
923
if (IN_CLASSD(ntohl(addr->sin_addr.s_addr)))
1146
if(addr->ss_family == AF_INET){
1147
if(IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)))
1148
return (INVALID_SOCKET);
1151
if(IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr))
1152
return (INVALID_SOCKET);
1157
return INVALID_SOCKET;
933
1162
printf("bind() fd %d, family %d, port %d, addr %s, flags=%d\n",
936
(int)ntohs(addr->sin_port),
1165
(int)ntohs(((struct sockaddr_in*)addr)->sin_port),
1171
* I/O Completion Ports don't care about the select and FD_SET
1173
#ifndef HAVE_IO_COMPLETION_PORT
940
1174
if (fd > maxactivefd)
941
1175
maxactivefd = fd;
942
1176
FD_SET(fd, &activefds);
1178
add_socket_to_list(fd);
945
1180
* set non-blocking,