1 /* 2 * ntp_io.c - input/output routines for ntpd. The socket-opening code 3 * was shamelessly stolen from ntpd. 4 */ 5 6 #ifdef HAVE_CONFIG_H 7 # include <config.h> 8 #endif 9 10 #include <stdio.h> 11 #include <signal.h> 12 #include <sys/types.h> 13 #ifdef HAVE_SYS_PARAM_H 14 # include <sys/param.h> 15 #endif /* HAVE_SYS_PARAM_H */ 16 #ifdef HAVE_SYS_TIME_H 17 # include <sys/time.h> 18 #endif 19 #ifdef HAVE_NETINET_IN_H 20 # include <netinet/in.h> 21 #endif 22 #ifdef HAVE_NETINET_IN_SYSTM_H 23 # include <netinet/in_systm.h> 24 #else /* Some old linux systems at least have in_system.h instead. */ 25 # include <netinet/in_system.h> 26 #endif /* HAVE_NETINET_IN_SYSTM_H */ 27 #include <netinet/ip.h> 28 #ifdef HAVE_SYS_IOCTL_H 29 # include <sys/ioctl.h> 30 #endif 31 #ifdef HAVE_SYS_SOCKIO_H /* UXPV: SIOC* #defines (Frank Vance <fvance@waii.com>) */ 32 # include <sys/sockio.h> 33 #endif 34 #include <arpa/inet.h> 35 36 #if _BSDI_VERSION >= 199510 37 # include <ifaddrs.h> 38 #endif 39 40 #include "ntp_machine.h" 41 #include "ntpd.h" 42 #include "ntp_io.h" 43 #include "iosignal.h" 44 #include "ntp_refclock.h" 45 #include "ntp_if.h" 46 #include "ntp_stdlib.h" 47 48 #if defined(VMS) /* most likely UCX-specific */ 49 50 #include <UCX$INETDEF.H> 51 52 /* "un*x"-compatible names for some items in UCX$INETDEF.H */ 53 #define ifreq IFREQDEF 54 #define ifr_name IFR$T_NAME 55 #define ifr_addr IFR$R_DUMMY.IFR$T_ADDR 56 #define ifr_broadaddr IFR$R_DUMMY.IFR$T_BROADADDR 57 #define ifr_flags IFR$R_DUMMY.IFR$R_DUMMY_1_OVRL.IFR$W_FLAGS 58 #define IFF_UP IFR$M_IFF_UP 59 #define IFF_BROADCAST IFR$M_IFF_BROADCAST 60 #define IFF_LOOPBACK IFR$M_IFF_LOOPBACK 61 62 #endif /* VMS */ 63 64 65 #if defined(VMS) || defined(SYS_WINNT) 66 /* structure used in SIOCGIFCONF request (after [KSR] OSF/1) */ 67 struct ifconf { 68 int ifc_len; /* size of buffer */ 69 union { 70 caddr_t ifcu_buf; 71 struct ifreq *ifcu_req; 72 } ifc_ifcu; 73 }; 74 #define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */ 75 #define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */ 76 77 #endif /* VMS */ 78 79 #if defined(USE_TTY_SIGPOLL) || defined(USE_UDP_SIGPOLL) 80 # if defined(SYS_AIX) && defined(_IO) /* XXX Identify AIX some other way */ 81 # undef _IO 82 # endif 83 # include <stropts.h> 84 #endif 85 86 /* 87 * We do asynchronous input using the SIGIO facility. A number of 88 * recvbuf buffers are preallocated for input. In the signal 89 * handler we poll to see which sockets are ready and read the 90 * packets from them into the recvbuf's along with a time stamp and 91 * an indication of the source host and the interface it was received 92 * through. This allows us to get as accurate receive time stamps 93 * as possible independent of other processing going on. 94 * 95 * We watch the number of recvbufs available to the signal handler 96 * and allocate more when this number drops below the low water 97 * mark. If the signal handler should run out of buffers in the 98 * interim it will drop incoming frames, the idea being that it is 99 * better to drop a packet than to be inaccurate. 100 */ 101 102 103 /* 104 * Other statistics of possible interest 105 */ 106 volatile u_long packets_dropped; /* total number of packets dropped on reception */ 107 volatile u_long packets_ignored; /* packets received on wild card interface */ 108 volatile u_long packets_received; /* total number of packets received */ 109 u_long packets_sent; /* total number of packets sent */ 110 u_long packets_notsent; /* total number of packets which couldn't be sent */ 111 112 volatile u_long handler_calls; /* number of calls to interrupt handler */ 113 volatile u_long handler_pkts; /* number of pkts received by handler */ 114 u_long io_timereset; /* time counters were reset */ 115 116 /* 117 * Interface stuff 118 */ 119 struct interface *any_interface; /* pointer to default interface */ 120 struct interface *loopback_interface; /* point to loopback interface */ 121 static struct interface inter_list[MAXINTERFACES]; 122 static int ninterfaces; 123 124 #ifdef REFCLOCK 125 /* 126 * Refclock stuff. We keep a chain of structures with data concerning 127 * the guys we are doing I/O for. 128 */ 129 static struct refclockio *refio; 130 #endif /* REFCLOCK */ 131 132 /* 133 * File descriptor masks etc. for call to select 134 */ 135 fd_set activefds; 136 int maxactivefd; 137 138 static int create_sockets P((u_int)); 139 static int open_socket P((struct sockaddr_in *, int, int)); 140 static void close_socket P((int)); 141 static void close_file P((int)); 142 static char * fdbits P((int, fd_set *)); 143 144 /* 145 * init_io - initialize I/O data structures and call socket creation routine 146 */ 147 void 148 init_io(void) 149 { 150 #ifdef SYS_WINNT 151 WORD wVersionRequested; 152 WSADATA wsaData; 153 init_transmitbuff(); 154 #endif /* SYS_WINNT */ 155 156 /* 157 * Init buffer free list and stat counters 158 */ 159 init_recvbuff(RECV_INIT); 160 161 packets_dropped = packets_received = 0; 162 packets_ignored = 0; 163 packets_sent = packets_notsent = 0; 164 handler_calls = handler_pkts = 0; 165 io_timereset = 0; 166 loopback_interface = 0; 167 168 #ifdef REFCLOCK 169 refio = 0; 170 #endif 171 172 #if defined(HAVE_SIGNALED_IO) 173 (void) set_signal(); 174 #endif 175 176 #ifdef SYS_WINNT 177 wVersionRequested = MAKEWORD(1,1); 178 if (WSAStartup(wVersionRequested, &wsaData)) 179 { 180 msyslog(LOG_ERR, "No useable winsock.dll: %m"); 181 exit(1); 182 } 183 #endif /* SYS_WINNT */ 184 185 /* 186 * Create the sockets 187 */ 188 BLOCKIO(); 189 (void) create_sockets(htons(NTP_PORT)); 190 UNBLOCKIO(); 191 192 #ifdef DEBUG 193 if (debug) 194 printf("init_io: maxactivefd %d\n", maxactivefd); 195 #endif 196 } 197 198 /* 199 * create_sockets - create a socket for each interface plus a default 200 * socket for when we don't know where to send 201 */ 202 static int 203 create_sockets( 204 u_int port 205 ) 206 { 207 #if _BSDI_VERSION >= 199510 208 int i, j; 209 struct ifaddrs *ifaddrs, *ifap; 210 struct sockaddr_in resmask; 211 #if _BSDI_VERSION < 199701 212 struct ifaddrs *lp; 213 int num_if; 214 #endif 215 #else /* _BSDI_VERSION >= 199510 */ 216 # ifdef STREAMS_TLI 217 struct strioctl ioc; 218 # endif /* STREAMS_TLI */ 219 char buf[MAXINTERFACES*sizeof(struct ifreq)]; 220 struct ifconf ifc; 221 struct ifreq ifreq, *ifr; 222 int n, i, j, vs, size = 0; 223 struct sockaddr_in resmask; 224 #endif /* _BSDI_VERSION >= 199510 */ 225 226 #ifdef DEBUG 227 if (debug) 228 printf("create_sockets(%d)\n", ntohs( (u_short) port)); 229 #endif 230 231 /* 232 * create pseudo-interface with wildcard address 233 */ 234 inter_list[0].sin.sin_family = AF_INET; 235 inter_list[0].sin.sin_port = port; 236 inter_list[0].sin.sin_addr.s_addr = htonl(INADDR_ANY); 237 (void) strncpy(inter_list[0].name, "wildcard", 238 sizeof(inter_list[0].name)); 239 inter_list[0].mask.sin_addr.s_addr = htonl(~ (u_int32)0); 240 inter_list[0].received = 0; 241 inter_list[0].sent = 0; 242 inter_list[0].notsent = 0; 243 inter_list[0].flags = INT_BROADCAST; 244 245 #if _BSDI_VERSION >= 199510 246 #if _BSDI_VERSION >= 199701 247 if (getifaddrs(&ifaddrs) < 0) 248 { 249 msyslog(LOG_ERR, "getifaddrs: %m"); 250 exit(1); 251 } 252 i = 1; 253 for (ifap = ifaddrs; ifap != NULL; ifap = ifap->ifa_next) 254 #else 255 if (getifaddrs(&ifaddrs, &num_if) < 0) 256 { 257 msyslog(LOG_ERR, "create_sockets: getifaddrs() failed: %m"); 258 exit(1); 259 } 260 261 i = 1; 262 263 for (ifap = ifaddrs, lp = ifap + num_if; ifap < lp; ifap++) 264 #endif 265 { 266 struct sockaddr_in *sin; 267 268 if (!ifap->ifa_addr) 269 continue; 270 271 if (ifap->ifa_addr->sa_family != AF_INET) 272 continue; 273 274 if ((ifap->ifa_flags & IFF_UP) == 0) 275 continue; 276 277 if (ifap->ifa_flags & IFF_LOOPBACK) 278 { 279 sin = (struct sockaddr_in *)ifap->ifa_addr; 280 if (ntohl(sin->sin_addr.s_addr) != 0x7f000001) 281 { 282 continue; 283 } 284 } 285 286 inter_list[i].flags = 0; 287 if (ifap->ifa_flags & IFF_BROADCAST) 288 inter_list[i].flags |= INT_BROADCAST; 289 290 (void)strcpy(inter_list[i].name, ifap->ifa_name); 291 292 sin = (struct sockaddr_in *)ifap->ifa_addr; 293 inter_list[i].sin = *sin; 294 inter_list[i].sin.sin_port = port; 295 296 if (ifap->ifa_flags & IFF_LOOPBACK) 297 { 298 inter_list[i].flags = INT_LOOPBACK; 299 if (loopback_interface == NULL 300 || ntohl(sin->sin_addr.s_addr) != 0x7f000001) 301 loopback_interface = &inter_list[i]; 302 } 303 304 if (inter_list[i].flags & INT_BROADCAST) 305 { 306 sin = (struct sockaddr_in *)ifap->ifa_broadaddr; 307 inter_list[i].bcast = *sin; 308 inter_list[i].bcast.sin_port = port; 309 } 310 311 if (ifap->ifa_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) 312 { 313 inter_list[i].mask.sin_addr.s_addr = 0xffffffff; 314 } 315 else 316 { 317 sin = (struct sockaddr_in *)ifap->ifa_netmask; 318 inter_list[i].mask = *sin; 319 } 320 inter_list[i].mask.sin_family = AF_INET; 321 inter_list[i].mask.sin_len = sizeof *sin; 322 323 /* 324 * look for an already existing source interface address. If 325 * the machine has multiple point to point interfaces, then 326 * the local address may appear more than once. 327 * 328 * A second problem exists if we have two addresses on 329 * the same network (via "ifconfig alias ..."). Don't 330 * make two xntp interfaces for the two aliases on the 331 * one physical interface. -wsr 332 */ 333 for (j=0; j < i; j++) 334 if (inter_list[j].sin.sin_addr.s_addr & 335 inter_list[j].mask.sin_addr.s_addr == 336 inter_list[i].sin.sin_addr.s_addr & 337 inter_list[i].mask.sin_addr.s_addr) 338 { 339 if (inter_list[j].flags & INT_LOOPBACK) 340 inter_list[j] = inter_list[i]; 341 break; 342 } 343 if (j == i) 344 i++; 345 if (i > MAXINTERFACES) 346 break; 347 } 348 free(ifaddrs); 349 #else /* _BSDI_VERSION >= 199510 */ 350 # ifdef USE_STREAMS_DEVICE_FOR_IF_CONFIG 351 if ((vs = open("/dev/ip", O_RDONLY)) < 0) 352 { 353 msyslog(LOG_ERR, "create_sockets: open(/dev/ip) failed: %m"); 354 exit(1); 355 } 356 # else /* not USE_STREAMS_DEVICE_FOR_IF_CONFIG */ 357 if ( 358 (vs = socket(AF_INET, SOCK_DGRAM, 0)) 359 # ifndef SYS_WINNT 360 < 0 361 # else /* SYS_WINNT */ 362 == INVALID_SOCKET 363 # endif /* SYS_WINNT */ 364 ) { 365 msyslog(LOG_ERR, "create_sockets: socket(AF_INET, SOCK_DGRAM) failed: %m"); 366 exit(1); 367 } 368 # endif /* not USE_STREAMS_DEVICE_FOR_IF_CONFIG */ 369 370 i = 1; 371 # if !defined(SYS_WINNT) 372 ifc.ifc_len = sizeof(buf); 373 # endif 374 # ifdef STREAMS_TLI 375 ioc.ic_cmd = SIOCGIFCONF; 376 ioc.ic_timout = 0; 377 ioc.ic_dp = (caddr_t)buf; 378 ioc.ic_len = sizeof(buf); 379 if(ioctl(vs, I_STR, &ioc) < 0 || 380 ioc.ic_len < sizeof(struct ifreq)) 381 { 382 msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFCONF) failed: %m - exiting"); 383 exit(1); 384 } 385 # ifdef SIZE_RETURNED_IN_BUFFER 386 ifc.ifc_len = ioc.ic_len - sizeof(int); 387 ifc.ifc_buf = buf + sizeof(int); 388 # else /* not SIZE_RETURNED_IN_BUFFER */ 389 ifc.ifc_len = ioc.ic_len; 390 ifc.ifc_buf = buf; 391 # endif /* not SIZE_RETURNED_IN_BUFFER */ 392 393 # else /* not STREAMS_TLI */ 394 ifc.ifc_len = sizeof(buf); 395 ifc.ifc_buf = buf; 396 # ifndef SYS_WINNT 397 if (ioctl(vs, SIOCGIFCONF, (char *)&ifc) < 0) 398 # else 399 if (WSAIoctl(vs, SIO_GET_INTERFACE_LIST, 0, 0, ifc.ifc_buf, ifc.ifc_len, &ifc.ifc_len, 0, 0) == SOCKET_ERROR) 400 # endif /* SYS_WINNT */ 401 { 402 msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFCONF) failed: %m - exiting"); 403 exit(1); 404 } 405 406 # endif /* not STREAMS_TLI */ 407 408 for(n = ifc.ifc_len, ifr = ifc.ifc_req; n > 0; 409 ifr = (struct ifreq *)((char *)ifr + size)) 410 { 411 extern int listen_to_virtual_ips; 412 413 size = sizeof(*ifr); 414 415 # ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR 416 if (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_addr)) 417 size += ifr->ifr_addr.sa_len - sizeof(struct sockaddr); 418 # endif 419 n -= size; 420 421 # if !defined(SYS_WINNT) 422 /* Exclude logical interfaces (indicated by ':' in the interface name) */ 423 if (debug) 424 printf("interface <%s> ", ifr->ifr_name); 425 if ((listen_to_virtual_ips == 0) 426 && (strchr(ifr->ifr_name, (int)':') != NULL)) { 427 if (debug) 428 printf("ignored\n"); 429 continue; 430 } 431 if (debug) 432 printf("OK\n"); 433 434 if ( 435 # ifdef VMS /* VMS+UCX */ 436 (((struct sockaddr *)&(ifr->ifr_addr))->sa_family != AF_INET) 437 # else 438 (ifr->ifr_addr.sa_family != AF_INET) 439 # endif /* VMS+UCX */ 440 ) { 441 if (debug) 442 printf("ignoring %s - not AF_INET\n", 443 ifr->ifr_name); 444 continue; 445 } 446 # endif /* SYS_WINNT */ 447 memcpy(&ifreq, ifr, sizeof(ifreq)); 448 inter_list[i].flags = 0; 449 /* is it broadcast capable? */ 450 # ifndef SYS_WINNT 451 # ifdef STREAMS_TLI 452 ioc.ic_cmd = SIOCGIFFLAGS; 453 ioc.ic_timout = 0; 454 ioc.ic_dp = (caddr_t)&ifreq; 455 ioc.ic_len = sizeof(struct ifreq); 456 if(ioctl(vs, I_STR, &ioc)) { 457 msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFFLAGS) failed: %m"); 458 continue; 459 } 460 # else /* not STREAMS_TLI */ 461 if (ioctl(vs, SIOCGIFFLAGS, (char *)&ifreq) < 0) { 462 if (errno != ENXIO) 463 msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFFLAGS) failed: %m"); 464 continue; 465 } 466 # endif /* not STREAMS_TLI */ 467 if ((ifreq.ifr_flags & IFF_UP) == 0) { 468 if (debug) 469 printf("ignoring %s - interface not UP\n", 470 ifr->ifr_name); 471 continue; 472 } 473 inter_list[i].flags = 0; 474 if (ifreq.ifr_flags & IFF_BROADCAST) 475 inter_list[i].flags |= INT_BROADCAST; 476 # endif /* not SYS_WINNT */ 477 # if !defined(SUN_3_3_STINKS) 478 if ( 479 # if defined(IFF_LOCAL_LOOPBACK) /* defined(SYS_HPUX) && (SYS_HPUX < 8) */ 480 (ifreq.ifr_flags & IFF_LOCAL_LOOPBACK) 481 # elif defined(IFF_LOOPBACK) 482 (ifreq.ifr_flags & IFF_LOOPBACK) 483 # else /* not IFF_LOCAL_LOOPBACK and not IFF_LOOPBACK */ 484 /* test against 127.0.0.1 (yuck!!) */ 485 (inter_list[i].sin.sin_addr.s_addr == inet_addr("127.0.0.1")) 486 # endif /* not IFF_LOCAL_LOOPBACK and not IFF_LOOPBACK */ 487 ) 488 { 489 # ifndef SYS_WINNT 490 inter_list[i].flags |= INT_LOOPBACK; 491 # endif /* not SYS_WINNT */ 492 if (loopback_interface == 0) 493 { 494 loopback_interface = &inter_list[i]; 495 } 496 } 497 # endif /* not SUN_3_3_STINKS */ 498 499 #if 0 500 # ifndef SYS_WINNT 501 # ifdef STREAMS_TLI 502 ioc.ic_cmd = SIOCGIFADDR; 503 ioc.ic_timout = 0; 504 ioc.ic_dp = (caddr_t)&ifreq; 505 ioc.ic_len = sizeof(struct ifreq); 506 if (ioctl(vs, I_STR, &ioc)) 507 { 508 msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFADDR) failed: %m"); 509 continue; 510 } 511 # else /* not STREAMS_TLI */ 512 if (ioctl(vs, SIOCGIFADDR, (char *)&ifreq) < 0) 513 { 514 if (errno != ENXIO) 515 msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFADDR) failed: %m"); 516 continue; 517 } 518 # endif /* not STREAMS_TLI */ 519 # endif /* not SYS_WINNT */ 520 #endif /* 0 */ 521 # if defined(SYS_WINNT) 522 {int TODO_FillInTheNameWithSomeThingReasonble;} 523 # else 524 (void)strncpy(inter_list[i].name, ifreq.ifr_name, 525 sizeof(inter_list[i].name)); 526 # endif 527 inter_list[i].sin = *(struct sockaddr_in *)&ifr->ifr_addr; 528 inter_list[i].sin.sin_family = AF_INET; 529 inter_list[i].sin.sin_port = port; 530 531 # if defined(SUN_3_3_STINKS) 532 /* 533 * Oh, barf! I'm too disgusted to even explain this 534 */ 535 if (SRCADR(&inter_list[i].sin) == 0x7f000001) 536 { 537 inter_list[i].flags |= INT_LOOPBACK; 538 if (loopback_interface == 0) 539 loopback_interface = &inter_list[i]; 540 } 541 # endif /* SUN_3_3_STINKS */ 542 # if !defined SYS_WINNT && !defined SYS_CYGWIN32 /* no interface flags on NT */ 543 if (inter_list[i].flags & INT_BROADCAST) { 544 # ifdef STREAMS_TLI 545 ioc.ic_cmd = SIOCGIFBRDADDR; 546 ioc.ic_timout = 0; 547 ioc.ic_dp = (caddr_t)&ifreq; 548 ioc.ic_len = sizeof(struct ifreq); 549 if(ioctl(vs, I_STR, &ioc)) { 550 msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFBRDADDR) failed: %m"); 551 exit(1); 552 } 553 # else /* not STREAMS_TLI */ 554 if (ioctl(vs, SIOCGIFBRDADDR, (char *)&ifreq) < 0) { 555 msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFBRDADDR) failed: %m"); 556 exit(1); 557 } 558 # endif /* not STREAMS_TLI */ 559 560 # ifndef ifr_broadaddr 561 inter_list[i].bcast = 562 *(struct sockaddr_in *)&ifreq.ifr_addr; 563 # else 564 inter_list[i].bcast = 565 *(struct sockaddr_in *)&ifreq.ifr_broadaddr; 566 # endif /* ifr_broadaddr */ 567 inter_list[i].bcast.sin_family = AF_INET; 568 inter_list[i].bcast.sin_port = port; 569 } 570 571 # ifdef STREAMS_TLI 572 ioc.ic_cmd = SIOCGIFNETMASK; 573 ioc.ic_timout = 0; 574 ioc.ic_dp = (caddr_t)&ifreq; 575 ioc.ic_len = sizeof(struct ifreq); 576 if(ioctl(vs, I_STR, &ioc)) { 577 msyslog(LOG_ERR, "create_sockets: ioctl(I_STR:SIOCGIFNETMASK) failed: %m"); 578 exit(1); 579 } 580 # else /* not STREAMS_TLI */ 581 if (ioctl(vs, SIOCGIFNETMASK, (char *)&ifreq) < 0) { 582 msyslog(LOG_ERR, "create_sockets: ioctl(SIOCGIFNETMASK) failed: %m"); 583 exit(1); 584 } 585 # endif /* not STREAMS_TLI */ 586 inter_list[i].mask = *(struct sockaddr_in *)&ifreq.ifr_addr; 587 # else 588 /* winnt here */ 589 inter_list[i].bcast = ifreq.ifr_broadaddr; 590 inter_list[i].bcast.sin_family = AF_INET; 591 inter_list[i].bcast.sin_port = port; 592 inter_list[i].mask = ifreq.ifr_mask; 593 # endif /* not SYS_WINNT */ 594 595 /* 596 * look for an already existing source interface address. If 597 * the machine has multiple point to point interfaces, then 598 * the local address may appear more than once. 599 */ 600 for (j=0; j < i; j++) 601 if (inter_list[j].sin.sin_addr.s_addr == 602 inter_list[i].sin.sin_addr.s_addr) { 603 break; 604 } 605 if (j == i) 606 i++; 607 if (i > MAXINTERFACES) 608 break; 609 } 610 closesocket(vs); 611 #endif /* _BSDI_VERSION >= 199510 */ 612 613 ninterfaces = i; 614 maxactivefd = 0; 615 FD_ZERO(&activefds); 616 for (i = 0; i < ninterfaces; i++) { 617 inter_list[i].fd = 618 open_socket(&inter_list[i].sin, 619 inter_list[i].flags & INT_BROADCAST, 0); 620 } 621 622 /* 623 * Now that we have opened all the sockets, turn off the reuse flag for 624 * security. 625 */ 626 for (i = 0; i < ninterfaces; i++) { 627 int off = 0; 628 629 /* 630 * if inter_list[ n ].fd is -1, we might have a adapter 631 * configured but not present 632 */ 633 if ( inter_list[ i ].fd != -1 ) { 634 if (setsockopt(inter_list[i].fd, SOL_SOCKET, 635 SO_REUSEADDR, (char *)&off, 636 sizeof(off))) { 637 msyslog(LOG_ERR, "create_sockets: setsockopt(SO_REUSEADDR,off) failed: %m"); 638 } 639 } 640 } 641 642 #if defined(MCAST) 643 /* 644 * enable possible multicast reception on the broadcast socket 645 */ 646 inter_list[0].bcast.sin_addr.s_addr = htonl(INADDR_ANY); 647 inter_list[0].bcast.sin_family = AF_INET; 648 inter_list[0].bcast.sin_port = port; 649 #endif /* MCAST */ 650 651 /* 652 * Blacklist all bound interface addresses 653 */ 654 resmask.sin_addr.s_addr = ~ (u_int32)0; 655 for (i = 1; i < ninterfaces; i++) 656 hack_restrict(RESTRICT_FLAGS, &inter_list[i].sin, &resmask, 657 RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE); 658 659 any_interface = &inter_list[0]; 660 #ifdef DEBUG 661 if (debug > 2) { 662 printf("create_sockets: ninterfaces=%d\n", ninterfaces); 663 for (i = 0; i < ninterfaces; i++) { 664 printf("interface %d: fd=%d, bfd=%d, name=%.8s, flags=0x%x\n", 665 i, 666 inter_list[i].fd, 667 inter_list[i].bfd, 668 inter_list[i].name, 669 inter_list[i].flags); 670 /* Leave these as three printf calls. */ 671 printf(" sin=%s", 672 inet_ntoa((inter_list[i].sin.sin_addr))); 673 if (inter_list[i].flags & INT_BROADCAST) 674 printf(" bcast=%s,", 675 inet_ntoa((inter_list[i].bcast.sin_addr))); 676 printf(" mask=%s\n", 677 inet_ntoa((inter_list[i].mask.sin_addr))); 678 } 679 } 680 #endif 681 #if defined (HAVE_IO_COMPLETION_PORT) 682 for (i = 0; i < ninterfaces; i++) { 683 io_completion_port_add_socket(&inter_list[i]); 684 } 685 #endif 686 return ninterfaces; 687 } 688 689 /* 690 * io_setbclient - open the broadcast client sockets 691 */ 692 void 693 io_setbclient(void) 694 { 695 int i; 696 697 for (i = 1; i < ninterfaces; i++) 698 { 699 if (!(inter_list[i].flags & INT_BROADCAST)) 700 continue; 701 if (inter_list[i].flags & INT_BCASTOPEN) 702 continue; 703 #ifdef SYS_SOLARIS 704 inter_list[i].bcast.sin_addr.s_addr = htonl(INADDR_ANY); 705 #endif 706 #ifdef OPEN_BCAST_SOCKET /* Was: !SYS_DOMAINOS && !SYS_LINUX */ 707 inter_list[i].bfd = open_socket(&inter_list[i].bcast, INT_BROADCAST, 1); 708 inter_list[i].flags |= INT_BCASTOPEN; 709 #endif 710 } 711 } 712 713 714 /* 715 * io_multicast_add() - add multicast group address 716 */ 717 void 718 io_multicast_add( 719 u_int32 addr 720 ) 721 { 722 #ifdef MCAST 723 struct ip_mreq mreq; 724 int i = ninterfaces; /* Use the next interface */ 725 u_int32 haddr = ntohl(addr); 726 struct in_addr iaddr; 727 int s; 728 struct sockaddr_in *sinp; 729 730 iaddr.s_addr = addr; 731 732 if (!IN_CLASSD(haddr)) 733 { 734 msyslog(LOG_ERR, 735 "cannot add multicast address %s as it is not class D", 736 inet_ntoa(iaddr)); 737 return; 738 } 739 740 for (i = 0; i < ninterfaces; i++) 741 { 742 /* Already have this address */ 743 if (inter_list[i].sin.sin_addr.s_addr == addr) return; 744 /* found a free slot */ 745 if (inter_list[i].sin.sin_addr.s_addr == 0 && 746 inter_list[i].fd <= 0 && inter_list[i].bfd <= 0 && 747 inter_list[i].flags == 0) break; 748 } 749 sinp = &(inter_list[i].sin); 750 751 memset((char *)&mreq, 0, sizeof(mreq)); 752 memset((char *)&inter_list[i], 0, sizeof inter_list[0]); 753 sinp->sin_family = AF_INET; 754 sinp->sin_addr = iaddr; 755 sinp->sin_port = htons(123); 756 757 s = open_socket(sinp, 0, 1); 758 /* Try opening a socket for the specified class D address */ 759 /* This works under SunOS 4.x, but not OSF1 .. :-( */ 760 if (s < 0) 761 { 762 memset((char *)&inter_list[i], 0, sizeof inter_list[0]); 763 i = 0; 764 /* HACK ! -- stuff in an address */ 765 inter_list[i].bcast.sin_addr.s_addr = addr; 766 msyslog(LOG_ERR, "...multicast address %s using wildcard socket", 767 inet_ntoa(iaddr)); 768 } 769 else 770 { 771 inter_list[i].fd = s; 772 inter_list[i].bfd = -1; 773 (void) strncpy(inter_list[i].name, "multicast", 774 sizeof(inter_list[i].name)); 775 inter_list[i].mask.sin_addr.s_addr = htonl(~(u_int32)0); 776 } 777 778 /* 779 * enable reception of multicast packets 780 */ 781 mreq.imr_multiaddr = iaddr; 782 mreq.imr_interface.s_addr = htonl(INADDR_ANY); 783 if (setsockopt(inter_list[i].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, 784 (char *)&mreq, sizeof(mreq)) == -1) 785 msyslog(LOG_ERR, 786 "setsockopt IP_ADD_MEMBERSHIP fails: %m for %x / %x (%s)", 787 mreq.imr_multiaddr.s_addr, mreq.imr_interface.s_addr, 788 inet_ntoa(iaddr)); 789 inter_list[i].flags |= INT_MULTICAST; 790 if (i >= ninterfaces) ninterfaces = i+1; 791 #else /* MCAST */ 792 struct in_addr iaddr; 793 794 iaddr.s_addr = addr; 795 msyslog(LOG_ERR, "cannot add multicast address %s as no MCAST support", 796 inet_ntoa(iaddr)); 797 #endif /* MCAST */ 798 } 799 800 /* 801 * io_unsetbclient - close the broadcast client sockets 802 */ 803 void 804 io_unsetbclient(void) 805 { 806 int i; 807 808 for (i = 1; i < ninterfaces; i++) 809 { 810 if (!(inter_list[i].flags & INT_BCASTOPEN)) 811 continue; 812 close_socket(inter_list[i].bfd); 813 inter_list[i].bfd = -1; 814 inter_list[i].flags &= ~INT_BCASTOPEN; 815 } 816 } 817 818 819 /* 820 * io_multicast_del() - delete multicast group address 821 */ 822 void 823 io_multicast_del( 824 u_int32 addr 825 ) 826 { 827 #ifdef MCAST 828 int i; 829 struct ip_mreq mreq; 830 u_int32 haddr = ntohl(addr); 831 struct sockaddr_in sinaddr; 832 833 if (!IN_CLASSD(haddr)) 834 { 835 sinaddr.sin_addr.s_addr = addr; 836 msyslog(LOG_ERR, 837 "invalid multicast address %s", ntoa(&sinaddr)); 838 return; 839 } 840 841 /* 842 * Disable reception of multicast packets 843 */ 844 mreq.imr_multiaddr.s_addr = addr; 845 mreq.imr_interface.s_addr = htonl(INADDR_ANY); 846 for (i = 0; i < ninterfaces; i++) 847 { 848 if (!(inter_list[i].flags & INT_MULTICAST)) 849 continue; 850 if (!(inter_list[i].fd < 0)) 851 continue; 852 if (addr != inter_list[i].sin.sin_addr.s_addr) 853 continue; 854 if (i != 0) 855 { 856 /* we have an explicit fd, so we can close it */ 857 close_socket(inter_list[i].fd); 858 memset((char *)&inter_list[i], 0, sizeof inter_list[0]); 859 inter_list[i].fd = -1; 860 inter_list[i].bfd = -1; 861 } 862 else 863 { 864 /* We are sharing "any address" port :-( Don't close it! */ 865 if (setsockopt(inter_list[i].fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, 866 (char *)&mreq, sizeof(mreq)) == -1) 867 msyslog(LOG_ERR, "setsockopt IP_DROP_MEMBERSHIP fails: %m"); 868 /* This is **WRONG** -- there may be others ! */ 869 /* There should be a count of users ... */ 870 inter_list[i].flags &= ~INT_MULTICAST; 871 } 872 } 873 #else /* not MCAST */ 874 msyslog(LOG_ERR, "this function requires multicast kernel"); 875 #endif /* not MCAST */ 876 } 877 878 879 /* 880 * open_socket - open a socket, returning the file descriptor 881 */ 882 static int 883 open_socket( 884 struct sockaddr_in *addr, 885 int flags, 886 int turn_off_reuse 887 ) 888 { 889 int fd, tos; 890 int on = 1, off = 0; 891 892 /* create a datagram (UDP) socket */ 893 if ( (fd = socket(AF_INET, SOCK_DGRAM, 0)) 894 #ifndef SYS_WINNT 895 < 0 896 #else 897 == INVALID_SOCKET 898 #endif /* SYS_WINNT */ 899 ) 900 { 901 msyslog(LOG_ERR, "socket(AF_INET, SOCK_DGRAM, 0) failed: %m"); 902 exit(1); 903 /*NOTREACHED*/ 904 } 905 906 /* set SO_REUSEADDR since we will be binding the same port 907 number on each interface */ 908 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 909 (char *)&on, sizeof(on))) 910 { 911 msyslog(LOG_ERR, "setsockopt SO_REUSEADDR on fails: %m"); 912 } 913 914 #if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS) 915 /* set IP_TOS to minimize packet delay */ 916 tos = IPTOS_LOWDELAY; 917 if (setsockopt(fd, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(tos)) < 0) 918 { 919 msyslog(LOG_ERR, "setsockopt IPTOS_LOWDELAY on fails: %m"); 920 } 921 #endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */ 922 923 /* 924 * bind the local address. 925 */ 926 if (bind(fd, (struct sockaddr *)addr, sizeof(*addr)) < 0) { 927 char buff[160]; 928 sprintf(buff, 929 "bind() fd %d, family %d, port %d, addr %s, in_classd=%d flags=%d fails: %%m", 930 fd, addr->sin_family, (int)ntohs(addr->sin_port), 931 ntoa(addr), 932 IN_CLASSD(ntohl(addr->sin_addr.s_addr)), flags); 933 msyslog(LOG_ERR, buff); 934 closesocket(fd); 935 936 /* 937 * soft fail if opening a class D address 938 */ 939 if (IN_CLASSD(ntohl(addr->sin_addr.s_addr))) 940 return -1; 941 #if 0 942 exit(1); 943 #else 944 return -1; 945 #endif 946 } 947 #ifdef DEBUG 948 if (debug) 949 printf("bind() fd %d, family %d, port %d, addr %s, flags=%d\n", 950 fd, 951 addr->sin_family, 952 (int)ntohs(addr->sin_port), 953 ntoa(addr), 954 flags); 955 #endif 956 if (fd > maxactivefd) 957 maxactivefd = fd; 958 FD_SET(fd, &activefds); 959 960 /* 961 * set non-blocking, 962 */ 963 964 #ifdef USE_FIONBIO 965 /* in vxWorks we use FIONBIO, but the others are defined for old systems, so 966 * all hell breaks loose if we leave them defined 967 */ 968 #undef O_NONBLOCK 969 #undef FNDELAY 970 #undef O_NDELAY 971 #endif 972 973 #if defined(O_NONBLOCK) /* POSIX */ 974 if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) 975 { 976 msyslog(LOG_ERR, "fcntl(O_NONBLOCK) fails: %m"); 977 exit(1); 978 /*NOTREACHED*/ 979 } 980 #elif defined(FNDELAY) 981 if (fcntl(fd, F_SETFL, FNDELAY) < 0) 982 { 983 msyslog(LOG_ERR, "fcntl(FNDELAY) fails: %m"); 984 exit(1); 985 /*NOTREACHED*/ 986 } 987 #elif defined(O_NDELAY) /* generally the same as FNDELAY */ 988 if (fcntl(fd, F_SETFL, O_NDELAY) < 0) 989 { 990 msyslog(LOG_ERR, "fcntl(O_NDELAY) fails: %m"); 991 exit(1); 992 /*NOTREACHED*/ 993 } 994 #elif defined(FIONBIO) 995 if ( 996 # if defined(VMS) 997 (ioctl(fd,FIONBIO,&1) < 0) 998 # elif defined(SYS_WINNT) 999 (ioctlsocket(fd,FIONBIO,(u_long *) &on) == SOCKET_ERROR) 1000 # else 1001 (ioctl(fd,FIONBIO,&on) < 0) 1002 # endif 1003 ) 1004 { 1005 msyslog(LOG_ERR, "ioctl(FIONBIO) fails: %m"); 1006 exit(1); 1007 /*NOTREACHED*/ 1008 } 1009 #elif defined(FIOSNBIO) 1010 if (ioctl(fd,FIOSNBIO,&on) < 0) 1011 { 1012 msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails: %m"); 1013 exit(1); 1014 /*NOTREACHED*/ 1015 } 1016 #else 1017 # include "Bletch: Need non-blocking I/O!" 1018 #endif 1019 1020 #ifdef HAVE_SIGNALED_IO 1021 init_socket_sig(fd); 1022 #endif /* not HAVE_SIGNALED_IO */ 1023 1024 /* 1025 * Turn off the SO_REUSEADDR socket option. It apparently 1026 * causes heartburn on systems with multicast IP installed. 1027 * On normal systems it only gets looked at when the address 1028 * is being bound anyway.. 1029 */ 1030 if (turn_off_reuse) 1031 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 1032 (char *)&off, sizeof(off))) 1033 { 1034 msyslog(LOG_ERR, "setsockopt SO_REUSEADDR off fails: %m"); 1035 } 1036 1037 #ifdef SO_BROADCAST 1038 /* if this interface can support broadcast, set SO_BROADCAST */ 1039 if (flags & INT_BROADCAST) 1040 { 1041 if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, 1042 (char *)&on, sizeof(on))) 1043 { 1044 msyslog(LOG_ERR, "setsockopt(SO_BROADCAST): %m"); 1045 } 1046 } 1047 #endif /* SO_BROADCAST */ 1048 1049 #if !defined(SYS_WINNT) && !defined(VMS) 1050 # ifdef DEBUG 1051 if (debug > 1) 1052 printf("flags for fd %d: 0%o\n", fd, 1053 fcntl(fd, F_GETFL, 0)); 1054 # endif 1055 #endif /* SYS_WINNT || VMS */ 1056 1057 return fd; 1058 } 1059 1060 1061 /* 1062 * close_socket - close a socket and remove from the activefd list 1063 */ 1064 static void 1065 close_socket( 1066 int fd 1067 ) 1068 { 1069 int i, newmax; 1070 1071 (void) closesocket(fd); 1072 FD_CLR( (u_int) fd, &activefds); 1073 1074 if (fd >= maxactivefd) 1075 { 1076 newmax = 0; 1077 for (i = 0; i < maxactivefd; i++) 1078 if (FD_ISSET(i, &activefds)) 1079 newmax = i; 1080 maxactivefd = newmax; 1081 } 1082 } 1083 1084 1085 /* 1086 * close_file - close a file and remove from the activefd list 1087 * added 1/31/1997 Greg Schueman for Windows NT portability 1088 */ 1089 static void 1090 close_file( 1091 int fd 1092 ) 1093 { 1094 int i, newmax; 1095 1096 (void) close(fd); 1097 FD_CLR( (u_int) fd, &activefds); 1098 1099 if (fd >= maxactivefd) 1100 { 1101 newmax = 0; 1102 for (i = 0; i < maxactivefd; i++) 1103 if (FD_ISSET(i, &activefds)) 1104 newmax = i; 1105 maxactivefd = newmax; 1106 } 1107 } 1108 1109 1110 /* 1111 * findbcastinter - find broadcast interface corresponding to address 1112 */ 1113 struct interface * 1114 findbcastinter( 1115 struct sockaddr_in *addr 1116 ) 1117 { 1118 #if defined(SIOCGIFCONF) || defined(SYS_WINNT) 1119 register int i; 1120 register u_int32 netnum; 1121 1122 netnum = NSRCADR(addr); 1123 for (i = 1; i < ninterfaces; i++) 1124 { 1125 if (!(inter_list[i].flags & INT_BROADCAST)) 1126 continue; 1127 if (NSRCADR(&inter_list[i].bcast) == netnum) 1128 return &inter_list[i]; 1129 if ((NSRCADR(&inter_list[i].sin) & NSRCADR(&inter_list[i].mask)) 1130 == (netnum & NSRCADR(&inter_list[i].mask))) 1131 return &inter_list[i]; 1132 } 1133 #endif /* SIOCGIFCONF */ 1134 return any_interface; 1135 } 1136 1137 1138 /* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */ 1139 /* 1140 * sendpkt - send a packet to the specified destination. Maintain a 1141 * send error cache so that only the first consecutive error for a 1142 * destination is logged. 1143 */ 1144 void 1145 sendpkt( 1146 struct sockaddr_in *dest, 1147 struct interface *inter, 1148 int ttl, 1149 struct pkt *pkt, 1150 int len 1151 ) 1152 { 1153 int cc, slot; 1154 #ifdef SYS_WINNT 1155 DWORD err; 1156 #endif /* SYS_WINNT */ 1157 1158 /* 1159 * Send error cache. Empty slots have port == 0 1160 * Set ERRORCACHESIZE to 0 to disable 1161 */ 1162 struct cache { 1163 u_short port; 1164 struct in_addr addr; 1165 }; 1166 1167 #ifndef ERRORCACHESIZE 1168 #define ERRORCACHESIZE 8 1169 #endif 1170 #if ERRORCACHESIZE > 0 1171 static struct cache badaddrs[ERRORCACHESIZE]; 1172 #else 1173 #define badaddrs ((struct cache *)0) /* Only used in empty loops! */ 1174 #endif 1175 1176 /* 1177 * check if the source address is a multicast address - replace 1178 * interface with any-interface if so. 1179 */ 1180 if (IN_MULTICAST(ntohl(inter->sin.sin_addr.s_addr))) 1181 inter = any_interface; 1182 #ifdef DEBUG 1183 if (debug > 1) 1184 printf("%ssendpkt(fd=%d dst=%s, src=%s, ttl=%d, len=%d)\n", 1185 (ttl >= 0) ? "\tMCAST\t*****" : "", 1186 inter->fd, ntoa(dest), 1187 ntoa(&inter->sin), ttl, len); 1188 #endif 1189 1190 #ifdef MCAST 1191 /* for the moment we use the bcast option to set multicast ttl */ 1192 if (ttl >= 0 && ttl != inter->last_ttl) 1193 { 1194 char mttl = ttl; 1195 1196 /* set the multicast ttl for outgoing packets */ 1197 if (setsockopt(inter->fd, IPPROTO_IP, IP_MULTICAST_TTL, 1198 &mttl, sizeof(mttl)) == -1) 1199 { 1200 msyslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL fails: %m"); 1201 } 1202 else inter->last_ttl = ttl; 1203 } 1204 #endif /* MCAST */ 1205 1206 for (slot = ERRORCACHESIZE; --slot >= 0; ) 1207 if (badaddrs[slot].port == dest->sin_port && 1208 badaddrs[slot].addr.s_addr == dest->sin_addr.s_addr) 1209 break; 1210 1211 #if defined(HAVE_IO_COMPLETION_PORT) 1212 err = io_completion_port_sendto(inter, pkt, len, dest); 1213 if (err != ERROR_SUCCESS) 1214 #else 1215 cc = sendto(inter->fd, (char *)pkt, len, 0, (struct sockaddr *)dest, 1216 sizeof(struct sockaddr_in)); 1217 if (cc == -1) 1218 #endif 1219 { 1220 inter->notsent++; 1221 packets_notsent++; 1222 #if defined(HAVE_IO_COMPLETION_PORT) 1223 if (err != WSAEWOULDBLOCK && err != WSAENOBUFS && slot < 0) 1224 #else 1225 if (errno != EWOULDBLOCK && errno != ENOBUFS && slot < 0) 1226 #endif 1227 { 1228 /* 1229 * Remember this, if there's an empty slot 1230 */ 1231 for (slot = ERRORCACHESIZE; --slot >= 0; ) 1232 if (badaddrs[slot].port == 0) 1233 { 1234 badaddrs[slot].port = dest->sin_port; 1235 badaddrs[slot].addr = dest->sin_addr; 1236 break; 1237 } 1238 msyslog(LOG_ERR, "sendto(%s): %m", ntoa(dest)); 1239 } 1240 } 1241 else 1242 { 1243 inter->sent++; 1244 packets_sent++; 1245 /* 1246 * He's not bad any more 1247 */ 1248 if (slot >= 0) 1249 { 1250 msyslog(LOG_INFO, "Connection re-established to %s", ntoa(dest)); 1251 badaddrs[slot].port = 0; 1252 } 1253 } 1254 } 1255 1256 #if !defined(HAVE_IO_COMPLETION_PORT) 1257 /* 1258 * fdbits - generate ascii representation of fd_set (FAU debug support) 1259 * HFDF format - highest fd first. 1260 */ 1261 static char * 1262 fdbits( 1263 int count, 1264 fd_set *set 1265 ) 1266 { 1267 static char buffer[256]; 1268 char * buf = buffer; 1269 1270 count = (count < 256) ? count : 255; 1271 1272 while (count >= 0) 1273 { 1274 *buf++ = FD_ISSET(count, set) ? '#' : '-'; 1275 count--; 1276 } 1277 *buf = '\0'; 1278 1279 return buffer; 1280 } 1281 1282 /* 1283 * input_handler - receive packets asynchronously 1284 */ 1285 extern void 1286 input_handler( 1287 l_fp *cts 1288 ) 1289 { 1290 register int i, n; 1291 register struct recvbuf *rb; 1292 register int doing; 1293 register int fd; 1294 struct timeval tvzero; 1295 int fromlen; 1296 l_fp ts; /* Timestamp at BOselect() gob */ 1297 l_fp ts_e; /* Timestamp at EOselect() gob */ 1298 fd_set fds; 1299 int select_count = 0; 1300 static int handler_count = 0; 1301 1302 ++handler_count; 1303 if (handler_count != 1) 1304 msyslog(LOG_ERR, "input_handler: handler_count is %d!", handler_count); 1305 handler_calls++; 1306 ts = *cts; 1307 1308 for (;;) 1309 { 1310 /* 1311 * Do a poll to see who has data 1312 */ 1313 1314 fds = activefds; 1315 tvzero.tv_sec = tvzero.tv_usec = 0; 1316 1317 /* 1318 * If we have something to do, freeze a timestamp. 1319 * See below for the other cases (nothing (left) to do or error) 1320 */ 1321 while (0 < (n = select(maxactivefd+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero))) 1322 { 1323 ++select_count; 1324 ++handler_pkts; 1325 1326 #ifdef REFCLOCK 1327 /* 1328 * Check out the reference clocks first, if any 1329 */ 1330 if (refio != 0) 1331 { 1332 register struct refclockio *rp; 1333 1334 for (rp = refio; rp != 0 && n > 0; rp = rp->next) 1335 { 1336 fd = rp->fd; 1337 if (FD_ISSET(fd, &fds)) 1338 { 1339 n--; 1340 if (free_recvbuffs() == 0) 1341 { 1342 char buf[RX_BUFF_SIZE]; 1343 1344 (void) read(fd, buf, sizeof buf); 1345 packets_dropped++; 1346 goto select_again; 1347 } 1348 1349 rb = get_free_recv_buffer(); 1350 1351 i = (rp->datalen == 0 1352 || rp->datalen > sizeof(rb->recv_space)) 1353 ? sizeof(rb->recv_space) : rp->datalen; 1354 rb->recv_length = 1355 read(fd, (char *)&rb->recv_space, (unsigned)i); 1356 1357 if (rb->recv_length == -1) 1358 { 1359 msyslog(LOG_ERR, "clock read fd %d: %m", fd); 1360 freerecvbuf(rb); 1361 goto select_again; 1362 } 1363 1364 /* 1365 * Got one. Mark how and when it got here, 1366 * put it on the full list and do bookkeeping. 1367 */ 1368 rb->recv_srcclock = rp->srcclock; 1369 rb->dstadr = 0; 1370 rb->fd = fd; 1371 rb->recv_time = ts; 1372 rb->receiver = rp->clock_recv; 1373 1374 if (rp->io_input) 1375 { 1376 /* 1377 * have direct input routine for refclocks 1378 */ 1379 if (rp->io_input(rb) == 0) 1380 { 1381 /* 1382 * data was consumed - nothing to pass up 1383 * into block input machine 1384 */ 1385 freerecvbuf(rb); 1386 #if 1 1387 goto select_again; 1388 #else 1389 continue; 1390 #endif 1391 } 1392 } 1393 1394 add_full_recv_buffer(rb); 1395 1396 rp->recvcount++; 1397 packets_received++; 1398 } 1399 } 1400 } 1401 #endif /* REFCLOCK */ 1402 1403 /* 1404 * Loop through the interfaces looking for data to read. 1405 */ 1406 for (i = ninterfaces - 1; (i >= 0) && (n > 0); i--) 1407 { 1408 for (doing = 0; (doing < 2) && (n > 0); doing++) 1409 { 1410 if (doing == 0) 1411 { 1412 fd = inter_list[i].fd; 1413 } 1414 else 1415 { 1416 if (!(inter_list[i].flags & INT_BCASTOPEN)) 1417 break; 1418 fd = inter_list[i].bfd; 1419 } 1420 if (fd < 0) continue; 1421 if (FD_ISSET(fd, &fds)) 1422 { 1423 n--; 1424 1425 /* 1426 * Get a buffer and read the frame. If we 1427 * haven't got a buffer, or this is received 1428 * on the wild card socket, just dump the 1429 * packet. 1430 */ 1431 if ( 1432 #ifdef UDP_WILDCARD_DELIVERY 1433 /* 1434 * these guys manage to put properly addressed 1435 * packets into the wildcard queue 1436 */ 1437 (free_recvbuffs() == 0) 1438 #else 1439 ((i == 0) || (free_recvbuffs() == 0)) 1440 #endif 1441 ) 1442 { 1443 char buf[RX_BUFF_SIZE]; 1444 struct sockaddr from; 1445 1446 fromlen = sizeof from; 1447 (void) recvfrom(fd, buf, sizeof(buf), 0, &from, &fromlen); 1448 #ifdef DEBUG 1449 if (debug) 1450 printf("%s on %d(%lu) fd=%d from %s\n", 1451 (i) ? "drop" : "ignore", 1452 i, free_recvbuffs(), fd, 1453 inet_ntoa(((struct sockaddr_in *) &from)->sin_addr)); 1454 #endif 1455 if (i == 0) 1456 packets_ignored++; 1457 else 1458 packets_dropped++; 1459 goto select_again; 1460 } 1461 1462 rb = get_free_recv_buffer(); 1463 1464 fromlen = sizeof(struct sockaddr_in); 1465 rb->recv_length = recvfrom(fd, 1466 (char *)&rb->recv_space, 1467 sizeof(rb->recv_space), 0, 1468 (struct sockaddr *)&rb->recv_srcadr, 1469 &fromlen); 1470 if (rb->recv_length == 0 1471 #ifdef EWOULDBLOCK 1472 || errno==EWOULDBLOCK 1473 #endif 1474 #ifdef EAGAIN 1475 || errno==EAGAIN 1476 #endif 1477 ) { 1478 freerecvbuf(rb); 1479 continue; 1480 } 1481 else if (rb->recv_length < 0) 1482 { 1483 msyslog(LOG_ERR, "recvfrom() fd=%d: %m", fd); 1484 #ifdef DEBUG 1485 if (debug) 1486 printf("input_handler: fd=%d dropped (bad recvfrom)\n", fd); 1487 #endif 1488 freerecvbuf(rb); 1489 continue; 1490 } 1491 #ifdef DEBUG 1492 if (debug > 2) 1493 printf("input_handler: fd=%d length %d from %08lx %s\n", 1494 fd, rb->recv_length, 1495 (u_long)ntohl(rb->recv_srcadr.sin_addr.s_addr) & 1496 0x00000000ffffffff, 1497 inet_ntoa(rb->recv_srcadr.sin_addr)); 1498 #endif 1499 1500 /* 1501 * Got one. Mark how and when it got here, 1502 * put it on the full list and do bookkeeping. 1503 */ 1504 rb->dstadr = &inter_list[i]; 1505 rb->fd = fd; 1506 rb->recv_time = ts; 1507 rb->receiver = receive; 1508 1509 add_full_recv_buffer(rb); 1510 1511 inter_list[i].received++; 1512 packets_received++; 1513 goto select_again; 1514 } 1515 /* Check more interfaces */ 1516 } 1517 } 1518 select_again:; 1519 /* 1520 * Done everything from that select. Poll again. 1521 */ 1522 } 1523 1524 /* 1525 * If nothing more to do, try again. 1526 * If nothing to do, just return. 1527 * If an error occurred, complain and return. 1528 */ 1529 if (n == 0) 1530 { 1531 if (select_count == 0) /* We really had nothing to do */ 1532 { 1533 if (debug) 1534 msyslog(LOG_DEBUG, "input_handler: select() returned 0"); 1535 --handler_count; 1536 return; 1537 } 1538 /* We've done our work */ 1539 get_systime(&ts_e); 1540 /* 1541 * (ts_e - ts) is the amount of time we spent processing 1542 * this gob of file descriptors. Log it. 1543 */ 1544 L_SUB(&ts_e, &ts); 1545 if (debug > 3) 1546 msyslog(LOG_INFO, "input_handler: Processed a gob of fd's in %s msec", lfptoms(&ts_e, 6)); 1547 1548 /* just bail. */ 1549 --handler_count; 1550 return; 1551 } 1552 else if (n == -1) 1553 { 1554 int err = errno; 1555 1556 /* 1557 * extended FAU debugging output 1558 */ 1559 msyslog(LOG_ERR, "select(%d, %s, 0L, 0L, &0.000000) error: %m", 1560 maxactivefd+1, fdbits(maxactivefd, &activefds)); 1561 if (err == EBADF) { 1562 int j, b; 1563 1564 fds = activefds; 1565 for (j = 0; j <= maxactivefd; j++) 1566 if ( 1567 (FD_ISSET(j, &fds) && (read(j, &b, 0) == -1)) 1568 ) 1569 msyslog(LOG_ERR, "Bad file descriptor %d", j); 1570 } 1571 --handler_count; 1572 return; 1573 } 1574 } 1575 msyslog(LOG_ERR, "input_handler: fell out of infinite for(;;) loop!"); 1576 --handler_count; 1577 return; 1578 } 1579 1580 #endif 1581 1582 /* 1583 * findinterface - utility used by other modules to find an interface 1584 * given an address. 1585 */ 1586 struct interface * 1587 findinterface( 1588 struct sockaddr_in *addr 1589 ) 1590 { 1591 register int i; 1592 register u_int32 saddr; 1593 1594 /* 1595 * Just match the address portion. 1596 */ 1597 saddr = addr->sin_addr.s_addr; 1598 for (i = 0; i < ninterfaces; i++) 1599 { 1600 if (inter_list[i].sin.sin_addr.s_addr == saddr) 1601 return &inter_list[i]; 1602 } 1603 return (struct interface *)0; 1604 } 1605 1606 1607 /* 1608 * io_clr_stats - clear I/O module statistics 1609 */ 1610 void 1611 io_clr_stats(void) 1612 { 1613 packets_dropped = 0; 1614 packets_ignored = 0; 1615 packets_received = 0; 1616 packets_sent = 0; 1617 packets_notsent = 0; 1618 1619 handler_calls = 0; 1620 handler_pkts = 0; 1621 io_timereset = current_time; 1622 } 1623 1624 1625 #ifdef REFCLOCK 1626 /* 1627 * This is a hack so that I don't have to fool with these ioctls in the 1628 * pps driver ... we are already non-blocking and turn on SIGIO thru 1629 * another mechanisim 1630 */ 1631 int 1632 io_addclock_simple( 1633 struct refclockio *rio 1634 ) 1635 { 1636 BLOCKIO(); 1637 /* 1638 * Stuff the I/O structure in the list and mark the descriptor 1639 * in use. There is a harmless (I hope) race condition here. 1640 */ 1641 rio->next = refio; 1642 refio = rio; 1643 1644 if (rio->fd > maxactivefd) 1645 maxactivefd = rio->fd; 1646 FD_SET(rio->fd, &activefds); 1647 UNBLOCKIO(); 1648 return 1; 1649 } 1650 1651 /* 1652 * io_addclock - add a reference clock to the list and arrange that we 1653 * get SIGIO interrupts from it. 1654 */ 1655 int 1656 io_addclock( 1657 struct refclockio *rio 1658 ) 1659 { 1660 BLOCKIO(); 1661 /* 1662 * Stuff the I/O structure in the list and mark the descriptor 1663 * in use. There is a harmless (I hope) race condition here. 1664 */ 1665 rio->next = refio; 1666 refio = rio; 1667 1668 # ifdef HAVE_SIGNALED_IO 1669 if (init_clock_sig(rio)) 1670 { 1671 refio = rio->next; 1672 UNBLOCKIO(); 1673 return 0; 1674 } 1675 # elif defined(HAVE_IO_COMPLETION_PORT) 1676 if (io_completion_port_add_clock_io(rio)) 1677 { 1678 refio = rio->next; 1679 UNBLOCKIO(); 1680 return 0; 1681 } 1682 # endif 1683 1684 if (rio->fd > maxactivefd) 1685 maxactivefd = rio->fd; 1686 FD_SET(rio->fd, &activefds); 1687 1688 UNBLOCKIO(); 1689 return 1; 1690 } 1691 1692 /* 1693 * io_closeclock - close the clock in the I/O structure given 1694 */ 1695 void 1696 io_closeclock( 1697 struct refclockio *rio 1698 ) 1699 { 1700 /* 1701 * Remove structure from the list 1702 */ 1703 if (refio == rio) 1704 { 1705 refio = rio->next; 1706 } 1707 else 1708 { 1709 register struct refclockio *rp; 1710 1711 for (rp = refio; rp != 0; rp = rp->next) 1712 if (rp->next == rio) 1713 { 1714 rp->next = rio->next; 1715 break; 1716 } 1717 1718 if (rp == 0) 1719 { 1720 /* 1721 * Internal error. Report it. 1722 */ 1723 msyslog(LOG_ERR, 1724 "internal error: refclockio structure not found"); 1725 return; 1726 } 1727 } 1728 1729 /* 1730 * Close the descriptor. 1731 */ 1732 close_file(rio->fd); 1733 } 1734 #endif /* REFCLOCK */ 1735 1736 void 1737 kill_asyncio(void) 1738 { 1739 int i; 1740 1741 BLOCKIO(); 1742 for (i = 0; i <= maxactivefd; i++) 1743 (void)close_socket(i); 1744 } 1745