~ubuntu-branches/debian/squeeze/ntp/squeeze-201010051545

« back to all changes in this revision

Viewing changes to ntpd/ntp_io.c

  • Committer: Bazaar Package Importer
  • Author(s): Matt Zimmerman
  • Date: 2004-10-11 16:10:27 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20041011161027-icyjbji8ujym633o
Tags: 1:4.2.0a-10ubuntu2
Use ntp.ubuntulinux.org instead of pool.ntp.org

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
#include "ntp_refclock.h"
15
15
#include "ntp_if.h"
16
16
#include "ntp_stdlib.h"
 
17
#include "ntp.h"
 
18
 
 
19
/* Don't include ISC's version of IPv6 variables and structures */
 
20
#define ISC_IPV6_H 1
 
21
#include <isc/interfaceiter.h>
 
22
#include <isc/list.h>
 
23
#include <isc/result.h>
 
24
 
 
25
#ifdef SIM
 
26
#include "ntpsim.h"
 
27
#endif
17
28
 
18
29
#include <stdio.h>
19
30
#include <signal.h>
26
37
#ifdef HAVE_NETINET_IN_SYSTM_H
27
38
# include <netinet/in_systm.h>
28
39
#else /* Some old linux systems at least have in_system.h instead. */
29
 
# include <netinet/in_system.h>
 
40
# ifdef HAVE_NETINET_IN_SYSTEM_H
 
41
#  include <netinet/in_system.h>
 
42
# endif
30
43
#endif /* HAVE_NETINET_IN_SYSTM_H */
31
 
#include <netinet/ip.h>
 
44
#ifdef HAVE_NETINET_IP_H
 
45
# include <netinet/ip.h>
 
46
#endif
32
47
#ifdef HAVE_SYS_IOCTL_H
33
48
# include <sys/ioctl.h>
34
49
#endif
37
52
#endif
38
53
#include <arpa/inet.h>
39
54
 
40
 
#if _BSDI_VERSION >= 199510
41
 
# include <ifaddrs.h>
 
55
extern int listen_to_virtual_ips;
 
56
 
 
57
#if defined(SYS_WINNT)
 
58
#include <transmitbuff.h>
 
59
#include <isc/win32os.h>
 
60
/*
 
61
 * Define this macro to control the behavior of connection
 
62
 * resets on UDP sockets.  See Microsoft KnowledgeBase Article Q263823
 
63
 * for details.
 
64
 * NOTE: This requires that Windows 2000 systems install Service Pack 2
 
65
 * or later.
 
66
 */
 
67
#ifndef SIO_UDP_CONNRESET 
 
68
#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12) 
42
69
#endif
43
70
 
44
 
#if defined(VMS)                /* most likely UCX-specific */
45
 
 
46
 
#include <UCX$INETDEF.H>
47
 
 
48
 
/* "un*x"-compatible names for some items in UCX$INETDEF.H */
49
 
#define ifreq           IFREQDEF
50
 
#define ifr_name        IFR$T_NAME
51
 
#define ifr_addr                IFR$R_DUMMY.IFR$T_ADDR
52
 
#define ifr_broadaddr   IFR$R_DUMMY.IFR$T_BROADADDR
53
 
#define ifr_flags               IFR$R_DUMMY.IFR$R_DUMMY_1_OVRL.IFR$W_FLAGS
54
 
#define IFF_UP          IFR$M_IFF_UP
55
 
#define IFF_BROADCAST   IFR$M_IFF_BROADCAST
56
 
#define IFF_LOOPBACK    IFR$M_IFF_LOOPBACK
57
 
 
58
 
#endif /* VMS */
59
 
 
60
 
 
61
 
#if defined(VMS) || defined(SYS_WINNT)
62
 
/* structure used in SIOCGIFCONF request (after [KSR] OSF/1) */
63
 
struct ifconf {
64
 
        int ifc_len;                    /* size of buffer */
65
 
        union {
66
 
                caddr_t ifcu_buf;
67
 
                struct ifreq *ifcu_req;
68
 
        } ifc_ifcu;
69
 
};
70
 
#define ifc_buf ifc_ifcu.ifcu_buf       /* buffer address */
71
 
#define ifc_req ifc_ifcu.ifcu_req       /* array of structures returned */
72
 
 
73
 
#endif /* VMS */
74
 
 
75
 
#if defined(USE_TTY_SIGPOLL) || defined(USE_UDP_SIGPOLL)
76
 
# if defined(SYS_AIX) && defined(_IO) /* XXX Identify AIX some other way */
77
 
#  undef _IO
78
 
# endif
79
 
# include <stropts.h>
80
71
#endif
81
72
 
82
73
/*
112
103
/*
113
104
 * Interface stuff
114
105
 */
115
 
struct interface *any_interface;        /* default interface */
116
 
struct interface *loopback_interface;   /* loopback interface */
117
 
struct interface inter_list[MAXINTERFACES];
118
 
int ninterfaces;
 
106
struct interface *any_interface;        /* default ipv4 interface */
 
107
struct interface *any6_interface;       /* default ipv6 interface */
 
108
struct interface *loopback_interface;   /* loopback ipv4 interface */
 
109
struct interface *loopback6_interface;  /* loopback ipv6 interface */
 
110
struct interface inter_list[MAXINTERFACES]; /* Interface list */
 
111
int ninterfaces;                        /* Total number of interfaces */
 
112
int nwilds;                             /* Total number of wildcard intefaces */
 
113
int wildipv4 = -1;                      /* Index into inter_list for IPv4 wildcard */
 
114
int wildipv6 = -1;                      /* Index into inter_list for IPv6 wildcard */
119
115
 
120
116
#ifdef REFCLOCK
121
117
/*
125
121
static  struct refclockio *refio;
126
122
#endif /* REFCLOCK */
127
123
 
 
124
 
 
125
/*
 
126
 * Define what the possible "soft" errors can be.  These are non-fatal returns
 
127
 * of various network related functions, like recv() and so on.
 
128
 *
 
129
 * For some reason, BSDI (and perhaps others) will sometimes return <0
 
130
 * from recv() but will have errno==0.  This is broken, but we have to
 
131
 * work around it here.
 
132
 */
 
133
#define SOFT_ERROR(e)   ((e) == EAGAIN || \
 
134
                         (e) == EWOULDBLOCK || \
 
135
                         (e) == EINTR || \
 
136
                         (e) == 0)
 
137
 
128
138
/*
129
139
 * File descriptor masks etc. for call to select
 
140
 * Not needed for I/O Completion Ports
130
141
 */
131
142
fd_set activefds;
132
143
int maxactivefd;
133
144
 
134
 
static  int create_sockets      P((u_int));
135
 
static  int open_socket         P((struct sockaddr_in *, int, int));
136
 
static  void    close_socket    P((int));
137
 
static  void    close_file      P((int));
 
145
static  int create_sockets      P((u_short));
 
146
static  SOCKET  open_socket     P((struct sockaddr_storage *, int, int));
 
147
static  void    close_socket    P((SOCKET));
 
148
#ifdef REFCLOCK
 
149
static  void    close_file      P((SOCKET));
 
150
#endif
138
151
static  char *  fdbits          P((int, fd_set *));
139
 
 
 
152
static  void    set_reuseaddr   P((int));
 
153
 
 
154
typedef struct vsock vsock_t;
 
155
 
 
156
struct vsock {
 
157
        SOCKET                          fd;
 
158
        ISC_LINK(vsock_t)               link;
 
159
};
 
160
 
 
161
ISC_LIST(vsock_t)       sockets_list;
 
162
 
 
163
typedef struct remaddr remaddr_t;
 
164
 
 
165
struct remaddr {
 
166
      struct sockaddr_storage        addr;
 
167
      int                            if_index;
 
168
      ISC_LINK(remaddr_t)              link;
 
169
};
 
170
 
 
171
ISC_LIST(remaddr_t)       remoteaddr_list;
 
172
 
 
173
void    add_socket_to_list      P((SOCKET));
 
174
void    delete_socket_from_list P((SOCKET));
 
175
void    add_addr_to_list        P((struct sockaddr_storage *, int));
 
176
void    delete_addr_from_list   P((struct sockaddr_storage *));
 
177
int     find_addr_in_list P((struct sockaddr_storage *));
 
178
int     create_wildcards        P((u_short));
 
179
isc_boolean_t address_okay      P((isc_interface_t *));
 
180
void    convert_isc_if          P((isc_interface_t *, struct interface *, u_short));
 
181
 
 
182
#ifdef SYS_WINNT
 
183
/*
 
184
 * Windows 2000 systems incorrectly cause UDP sockets using WASRecvFrom
 
185
 * to not work correctly, returning a WSACONNRESET error when a WSASendTo
 
186
 * fails with an "ICMP port unreachable" response and preventing the
 
187
 * socket from using the WSARecvFrom in subsequent operations.
 
188
 * The function below fixes this, but requires that Windows 2000
 
189
 * Service Pack 2 or later be installed on the system.  NT 4.0
 
190
 * systems are not affected by this and work correctly.
 
191
 * See Microsoft Knowledge Base Article Q263823 for details of this.
 
192
 */
 
193
isc_result_t
 
194
connection_reset_fix(SOCKET fd) {
 
195
        DWORD dwBytesReturned = 0;
 
196
        BOOL  bNewBehavior = FALSE;
 
197
        DWORD status;
 
198
 
 
199
        if(isc_win32os_majorversion() < 5)
 
200
                return (ISC_R_SUCCESS); /*  NT 4.0 has no problem */
 
201
 
 
202
        /* disable bad behavior using IOCTL: SIO_UDP_CONNRESET */
 
203
        status = WSAIoctl(fd, SIO_UDP_CONNRESET, &bNewBehavior,
 
204
                          sizeof(bNewBehavior), NULL, 0,
 
205
                          &dwBytesReturned, NULL, NULL);
 
206
        if (status != SOCKET_ERROR)
 
207
                return (ISC_R_SUCCESS);
 
208
        else
 
209
                return (ISC_R_UNEXPECTED);
 
210
}
 
211
#endif
140
212
/*
141
213
 * init_io - initialize I/O data structures and call socket creation routine
142
214
 */
144
216
init_io(void)
145
217
{
146
218
#ifdef SYS_WINNT
147
 
        WORD wVersionRequested;
148
 
        WSADATA wsaData;
149
219
        init_transmitbuff();
150
220
#endif /* SYS_WINNT */
151
221
 
159
229
        packets_sent = packets_notsent = 0;
160
230
        handler_calls = handler_pkts = 0;
161
231
        io_timereset = 0;
162
 
        loopback_interface = 0;
 
232
        loopback_interface = NULL;
 
233
        loopback6_interface = NULL;
163
234
 
164
235
#ifdef REFCLOCK
165
236
        refio = 0;
170
241
#endif
171
242
 
172
243
#ifdef SYS_WINNT
173
 
        wVersionRequested = MAKEWORD(1,1);
174
 
        if (WSAStartup(wVersionRequested, &wsaData))
 
244
        if (!Win32InitSockets())
175
245
        {
176
 
                msyslog(LOG_ERR, "No useable winsock.dll: %m");
 
246
                netsyslog(LOG_ERR, "No useable winsock.dll: %m");
177
247
                exit(1);
178
248
        }
179
249
#endif /* SYS_WINNT */
180
250
 
 
251
        ISC_LIST_INIT(sockets_list);
 
252
 
 
253
        ISC_LIST_INIT(remoteaddr_list);
 
254
 
181
255
        /*
182
256
         * Create the sockets
183
257
         */
191
265
#endif
192
266
}
193
267
 
 
268
int
 
269
create_wildcards(u_short port) {
 
270
 
 
271
        int idx = 0;
 
272
        isc_boolean_t okipv4 = ISC_TRUE;
 
273
        /*
 
274
         * create pseudo-interface with wildcard IPv4 address
 
275
         */
 
276
#ifdef IPV6_V6ONLY
 
277
        if(isc_net_probeipv4() != ISC_R_SUCCESS)
 
278
                okipv4 = ISC_FALSE;
 
279
#endif
 
280
 
 
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];
 
295
#if defined(MCAST)
 
296
        /*
 
297
         * enable possible multicast reception on the broadcast socket
 
298
         */
 
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);
 
302
#endif /* MCAST */
 
303
                wildipv4 = idx;
 
304
                idx++;
 
305
        }
 
306
 
 
307
#ifdef ISC_PLATFORM_HAVEIPV6
 
308
        /*
 
309
         * create pseudo-interface with wildcard IPv6 address
 
310
         */
 
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];
 
325
                wildipv6 = idx;
 
326
                idx++;
 
327
        }
 
328
#endif
 
329
        return (idx);
 
330
}
 
331
 
 
332
isc_boolean_t
 
333
address_okay(isc_interface_t *isc_if) {
 
334
 
 
335
#ifdef DEBUG
 
336
        if (debug > 2)
 
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));
 
339
#endif
 
340
 
 
341
        if (listen_to_virtual_ips == 0  && (strchr(isc_if->name, (int)':') != NULL))
 
342
                return (ISC_FALSE);
 
343
 
 
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.
 
347
         */
 
348
/*      if ((isc_if->flags & INTERFACE_F_UP) == 0)
 
349
                return (ISC_FALSE);
 
350
*/
 
351
        return (ISC_TRUE);
 
352
}
 
353
void
 
354
convert_isc_if(isc_interface_t *isc_if, struct interface *itf, u_short port) {
 
355
 
 
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;
 
363
 
 
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;
 
371
                }
 
372
 
 
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;
 
378
 
 
379
                if (((isc_if->flags & INTERFACE_F_LOOPBACK) != 0) && (loopback_interface == NULL))
 
380
                {
 
381
                        loopback_interface = itf;
 
382
                }
 
383
        }
 
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;
 
392
 
 
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;
 
398
 
 
399
                if (((isc_if->flags & INTERFACE_F_LOOPBACK) != 0) && (loopback6_interface == NULL))
 
400
                {
 
401
                        loopback6_interface = itf;
 
402
                }
 
403
        }
 
404
#endif /* ISC_PLATFORM_HAVEIPV6 */
 
405
 
 
406
                /* Process the rest of the flags */
 
407
 
 
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;
 
414
 
 
415
        /* Copy the scopeid and the interface index */
 
416
        itf->ifindex = isc_if->ifindex;
 
417
        itf->scopeid = isc_if->scopeid;
 
418
}
194
419
/*
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
197
422
 */
198
423
static int
199
424
create_sockets(
200
 
        u_int port
 
425
        u_short port
201
426
        )
202
427
{
203
 
#if _BSDI_VERSION >= 199510
204
 
        int i, j;
205
 
        struct ifaddrs *ifaddrs, *ifap;
206
 
        struct sockaddr_in resmask;
207
 
#if     _BSDI_VERSION < 199701
208
 
        struct ifaddrs *lp;
209
 
        int num_if;
210
 
#endif
211
 
#else   /* _BSDI_VERSION >= 199510 */
212
 
# ifdef STREAMS_TLI
213
 
        struct strioctl ioc;
214
 
# endif /* STREAMS_TLI */
215
 
        char    buf[MAXINTERFACES*sizeof(struct ifreq)];
216
 
        struct  ifconf  ifc;
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;
 
429
        int i;
 
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;
 
434
        isc_result_t result;
 
435
        int idx = 0;
221
436
 
222
437
#ifdef DEBUG
223
438
        if (debug)
224
439
            printf("create_sockets(%d)\n", ntohs( (u_short) port));
225
440
#endif
226
441
 
 
442
        if (isc_net_probeipv6() == ISC_R_SUCCESS)
 
443
                scan_ipv6 = ISC_TRUE;
 
444
#if defined(ISC_PLATFORM_HAVEIPV6) && defined(DEBUG)
 
445
        else
 
446
                if(debug)
 
447
                        netsyslog(LOG_ERR, "no IPv6 interfaces found");
 
448
#endif
 
449
 
 
450
        if (isc_net_probeipv4() == ISC_R_SUCCESS)
 
451
                scan_ipv4 = ISC_TRUE;
 
452
#ifdef DEBUG
 
453
        else
 
454
                if(debug)
 
455
                        netsyslog(LOG_ERR, "no IPv4 interfaces found");
 
456
#endif
 
457
 
 
458
        nwilds = create_wildcards(port);
 
459
        idx = nwilds;
 
460
 
 
461
        result = isc_interfaceiter_create(mctx, &iter);
 
462
        if (result != ISC_R_SUCCESS)
 
463
                return (result);
 
464
 
 
465
        for (result = isc_interfaceiter_first(iter);
 
466
             result == ISC_R_SUCCESS;
 
467
             result = isc_interfaceiter_next(iter))
 
468
        {
 
469
                isc_interface_t isc_if;
 
470
                unsigned int family; 
 
471
 
 
472
                result = isc_interfaceiter_current(iter, &isc_if);
 
473
                if (result != ISC_R_SUCCESS)
 
474
                        break;
 
475
 
 
476
                /* See if we have a valid family to use */
 
477
                family = isc_if.address.family;
 
478
                if (family != AF_INET && family != AF_INET6)
 
479
                        continue;
 
480
                if (scan_ipv4 == ISC_FALSE && family == AF_INET)
 
481
                        continue;
 
482
                if (scan_ipv6 == ISC_FALSE && family == AF_INET6)
 
483
                        continue;
 
484
 
 
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;
 
494
                        idx++;
 
495
                }
 
496
        }
 
497
        isc_interfaceiter_destroy(&iter);
 
498
 
 
499
        ninterfaces = idx;
227
500
        /*
228
 
         * create pseudo-interface with wildcard address
 
501
         * I/O Completion Ports don't care about the select and FD_SET
229
502
         */
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];
241
 
 
242
 
#if _BSDI_VERSION >= 199510
243
 
#if     _BSDI_VERSION >= 199701
244
 
        if (getifaddrs(&ifaddrs) < 0)
245
 
        {
246
 
                msyslog(LOG_ERR, "getifaddrs: %m");
247
 
                exit(1);
248
 
        }
249
 
        i = 1;
250
 
        for (ifap = ifaddrs; ifap != NULL; ifap = ifap->ifa_next)
251
 
#else
252
 
            if (getifaddrs(&ifaddrs, &num_if) < 0)
253
 
            {
254
 
                    msyslog(LOG_ERR, "create_sockets: getifaddrs() failed: %m");
255
 
                    exit(1);
256
 
            }
257
 
 
258
 
        i = 1;
259
 
 
260
 
        for (ifap = ifaddrs, lp = ifap + num_if; ifap < lp; ifap++)
261
 
#endif
262
 
        {
263
 
                struct sockaddr_in *sin;
264
 
 
265
 
                if (!ifap->ifa_addr)
266
 
                    continue;
267
 
 
268
 
                if (ifap->ifa_addr->sa_family != AF_INET)
269
 
                    continue;
270
 
 
271
 
                if ((ifap->ifa_flags & IFF_UP) == 0)
272
 
                    continue;
273
 
 
274
 
                if (ifap->ifa_flags & IFF_LOOPBACK) {
275
 
                        sin = (struct sockaddr_in *)ifap->ifa_addr;
276
 
                        if (ntohl(sin->sin_addr.s_addr) != 0x7f000001)
277
 
                                continue;
278
 
                }
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];
291
 
                }
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;
296
 
                }
297
 
                if (ifap->ifa_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) {
298
 
                        inter_list[i].mask.sin_addr.s_addr = 0xffffffff;
299
 
                } else {
300
 
                        sin = (struct sockaddr_in *)ifap->ifa_netmask;
301
 
                        inter_list[i].mask = *sin;
302
 
                }
303
 
                inter_list[i].mask.sin_family = AF_INET;
304
 
                inter_list[i].mask.sin_len = sizeof *sin;
305
 
 
306
 
                /*
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.
310
 
                 *
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
315
 
                 */
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)
321
 
                    {
322
 
                            if (inter_list[j].flags & INT_LOOPBACK)
323
 
                                inter_list[j] = inter_list[i];
324
 
                            break;
325
 
                    }
326
 
                if (j == i)
327
 
                    i++;
328
 
                if (i > MAXINTERFACES)
329
 
                    break;
330
 
        }
331
 
        free(ifaddrs);
332
 
#else   /* _BSDI_VERSION >= 199510 */
333
 
# ifdef USE_STREAMS_DEVICE_FOR_IF_CONFIG
334
 
        if ((vs = open("/dev/ip", O_RDONLY)) < 0)
335
 
        {
336
 
                msyslog(LOG_ERR, "create_sockets: open(/dev/ip) failed: %m");
337
 
                exit(1);
338
 
        }
339
 
# else /* not USE_STREAMS_DEVICE_FOR_IF_CONFIG */
340
 
        if (
341
 
                (vs = socket(AF_INET, SOCK_DGRAM, 0))
342
 
#  ifndef SYS_WINNT
343
 
                < 0
344
 
#  else /* SYS_WINNT */
345
 
                == INVALID_SOCKET
346
 
#  endif /* SYS_WINNT */
347
 
                ) {
348
 
                msyslog(LOG_ERR, "create_sockets: socket(AF_INET, SOCK_DGRAM) failed: %m");
349
 
                exit(1);
350
 
        }
351
 
# endif /* not USE_STREAMS_DEVICE_FOR_IF_CONFIG */
352
 
 
353
 
        i = 1;
354
 
# if !defined(SYS_WINNT)
355
 
        ifc.ifc_len = sizeof(buf);
356
 
# endif
357
 
# ifdef STREAMS_TLI
358
 
        ioc.ic_cmd = SIOCGIFCONF;
359
 
        ioc.ic_timout = 0;
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))
364
 
        {
365
 
                msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFCONF) failed: %m - exiting");
366
 
                exit(1);
367
 
        }
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;
373
 
        ifc.ifc_buf = buf;
374
 
#  endif /* not SIZE_RETURNED_IN_BUFFER */
375
 
 
376
 
# else /* not STREAMS_TLI */
377
 
        ifc.ifc_len = sizeof(buf);
378
 
        ifc.ifc_buf = buf;
379
 
#  ifndef SYS_WINNT
380
 
        if (ioctl(vs, SIOCGIFCONF, (char *)&ifc) < 0)
381
 
#  else
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 */
384
 
{
385
 
                msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFCONF) failed: %m - exiting");
386
 
                exit(1);
387
 
}
388
 
 
389
 
# endif /* not STREAMS_TLI */
390
 
 
391
 
        for(n = ifc.ifc_len, ifr = ifc.ifc_req; n > 0;
392
 
            ifr = (struct ifreq *)((char *)ifr + size))
393
 
        {
394
 
                extern int listen_to_virtual_ips;
395
 
 
396
 
                size = sizeof(*ifr);
397
 
 
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);
401
 
# endif
402
 
                n -= size;
403
 
 
404
 
# if !defined(SYS_WINNT)
405
 
                /* Exclude logical interfaces (indicated by ':' in the interface name)  */
406
 
                if (debug)
407
 
                        printf("interface <%s> ", ifr->ifr_name);
408
 
                if ((listen_to_virtual_ips == 0)
409
 
                    && (strchr(ifr->ifr_name, (int)':') != NULL)) {
410
 
                        if (debug)
411
 
                            printf("ignored\n");
412
 
                        continue;
413
 
                }
414
 
                if (debug)
415
 
                    printf("OK\n");
416
 
 
417
 
                if (
418
 
#  ifdef VMS /* VMS+UCX */
419
 
                        (((struct sockaddr *)&(ifr->ifr_addr))->sa_family != AF_INET)
420
 
#  else
421
 
                        (ifr->ifr_addr.sa_family != AF_INET)
422
 
#  endif /* VMS+UCX */
423
 
                        ) {
424
 
                        if (debug)
425
 
                            printf("ignoring %s - not AF_INET\n",
426
 
                                   ifr->ifr_name);
427
 
                        continue;
428
 
                }
429
 
# endif /* SYS_WINNT */
430
 
                ifreq = *ifr;
431
 
                inter_list[i].flags = 0;
432
 
                /* is it broadcast capable? */
433
 
# ifndef SYS_WINNT
434
 
#  ifdef STREAMS_TLI
435
 
                ioc.ic_cmd = SIOCGIFFLAGS;
436
 
                ioc.ic_timout = 0;
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");
441
 
                        continue;
442
 
                }
443
 
#  else /* not STREAMS_TLI */
444
 
                if (ioctl(vs, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
445
 
                        if (errno != ENXIO)
446
 
                            msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFFLAGS) failed: %m");
447
 
                        continue;
448
 
                }
449
 
#  endif /* not STREAMS_TLI */
450
 
                if ((ifreq.ifr_flags & IFF_UP) == 0) {
451
 
                        if (debug)
452
 
                            printf("ignoring %s - interface not UP\n",
453
 
                                   ifr->ifr_name);
454
 
                        continue;
455
 
                }
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)
461
 
                if (
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 */
470
 
                        )
471
 
                {
472
 
#  ifndef SYS_WINNT
473
 
                        inter_list[i].flags |= INT_LOOPBACK;
474
 
#  endif /* not SYS_WINNT */
475
 
                        if (loopback_interface == 0)
476
 
                        {
477
 
                                loopback_interface = &inter_list[i];
478
 
                        }
479
 
                }
480
 
# endif /* not SUN_3_3_STINKS */
481
 
 
482
 
#if 0
483
 
# ifndef SYS_WINNT
484
 
#  ifdef STREAMS_TLI
485
 
                ioc.ic_cmd = SIOCGIFADDR;
486
 
                ioc.ic_timout = 0;
487
 
                ioc.ic_dp = (caddr_t)&ifreq;
488
 
                ioc.ic_len = sizeof(struct ifreq);
489
 
                if (ioctl(vs, I_STR, &ioc))
490
 
                {
491
 
                        msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFADDR) failed: %m");
492
 
                        continue;
493
 
                }
494
 
#  else /* not STREAMS_TLI */
495
 
                if (ioctl(vs, SIOCGIFADDR, (char *)&ifreq) < 0)
496
 
                {
497
 
                        if (errno != ENXIO)
498
 
                            msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFADDR) failed: %m");
499
 
                        continue;
500
 
                }
501
 
#  endif /* not STREAMS_TLI */
502
 
# endif /* not SYS_WINNT */
503
 
#endif /* 0 */
504
 
# if defined(SYS_WINNT)
505
 
                {int TODO_FillInTheNameWithSomeThingReasonble;}
506
 
# else
507
 
                (void)strncpy(inter_list[i].name, ifreq.ifr_name,
508
 
                              sizeof(inter_list[i].name));
509
 
# endif
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;
513
 
 
514
 
# if defined(SUN_3_3_STINKS)
515
 
                /*
516
 
                 * Oh, barf!  I'm too disgusted to even explain this
517
 
                 */
518
 
                if (SRCADR(&inter_list[i].sin) == 0x7f000001)
519
 
                {
520
 
                        inter_list[i].flags |= INT_LOOPBACK;
521
 
                        if (loopback_interface == 0)
522
 
                            loopback_interface = &inter_list[i];
523
 
                }
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) {
527
 
#  ifdef STREAMS_TLI
528
 
                        ioc.ic_cmd = SIOCGIFBRDADDR;
529
 
                        ioc.ic_timout = 0;
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");
534
 
                                exit(1);
535
 
                        }
536
 
#  else /* not STREAMS_TLI */
537
 
                        if (ioctl(vs, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
538
 
                                msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFBRDADDR) failed: %m");
539
 
                                exit(1);
540
 
                        }
541
 
#  endif /* not STREAMS_TLI */
542
 
 
543
 
#  ifndef ifr_broadaddr
544
 
                        inter_list[i].bcast =
545
 
                            *(struct sockaddr_in *)&ifreq.ifr_addr;
546
 
#  else
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;
552
 
                }
553
 
 
554
 
#  ifdef STREAMS_TLI
555
 
                ioc.ic_cmd = SIOCGIFNETMASK;
556
 
                ioc.ic_timout = 0;
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");
561
 
                        exit(1);
562
 
                }
563
 
#  else /* not STREAMS_TLI */
564
 
                if (ioctl(vs, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
565
 
                        msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFNETMASK) failed: %m");
566
 
                        exit(1);
567
 
                }
568
 
#  endif /* not STREAMS_TLI */
569
 
                inter_list[i].mask                 = *(struct sockaddr_in *)&ifreq.ifr_addr;
570
 
# else
571
 
                /* winnt here */
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 */
577
 
 
578
 
                /*
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.
582
 
                 */
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) {
586
 
                            break;
587
 
                    }
588
 
                if (j == i)
589
 
                    i++;
590
 
                if (i > MAXINTERFACES)
591
 
                    break;
592
 
        }
593
 
        closesocket(vs);
594
 
#endif  /* _BSDI_VERSION >= 199510 */
595
 
 
596
 
        ninterfaces = i;
 
503
#ifndef HAVE_IO_COMPLETION_PORT
597
504
        maxactivefd = 0;
598
505
        FD_ZERO(&activefds);
 
506
#endif
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);
602
 
        }
603
 
 
604
 
        /*
605
 
         * Now that we have opened all the sockets, turn off the reuse flag for
606
 
         * security.
607
 
         */
608
 
        for (i = 0; i < ninterfaces; i++) {
609
 
                int off = 0;
610
 
 
611
 
                /*
612
 
                 * if inter_list[ n ].fd  is -1, we might have a adapter
613
 
                 * configured but not present
614
 
                 */
615
 
                if ( inter_list[ i ].fd != -1 ) {
616
 
                        if (setsockopt(inter_list[i].fd, SOL_SOCKET,
617
 
                                       SO_REUSEADDR, (char *)&off,
618
 
                                       sizeof(off))) {
619
 
                                msyslog(LOG_ERR, "create_sockets: setsockopt(SO_REUSEADDR,off) failed: %m");
620
 
                        }
 
510
                if (inter_list[i].fd != INVALID_SOCKET)
 
511
                        msyslog(LOG_INFO, "Listening on interface %s, %s#%d",
 
512
                                inter_list[i].name,
 
513
                                stoa((&inter_list[i].sin)),
 
514
                                NTP_PORT);
 
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)),
 
519
                                NTP_PORT);
 
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]);
621
523
                }
 
524
#endif
622
525
        }
623
526
 
624
 
#if defined(MCAST)
625
527
        /*
626
 
         * enable possible multicast reception on the broadcast socket
 
528
         * Now that we have opened all the sockets, turn off the reuse
 
529
         * flag for security.
627
530
         */
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;
631
 
#endif /* MCAST */
 
531
        set_reuseaddr(0);
632
532
 
633
533
        /*
634
534
         * Blacklist all bound interface addresses
 
535
         * Wildcard interfaces are ignored.
635
536
         */
636
 
        resmask.sin_addr.s_addr = ~ (u_int32)0;
637
 
        for (i = 1; i < ninterfaces; i++)
 
537
 
 
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);
 
542
        }
 
543
 
 
544
        /*
 
545
         * Calculate the address hash for each interface address.
 
546
         */
 
547
        for (i = 0; i < ninterfaces; i++) {
 
548
                inter_list[i].addr_refid = addr2refid(&inter_list[i].sin);
 
549
        }
 
550
 
 
551
 
640
552
#ifdef DEBUG
641
553
        if (debug > 1) {
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",
645
557
                               i,
646
558
                               inter_list[i].fd,
647
559
                               inter_list[i].bfd,
648
560
                               inter_list[i].name,
649
 
                               inter_list[i].flags);
 
561
                               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)));
658
571
                }
659
572
        }
660
573
#endif
661
 
#if defined (HAVE_IO_COMPLETION_PORT)
662
 
        for (i = 0; i < ninterfaces; i++) {
663
 
                io_completion_port_add_socket(&inter_list[i]);
664
 
        }
665
 
#endif
666
574
        return ninterfaces;
667
575
}
668
576
 
672
580
void
673
581
io_setbclient(void)
674
582
{
 
583
#ifdef OPEN_BCAST_SOCKET 
675
584
        int i;
676
 
 
677
 
        for (i = 1; i < ninterfaces; i++) {
 
585
        int nif = 0;
 
586
 
 
587
        set_reuseaddr(1);
 
588
 
 
589
        for (i = nwilds; i < ninterfaces; i++) {
 
590
                /* Only IPv4 addresses are valid for broadcast */
 
591
                if (inter_list[i].bcast.ss_family != AF_INET)
 
592
                        continue;
 
593
 
 
594
                /* Is this a broadcast address? */
678
595
                if (!(inter_list[i].flags & INT_BROADCAST))
679
596
                        continue;
680
597
 
 
598
                /* Do we already have the broadcast address open? */
681
599
                if (inter_list[i].flags & INT_BCASTOPEN)
682
600
                        continue;
683
601
 
684
 
#ifdef  SYS_SOLARIS
685
 
                inter_list[i].bcast.sin_addr.s_addr = htonl(INADDR_ANY);
686
 
#endif
687
 
#ifdef OPEN_BCAST_SOCKET /* Was: !SYS_DOMAINOS && !SYS_LINUX */
688
602
                inter_list[i].bfd = open_socket(&inter_list[i].bcast,
689
603
                    INT_BROADCAST, 1);
690
 
                inter_list[i].flags |= INT_BCASTOPEN;
691
 
#endif
 
604
                if (inter_list[i].bfd != INVALID_SOCKET) {
 
605
                        inter_list[i].flags |= INT_BCASTOPEN;
 
606
                        nif++;
 
607
#if defined (HAVE_IO_COMPLETION_PORT)
 
608
                        io_completion_port_add_socket(inter_list[i].bfd, &inter_list[i]);
 
609
#endif
 
610
                }
 
611
#ifdef DEBUG
 
612
                if (debug) {
 
613
                        if (inter_list[i].bfd != INVALID_SOCKET)
 
614
                                printf("io_setbclient: Opened broadcast client on interface %d, socket: %d\n",
 
615
                                i, inter_list[i].bfd);
 
616
                        else
 
617
                                printf("io_setbclient: Unable to Open broadcast client on interface %d\n",
 
618
                                i);
 
619
                }
 
620
#endif
 
621
        }
 
622
        set_reuseaddr(0);
 
623
#ifdef DEBUG
 
624
        if (debug)
 
625
                if (nif > 0)
 
626
                        printf("io_setbclient: Opened broadcast clients\n");
 
627
#endif
 
628
                if (nif == 0)
 
629
                        netsyslog(LOG_ERR, "Unable to listen for broadcasts, no broadcast interfaces available");
 
630
#else
 
631
        netsyslog(LOG_ERR, "io_setbclient: Broadcast Client disabled by build");
 
632
#endif
 
633
}
 
634
 
 
635
/*
 
636
 * set_reuseaddr() - set/clear REUSEADDR on all sockets
 
637
 *                      NB possible hole - should we be doing this on broadcast
 
638
 *                      fd's also?
 
639
 */
 
640
static void
 
641
set_reuseaddr(int flag) {
 
642
        int i;
 
643
 
 
644
        for (i=0; i < ninterfaces; i++) {
 
645
                /*
 
646
                 * if inter_list[ n ].fd  is -1, we might have a adapter
 
647
                 * configured but not present
 
648
                 */
 
649
                if (inter_list[i].fd != INVALID_SOCKET) {
 
650
                        if (setsockopt(inter_list[i].fd, SOL_SOCKET,
 
651
                                        SO_REUSEADDR, (char *)&flag,
 
652
                                        sizeof(flag))) {
 
653
                                netsyslog(LOG_ERR, "set_reuseaddr: setsockopt(SO_REUSEADDR, %s) failed: %m", flag ? "on" : "off");
 
654
                        }
 
655
                }
692
656
        }
693
657
}
694
658
 
698
662
 */
699
663
void
700
664
io_multicast_add(
701
 
        u_int32 addr
 
665
        struct sockaddr_storage addr
702
666
        )
703
667
{
704
668
#ifdef MCAST
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;
709
 
        int s;
 
673
        SOCKET s;
710
674
        struct sockaddr_in *sinp;
711
675
 
712
 
        iaddr.s_addr = addr;
713
 
        if (!IN_CLASSD(haddr)) {
714
 
                msyslog(LOG_ERR,
715
 
                    "multicast address %s not class D",
716
 
                        inet_ntoa(iaddr));
717
 
                return;
718
 
        }
719
 
        for (i = 0; i < ninterfaces; i++) {
720
 
                /* Already have this address */
721
 
                if (inter_list[i].sin.sin_addr.s_addr == addr)
722
 
                        return;
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)
727
 
                break;
728
 
        }
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);
735
 
 
736
 
        /*
737
 
         * Try opening a socket for the specified class D address. This
738
 
         * works under SunOS 4.x, but not OSF1 .. :-(
739
 
         */
740
 
        s = open_socket(sinp, 0, 1);
741
 
        if (s < 0) {
742
 
                memset((char *)&inter_list[i], 0, sizeof inter_list[0]);
743
 
                i = 0;
744
 
                /* HACK ! -- stuff in an address */
745
 
                inter_list[i].bcast.sin_addr.s_addr = addr;
746
 
                msyslog(LOG_ERR,
747
 
                    "...multicast address %s using wildcard socket",
748
 
                    inet_ntoa(iaddr));
749
 
        } else {
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);
755
 
        }
756
 
 
757
 
        /*
758
 
         * enable reception of multicast packets
759
 
         */
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)
764
 
                msyslog(LOG_ERR,
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)
770
 
            ninterfaces = i+1;
 
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 */
 
681
 
 
682
        switch (addr.ss_family)
 
683
        {
 
684
        case AF_INET :
 
685
                iaddr = (((struct sockaddr_in*)&addr)->sin_addr);
 
686
                if (!IN_CLASSD(haddr)) {
 
687
                        netsyslog(LOG_ERR,
 
688
                        "multicast address %s not class D",
 
689
                                inet_ntoa(iaddr));
 
690
                        return;
 
691
                }
 
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)
 
695
                                continue;
 
696
                        /* Already have this address */
 
697
                        if (SOCKCMP(&inter_list[i].sin, &addr))
 
698
                                return;
 
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)
 
703
                        break;
 
704
                }
 
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);
 
711
 
 
712
                /*
 
713
                * Try opening a socket for the specified class D address. This
 
714
                * works under SunOS 4.x, but not OSF1 .. :-(
 
715
                */
 
716
                set_reuseaddr(1);
 
717
                s = open_socket((struct sockaddr_storage*)sinp, 0, 1);
 
718
                set_reuseaddr(0);
 
719
                if (s == INVALID_SOCKET) {
 
720
                        memset((char *)&inter_list[i], 0, sizeof(struct interface));
 
721
                        if (wildipv4 >= 0) {
 
722
                                i = wildipv4;
 
723
                                /* HACK ! -- stuff in an address */
 
724
                                inter_list[i].bcast = addr;
 
725
                                netsyslog(LOG_ERR,
 
726
                                "...multicast address %s using wildcard socket",
 
727
                                inet_ntoa(iaddr));
 
728
                        } else {
 
729
                                netsyslog(LOG_ERR,
 
730
                                "No wildcard socket available to use for address %s",
 
731
                                inet_ntoa(iaddr));
 
732
                                return;
 
733
                        }
 
734
                } else {
 
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]);
 
742
#endif
 
743
                }
 
744
 
 
745
                /*
 
746
                * enable reception of multicast packets
 
747
                */
 
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)
 
752
                        netsyslog(LOG_ERR,
 
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)
 
759
                        ninterfaces = i+1;
 
760
 
 
761
                add_addr_to_list(&addr, i);
 
762
                break;
 
763
 
 
764
#ifdef ISC_PLATFORM_HAVEIPV6
 
765
        case AF_INET6 :
 
766
 
 
767
                iaddr6 = ((struct sockaddr_in6*)&addr)->sin6_addr;
 
768
                if (!IN6_IS_ADDR_MULTICAST(&iaddr6)) {
 
769
                        netsyslog(LOG_ERR,
 
770
                            "address %s not IPv6 multicast address",
 
771
                                stoa(&addr));
 
772
                        return;
 
773
                }
 
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)
 
777
                                continue;
 
778
                        /* Already have this address */
 
779
                        if (SOCKCMP(&inter_list[i].sin, &addr))
 
780
                                return;
 
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)
 
785
                        break;
 
786
                }
 
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);
 
794
 
 
795
                /*
 
796
                 * Try opening a socket for the specified class D address. This
 
797
                 * works under SunOS 4.x, but not OSF1 .. :-(
 
798
                 */
 
799
                set_reuseaddr(1);
 
800
                s = open_socket((struct sockaddr_storage*)sin6p, 0, 1);
 
801
                set_reuseaddr(0);
 
802
                if(s == INVALID_SOCKET){
 
803
                        memset((char *)&inter_list[i], 0, sizeof(struct interface));
 
804
                        if (wildipv6 >= 0) {
 
805
                                i = wildipv6;
 
806
                                /* HACK ! -- stuff in an address */
 
807
                                inter_list[i].bcast = addr;
 
808
                                netsyslog(LOG_ERR,
 
809
                                 "...multicast address %s using wildcard socket",
 
810
                                 stoa(&addr));
 
811
                        } else {
 
812
                                netsyslog(LOG_ERR,
 
813
                                "No wildcard socket available to use for address %s",
 
814
                                stoa(&addr));
 
815
                                return;
 
816
                        }
 
817
                } else {
 
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]);
 
825
#endif
 
826
                }
 
827
 
 
828
                /*
 
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.
 
833
                 */
 
834
                mreq6.ipv6mr_multiaddr = iaddr6;
 
835
                if (IN6_IS_ADDR_MC_LINKLOCAL(&iaddr6))
 
836
                        mreq6.ipv6mr_interface = sin6p->sin6_scope_id;
 
837
                else
 
838
                        mreq6.ipv6mr_interface = 0;
 
839
 
 
840
                if(setsockopt(inter_list[i].fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
 
841
                   (char *)&mreq6, sizeof(mreq6)) == -1)
 
842
                        netsyslog(LOG_ERR,
 
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++;
 
847
                if(i >= ninterfaces)
 
848
                        ninterfaces = i+1;
 
849
 
 
850
                add_addr_to_list(&addr, i);
 
851
                break;
 
852
#endif /* ISC_PLATFORM_HAVEIPV6 */
 
853
        }
 
854
 
 
855
#ifdef DEBUG
 
856
        if (debug)
 
857
                printf("io_multicast_add %s\n", stoa(&addr));
 
858
#endif
771
859
#else /* MCAST */
772
 
        struct in_addr iaddr;
773
 
 
774
 
        iaddr.s_addr = addr;
775
 
        msyslog(LOG_ERR,
 
860
        netsyslog(LOG_ERR,
776
861
            "cannot add multicast address %s as no MCAST support",
777
 
            inet_ntoa(iaddr));
 
862
            stoa(&addr));
778
863
#endif /* MCAST */
779
864
}
780
865
 
786
871
{
787
872
        int i;
788
873
 
789
 
        for (i = 1; i < ninterfaces; i++)
 
874
        for (i = nwilds; i < ninterfaces; i++)
790
875
        {
791
876
                if (!(inter_list[i].flags & INT_BCASTOPEN))
792
877
                    continue;
793
878
                close_socket(inter_list[i].bfd);
794
 
                inter_list[i].bfd = -1;
 
879
                inter_list[i].bfd = INVALID_SOCKET;
795
880
                inter_list[i].flags &= ~INT_BCASTOPEN;
796
881
        }
797
882
}
802
887
 */
803
888
void
804
889
io_multicast_del(
805
 
        u_int32 addr
 
890
        struct sockaddr_storage addr
806
891
        )
807
892
{
808
893
#ifdef MCAST
809
894
        int i;
810
895
        struct ip_mreq mreq;
811
 
        u_int32 haddr = ntohl(addr);
812
 
        struct sockaddr_in sinaddr;
813
 
 
814
 
        if (!IN_CLASSD(haddr))
815
 
        {
816
 
                sinaddr.sin_addr.s_addr = addr;
817
 
                msyslog(LOG_ERR,
818
 
                        "invalid multicast address %s", ntoa(&sinaddr));
819
 
                return;
820
 
        }
821
 
 
822
 
        /*
823
 
         * Disable reception of multicast packets
824
 
         */
825
 
        mreq.imr_multiaddr.s_addr = addr;
826
 
        mreq.imr_interface.s_addr = htonl(INADDR_ANY);
827
 
        for (i = 0; i < ninterfaces; i++)
828
 
        {
829
 
                if (!(inter_list[i].flags & INT_MULTICAST))
830
 
                    continue;
831
 
                if (!(inter_list[i].fd < 0))
832
 
                    continue;
833
 
                if (addr != inter_list[i].sin.sin_addr.s_addr)
834
 
                    continue;
835
 
                if (i != 0)
836
 
                {
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;
842
 
                }
843
 
                else
844
 
                {
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;
852
 
                }
853
 
        }
 
896
        u_int32 haddr;
 
897
 
 
898
#ifdef ISC_PLATFORM_HAVEIPV6
 
899
        struct ipv6_mreq mreq6;
 
900
        struct in6_addr haddr6;
 
901
#endif /* ISC_PLATFORM_HAVEIPV6 */
 
902
 
 
903
        switch (addr.ss_family)
 
904
        {
 
905
        case AF_INET :
 
906
 
 
907
                haddr = ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr);
 
908
 
 
909
                if (!IN_CLASSD(haddr))
 
910
                {
 
911
                        netsyslog(LOG_ERR,
 
912
                                 "invalid multicast address %s", stoa(&addr));
 
913
                        return;
 
914
                }
 
915
 
 
916
                /*
 
917
                * Disable reception of multicast packets
 
918
                */
 
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++)
 
922
                {
 
923
                        /* Be sure it's the correct family */
 
924
                        if (inter_list[i].sin.ss_family != AF_INET)
 
925
                                continue;
 
926
                        if (!(inter_list[i].flags & INT_MULTICAST))
 
927
                                continue;
 
928
                        if (!(inter_list[i].fd < 0))
 
929
                                continue;
 
930
                        if (!SOCKCMP(&addr, &inter_list[i].sin))
 
931
                                continue;
 
932
                        if (i != wildipv4)
 
933
                        {
 
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;
 
939
                        }
 
940
                        else
 
941
                        {
 
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",
 
946
                                        stoa(&addr));
 
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;
 
951
                        }
 
952
                }
 
953
                break;
 
954
 
 
955
#ifdef ISC_PLATFORM_HAVEIPV6
 
956
        case AF_INET6 :
 
957
                haddr6 = ((struct sockaddr_in6*)&addr)->sin6_addr;
 
958
 
 
959
                if (!IN6_IS_ADDR_MULTICAST(&haddr6))
 
960
                {
 
961
                        netsyslog(LOG_ERR,
 
962
                                "invalid multicast address %s", stoa(&addr));
 
963
                        return;
 
964
                }
 
965
 
 
966
                /*
 
967
                * Disable reception of multicast packets
 
968
                */
 
969
                mreq6.ipv6mr_multiaddr = ((struct sockaddr_in6*)&addr)->sin6_addr;
 
970
                mreq6.ipv6mr_interface = 0;
 
971
                for (i = 0; i < ninterfaces; i++)
 
972
                {
 
973
                        /* Be sure it's the correct family */
 
974
                        if (inter_list[i].sin.ss_family != AF_INET6)
 
975
                                continue;
 
976
                        if (!(inter_list[i].flags & INT_MULTICAST))
 
977
                                continue;
 
978
                        if (!(inter_list[i].fd < 0))
 
979
                                continue;
 
980
                        if (!SOCKCMP(&addr, &inter_list[i].sin))
 
981
                                continue;
 
982
                        if (i != wildipv6)
 
983
                        {
 
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;
 
989
                        }
 
990
                        else
 
991
                        {
 
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",
 
996
                                        stoa(&addr));
 
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;
 
1000
                        }
 
1001
                }
 
1002
                break;
 
1003
#endif /* ISC_PLATFORM_HAVEIPV6 */
 
1004
        }/* switch */
 
1005
        delete_addr_from_list(&addr);
 
1006
 
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 */
857
1010
}
858
1011
 
860
1013
/*
861
1014
 * open_socket - open a socket, returning the file descriptor
862
1015
 */
863
 
static int
 
1016
 
 
1017
static SOCKET
864
1018
open_socket(
865
 
        struct sockaddr_in *addr,
 
1019
        struct sockaddr_storage *addr,
866
1020
        int flags,
867
1021
        int turn_off_reuse
868
1022
        )
869
1023
{
870
 
        int fd;
 
1024
        int errval;
 
1025
        SOCKET fd;
871
1026
        int on = 1, off = 0;
872
1027
#if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS)
873
1028
        int tos;
874
1029
#endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */
875
1030
 
 
1031
        if ((addr->ss_family == AF_INET6) && (isc_net_probeipv6() != ISC_R_SUCCESS))
 
1032
                return (INVALID_SOCKET);
 
1033
 
876
1034
        /* create a datagram (UDP) socket */
877
 
        if (  (fd = socket(AF_INET, SOCK_DGRAM, 0))
878
1035
#ifndef SYS_WINNT
879
 
              < 0
 
1036
        if (  (fd = socket(addr->ss_family, SOCK_DGRAM, 0)) < 0) {
 
1037
                errval = errno;
 
1038
                if(addr->ss_family == AF_INET)
 
1039
                        netsyslog(LOG_ERR, "socket(AF_INET, SOCK_DGRAM, 0) failed on address %s: %m",
 
1040
                                stoa(addr));
 
1041
                else if(addr->ss_family == AF_INET6)
 
1042
                        netsyslog(LOG_ERR, "socket(AF_INET6, SOCK_DGRAM, 0) failed on address %s: %m",
 
1043
                                stoa(addr));
 
1044
                if (errval == EPROTONOSUPPORT || errval == EAFNOSUPPORT ||
 
1045
                    errval == EPFNOSUPPORT)
 
1046
                        return (INVALID_SOCKET);
 
1047
                exit(1);
 
1048
                /*NOTREACHED*/
 
1049
        }
880
1050
#else
881
 
              == 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",
 
1055
                                stoa(addr));
 
1056
                else if(addr->ss_family == AF_INET6)
 
1057
                        netsyslog(LOG_ERR, "socket(AF_INET6, SOCK_DGRAM, 0) failed on address %s: %m",
 
1058
                                stoa(addr));
 
1059
                if (errval == WSAEPROTONOSUPPORT || errval == WSAEAFNOSUPPORT ||
 
1060
                    errval == WSAEPFNOSUPPORT)
 
1061
                        return (INVALID_SOCKET);
 
1062
                exit(1);
 
1063
                /*NOTREACHED*/
 
1064
        }
 
1065
        if (connection_reset_fix(fd) != ISC_R_SUCCESS) {
 
1066
                netsyslog(LOG_ERR, "connection_reset_fix(fd) failed on address %s: %m",
 
1067
                        stoa(addr));
 
1068
        }
 
1069
 
882
1070
#endif /* SYS_WINNT */
883
 
              )
884
 
        {
885
 
                msyslog(LOG_ERR, "socket(AF_INET, SOCK_DGRAM, 0) failed: %m");
886
 
                exit(1);
887
 
                /*NOTREACHED*/
888
 
        }
889
1071
 
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)))
894
1076
        {
895
 
                msyslog(LOG_ERR, "setsockopt SO_REUSEADDR on fails: %m");
 
1077
                netsyslog(LOG_ERR, "setsockopt SO_REUSEADDR on fails on address %s: %m",
 
1078
                        stoa(addr));
896
1079
        }
897
1080
 
 
1081
        /*
 
1082
         * IPv4 specific options go here
 
1083
         */
 
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)
902
 
        {
903
 
                msyslog(LOG_ERR, "setsockopt IPTOS_LOWDELAY on fails: %m");
904
 
        }
 
1087
                tos = IPTOS_LOWDELAY;
 
1088
                if (setsockopt(fd, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(tos)) < 0)
 
1089
                {
 
1090
                        netsyslog(LOG_ERR, "setsockopt IPTOS_LOWDELAY on fails on address %s: %m",
 
1091
                                stoa(addr));
 
1092
                }
905
1093
#endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */
 
1094
        }
 
1095
 
 
1096
        /*
 
1097
         * IPv6 specific options go here
 
1098
         */
 
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)))
 
1103
                {
 
1104
                        netsyslog(LOG_ERR, "setsockopt IPV6_V6ONLY on fails on address %s: %m",
 
1105
                                stoa(addr));
 
1106
                }
 
1107
#else /* IPV6_V6ONLY */
 
1108
#if defined(IPV6_BINDV6ONLY)
 
1109
                if (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDV6ONLY,
 
1110
                        (char*)&on, sizeof(on)))
 
1111
                {
 
1112
                        netsyslog(LOG_ERR,
 
1113
                            "setsockopt IPV6_BINDV6ONLY on fails on address %s: %m",
 
1114
                            stoa(addr));
 
1115
                }
 
1116
#endif /* IPV6_BINDV6ONLY */
 
1117
#endif /* IPV6_V6ONLY */
 
1118
        }
906
1119
 
907
1120
        /*
908
1121
         * bind the local address.
909
1122
         */
910
 
        if (bind(fd, (struct sockaddr *)addr, sizeof(*addr)) < 0) {
 
1123
        if (bind(fd, (struct sockaddr *)addr, SOCKLEN(addr)) < 0) {
911
1124
                char buff[160];
912
 
                sprintf(buff,
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),
915
 
                        ntoa(addr),
916
 
                        IN_CLASSD(ntohl(addr->sin_addr.s_addr)), flags);
917
 
                msyslog(LOG_ERR, buff);
 
1125
 
 
1126
                if(addr->ss_family == AF_INET)
 
1127
                        sprintf(buff,
 
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),
 
1130
                                stoa(addr),
 
1131
                                IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)), flags);
 
1132
                else if(addr->ss_family == AF_INET6)
 
1133
                                sprintf(buff,
 
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),
 
1136
                                stoa(addr),
 
1137
                                IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr), flags);
 
1138
                else return INVALID_SOCKET;
 
1139
 
 
1140
                netsyslog(LOG_ERR, buff);
918
1141
                closesocket(fd);
919
1142
 
920
1143
                /*
921
 
                 * soft fail if opening a class D address
 
1144
                 * soft fail if opening a multicast address
922
1145
                 */
923
 
                if (IN_CLASSD(ntohl(addr->sin_addr.s_addr)))
924
 
                    return -1;
 
1146
                if(addr->ss_family == AF_INET){
 
1147
                        if(IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)))
 
1148
                                return (INVALID_SOCKET);
 
1149
                }
 
1150
                else {
 
1151
                        if(IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr))
 
1152
                                return (INVALID_SOCKET);
 
1153
                }
925
1154
#if 0
926
1155
                exit(1);
927
1156
#else
928
 
                return -1;
 
1157
                return INVALID_SOCKET;
929
1158
#endif
930
1159
        }
931
1160
#ifdef DEBUG
932
1161
        if (debug)
933
1162
            printf("bind() fd %d, family %d, port %d, addr %s, flags=%d\n",
934
1163
                   fd,
935
 
                   addr->sin_family,
936
 
                   (int)ntohs(addr->sin_port),
937
 
                   ntoa(addr),
 
1164
                   addr->ss_family,
 
1165
                   (int)ntohs(((struct sockaddr_in*)addr)->sin_port),
 
1166
                   stoa(addr),
938
1167
                   flags);
939
1168
#endif
 
1169
 
 
1170
        /*
 
1171
         * I/O Completion Ports don't care about the select and FD_SET
 
1172
         */
 
1173
#ifndef HAVE_IO_COMPLETION_PORT
940
1174
        if (fd > maxactivefd)
941
1175
            maxactivefd = fd;
942
1176
        FD_SET(fd, &activefds);
943
 
 
 
1177
#endif
 
1178
        add_socket_to_list(fd);
944
1179
        /*
945
1180
         * set non-blocking,
946
1181
         */
957
1192
#if defined(O_NONBLOCK) /* POSIX */
958
1193
        if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
959
1194
        {
960
 
                msyslog(LOG_ERR, "fcntl(O_NONBLOCK) fails: %m");
 
1195
                netsyslog(LOG_ERR, "fcntl(O_NONBLOCK) fails on address %s: %m",
 
1196
                        stoa(addr));
961
1197
                exit(1);
962
1198
                /*NOTREACHED*/
963
1199
        }
964
1200
#elif defined(FNDELAY)
965
1201
        if (fcntl(fd, F_SETFL, FNDELAY) < 0)
966
1202
        {
967
 
                msyslog(LOG_ERR, "fcntl(FNDELAY) fails: %m");
 
1203
                netsyslog(LOG_ERR, "fcntl(FNDELAY) fails on address %s: %m",
 
1204
                        stoa(addr));
968
1205
                exit(1);
969
1206
                /*NOTREACHED*/
970
1207
        }
971
1208
#elif defined(O_NDELAY) /* generally the same as FNDELAY */
972
1209
        if (fcntl(fd, F_SETFL, O_NDELAY) < 0)
973
1210
        {
974
 
                msyslog(LOG_ERR, "fcntl(O_NDELAY) fails: %m");
 
1211
                netsyslog(LOG_ERR, "fcntl(O_NDELAY) fails on address %s: %m",
 
1212
                        stoa(addr));
975
1213
                exit(1);
976
1214
                /*NOTREACHED*/
977
1215
        }
978
1216
#elif defined(FIONBIO)
979
 
        if (
980
 
# if defined(VMS)
981
 
                (ioctl(fd,FIONBIO,&1) < 0)
982
 
# elif defined(SYS_WINNT)
983
 
                (ioctlsocket(fd,FIONBIO,(u_long *) &on) == SOCKET_ERROR)
 
1217
# if defined(SYS_WINNT)
 
1218
                if (ioctlsocket(fd,FIONBIO,(u_long *) &on) == SOCKET_ERROR)
984
1219
# else
985
 
                (ioctl(fd,FIONBIO,&on) < 0)
 
1220
                if (ioctl(fd,FIONBIO,&on) < 0)
986
1221
# endif
987
 
           )
988
1222
        {
989
 
                msyslog(LOG_ERR, "ioctl(FIONBIO) fails: %m");
 
1223
                netsyslog(LOG_ERR, "ioctl(FIONBIO) fails on address %s: %m",
 
1224
                        stoa(addr));
990
1225
                exit(1);
991
1226
                /*NOTREACHED*/
992
1227
        }
993
1228
#elif defined(FIOSNBIO)
994
1229
        if (ioctl(fd,FIOSNBIO,&on) < 0)
995
1230
        {
996
 
                msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails: %m");
 
1231
                netsyslog(LOG_ERR, "ioctl(FIOSNBIO) fails on address %s: %m",
 
1232
                        stoa(addr));
997
1233
                exit(1);
998
1234
                /*NOTREACHED*/
999
1235
        }
1015
1251
            if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1016
1252
                           (char *)&off, sizeof(off)))
1017
1253
            {
1018
 
                    msyslog(LOG_ERR, "setsockopt SO_REUSEADDR off fails: %m");
 
1254
                    netsyslog(LOG_ERR, "setsockopt SO_REUSEADDR off fails on address %s: %m",
 
1255
                            stoa(addr));
1019
1256
            }
1020
1257
 
1021
1258
#ifdef SO_BROADCAST
1025
1262
                if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
1026
1263
                               (char *)&on, sizeof(on)))
1027
1264
                {
1028
 
                        msyslog(LOG_ERR, "setsockopt(SO_BROADCAST): %m");
 
1265
                        netsyslog(LOG_ERR, "setsockopt(SO_BROADCAST) on address %s: %m",
 
1266
                                stoa(addr));
1029
1267
                }
1030
1268
        }
1031
1269
#endif /* SO_BROADCAST */
1047
1285
 */
1048
1286
static void
1049
1287
close_socket(
1050
 
        int fd
 
1288
             SOCKET fd
1051
1289
        )
1052
1290
{
1053
 
        int i, newmax;
 
1291
        SOCKET i, newmax;
1054
1292
 
1055
1293
        (void) closesocket(fd);
 
1294
 
 
1295
        /*
 
1296
         * I/O Completion Ports don't care about select and fd_set
 
1297
         */
 
1298
#ifndef HAVE_IO_COMPLETION_PORT
1056
1299
        FD_CLR( (u_int) fd, &activefds);
1057
1300
 
1058
 
        if (fd >= maxactivefd) {
 
1301
        if (fd == maxactivefd) {
1059
1302
                newmax = 0;
1060
1303
                for (i = 0; i < maxactivefd; i++)
1061
1304
                        if (FD_ISSET(i, &activefds))
1062
1305
                                newmax = i;
1063
1306
                maxactivefd = newmax;
1064
1307
        }
 
1308
#endif
 
1309
        delete_socket_from_list(fd);
 
1310
 
1065
1311
}
1066
1312
 
1067
1313
 
1069
1315
 * close_file - close a file and remove from the activefd list
1070
1316
 * added 1/31/1997 Greg Schueman for Windows NT portability
1071
1317
 */
 
1318
#ifdef REFCLOCK
1072
1319
static void
1073
1320
close_file(
1074
 
        int fd
 
1321
        SOCKET fd
1075
1322
        )
1076
1323
{
1077
1324
        int i, newmax;
1078
1325
 
1079
1326
        (void) close(fd);
 
1327
        /*
 
1328
         * I/O Completion Ports don't care about select and fd_set
 
1329
         */
 
1330
#ifndef HAVE_IO_COMPLETION_PORT
1080
1331
        FD_CLR( (u_int) fd, &activefds);
1081
1332
 
1082
 
        if (fd >= maxactivefd) {
 
1333
        if (fd == maxactivefd) {
1083
1334
                newmax = 0;
1084
1335
                for (i = 0; i < maxactivefd; i++)
1085
1336
                        if (FD_ISSET(i, &activefds))
1086
1337
                                newmax = i;
1087
1338
                maxactivefd = newmax;
1088
1339
        }
 
1340
#endif
 
1341
        delete_socket_from_list(fd);
 
1342
 
1089
1343
}
 
1344
#endif
1090
1345
 
1091
1346
 
1092
1347
/* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */
1097
1352
 */
1098
1353
void
1099
1354
sendpkt(
1100
 
        struct sockaddr_in *dest,
 
1355
        struct sockaddr_storage *dest,
1101
1356
        struct interface *inter,
1102
1357
        int ttl,
1103
1358
        struct pkt *pkt,
1110
1365
#endif /* SYS_WINNT */
1111
1366
 
1112
1367
        /*
1113
 
         * Send error cache. Empty slots have port == 0
 
1368
         * Send error caches. Empty slots have port == 0
1114
1369
         * Set ERRORCACHESIZE to 0 to disable
1115
1370
         */
1116
1371
        struct cache {
1118
1373
                struct  in_addr addr;
1119
1374
        };
1120
1375
 
 
1376
#ifdef ISC_PLATFORM_HAVEIPV6
 
1377
        struct cache6 {
 
1378
                u_short port;
 
1379
                struct in6_addr addr;
 
1380
        };
 
1381
#endif /* ISC_PLATFORM_HAVEIPV6 */
 
1382
 
1121
1383
#ifndef ERRORCACHESIZE
1122
1384
#define ERRORCACHESIZE 8
1123
1385
#endif
1124
1386
#if ERRORCACHESIZE > 0
1125
1387
        static struct cache badaddrs[ERRORCACHESIZE];
 
1388
#ifdef ISC_PLATFORM_HAVEIPV6
 
1389
        static struct cache6 badaddrs6[ERRORCACHESIZE];
 
1390
#endif /* ISC_PLATFORM_HAVEIPV6 */
1126
1391
#else
1127
1392
#define badaddrs ((struct cache *)0)            /* Only used in empty loops! */
 
1393
#ifdef ISC_PLATFORM_HAVEIPV6
 
1394
#define badaddrs6 ((struct cache6 *)0)          /* Only used in empty loops! */
 
1395
#endif /* ISC_PLATFORM_HAVEIPV6 */
1128
1396
#endif
1129
1397
#ifdef DEBUG
1130
1398
        if (debug > 1)
1131
1399
            printf("%ssendpkt(fd=%d dst=%s, src=%s, ttl=%d, len=%d)\n",
1132
1400
                   (ttl >= 0) ? "\tMCAST\t*****" : "",
1133
 
                   inter->fd, ntoa(dest),
1134
 
                   ntoa(&inter->sin), ttl, len);
 
1401
                   inter->fd, stoa(dest),
 
1402
                   stoa(&inter->sin), ttl, len);
1135
1403
#endif
1136
1404
 
1137
1405
#ifdef MCAST
1138
 
        /*
1139
 
         * for the moment we use the bcast option to set multicast ttl
1140
 
         */
1141
 
        if (ttl > 0 && ttl != inter->last_ttl) {
1142
 
                char mttl = ttl;
 
1406
 
 
1407
        switch (inter->sin.ss_family) {
 
1408
 
 
1409
        case AF_INET :
1143
1410
 
1144
1411
                /*
1145
 
                 * set the multicast ttl for outgoing packets
 
1412
                * for the moment we use the bcast option to set multicast ttl
 
1413
                */
 
1414
                if (ttl > 0 && ttl != inter->last_ttl) {
 
1415
 
 
1416
                        /*
 
1417
                        * set the multicast ttl for outgoing packets
 
1418
                        */
 
1419
                        u_char mttl = (u_char) ttl;
 
1420
                        if (setsockopt(inter->fd, IPPROTO_IP, IP_MULTICAST_TTL,
 
1421
                                (const void *) &mttl, sizeof(mttl)) != 0) {
 
1422
                                netsyslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL fails on address %s: %m",
 
1423
                                        stoa(&inter->sin));
 
1424
                        }
 
1425
                        else
 
1426
                                inter->last_ttl = ttl;
 
1427
                }
 
1428
                break;
 
1429
 
 
1430
#ifdef ISC_PLATFORM_HAVEIPV6
 
1431
        case AF_INET6 :
 
1432
 
 
1433
                /*
 
1434
                 * for the moment we use the bcast option to set
 
1435
                 * multicast max hops
1146
1436
                 */
1147
 
                if (setsockopt(inter->fd, IPPROTO_IP, IP_MULTICAST_TTL,
1148
 
                    &mttl, sizeof(mttl)) == -1)
1149
 
                        msyslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL fails: %m");
1150
 
                else
1151
 
                        inter->last_ttl = ttl;
 
1437
                if (ttl > 0 && ttl != inter->last_ttl) {
 
1438
 
 
1439
                        /*
 
1440
                        * set the multicast ttl for outgoing packets
 
1441
                        */
 
1442
                        u_int ittl = (u_int) ttl;
 
1443
                        if (setsockopt(inter->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
 
1444
                        (const void *) &ittl, sizeof(ittl)) == -1)
 
1445
                                netsyslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL fails on address %s: %m",
 
1446
                                        stoa(&inter->sin));
 
1447
                        else
 
1448
                                inter->last_ttl = ttl;
 
1449
                }
 
1450
                break;
 
1451
#endif /* ISC_PLATFORM_HAVEIPV6 */
 
1452
 
 
1453
        default :
 
1454
                exit(1);
 
1455
 
1152
1456
        }
 
1457
 
 
1458
 
1153
1459
#endif /* MCAST */
1154
1460
 
1155
1461
        for (slot = ERRORCACHESIZE; --slot >= 0; )
1156
 
            if (badaddrs[slot].port == dest->sin_port &&
1157
 
                badaddrs[slot].addr.s_addr == dest->sin_addr.s_addr)
1158
 
                break;
 
1462
                if(dest->ss_family == AF_INET) {
 
1463
                        if (badaddrs[slot].port == ((struct sockaddr_in*)dest)->sin_port &&
 
1464
                                badaddrs[slot].addr.s_addr == ((struct sockaddr_in*)dest)->sin_addr.s_addr)
 
1465
                        break;
 
1466
                }
 
1467
#ifdef ISC_PLATFORM_HAVEIPV6
 
1468
                else if (dest->ss_family == AF_INET6) {
 
1469
                        if (badaddrs6[slot].port == ((struct sockaddr_in6*)dest)->sin6_port &&
 
1470
                                badaddrs6[slot].addr.s6_addr == ((struct sockaddr_in6*)dest)->sin6_addr.s6_addr)
 
1471
                        break;
 
1472
                }
 
1473
#endif /* ISC_PLATFORM_HAVEIPV6 */
 
1474
                else exit(1);  /* address family not supported yet */
1159
1475
 
1160
1476
#if defined(HAVE_IO_COMPLETION_PORT)
1161
1477
        err = io_completion_port_sendto(inter, pkt, len, dest);
1162
1478
        if (err != ERROR_SUCCESS)
1163
1479
#else
1164
 
        cc = sendto(inter->fd, (char *)pkt, (size_t)len, 0, (struct sockaddr *)dest,
1165
 
                    sizeof(struct sockaddr_in));
 
1480
#ifdef SIM
 
1481
        cc = srvr_rply(&ntp_node,  dest, inter, pkt);
 
1482
#else /* SIM */
 
1483
        cc = sendto(inter->fd, (char *)pkt, (unsigned int)len, 0, (struct sockaddr *)dest,
 
1484
                    SOCKLEN(dest));
 
1485
#endif /* SIM */
1166
1486
        if (cc == -1)
1167
1487
#endif
1168
1488
        {
1169
1489
                inter->notsent++;
1170
1490
                packets_notsent++;
1171
1491
#if defined(HAVE_IO_COMPLETION_PORT)
 
1492
                err = WSAGetLastError();
1172
1493
                if (err != WSAEWOULDBLOCK && err != WSAENOBUFS && slot < 0)
1173
1494
#else
1174
1495
                if (errno != EWOULDBLOCK && errno != ENOBUFS && slot < 0)
1177
1498
                        /*
1178
1499
                         * Remember this, if there's an empty slot
1179
1500
                         */
1180
 
                        for (slot = ERRORCACHESIZE; --slot >= 0; )
1181
 
                            if (badaddrs[slot].port == 0)
1182
 
                            {
1183
 
                                    badaddrs[slot].port = dest->sin_port;
1184
 
                                    badaddrs[slot].addr = dest->sin_addr;
1185
 
                                    break;
1186
 
                            }
1187
 
                        msyslog(LOG_ERR, "sendto(%s): %m", ntoa(dest));
 
1501
                        switch (dest->ss_family) {
 
1502
 
 
1503
                        case AF_INET :
 
1504
 
 
1505
                                for (slot = ERRORCACHESIZE; --slot >= 0; )
 
1506
                                        if (badaddrs[slot].port == 0)
 
1507
                                        {
 
1508
                                                badaddrs[slot].port = SRCPORT(dest);
 
1509
                                                badaddrs[slot].addr = ((struct sockaddr_in*)dest)->sin_addr;
 
1510
                                                break;
 
1511
                                        }
 
1512
                                break;
 
1513
 
 
1514
#ifdef ISC_PLATFORM_HAVEIPV6
 
1515
                        case AF_INET6 :
 
1516
 
 
1517
                                for (slot = ERRORCACHESIZE; --slot >= 0; )
 
1518
                                        if (badaddrs6[slot].port == 0)
 
1519
                                        {
 
1520
                                                badaddrs6[slot].port = SRCPORT(dest);
 
1521
                                                badaddrs6[slot].addr = ((struct sockaddr_in6*)dest)->sin6_addr;
 
1522
                                                break;
 
1523
                                        }
 
1524
                                break;
 
1525
#endif /* ISC_PLATFORM_HAVEIPV6 */
 
1526
 
 
1527
                        default :
 
1528
                                exit(1);
 
1529
                        }
 
1530
 
 
1531
                        netsyslog(LOG_ERR, "sendto(%s): %m", stoa(dest));
1188
1532
                }
1189
1533
        }
1190
1534
        else
1196
1540
                 */
1197
1541
                if (slot >= 0)
1198
1542
                {
1199
 
                        msyslog(LOG_INFO, "Connection re-established to %s", ntoa(dest));
1200
 
                        badaddrs[slot].port = 0;
 
1543
                        netsyslog(LOG_INFO, "Connection re-established to %s", stoa(dest));
 
1544
                        switch (dest->ss_family) {
 
1545
                        case AF_INET :
 
1546
                                badaddrs[slot].port = 0;
 
1547
                                break;
 
1548
#ifdef ISC_PLATFORM_HAVEIPV6
 
1549
                        case AF_INET6 :
 
1550
                                badaddrs6[slot].port = 0;
 
1551
                                break;
 
1552
#endif /* ISC_PLATFORM_HAVEIPV6 */
 
1553
                        }
1201
1554
                }
1202
1555
        }
1203
1556
}
1231
1584
/*
1232
1585
 * input_handler - receive packets asynchronously
1233
1586
 */
1234
 
extern void
 
1587
void
1235
1588
input_handler(
1236
1589
        l_fp *cts
1237
1590
        )
1239
1592
        register int i, n;
1240
1593
        register struct recvbuf *rb;
1241
1594
        register int doing;
1242
 
        register int fd;
 
1595
        register SOCKET fd;
1243
1596
        struct timeval tvzero;
1244
1597
        int fromlen;
1245
1598
        l_fp ts;                        /* Timestamp at BOselect() gob */
1305
1658
 
1306
1659
                                                if (rb->recv_length == -1)
1307
1660
                                                {
1308
 
                                                        msyslog(LOG_ERR, "clock read fd %d: %m", fd);
 
1661
                                                        netsyslog(LOG_ERR, "clock read fd %d: %m", fd);
1309
1662
                                                        freerecvbuf(rb);
1310
1663
                                                        goto select_again;
1311
1664
                                                }
1312
1665
 
1313
1666
                                                /*
1314
 
                                                 * Got one.  Mark how and when it got here,
1315
 
                                                 * put it on the full list and do bookkeeping.
 
1667
                                                 * Got one.  Mark how
 
1668
                                                 * and when it got here,
 
1669
                                                 * put it on the full
 
1670
                                                 * list and do
 
1671
                                                 * bookkeeping.
1316
1672
                                                 */
1317
1673
                                                rb->recv_srcclock = rp->srcclock;
1318
1674
                                                rb->dstadr = 0;
1323
1679
                                                if (rp->io_input)
1324
1680
                                                {
1325
1681
                                                        /*
1326
 
                                                         * have direct input routine for refclocks
 
1682
                                                         * have direct
 
1683
                                                         * input routine
 
1684
                                                         * for refclocks
1327
1685
                                                         */
1328
1686
                                                        if (rp->io_input(rb) == 0)
1329
1687
                                                        {
1330
1688
                                                                /*
1331
 
                                                                 * data was consumed - nothing to pass up
1332
 
                                                                 * into block input machine
 
1689
                                                                 * data
 
1690
                                                                 * was
 
1691
                                                                 * consumed
 
1692
                                                                 * -
 
1693
                                                                 * nothing
 
1694
                                                                 * to
 
1695
                                                                 * pass
 
1696
                                                                 * up
 
1697
                                                                 * into
 
1698
                                                                 * block
 
1699
                                                                 * input
 
1700
                                                                 * machine
1333
1701
                                                                 */
1334
1702
                                                                freerecvbuf(rb);
1335
1703
#if 1
1350
1718
#endif /* REFCLOCK */
1351
1719
 
1352
1720
                        /*
1353
 
                         * Loop through the interfaces looking for data to read.
 
1721
                         * Loop through the interfaces looking for data
 
1722
                         * to read.
1354
1723
                         */
1355
1724
                        for (i = ninterfaces - 1; (i >= 0) && (n > 0); i--)
1356
1725
                        {
1372
1741
                                                n--;
1373
1742
 
1374
1743
                                                /*
1375
 
                                                 * Get a buffer and read the frame.  If we
1376
 
                                                 * haven't got a buffer, or this is received
1377
 
                                                 * on the wild card socket, just dump the
 
1744
                                                 * Get a buffer and read
 
1745
                                                 * the frame.  If we
 
1746
                                                 * haven't got a buffer,
 
1747
                                                 * or this is received
 
1748
                                                 * on the wild card
 
1749
                                                 * socket, just dump the
1378
1750
                                                 * packet.
1379
1751
                                                 */
1380
1752
                                                if (
1385
1757
                                 */
1386
1758
                                                        (free_recvbuffs() == 0)
1387
1759
#else
1388
 
                                                        ((i == 0) || (free_recvbuffs() == 0))
 
1760
                                                        ((i == wildipv4) || (i == wildipv6)||
 
1761
                                                        (free_recvbuffs() == 0))
1389
1762
#endif
1390
1763
                                                        )
1391
1764
        {
1392
1765
                char buf[RX_BUFF_SIZE];
1393
 
                struct sockaddr from;
 
1766
                struct sockaddr_storage from;
1394
1767
 
1395
1768
                fromlen = sizeof from;
1396
 
                (void) recvfrom(fd, buf, sizeof(buf), 0, &from, &fromlen);
 
1769
                (void) recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&from, &fromlen);
1397
1770
#ifdef DEBUG
1398
1771
                if (debug)
1399
1772
                    printf("%s on %d(%lu) fd=%d from %s\n",
1400
1773
                           (i) ? "drop" : "ignore",
1401
1774
                           i, free_recvbuffs(), fd,
1402
 
                           inet_ntoa(((struct sockaddr_in *) &from)->sin_addr));
 
1775
                           stoa(&from));
1403
1776
#endif
1404
 
                if (i == 0)
 
1777
                if (i == wildipv4 || i == wildipv6)
1405
1778
                    packets_ignored++;
1406
1779
                else
1407
1780
                    packets_dropped++;
1410
1783
 
1411
1784
        rb = get_free_recv_buffer();
1412
1785
 
1413
 
        fromlen = sizeof(struct sockaddr_in);
 
1786
        fromlen = sizeof(struct sockaddr_storage);
1414
1787
        rb->recv_length = recvfrom(fd,
1415
1788
                                   (char *)&rb->recv_space,
1416
1789
                                   sizeof(rb->recv_space), 0,
1429
1802
        }
1430
1803
        else if (rb->recv_length < 0)
1431
1804
        {
1432
 
                msyslog(LOG_ERR, "recvfrom(%s) fd=%d: %m",
1433
 
                        inet_ntoa(rb->recv_srcadr.sin_addr), fd);
 
1805
                netsyslog(LOG_ERR, "recvfrom(%s) fd=%d: %m",
 
1806
                        stoa(&rb->recv_srcadr), fd);
1434
1807
#ifdef DEBUG
1435
1808
                if (debug)
1436
1809
                    printf("input_handler: fd=%d dropped (bad recvfrom)\n", fd);
1439
1812
                continue;
1440
1813
        }
1441
1814
#ifdef DEBUG
1442
 
        if (debug > 2)
1443
 
            printf("input_handler: if=%d fd=%d length %d from %08lx %s\n",
1444
 
                   i, fd, rb->recv_length,
1445
 
                   (u_long)ntohl(rb->recv_srcadr.sin_addr.s_addr) &
1446
 
                   0x00000000ffffffff,
1447
 
                   inet_ntoa(rb->recv_srcadr.sin_addr));
 
1815
        if (debug > 2) {
 
1816
                if(rb->recv_srcadr.ss_family == AF_INET)
 
1817
                        printf("input_handler: if=%d fd=%d length %d from %08lx %s\n",
 
1818
                                i, fd, rb->recv_length,
 
1819
                                (u_long)ntohl(((struct sockaddr_in*)&rb->recv_srcadr)->sin_addr.s_addr) &
 
1820
                                0x00000000ffffffff,
 
1821
                                stoa(&rb->recv_srcadr));
 
1822
                else
 
1823
                        printf("input_handler: if=%d fd=%d length %d from %s\n",
 
1824
                                i, fd, rb->recv_length,
 
1825
                                stoa(&rb->recv_srcadr));
 
1826
        }
1448
1827
#endif
1449
1828
 
1450
1829
        /*
1457
1836
        rb->receiver = receive;
1458
1837
 
1459
1838
        add_full_recv_buffer(rb);
1460
 
        
 
1839
 
1461
1840
        inter_list[i].received++;
1462
1841
        packets_received++;
1463
1842
        goto select_again;
1481
1860
                        if (select_count == 0) /* We really had nothing to do */
1482
1861
                        {
1483
1862
                                if (debug)
1484
 
                                    msyslog(LOG_DEBUG, "input_handler: select() returned 0");
 
1863
                                    netsyslog(LOG_DEBUG, "input_handler: select() returned 0");
1485
1864
                                --handler_count;
1486
1865
                                return;
1487
1866
                        }
1488
1867
                        /* We've done our work */
1489
1868
                        get_systime(&ts_e);
1490
1869
                        /*
1491
 
                         * (ts_e - ts) is the amount of time we spent processing
1492
 
                         * this gob of file descriptors.  Log it.
 
1870
                         * (ts_e - ts) is the amount of time we spent
 
1871
                         * processing this gob of file descriptors.  Log
 
1872
                         * it.
1493
1873
                         */
1494
1874
                        L_SUB(&ts_e, &ts);
1495
1875
                        if (debug > 3)
1496
 
                            msyslog(LOG_INFO, "input_handler: Processed a gob of fd's in %s msec", lfptoms(&ts_e, 6));
 
1876
                            netsyslog(LOG_INFO, "input_handler: Processed a gob of fd's in %s msec", lfptoms(&ts_e, 6));
1497
1877
 
1498
1878
                        /* just bail. */
1499
1879
                        --handler_count;
1506
1886
                        /*
1507
1887
                         * extended FAU debugging output
1508
1888
                         */
1509
 
                        msyslog(LOG_ERR, "select(%d, %s, 0L, 0L, &0.000000) error: %m",
1510
 
                                maxactivefd+1, fdbits(maxactivefd, &activefds));
 
1889
                        if (err != EINTR)
 
1890
                            netsyslog(LOG_ERR,
 
1891
                                      "select(%d, %s, 0L, 0L, &0.0) error: %m",
 
1892
                                      maxactivefd+1,
 
1893
                                      fdbits(maxactivefd, &activefds));
1511
1894
                        if (err == EBADF) {
1512
1895
                                int j, b;
1513
1896
 
1516
1899
                                    if (
1517
1900
                                            (FD_ISSET(j, &fds) && (read(j, &b, 0) == -1))
1518
1901
                                            )
1519
 
                                        msyslog(LOG_ERR, "Bad file descriptor %d", j);
 
1902
                                        netsyslog(LOG_ERR, "Bad file descriptor %d", j);
1520
1903
                        }
1521
1904
                        --handler_count;
1522
1905
                        return;
1528
1911
}
1529
1912
 
1530
1913
#endif
1531
 
 
1532
1914
/*
1533
1915
 * findinterface - find interface corresponding to address
1534
1916
 */
1535
1917
struct interface *
1536
1918
findinterface(
1537
 
        struct sockaddr_in *addr
 
1919
        struct sockaddr_storage *addr
1538
1920
        )
1539
1921
{
1540
 
        int s, rtn, i;
1541
 
        struct sockaddr_in saddr;
1542
 
        int saddrlen = sizeof(saddr);
1543
 
        u_int32 xaddr;
1544
 
 
 
1922
        SOCKET s;
 
1923
        int rtn, i;
 
1924
        struct sockaddr_storage saddr;
 
1925
        int saddrlen = SOCKLEN(addr);
1545
1926
        /*
1546
1927
         * This is considerably hoke. We open a socket, connect to it
1547
1928
         * and slap a getsockname() on it. If anything breaks, as it
1548
1929
         * probably will in some j-random knockoff, we just return the
1549
1930
         * wildcard interface.
1550
1931
         */
1551
 
        saddr.sin_family = AF_INET;
1552
 
        saddr.sin_addr.s_addr = addr->sin_addr.s_addr;
1553
 
        saddr.sin_port = htons(2000);
1554
 
        s = socket(AF_INET, SOCK_DGRAM, 0);
1555
 
        if (s < 0)
1556
 
                return (any_interface);
1557
 
        
1558
 
        rtn = connect(s, (struct sockaddr *)&saddr, sizeof(saddr));
 
1932
        memset(&saddr, 0, sizeof(saddr));
 
1933
        saddr.ss_family = addr->ss_family;
 
1934
        if(addr->ss_family == AF_INET)
 
1935
                memcpy(&((struct sockaddr_in*)&saddr)->sin_addr, &((struct sockaddr_in*)addr)->sin_addr, sizeof(struct in_addr));
 
1936
        else if(addr->ss_family == AF_INET6)
 
1937
                memcpy(&((struct sockaddr_in6*)&saddr)->sin6_addr, &((struct sockaddr_in6*)addr)->sin6_addr, sizeof(struct in6_addr));
 
1938
        ((struct sockaddr_in*)&saddr)->sin_port = htons(2000);
 
1939
        s = socket(addr->ss_family, SOCK_DGRAM, 0);
 
1940
        if (s == INVALID_SOCKET)
 
1941
                return ANY_INTERFACE_CHOOSE(addr);
 
1942
 
 
1943
        rtn = connect(s, (struct sockaddr *)&saddr, SOCKLEN(&saddr));
 
1944
#ifndef SYS_WINNT
1559
1945
        if (rtn < 0)
1560
 
                return (any_interface);
 
1946
#else
 
1947
        if (rtn == SOCKET_ERROR)
 
1948
#endif
 
1949
        {
 
1950
                closesocket(s);
 
1951
                return ANY_INTERFACE_CHOOSE(addr);
 
1952
        }
1561
1953
 
1562
1954
        rtn = getsockname(s, (struct sockaddr *)&saddr, &saddrlen);
 
1955
        closesocket(s);
 
1956
#ifndef SYS_WINNT
1563
1957
        if (rtn < 0)
1564
 
                return (any_interface);
1565
 
 
1566
 
        close(s);
1567
 
        xaddr = NSRCADR(&saddr);
1568
 
        for (i = 1; i < ninterfaces; i++) {
1569
 
 
 
1958
#else
 
1959
        if (rtn == SOCKET_ERROR)
 
1960
#endif
 
1961
                return ANY_INTERFACE_CHOOSE(addr);
 
1962
 
 
1963
        for (i = 0; i < ninterfaces; i++) {
 
1964
                /*
 
1965
                * First look if is the the correct family
 
1966
                */
 
1967
                if(inter_list[i].sin.ss_family != saddr.ss_family)
 
1968
                        continue;
1570
1969
                /*
1571
1970
                 * We match the unicast address only.
1572
1971
                 */
1573
 
                if (NSRCADR(&inter_list[i].sin) == xaddr)
 
1972
                if (SOCKCMP(&inter_list[i].sin, &saddr))
1574
1973
                        return (&inter_list[i]);
1575
1974
        }
1576
 
        return (any_interface);
 
1975
        return ANY_INTERFACE_CHOOSE(addr);
1577
1976
}
1578
1977
 
1579
 
 
1580
1978
/*
1581
1979
 * findbcastinter - find broadcast interface corresponding to address
1582
1980
 */
1583
1981
struct interface *
1584
1982
findbcastinter(
1585
 
        struct sockaddr_in *addr
 
1983
        struct sockaddr_storage *addr
1586
1984
        )
1587
1985
{
1588
 
#if defined(SIOCGIFCONF) || defined(SYS_WINNT)
 
1986
#if !defined(MPE) && (defined(SIOCGIFCONF) || defined(SYS_WINNT))
1589
1987
        register int i;
1590
 
        register u_int32 xaddr;
1591
 
 
1592
 
        xaddr = NSRCADR(addr);
1593
 
        for (i = 1; i < ninterfaces; i++) {
1594
 
 
 
1988
        
 
1989
        i = find_addr_in_list(addr);
 
1990
        if(i >= 0)
 
1991
             return (&inter_list[i]);
 
1992
 
 
1993
        for (i = 0; i < ninterfaces; i++) {
 
1994
                /*
 
1995
                * First look if this is the correct family
 
1996
                */
 
1997
                if(inter_list[i].sin.ss_family != addr->ss_family)
 
1998
                        continue;
1595
1999
                /*
1596
2000
                 * We match only those interfaces marked as
1597
2001
                 * broadcastable and either the explicit broadcast
1600
2004
                 */
1601
2005
                if (!(inter_list[i].flags & INT_BROADCAST))
1602
2006
                        continue;
1603
 
                if (NSRCADR(&inter_list[i].bcast) == xaddr)
1604
 
                        return (&inter_list[i]);
1605
 
                if ((NSRCADR(&inter_list[i].sin) &
1606
 
                    NSRCADR(&inter_list[i].mask)) == (xaddr &
1607
 
                    NSRCADR(&inter_list[i].mask)))
1608
 
                        return (&inter_list[i]);
 
2007
                if(addr->ss_family == AF_INET) {
 
2008
                        if (SOCKCMP(&inter_list[i].bcast, addr))
 
2009
                                return (&inter_list[i]);
 
2010
                        if ((NSRCADR(&inter_list[i].sin) &
 
2011
                                NSRCADR(&inter_list[i].mask)) == (NSRCADR(addr) &
 
2012
                                NSRCADR(&inter_list[i].mask)))
 
2013
                                return (&inter_list[i]);
 
2014
                }
 
2015
                else if(addr->ss_family == AF_INET6) {
 
2016
                        if (SOCKCMP(&inter_list[i].bcast, addr))
 
2017
                                return (&inter_list[i]);
 
2018
                        if (SOCKCMP(netof(&inter_list[i].sin), netof(addr)))
 
2019
                                return (&inter_list[i]);
 
2020
                     }
1609
2021
        }
1610
2022
#endif /* SIOCGIFCONF */
1611
 
        return (any_interface);
 
2023
        return ANY_INTERFACE_CHOOSE(addr);
1612
2024
}
1613
2025
 
1614
2026
 
1649
2061
        rio->next = refio;
1650
2062
        refio = rio;
1651
2063
 
 
2064
        /*
 
2065
         * I/O Completion Ports don't care about select and fd_set
 
2066
         */
 
2067
#ifndef HAVE_IO_COMPLETION_PORT
1652
2068
        if (rio->fd > maxactivefd)
1653
2069
            maxactivefd = rio->fd;
1654
2070
        FD_SET(rio->fd, &activefds);
 
2071
#endif
1655
2072
        UNBLOCKIO();
1656
2073
        return 1;
1657
2074
}
1683
2100
# elif defined(HAVE_IO_COMPLETION_PORT)
1684
2101
        if (io_completion_port_add_clock_io(rio))
1685
2102
        {
 
2103
                add_socket_to_list(rio->fd);
1686
2104
                refio = rio->next;
1687
2105
                UNBLOCKIO();
1688
2106
                return 0;
1689
2107
        }
1690
2108
# endif
1691
2109
 
 
2110
        /*
 
2111
         * I/O Completion Ports don't care about select and fd_set
 
2112
         */
 
2113
#ifndef HAVE_IO_COMPLETION_PORT
1692
2114
        if (rio->fd > maxactivefd)
1693
2115
            maxactivefd = rio->fd;
1694
2116
        FD_SET(rio->fd, &activefds);
1695
 
 
 
2117
#endif
1696
2118
        UNBLOCKIO();
1697
2119
        return 1;
1698
2120
}
1741
2163
}
1742
2164
#endif  /* REFCLOCK */
1743
2165
 
 
2166
        /*
 
2167
         * I/O Completion Ports don't care about select and fd_set
 
2168
         */
 
2169
#ifndef HAVE_IO_COMPLETION_PORT
1744
2170
void
1745
 
kill_asyncio(void)
 
2171
kill_asyncio(
 
2172
        int startfd
 
2173
        )
1746
2174
{
1747
 
        int i;
 
2175
        SOCKET i;
1748
2176
 
1749
2177
        BLOCKIO();
1750
 
        for (i = 0; i <= maxactivefd; i++)
 
2178
        for (i = startfd; i <= maxactivefd; i++)
1751
2179
            (void)close_socket(i);
1752
2180
}
 
2181
#else
 
2182
/*
 
2183
 * On NT a SOCKET is an unsigned int so we cannot possibly keep it in
 
2184
 * an array. So we use one of the ISC_LIST functions to hold the
 
2185
 * socket value and use that when we want to enumerate it.
 
2186
 */
 
2187
void
 
2188
kill_asyncio(int startfd)
 
2189
{
 
2190
        vsock_t *lsock;
 
2191
        vsock_t *next;
 
2192
 
 
2193
        BLOCKIO();
 
2194
 
 
2195
        lsock = ISC_LIST_HEAD(sockets_list);
 
2196
        while (lsock != NULL) {
 
2197
                next = ISC_LIST_NEXT(lsock, link);
 
2198
                close_socket(lsock->fd);
 
2199
                lsock = next;
 
2200
        }
 
2201
 
 
2202
}
 
2203
#endif
 
2204
/*
 
2205
 * Add and delete functions for the list of open sockets
 
2206
 */
 
2207
void
 
2208
add_socket_to_list(SOCKET fd){
 
2209
        vsock_t *lsock = malloc(sizeof(vsock_t));
 
2210
        lsock->fd = fd;
 
2211
 
 
2212
        ISC_LIST_APPEND(sockets_list, lsock, link);
 
2213
}
 
2214
void
 
2215
delete_socket_from_list(SOCKET fd) {
 
2216
 
 
2217
        vsock_t *next;
 
2218
        vsock_t *lsock = ISC_LIST_HEAD(sockets_list);
 
2219
 
 
2220
        while(lsock != NULL) {
 
2221
                next = ISC_LIST_NEXT(lsock, link);
 
2222
                if(lsock->fd == fd) {
 
2223
                        ISC_LIST_DEQUEUE(sockets_list, lsock, link);
 
2224
                        free(lsock);
 
2225
                        break;
 
2226
                }
 
2227
                else
 
2228
                        lsock = next;
 
2229
        }
 
2230
}
 
2231
void
 
2232
add_addr_to_list(struct sockaddr_storage *addr, int if_index){
 
2233
        remaddr_t *laddr = malloc(sizeof(remaddr_t));
 
2234
        memcpy(&laddr->addr, addr, sizeof(addr));
 
2235
        laddr->if_index = if_index;
 
2236
 
 
2237
        ISC_LIST_APPEND(remoteaddr_list, laddr, link);
 
2238
#ifdef DEBUG
 
2239
        if (debug)
 
2240
            printf("Added addr %s to list of addresses\n",
 
2241
                   stoa(addr));
 
2242
#endif
 
2243
 
 
2244
 
 
2245
}
 
2246
void
 
2247
delete_addr_from_list(struct sockaddr_storage *addr) {
 
2248
 
 
2249
        remaddr_t *next;
 
2250
        remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list);
 
2251
 
 
2252
        while(laddr != NULL) {
 
2253
                next = ISC_LIST_NEXT(laddr, link);
 
2254
                if(SOCKCMP(&laddr->addr, addr)) {
 
2255
                        ISC_LIST_DEQUEUE(remoteaddr_list, laddr, link);
 
2256
                        free(laddr);
 
2257
                        break;
 
2258
                }
 
2259
                else
 
2260
                        laddr = next;
 
2261
        }
 
2262
#ifdef DEBUG
 
2263
        if (debug)
 
2264
            printf("Deleted addr %s from list of addresses\n",
 
2265
                   stoa(addr));
 
2266
#endif
 
2267
}
 
2268
int
 
2269
find_addr_in_list(struct sockaddr_storage *addr) {
 
2270
 
 
2271
        remaddr_t *next;
 
2272
        remaddr_t *laddr = ISC_LIST_HEAD(remoteaddr_list);
 
2273
#ifdef DEBUG
 
2274
        if (debug)
 
2275
            printf("Finding addr %s in list of addresses\n",
 
2276
                   stoa(addr));
 
2277
#endif
 
2278
 
 
2279
        while(laddr != NULL) {
 
2280
                next = ISC_LIST_NEXT(laddr, link);
 
2281
                if(SOCKCMP(&laddr->addr, addr)) {
 
2282
                        return (laddr->if_index);
 
2283
                        break;
 
2284
                }
 
2285
                else
 
2286
                        laddr = next;
 
2287
        }
 
2288
        return (-1); /* Not found */
 
2289
}