diff options
Diffstat (limited to 'contrib/ntp/ntpd/ntp_io.c')
-rw-r--r-- | contrib/ntp/ntpd/ntp_io.c | 298 |
1 files changed, 153 insertions, 145 deletions
diff --git a/contrib/ntp/ntpd/ntp_io.c b/contrib/ntp/ntpd/ntp_io.c index e209d6d29c1f..23c0cb735e08 100644 --- a/contrib/ntp/ntpd/ntp_io.c +++ b/contrib/ntp/ntpd/ntp_io.c @@ -7,15 +7,19 @@ # include <config.h> #endif +#include "ntp_machine.h" +#include "ntpd.h" +#include "ntp_io.h" +#include "iosignal.h" +#include "ntp_refclock.h" +#include "ntp_if.h" +#include "ntp_stdlib.h" + #include <stdio.h> #include <signal.h> -#include <sys/types.h> #ifdef HAVE_SYS_PARAM_H # include <sys/param.h> #endif /* HAVE_SYS_PARAM_H */ -#ifdef HAVE_SYS_TIME_H -# include <sys/time.h> -#endif #ifdef HAVE_NETINET_IN_H # include <netinet/in.h> #endif @@ -37,14 +41,6 @@ # include <ifaddrs.h> #endif -#include "ntp_machine.h" -#include "ntpd.h" -#include "ntp_io.h" -#include "iosignal.h" -#include "ntp_refclock.h" -#include "ntp_if.h" -#include "ntp_stdlib.h" - #if defined(VMS) /* most likely UCX-specific */ #include <UCX$INETDEF.H> @@ -116,10 +112,10 @@ u_long io_timereset; /* time counters were reset */ /* * Interface stuff */ -struct interface *any_interface; /* pointer to default interface */ -struct interface *loopback_interface; /* point to loopback interface */ -static struct interface inter_list[MAXINTERFACES]; -static int ninterfaces; +struct interface *any_interface; /* default interface */ +struct interface *loopback_interface; /* loopback interface */ +struct interface inter_list[MAXINTERFACES]; +int ninterfaces; #ifdef REFCLOCK /* @@ -241,6 +237,7 @@ create_sockets( inter_list[0].sent = 0; inter_list[0].notsent = 0; inter_list[0].flags = INT_BROADCAST; + any_interface = &inter_list[0]; #if _BSDI_VERSION >= 199510 #if _BSDI_VERSION >= 199701 @@ -274,46 +271,32 @@ create_sockets( if ((ifap->ifa_flags & IFF_UP) == 0) continue; - if (ifap->ifa_flags & IFF_LOOPBACK) - { + if (ifap->ifa_flags & IFF_LOOPBACK) { sin = (struct sockaddr_in *)ifap->ifa_addr; if (ntohl(sin->sin_addr.s_addr) != 0x7f000001) - { continue; - } } - inter_list[i].flags = 0; if (ifap->ifa_flags & IFF_BROADCAST) - inter_list[i].flags |= INT_BROADCAST; - - (void)strcpy(inter_list[i].name, ifap->ifa_name); - + inter_list[i].flags |= INT_BROADCAST; + strcpy(inter_list[i].name, ifap->ifa_name); sin = (struct sockaddr_in *)ifap->ifa_addr; inter_list[i].sin = *sin; inter_list[i].sin.sin_port = port; - - if (ifap->ifa_flags & IFF_LOOPBACK) - { + if (ifap->ifa_flags & IFF_LOOPBACK) { inter_list[i].flags = INT_LOOPBACK; if (loopback_interface == NULL || ntohl(sin->sin_addr.s_addr) != 0x7f000001) loopback_interface = &inter_list[i]; } - - if (inter_list[i].flags & INT_BROADCAST) - { + if (inter_list[i].flags & INT_BROADCAST) { sin = (struct sockaddr_in *)ifap->ifa_broadaddr; inter_list[i].bcast = *sin; inter_list[i].bcast.sin_port = port; } - - if (ifap->ifa_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) - { + if (ifap->ifa_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) { inter_list[i].mask.sin_addr.s_addr = 0xffffffff; - } - else - { + } else { sin = (struct sockaddr_in *)ifap->ifa_netmask; inter_list[i].mask = *sin; } @@ -444,7 +427,7 @@ create_sockets( continue; } # endif /* SYS_WINNT */ - memcpy(&ifreq, ifr, sizeof(ifreq)); + ifreq = *ifr; inter_list[i].flags = 0; /* is it broadcast capable? */ # ifndef SYS_WINNT @@ -614,9 +597,8 @@ create_sockets( maxactivefd = 0; FD_ZERO(&activefds); for (i = 0; i < ninterfaces; i++) { - inter_list[i].fd = - open_socket(&inter_list[i].sin, - inter_list[i].flags & INT_BROADCAST, 0); + inter_list[i].fd = open_socket(&inter_list[i].sin, + inter_list[i].flags & INT_BROADCAST, 0); } /* @@ -653,12 +635,10 @@ create_sockets( */ resmask.sin_addr.s_addr = ~ (u_int32)0; for (i = 1; i < ninterfaces; i++) - hack_restrict(RESTRICT_FLAGS, &inter_list[i].sin, &resmask, - RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE); - - any_interface = &inter_list[0]; + hack_restrict(RESTRICT_FLAGS, &inter_list[i].sin, &resmask, + RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE); #ifdef DEBUG - if (debug > 2) { + if (debug > 1) { printf("create_sockets: ninterfaces=%d\n", ninterfaces); for (i = 0; i < ninterfaces; i++) { printf("interface %d: fd=%d, bfd=%d, name=%.8s, flags=0x%x\n", @@ -694,17 +674,19 @@ io_setbclient(void) { int i; - for (i = 1; i < ninterfaces; i++) - { + for (i = 1; i < ninterfaces; i++) { if (!(inter_list[i].flags & INT_BROADCAST)) - continue; + continue; + if (inter_list[i].flags & INT_BCASTOPEN) - continue; + continue; + #ifdef SYS_SOLARIS inter_list[i].bcast.sin_addr.s_addr = htonl(INADDR_ANY); #endif #ifdef OPEN_BCAST_SOCKET /* Was: !SYS_DOMAINOS && !SYS_LINUX */ - inter_list[i].bfd = open_socket(&inter_list[i].bcast, INT_BROADCAST, 1); + inter_list[i].bfd = open_socket(&inter_list[i].bcast, + INT_BROADCAST, 1); inter_list[i].flags |= INT_BCASTOPEN; #endif } @@ -728,50 +710,47 @@ io_multicast_add( struct sockaddr_in *sinp; iaddr.s_addr = addr; - - if (!IN_CLASSD(haddr)) - { + if (!IN_CLASSD(haddr)) { msyslog(LOG_ERR, - "cannot add multicast address %s as it is not class D", + "multicast address %s not class D", inet_ntoa(iaddr)); return; } - - for (i = 0; i < ninterfaces; i++) - { + for (i = 0; i < ninterfaces; i++) { /* Already have this address */ - if (inter_list[i].sin.sin_addr.s_addr == addr) return; + if (inter_list[i].sin.sin_addr.s_addr == addr) + return; /* found a free slot */ if (inter_list[i].sin.sin_addr.s_addr == 0 && inter_list[i].fd <= 0 && inter_list[i].bfd <= 0 && - inter_list[i].flags == 0) break; + inter_list[i].flags == 0) + break; } sinp = &(inter_list[i].sin); - memset((char *)&mreq, 0, sizeof(mreq)); memset((char *)&inter_list[i], 0, sizeof inter_list[0]); sinp->sin_family = AF_INET; sinp->sin_addr = iaddr; sinp->sin_port = htons(123); + /* + * Try opening a socket for the specified class D address. This + * works under SunOS 4.x, but not OSF1 .. :-( + */ s = open_socket(sinp, 0, 1); - /* Try opening a socket for the specified class D address */ - /* This works under SunOS 4.x, but not OSF1 .. :-( */ - if (s < 0) - { + if (s < 0) { memset((char *)&inter_list[i], 0, sizeof inter_list[0]); i = 0; /* HACK ! -- stuff in an address */ inter_list[i].bcast.sin_addr.s_addr = addr; - msyslog(LOG_ERR, "...multicast address %s using wildcard socket", - inet_ntoa(iaddr)); - } - else - { + msyslog(LOG_ERR, + "...multicast address %s using wildcard socket", + inet_ntoa(iaddr)); + } else { inter_list[i].fd = s; inter_list[i].bfd = -1; (void) strncpy(inter_list[i].name, "multicast", - sizeof(inter_list[i].name)); + sizeof(inter_list[i].name)); inter_list[i].mask.sin_addr.s_addr = htonl(~(u_int32)0); } @@ -781,19 +760,21 @@ io_multicast_add( mreq.imr_multiaddr = iaddr; mreq.imr_interface.s_addr = htonl(INADDR_ANY); if (setsockopt(inter_list[i].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, - (char *)&mreq, sizeof(mreq)) == -1) - msyslog(LOG_ERR, + (char *)&mreq, sizeof(mreq)) == -1) + msyslog(LOG_ERR, "setsockopt IP_ADD_MEMBERSHIP fails: %m for %x / %x (%s)", - mreq.imr_multiaddr.s_addr, mreq.imr_interface.s_addr, - inet_ntoa(iaddr)); + mreq.imr_multiaddr.s_addr, + mreq.imr_interface.s_addr, inet_ntoa(iaddr)); inter_list[i].flags |= INT_MULTICAST; - if (i >= ninterfaces) ninterfaces = i+1; + if (i >= ninterfaces) + ninterfaces = i+1; #else /* MCAST */ struct in_addr iaddr; iaddr.s_addr = addr; - msyslog(LOG_ERR, "cannot add multicast address %s as no MCAST support", - inet_ntoa(iaddr)); + msyslog(LOG_ERR, + "cannot add multicast address %s as no MCAST support", + inet_ntoa(iaddr)); #endif /* MCAST */ } @@ -886,8 +867,11 @@ open_socket( int turn_off_reuse ) { - int fd, tos; + int fd; int on = 1, off = 0; +#if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS) + int tos; +#endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */ /* create a datagram (UDP) socket */ if ( (fd = socket(AF_INET, SOCK_DGRAM, 0)) @@ -1071,12 +1055,11 @@ close_socket( (void) closesocket(fd); FD_CLR( (u_int) fd, &activefds); - if (fd >= maxactivefd) - { + if (fd >= maxactivefd) { newmax = 0; for (i = 0; i < maxactivefd; i++) - if (FD_ISSET(i, &activefds)) - newmax = i; + if (FD_ISSET(i, &activefds)) + newmax = i; maxactivefd = newmax; } } @@ -1096,45 +1079,16 @@ close_file( (void) close(fd); FD_CLR( (u_int) fd, &activefds); - if (fd >= maxactivefd) - { + if (fd >= maxactivefd) { newmax = 0; for (i = 0; i < maxactivefd; i++) - if (FD_ISSET(i, &activefds)) - newmax = i; + if (FD_ISSET(i, &activefds)) + newmax = i; maxactivefd = newmax; } } -/* - * findbcastinter - find broadcast interface corresponding to address - */ -struct interface * -findbcastinter( - struct sockaddr_in *addr - ) -{ -#if defined(SIOCGIFCONF) || defined(SYS_WINNT) - register int i; - register u_int32 netnum; - - netnum = NSRCADR(addr); - for (i = 1; i < ninterfaces; i++) - { - if (!(inter_list[i].flags & INT_BROADCAST)) - continue; - if (NSRCADR(&inter_list[i].bcast) == netnum) - return &inter_list[i]; - if ((NSRCADR(&inter_list[i].sin) & NSRCADR(&inter_list[i].mask)) - == (netnum & NSRCADR(&inter_list[i].mask))) - return &inter_list[i]; - } -#endif /* SIOCGIFCONF */ - return any_interface; -} - - /* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c */ /* * sendpkt - send a packet to the specified destination. Maintain a @@ -1172,13 +1126,6 @@ sendpkt( #else #define badaddrs ((struct cache *)0) /* Only used in empty loops! */ #endif - - /* - * check if the source address is a multicast address - replace - * interface with any-interface if so. - */ - if (IN_MULTICAST(ntohl(inter->sin.sin_addr.s_addr))) - inter = any_interface; #ifdef DEBUG if (debug > 1) printf("%ssendpkt(fd=%d dst=%s, src=%s, ttl=%d, len=%d)\n", @@ -1188,18 +1135,20 @@ sendpkt( #endif #ifdef MCAST - /* for the moment we use the bcast option to set multicast ttl */ - if (ttl >= 0 && ttl != inter->last_ttl) - { + /* + * for the moment we use the bcast option to set multicast ttl + */ + if (ttl > 0 && ttl != inter->last_ttl) { char mttl = ttl; - /* set the multicast ttl for outgoing packets */ + /* + * set the multicast ttl for outgoing packets + */ if (setsockopt(inter->fd, IPPROTO_IP, IP_MULTICAST_TTL, - &mttl, sizeof(mttl)) == -1) - { + &mttl, sizeof(mttl)) == -1) msyslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL fails: %m"); - } - else inter->last_ttl = ttl; + else + inter->last_ttl = ttl; } #endif /* MCAST */ @@ -1212,7 +1161,7 @@ sendpkt( err = io_completion_port_sendto(inter, pkt, len, dest); if (err != ERROR_SUCCESS) #else - cc = sendto(inter->fd, (char *)pkt, len, 0, (struct sockaddr *)dest, + cc = sendto(inter->fd, (char *)pkt, (size_t)len, 0, (struct sockaddr *)dest, sizeof(struct sockaddr_in)); if (cc == -1) #endif @@ -1480,7 +1429,8 @@ input_handler( } else if (rb->recv_length < 0) { - msyslog(LOG_ERR, "recvfrom() fd=%d: %m", fd); + msyslog(LOG_ERR, "recvfrom(%s) fd=%d: %m", + inet_ntoa(rb->recv_srcadr.sin_addr), fd); #ifdef DEBUG if (debug) printf("input_handler: fd=%d dropped (bad recvfrom)\n", fd); @@ -1490,8 +1440,8 @@ input_handler( } #ifdef DEBUG if (debug > 2) - printf("input_handler: fd=%d length %d from %08lx %s\n", - fd, rb->recv_length, + printf("input_handler: if=%d fd=%d length %d from %08lx %s\n", + i, fd, rb->recv_length, (u_long)ntohl(rb->recv_srcadr.sin_addr.s_addr) & 0x00000000ffffffff, inet_ntoa(rb->recv_srcadr.sin_addr)); @@ -1580,27 +1530,85 @@ input_handler( #endif /* - * findinterface - utility used by other modules to find an interface - * given an address. + * findinterface - find interface corresponding to address */ struct interface * findinterface( struct sockaddr_in *addr ) { - register int i; - register u_int32 saddr; + int s, rtn, i; + struct sockaddr_in saddr; + int saddrlen = sizeof(saddr); + u_int32 xaddr; /* - * Just match the address portion. + * This is considerably hoke. We open a socket, connect to it + * and slap a getsockname() on it. If anything breaks, as it + * probably will in some j-random knockoff, we just return the + * wildcard interface. */ - saddr = addr->sin_addr.s_addr; - for (i = 0; i < ninterfaces; i++) - { - if (inter_list[i].sin.sin_addr.s_addr == saddr) - return &inter_list[i]; + saddr.sin_family = AF_INET; + saddr.sin_addr.s_addr = addr->sin_addr.s_addr; + saddr.sin_port = htons(2000); + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) + return (any_interface); + + rtn = connect(s, (struct sockaddr *)&saddr, sizeof(saddr)); + if (rtn < 0) + return (any_interface); + + rtn = getsockname(s, (struct sockaddr *)&saddr, &saddrlen); + if (rtn < 0) + return (any_interface); + + close(s); + xaddr = NSRCADR(&saddr); + for (i = 1; i < ninterfaces; i++) { + + /* + * We match the unicast address only. + */ + if (NSRCADR(&inter_list[i].sin) == xaddr) + return (&inter_list[i]); } - return (struct interface *)0; + return (any_interface); +} + + +/* + * findbcastinter - find broadcast interface corresponding to address + */ +struct interface * +findbcastinter( + struct sockaddr_in *addr + ) +{ +#if defined(SIOCGIFCONF) || defined(SYS_WINNT) + register int i; + register u_int32 xaddr; + + xaddr = NSRCADR(addr); + for (i = 1; i < ninterfaces; i++) { + + /* + * We match only those interfaces marked as + * broadcastable and either the explicit broadcast + * address or the network portion of the IP address. + * Sloppy. + */ + if (!(inter_list[i].flags & INT_BROADCAST)) + continue; + if (NSRCADR(&inter_list[i].bcast) == xaddr) + return (&inter_list[i]); + if ((NSRCADR(&inter_list[i].sin) & + NSRCADR(&inter_list[i].mask)) == (xaddr & + NSRCADR(&inter_list[i].mask))) + return (&inter_list[i]); + } +#endif /* SIOCGIFCONF */ + return (any_interface); } |