new copyright notice
[unix-history] / usr / src / usr.sbin / timed / timed / readmsg.c
index e931c47..d7c3cd6 100644 (file)
@@ -1,12 +1,13 @@
 /*
  * Copyright (c) 1983 Regents of the University of California.
 /*
  * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * All rights reserved.
+ *
+ * %sccs.include.redist.c%
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)readmsg.c  1.3 (Berkeley) %G%";
-#endif not lint
+static char sccsid[] = "@(#)readmsg.c  2.12 (Berkeley) %G%";
+#endif /* not lint */
 
 #include "globals.h"
 #include <protocols/timed.h>
 
 #include "globals.h"
 #include <protocols/timed.h>
@@ -18,16 +19,18 @@ extern char *tsptype[];
  * the right machine, returning 1 in case of affirmative answer 
  */
 
  * the right machine, returning 1 in case of affirmative answer 
  */
 
-#define LOOKAT(msg, mtype, mfrom) \
+#define LOOKAT(msg, mtype, mfrom, netp, froms) \
        (((((mtype) == TSP_ANY) || ((mtype) == (msg).tsp_type)) && \
        (((((mtype) == TSP_ANY) || ((mtype) == (msg).tsp_type)) && \
-       (((mfrom) == NULL) || (strcmp((mfrom), (msg).tsp_name) == 0))) \
+       (((mfrom) == NULL) || (strcmp((mfrom), (msg).tsp_name) == 0)) && \
+       (((netp) == NULL) || \
+       (((netp)->mask & (froms).sin_addr.s_addr) == (netp)->net))) \
        ? 1 : 0)
 
        ? 1 : 0)
 
-#define ISTOUTOFF(rtime, rtout) \
+#define MORETIME(rtime, rtout) \
        (((rtime).tv_sec > (rtout).tv_sec || \
            ((rtime).tv_sec == (rtout).tv_sec && \
                (rtime).tv_usec >= (rtout).tv_usec)) \
        (((rtime).tv_sec > (rtout).tv_sec || \
            ((rtime).tv_sec == (rtout).tv_sec && \
                (rtime).tv_usec >= (rtout).tv_usec)) \
-       ? 1 : 0)
+       ? 0 : 1)
 
 struct timeval rtime, rwait, rtout;
 struct tsp msgin;
 
 struct timeval rtime, rwait, rtout;
 struct tsp msgin;
@@ -36,12 +39,8 @@ static struct tsplist {
        struct sockaddr_in addr;
        struct tsplist *p;
 } msgslist;
        struct sockaddr_in addr;
        struct tsplist *p;
 } msgslist;
-struct tsplist *ptr, *prev;
 struct sockaddr_in from;
 struct sockaddr_in from;
-extern int trace;
-extern int sock;
-extern char hostname[];
-extern FILE *fd;
+struct netinfo *fromnet;
 
 /*
  * `readmsg' returns message `type' sent by `machfrom' if it finds it 
 
 /*
  * `readmsg' returns message `type' sent by `machfrom' if it finds it 
@@ -51,29 +50,30 @@ extern FILE *fd;
  * `intvl' seconds. If not, it returns NULL.
  */
 
  * `intvl' seconds. If not, it returns NULL.
  */
 
-struct tsp *readmsg(type, machfrom, intvl)
+struct tsp *
+readmsg(type, machfrom, intvl, netfrom)
+
 int type;
 char *machfrom;
 struct timeval *intvl;
 int type;
 char *machfrom;
 struct timeval *intvl;
+struct netinfo *netfrom;
 {
        int length;
 {
        int length;
-       int ready, found;
-       struct tsp *ret = NULL;
-       extern int status;
+       fd_set ready;
        static struct tsplist *head = &msgslist;
        static struct tsplist *tail = &msgslist;
        static struct tsplist *head = &msgslist;
        static struct tsplist *tail = &msgslist;
-       int inet_netof();
-       char *malloc(), *strcpy();
-       int bytenetorder(), bytehostorder();
+       struct tsplist *prev;
+       register struct netinfo *ntp;
+       register struct tsplist *ptr;
 
        if (trace) {
                fprintf(fd, "looking for %s from %s\n",
 
        if (trace) {
                fprintf(fd, "looking for %s from %s\n",
-                       tsptype[type], machfrom);
+                       tsptype[type], machfrom == NULL ? "ANY" : machfrom);
                ptr = head->p;
                fprintf(fd, "msgqueue:\n");
                while (ptr != NULL) {
                        fprintf(fd, "\t");
                ptr = head->p;
                fprintf(fd, "msgqueue:\n");
                while (ptr != NULL) {
                        fprintf(fd, "\t");
-                       print(&ptr->info);
+                       print(&ptr->info, &ptr->addr);
                        ptr = ptr->p;
                }
        }
                        ptr = ptr->p;
                }
        }
@@ -87,24 +87,35 @@ struct timeval *intvl;
         */
 
        while (ptr != NULL) {
         */
 
        while (ptr != NULL) {
-               if (LOOKAT(ptr->info, type, machfrom)) {
-                       ret = (struct tsp *)malloc(sizeof(struct tsp)); 
-                       *ret = ptr->info;
+               if (LOOKAT(ptr->info, type, machfrom, netfrom, ptr->addr)) {
+                       msgin = ptr->info;
                        from = ptr->addr;
                        prev->p = ptr->p;
                        if (ptr == tail) 
                                tail = prev;
                        free((char *)ptr);
                        from = ptr->addr;
                        prev->p = ptr->p;
                        if (ptr == tail) 
                                tail = prev;
                        free((char *)ptr);
-                       break;
+                       fromnet = NULL;
+                       if (netfrom == NULL)
+                           for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
+                                   if ((ntp->mask & from.sin_addr.s_addr) ==
+                                       ntp->net) {
+                                           fromnet = ntp;
+                                           break;
+                                   }
+                           }
+                       else
+                           fromnet = netfrom;
+                       if (trace) {
+                               fprintf(fd, "readmsg: ");
+                               print(&msgin, &from);
+                       }
+                       return(&msgin);
                } else {
                        prev = ptr;
                        ptr = ptr->p;
                }
        }
 
                } else {
                        prev = ptr;
                        ptr = ptr->p;
                }
        }
 
-       if (ret != NULL)
-               goto out;
-
        /*
         * If the message was not in the linked list, it may still be
         * coming from the network. Set the timer and wait 
        /*
         * If the message was not in the linked list, it may still be
         * coming from the network. Set the timer and wait 
@@ -120,7 +131,9 @@ struct timeval *intvl;
                rtout.tv_sec++;
        }
 
                rtout.tv_sec++;
        }
 
-       for (;;) {
+       FD_ZERO(&ready);
+       for (; MORETIME(rtime, rtout);
+           (void)gettimeofday(&rtime, (struct timezone *)0)) {
                rwait.tv_sec = rtout.tv_sec - rtime.tv_sec;
                rwait.tv_usec = rtout.tv_usec - rtime.tv_usec;
                if (rwait.tv_usec < 0) {
                rwait.tv_sec = rtout.tv_sec - rtime.tv_sec;
                rwait.tv_usec = rtout.tv_usec - rtime.tv_usec;
                if (rwait.tv_usec < 0) {
@@ -133,11 +146,10 @@ struct timeval *intvl;
                if (trace) {
                        fprintf(fd, "readmsg: wait: (%d %d)\n", 
                                                rwait.tv_sec, rwait.tv_usec);
                if (trace) {
                        fprintf(fd, "readmsg: wait: (%d %d)\n", 
                                                rwait.tv_sec, rwait.tv_usec);
-                       (void)fflush(fd);
                }
                }
-               ready = 1<<sock;
-               found = select(20, &ready, (int *)0, (int *)0, &rwait);
-               if (found) {
+               FD_SET(sock, &ready);
+               if (select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0,
+                   &rwait)) {
                        length = sizeof(struct sockaddr_in);
                        if (recvfrom(sock, (char *)&msgin, sizeof(struct tsp), 
                                                0, &from, &length) < 0) {
                        length = sizeof(struct sockaddr_in);
                        if (recvfrom(sock, (char *)&msgin, sizeof(struct tsp), 
                                                0, &from, &length) < 0) {
@@ -147,17 +159,45 @@ struct timeval *intvl;
 
                        bytehostorder(&msgin);
 
 
                        bytehostorder(&msgin);
 
-                       if ((from.sin_addr.s_addr & netmask) != mynet) {
+                       if (msgin.tsp_vers > TSPVERSION) {
                                if (trace) {
                                if (trace) {
-                                       fprintf(fd, "readmsg: wrong network: ");
-                                       print(&msgin);
+                                   fprintf(fd, "readmsg: version mismatch\n");
+                                   /* should do a dump of the packet, but... */
                                }
                                }
-                               (void)gettimeofday(&rtime,(struct timezone *)0);
-                               if (ISTOUTOFF(rtime, rtout))
+                               continue;
+                       }
+
+                       fromnet = NULL;
+                       for (ntp = nettab; ntp != NULL; ntp = ntp->next)
+                               if ((ntp->mask & from.sin_addr.s_addr) ==
+                                   ntp->net) {
+                                       fromnet = ntp;
                                        break;
                                        break;
-                               else
+                               }
+
+                       /*
+                        * drop packets from nets we are ignoring permanently
+                        */
+                       if (fromnet == NULL) {
+                               /* 
+                                * The following messages may originate on
+                                * this host with an ignored network address
+                                */
+                               if (msgin.tsp_type != TSP_TRACEON &&
+                                   msgin.tsp_type != TSP_SETDATE &&
+                                   msgin.tsp_type != TSP_MSITE &&
+#ifdef TESTING
+                                   msgin.tsp_type != TSP_TEST &&
+#endif
+                                   msgin.tsp_type != TSP_TRACEOFF) {
+                                       if (trace) {
+                                           fprintf(fd, "readmsg: discarded: ");
+                                           print(&msgin, &from);
+                                       }
                                        continue;
                                        continue;
+                               }
                        }
                        }
+
                        /*
                         * Throw away messages coming from this machine, unless
                         * they are of some particular type.
                        /*
                         * Throw away messages coming from this machine, unless
                         * they are of some particular type.
@@ -165,22 +205,20 @@ struct timeval *intvl;
                         * master processing time.
                         */
                        if ( !(strcmp(msgin.tsp_name, hostname) != 0 ||
                         * master processing time.
                         */
                        if ( !(strcmp(msgin.tsp_name, hostname) != 0 ||
-                                       msgin.tsp_type == TSP_DATE ||
+                                       msgin.tsp_type == TSP_SETDATE ||
 #ifdef TESTING
                                        msgin.tsp_type == TSP_TEST ||
 #endif
                                        msgin.tsp_type == TSP_MSITE ||
 #ifdef TESTING
                                        msgin.tsp_type == TSP_TEST ||
 #endif
                                        msgin.tsp_type == TSP_MSITE ||
+                                       (msgin.tsp_type == TSP_LOOP &&
+                                       msgin.tsp_hopcnt != 10) ||
                                        msgin.tsp_type == TSP_TRACEON ||
                                        msgin.tsp_type == TSP_TRACEOFF)) {
                                if (trace) {
                                        fprintf(fd, "readmsg: discarded: ");
                                        msgin.tsp_type == TSP_TRACEON ||
                                        msgin.tsp_type == TSP_TRACEOFF)) {
                                if (trace) {
                                        fprintf(fd, "readmsg: discarded: ");
-                                       print(&msgin);
+                                       print(&msgin, &from);
                                }
                                }
-                               (void)gettimeofday(&rtime,(struct timezone *)0);
-                               if (ISTOUTOFF(rtime, rtout))
-                                       break;
-                               else
-                                       continue;
+                               continue;
                        }
 
                        /*
                        }
 
                        /*
@@ -189,14 +227,19 @@ struct timeval *intvl;
                         * higher level routine.  Different acknowledgements are
                         * necessary, depending on status.
                         */
                         * higher level routine.  Different acknowledgements are
                         * necessary, depending on status.
                         */
-                       if (status == MASTER)
+                       if (fromnet->status == MASTER)
                                masterack();
                                masterack();
-                       else 
+                       else if (fromnet->status == SLAVE)
                                slaveack();
                                slaveack();
-
-                       if (LOOKAT(msgin, type, machfrom)) {
-                               ret = &msgin;
-                               break;
+                       else
+                               ignoreack();
+                               
+                       if (LOOKAT(msgin, type, machfrom, netfrom, from)) {
+                               if (trace) {
+                                       fprintf(fd, "readmsg: ");
+                                       print(&msgin, &from);
+                               }
+                               return(&msgin);
                        } else {
                                tail->p = (struct tsplist *)
                                                malloc(sizeof(struct tsplist)); 
                        } else {
                                tail->p = (struct tsplist *)
                                                malloc(sizeof(struct tsplist)); 
@@ -205,22 +248,11 @@ struct timeval *intvl;
                                tail->info = msgin;
                                tail->addr = from;
                        }
                                tail->info = msgin;
                                tail->addr = from;
                        }
-
-                       (void)gettimeofday(&rtime, (struct timezone *)0);
-                       if (ISTOUTOFF(rtime, rtout))
-                               break;
                } else {
                        break;
                }
        }
                } else {
                        break;
                }
        }
-out:
-       if (ret != NULL) {
-               if (trace) {
-                       fprintf(fd, "readmsg: ");
-                       print(ret);
-               }
-       }
-       return(ret);
+       return((struct tsp *)NULL);
 }
 
 /*
 }
 
 /*
@@ -249,7 +281,42 @@ slaveack()
                (void)strcpy(resp.tsp_name, hostname);
                if (trace) {
                        fprintf(fd, "Slaveack: ");
                (void)strcpy(resp.tsp_name, hostname);
                if (trace) {
                        fprintf(fd, "Slaveack: ");
-                       print(&resp);
+                       print(&resp, &from);
+               }
+               bytenetorder(&resp);     /* this is not really necessary here */
+               if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
+                                               &from, length) < 0) {
+                       syslog(LOG_ERR, "sendto: %m");
+                       exit(1);
+               }
+               break;
+       default:
+               break;
+       }
+}
+
+/*
+ * Certain packets may arrive from this machine on ignored networks.
+ * These packets should be acknowledged.
+ */
+
+ignoreack()
+{
+       int length;
+       struct tsp resp;
+
+       length = sizeof(struct sockaddr_in);
+       switch(msgin.tsp_type) {
+
+       case TSP_TRACEON:
+       case TSP_TRACEOFF:
+               resp = msgin;
+               resp.tsp_type = TSP_ACK;
+               resp.tsp_vers = TSPVERSION;
+               (void)strcpy(resp.tsp_name, hostname);
+               if (trace) {
+                       fprintf(fd, "Ignoreack: ");
+                       print(&resp, &from);
                }
                bytenetorder(&resp);     /* this is not really necessary here */
                if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
                }
                bytenetorder(&resp);     /* this is not really necessary here */
                if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
@@ -290,7 +357,7 @@ masterack()
                bytenetorder(&resp);
                if (trace) {
                        fprintf(fd, "Masterack: ");
                bytenetorder(&resp);
                if (trace) {
                        fprintf(fd, "Masterack: ");
-                       print(&resp);
+                       print(&resp, &from);
                }
                if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
                                                &from, length) < 0) {
                }
                if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
                                                &from, length) < 0) {
@@ -304,7 +371,7 @@ masterack()
                bytenetorder(&resp);
                if (trace) {
                        fprintf(fd, "Masterack: ");
                bytenetorder(&resp);
                if (trace) {
                        fprintf(fd, "Masterack: ");
-                       print(&resp);
+                       print(&resp, &from);
                }
                if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
                                                &from, length) < 0) {
                }
                if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
                                                &from, length) < 0) {
@@ -312,12 +379,12 @@ masterack()
                        exit(1);
                }
                break;
                        exit(1);
                }
                break;
-       case TSP_DATEREQ:
+       case TSP_SETDATEREQ:
                resp.tsp_type = TSP_DATEACK;
                bytenetorder(&resp);
                if (trace) {
                        fprintf(fd, "Masterack: ");
                resp.tsp_type = TSP_DATEACK;
                bytenetorder(&resp);
                if (trace) {
                        fprintf(fd, "Masterack: ");
-                       print(&resp);
+                       print(&resp, &from);
                }
                if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
                                                &from, length) < 0) {
                }
                if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
                                                &from, length) < 0) {
@@ -333,17 +400,43 @@ masterack()
 /*
  * Print a TSP message 
  */
 /*
  * Print a TSP message 
  */
-print(msg)
+print(msg, addr)
 struct tsp *msg;
 struct tsp *msg;
+struct sockaddr_in *addr;
 {
 {
-       extern char *tsptype[];
-
-       fprintf(fd, "%s %d %d (%d, %d) %s\n",
-               tsptype[msg->tsp_type],
-               msg->tsp_vers,
-               msg->tsp_seq,
-               msg->tsp_time.tv_sec, 
-               msg->tsp_time.tv_usec, 
-               msg->tsp_name);
-       (void)fflush(fd);
+       switch (msg->tsp_type) {
+
+       case TSP_LOOP:
+               fprintf(fd, "%s %d %d (#%d) %s %s\n",
+                       tsptype[msg->tsp_type],
+                       msg->tsp_vers,
+                       msg->tsp_seq,
+                       msg->tsp_hopcnt,
+                       msg->tsp_name,
+                       inet_ntoa(addr->sin_addr));
+               break;
+
+       case TSP_SETTIME:
+       case TSP_ADJTIME:
+       case TSP_SETDATE:
+       case TSP_SETDATEREQ:
+               fprintf(fd, "%s %d %d (%d, %d) %s %s\n",
+                       tsptype[msg->tsp_type],
+                       msg->tsp_vers,
+                       msg->tsp_seq,
+                       msg->tsp_time.tv_sec, 
+                       msg->tsp_time.tv_usec, 
+                       msg->tsp_name,
+                       inet_ntoa(addr->sin_addr));
+               break;
+
+       default:
+               fprintf(fd, "%s %d %d %s %s\n",
+                       tsptype[msg->tsp_type],
+                       msg->tsp_vers,
+                       msg->tsp_seq,
+                       msg->tsp_name,
+                       inet_ntoa(addr->sin_addr));
+               break;
+       }
 }
 }