Annotation of 43BSDReno/usr.sbin/timed/timedc/cmds.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted provided
                      6:  * that: (1) source distributions retain this entire copyright notice and
                      7:  * comment, and (2) distributions including binaries display the following
                      8:  * acknowledgement:  ``This product includes software developed by the
                      9:  * University of California, Berkeley and its contributors'' in the
                     10:  * documentation or other materials provided with the distribution and in
                     11:  * all advertising materials mentioning features or use of this software.
                     12:  * Neither the name of the University nor the names of its contributors may
                     13:  * be used to endorse or promote products derived from this software without
                     14:  * specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: static char sccsid[] = "@(#)cmds.c     2.7 (Berkeley) 6/1/90";
                     22: #endif /* not lint */
                     23: 
                     24: #include "timedc.h"
                     25: #include <netinet/in_systm.h>
                     26: #include <netinet/ip.h>
                     27: #include <netinet/ip_icmp.h>
                     28: #define TSPTYPES
                     29: #include <protocols/timed.h>
                     30: #include <sys/file.h>
                     31: 
                     32: int id;
                     33: int sock;
                     34: int sock_raw;
                     35: char hostname[MAXHOSTNAMELEN];
                     36: struct hostent *hp, *gethostbyname();
                     37: struct sockaddr_in server;
                     38: extern int measure_delta;
                     39: int bytenetorder(), bytehostorder();
                     40: char *strcpy();
                     41: 
                     42: /*
                     43:  * Clockdiff computes the difference between the time of the machine on 
                     44:  * which it is called and the time of the machines given as argument.
                     45:  * The time differences measured by clockdiff are obtained using a sequence
                     46:  * of ICMP TSTAMP messages which are returned to the sender by the IP module
                     47:  * in the remote machine.
                     48:  * In order to compare clocks of machines in different time zones, the time 
                     49:  * is transmitted (as a 32-bit value) in milliseconds since midnight UT. 
                     50:  * If a hosts uses a different time format, it should set the high order
                     51:  * bit of the 32-bit quantity it transmits.
                     52:  * However, VMS apparently transmits the time in milliseconds since midnight
                     53:  * local time (rather than GMT) without setting the high order bit. 
                     54:  * Furthermore, it does not understand daylight-saving time.  This makes 
                     55:  * clockdiff behaving inconsistently with hosts running VMS.
                     56:  *
                     57:  * In order to reduce the sensitivity to the variance of message transmission 
                     58:  * time, clockdiff sends a sequence of messages.  Yet, measures between 
                     59:  * two `distant' hosts can be affected by a small error. The error can, however,
                     60:  * be reduced by increasing the number of messages sent in each measurement.
                     61:  */
                     62: 
                     63: clockdiff(argc, argv)
                     64: int argc;
                     65: char *argv[];
                     66: {
                     67:        int measure_status;
                     68:        struct timeval ack;
                     69:        int measure();
                     70: 
                     71:        if(argc < 2)  {
                     72:                printf("Usage: clockdiff host ... \n");
                     73:                return;
                     74:        }
                     75: 
                     76:        id = getpid();
                     77:        (void)gethostname(hostname,sizeof(hostname));
                     78: 
                     79:        while (argc > 1) {
                     80:                argc--; argv++;
                     81:                hp = gethostbyname(*argv);
                     82:                if (hp == NULL) {
                     83:                        fprintf(stderr, "timed: %s: ", *argv);
                     84:                        herror((char *)NULL);
                     85:                        continue;
                     86:                }
                     87:                server.sin_family = hp->h_addrtype;
                     88:                bcopy(hp->h_addr, &(server.sin_addr.s_addr), hp->h_length); 
                     89:                ack.tv_sec = 10;
                     90:                ack.tv_usec = 0;
                     91:                if ((measure_status = measure(&ack, &server)) < 0) {
                     92:                        perror("measure");
                     93:                        return;
                     94:                }
                     95:                switch (measure_status) {
                     96: 
                     97:                case HOSTDOWN:
                     98:                        printf("%s is down\n", hp->h_name);
                     99:                        continue;
                    100:                        break;
                    101:                case NONSTDTIME:
                    102:                        printf("%s time transmitted in a non-standard format\n",                                                 hp->h_name);
                    103:                        continue;
                    104:                        break;
                    105:                case UNREACHABLE:
                    106:                        printf("%s is unreachable\n", hp->h_name);
                    107:                        continue;
                    108:                        break;
                    109:                default:
                    110:                        break;
                    111:                }
                    112: 
                    113:                if (measure_delta > 0)
                    114:                        printf("time on %s is %d ms. ahead of time on %s\n", 
                    115:                                                hp->h_name, measure_delta,
                    116:                                                hostname);
                    117:                else
                    118:                        if (measure_delta == 0)
                    119:                                printf("%s and %s have the same time\n", 
                    120:                                                hp->h_name, hostname);
                    121:                        else
                    122:                             printf("time on %s is %d ms. behind time on %s\n",
                    123:                                        hp->h_name, -measure_delta, hostname);
                    124:        }
                    125:        return;
                    126: }
                    127: /*
                    128:  * finds location of master timedaemon
                    129:  */
                    130: 
                    131: msite(argc)
                    132: int argc;
                    133: {
                    134:        int length;
                    135:        int cc;
                    136:        fd_set ready;
                    137:        struct sockaddr_in dest;
                    138:        struct timeval tout;
                    139:        struct sockaddr_in from;
                    140:        struct tsp msg;
                    141:        struct servent *srvp;
                    142: 
                    143:        if (argc != 1) {
                    144:                printf("Usage: msite\n");
                    145:                return;
                    146:        }
                    147: 
                    148:        srvp = getservbyname("timed", "udp");
                    149:        if (srvp == 0) {
                    150:                fprintf(stderr, "udp/timed: unknown service\n");
                    151:                return;
                    152:        }
                    153:        dest.sin_port = srvp->s_port;
                    154:        dest.sin_family = AF_INET;
                    155: 
                    156:        (void)gethostname(hostname, sizeof(hostname));
                    157:        hp = gethostbyname(hostname);
                    158:        if (hp == NULL) {
                    159:                fprintf(stderr, "timed: %s: ", hostname);
                    160:                herror((char *)NULL);
                    161:                return;
                    162:        }
                    163:        bcopy(hp->h_addr, &dest.sin_addr.s_addr, hp->h_length);
                    164: 
                    165:        (void)strcpy(msg.tsp_name, hostname);
                    166:        msg.tsp_type = TSP_MSITE;
                    167:        msg.tsp_vers = TSPVERSION;
                    168:        bytenetorder(&msg);
                    169:        length = sizeof(struct sockaddr_in);
                    170:        if (sendto(sock, (char *)&msg, sizeof(struct tsp), 0, 
                    171:                                                &dest, length) < 0) {
                    172:                perror("sendto");
                    173:                return;
                    174:        }
                    175: 
                    176:        tout.tv_sec = 15;
                    177:        tout.tv_usec = 0;
                    178:        FD_ZERO(&ready);
                    179:        FD_SET(sock, &ready);
                    180:        if (select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0, &tout)) {
                    181:                length = sizeof(struct sockaddr_in);
                    182:                cc = recvfrom(sock, (char *)&msg, sizeof(struct tsp), 0, 
                    183:                                                        &from, &length);
                    184:                if (cc < 0) {
                    185:                        perror("recvfrom");
                    186:                        return;
                    187:                }
                    188:                bytehostorder(&msg);
                    189:                if (msg.tsp_type == TSP_ACK)
                    190:                        printf("master timedaemon runs on %s\n", msg.tsp_name);
                    191:                else
                    192:                        printf("received wrong ack: %s\n", 
                    193:                                                tsptype[msg.tsp_type]);
                    194:        } else
                    195:                printf("communication error\n");
                    196: }
                    197: 
                    198: /*
                    199:  * quits timedc
                    200:  */
                    201: 
                    202: quit()
                    203: {
                    204:        exit(0);
                    205: }
                    206: 
                    207: #define MAXH   4       /* max no. of hosts where election can occur */
                    208: 
                    209: /*
                    210:  * Causes the election timer to expire on the selected hosts
                    211:  * It sends just one udp message per machine, relying on
                    212:  * reliability of communication channel.
                    213:  */
                    214: 
                    215: testing(argc, argv)
                    216: int argc;
                    217: char *argv[];
                    218: {
                    219:        int length;
                    220:        int nhosts;
                    221:        struct servent *srvp;
                    222:        struct sockaddr_in sin[MAXH];
                    223:        struct tsp msg;
                    224: 
                    225:        if(argc < 2)  {
                    226:                printf("Usage: testing host ...\n");
                    227:                return;
                    228:        }
                    229: 
                    230:        srvp = getservbyname("timed", "udp");
                    231:        if (srvp == 0) {
                    232:                fprintf(stderr, "udp/timed: unknown service\n");
                    233:                return;
                    234:        }       
                    235: 
                    236:        nhosts = 0;
                    237:        while (argc > 1) {
                    238:                argc--; argv++;
                    239:                hp = gethostbyname(*argv);
                    240:                if (hp == NULL) {
                    241:                        fprintf(stderr, "timed: %s: ", *argv);
                    242:                        herror((char *)NULL);
                    243:                        argc--; argv++;
                    244:                        continue;
                    245:                }
                    246:                sin[nhosts].sin_port = srvp->s_port;
                    247:                sin[nhosts].sin_family = hp->h_addrtype;
                    248:                bcopy(hp->h_addr, &(sin[nhosts].sin_addr.s_addr), hp->h_length);
                    249:                if (++nhosts == MAXH)
                    250:                        break;
                    251:        }
                    252: 
                    253:        msg.tsp_type = TSP_TEST;
                    254:        msg.tsp_vers = TSPVERSION;
                    255:        (void)gethostname(hostname, sizeof(hostname));
                    256:        (void)strcpy(msg.tsp_name, hostname);
                    257:        bytenetorder(&msg);     /* it is not really necessary here */
                    258:        while (nhosts-- > 0) {
                    259:                length = sizeof(struct sockaddr_in);
                    260:                if (sendto(sock, (char *)&msg, sizeof(struct tsp), 0, 
                    261:                                                &sin[nhosts], length) < 0) {
                    262:                        perror("sendto");
                    263:                        return;
                    264:                }
                    265:        }
                    266: }
                    267: 
                    268: /*
                    269:  * Enables or disables tracing on local timedaemon
                    270:  */
                    271: 
                    272: tracing(argc, argv)
                    273: int argc;
                    274: char *argv[];
                    275: {
                    276:        int onflag;
                    277:        int length;
                    278:        int cc;
                    279:        fd_set ready;
                    280:        struct sockaddr_in dest;
                    281:        struct timeval tout;
                    282:        struct sockaddr_in from;
                    283:        struct tsp msg;
                    284:        struct servent *srvp;
                    285: 
                    286:        if (argc != 2) {
                    287:                printf("Usage: tracing { on | off }\n");
                    288:                return;
                    289:        }
                    290: 
                    291:        srvp = getservbyname("timed", "udp");
                    292:        if (srvp == 0) {
                    293:                fprintf(stderr, "udp/timed: unknown service\n");
                    294:                return;
                    295:        }       
                    296:        dest.sin_port = srvp->s_port;
                    297:        dest.sin_family = AF_INET;
                    298: 
                    299:        (void)gethostname(hostname,sizeof(hostname));
                    300:        hp = gethostbyname(hostname);
                    301:        bcopy(hp->h_addr, &dest.sin_addr.s_addr, hp->h_length);
                    302: 
                    303:        if (strcmp(argv[1], "on") == 0) {
                    304:                msg.tsp_type = TSP_TRACEON;
                    305:                onflag = ON;
                    306:        } else {
                    307:                msg.tsp_type = TSP_TRACEOFF;
                    308:                onflag = OFF;
                    309:        }
                    310: 
                    311:        (void)strcpy(msg.tsp_name, hostname);
                    312:        msg.tsp_vers = TSPVERSION;
                    313:        bytenetorder(&msg);
                    314:        length = sizeof(struct sockaddr_in);
                    315:        if (sendto(sock, (char *)&msg, sizeof(struct tsp), 0, 
                    316:                                                &dest, length) < 0) {
                    317:                perror("sendto");
                    318:                return;
                    319:        }
                    320: 
                    321:        tout.tv_sec = 5;
                    322:        tout.tv_usec = 0;
                    323:        FD_ZERO(&ready);
                    324:        FD_SET(sock, &ready);
                    325:        if (select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0, &tout)) {
                    326:                length = sizeof(struct sockaddr_in);
                    327:                cc = recvfrom(sock, (char *)&msg, sizeof(struct tsp), 0, 
                    328:                                                        &from, &length);
                    329:                if (cc < 0) {
                    330:                        perror("recvfrom");
                    331:                        return;
                    332:                }
                    333:                bytehostorder(&msg);
                    334:                if (msg.tsp_type == TSP_ACK)
                    335:                        if (onflag)
                    336:                                printf("timed tracing enabled\n");
                    337:                        else
                    338:                                printf("timed tracing disabled\n");
                    339:                else
                    340:                        printf("wrong ack received: %s\n", 
                    341:                                                tsptype[msg.tsp_type]);
                    342:        } else
                    343:                printf("communication error\n");
                    344: }
                    345: 
                    346: priv_resources()
                    347: {
                    348:        int port;
                    349:        struct sockaddr_in sin;
                    350: 
                    351:        sock = socket(AF_INET, SOCK_DGRAM, 0);
                    352:        if (sock < 0) {
                    353:                perror("opening socket");
                    354:                return(-1);
                    355:        }
                    356: 
                    357:        sin.sin_family = AF_INET;
                    358:        sin.sin_addr.s_addr = 0;
                    359:        for (port = IPPORT_RESERVED - 1; port > IPPORT_RESERVED / 2; port--) {
                    360:                sin.sin_port = htons((u_short)port);
                    361:                if (bind(sock, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
                    362:                        break;
                    363:                if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) {
                    364:                        perror("bind");
                    365:                        (void) close(sock);
                    366:                        return(-1);
                    367:                }
                    368:        }
                    369:        if (port == IPPORT_RESERVED / 2) {
                    370:                fprintf(stderr, "all reserved ports in use\n");
                    371:                (void) close(sock);
                    372:                return(-1);
                    373:        }
                    374: 
                    375:        sock_raw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); 
                    376:        if (sock_raw < 0)  {
                    377:                perror("opening raw socket");
                    378:                (void) close(sock_raw);
                    379:                return(-1);
                    380:        }
                    381:        return(1);
                    382: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.