11553Srgrimes/*- 21553Srgrimes * Copyright (c) 1985, 1993 31553Srgrimes * The Regents of the University of California. All rights reserved. 41553Srgrimes * 51553Srgrimes * Redistribution and use in source and binary forms, with or without 61553Srgrimes * modification, are permitted provided that the following conditions 71553Srgrimes * are met: 81553Srgrimes * 1. Redistributions of source code must retain the above copyright 91553Srgrimes * notice, this list of conditions and the following disclaimer. 101553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111553Srgrimes * notice, this list of conditions and the following disclaimer in the 121553Srgrimes * documentation and/or other materials provided with the distribution. 131553Srgrimes * 4. Neither the name of the University nor the names of its contributors 141553Srgrimes * may be used to endorse or promote products derived from this software 151553Srgrimes * without specific prior written permission. 161553Srgrimes * 171553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271553Srgrimes * SUCH DAMAGE. 281553Srgrimes */ 291553Srgrimes 30117278Scharnier#if 0 311553Srgrimes#ifndef lint 321553Srgrimesstatic char sccsid[] = "@(#)cmds.c 8.1 (Berkeley) 6/6/93"; 33117278Scharnier#endif /* not lint */ 3430642Scharnier#endif 35117278Scharnier#include <sys/cdefs.h> 36117278Scharnier__FBSDID("$FreeBSD: releng/10.3/usr.sbin/timed/timedc/cmds.c 246209 2013-02-01 14:26:54Z charnier $"); 37117278Scharnier 381553Srgrimes#include "timedc.h" 391553Srgrimes#include <sys/file.h> 401553Srgrimes 4190868Smike#include <arpa/inet.h> 4290868Smike 431553Srgrimes#include <netinet/in_systm.h> 441553Srgrimes#include <netinet/ip.h> 451553Srgrimes#include <netinet/ip_icmp.h> 461553Srgrimes 4730642Scharnier#include <err.h> 481553Srgrimes#include <stdlib.h> 49116078Simp#include <string.h> 501553Srgrimes#include <unistd.h> 511553Srgrimes 521553Srgrimes#define TSPTYPES 531553Srgrimes#include <protocols/timed.h> 541553Srgrimes 551553Srgrimes#define SECHR (60*60) 561553Srgrimes#define SECDAY (24*SECHR) 571553Srgrimes 581553Srgrimes# define DATE_PROTO "udp" 591553Srgrimes# define DATE_PORT "time" 601553Srgrimes 611553Srgrimes 621553Srgrimesint sock; 631553Srgrimesint sock_raw; 6430872Scharnierchar myname[MAXHOSTNAMELEN]; 651553Srgrimesstruct hostent *hp; 661553Srgrimesstruct sockaddr_in server; 671553Srgrimesstruct sockaddr_in dayaddr; 681553Srgrimesextern int measure_delta; 691553Srgrimes 701553Srgrimesvoid bytenetorder(struct tsp *); 711553Srgrimesvoid bytehostorder(struct tsp *); 721553Srgrimes 731553Srgrimes 741611Srgrimes#define BU (2208988800UL) /* seconds before UNIX epoch */ 751553Srgrimes 761553Srgrimes 771553Srgrimes/* compute the difference between our date and another machine 781553Srgrimes */ 791553Srgrimesstatic int /* difference in days from our time */ 80246209Scharnierdaydiff(char *hostname) 811553Srgrimes{ 821553Srgrimes int i; 831553Srgrimes int trials; 841553Srgrimes struct timeval tout, now; 851553Srgrimes fd_set ready; 861553Srgrimes struct sockaddr from; 871553Srgrimes int fromlen; 881553Srgrimes unsigned long sec; 891553Srgrimes 901553Srgrimes 911553Srgrimes /* wait 2 seconds between 10 tries */ 921553Srgrimes tout.tv_sec = 2; 931553Srgrimes tout.tv_usec = 0; 941553Srgrimes for (trials = 0; trials < 10; trials++) { 951553Srgrimes /* ask for the time */ 961553Srgrimes sec = 0; 971553Srgrimes if (sendto(sock, &sec, sizeof(sec), 0, 981553Srgrimes (struct sockaddr*)&dayaddr, sizeof(dayaddr)) < 0) { 9930642Scharnier warn("sendto(sock)"); 1001553Srgrimes return 0; 1011553Srgrimes } 1021553Srgrimes 1031553Srgrimes for (;;) { 1041553Srgrimes FD_ZERO(&ready); 1051553Srgrimes FD_SET(sock, &ready); 1061553Srgrimes i = select(sock+1, &ready, (fd_set *)0, 1071553Srgrimes (fd_set *)0, &tout); 1081553Srgrimes if (i < 0) { 10930642Scharnier if (errno == EINTR) 1101553Srgrimes continue; 11130642Scharnier warn("select(date read)"); 1121553Srgrimes return 0; 1131553Srgrimes } 1141553Srgrimes if (0 == i) 1151553Srgrimes break; 1161553Srgrimes 1171553Srgrimes fromlen = sizeof(from); 1181553Srgrimes if (recvfrom(sock,&sec,sizeof(sec),0, 1191553Srgrimes &from,&fromlen) < 0) { 12030642Scharnier warn("recvfrom(date read)"); 1211553Srgrimes return 0; 1221553Srgrimes } 1231553Srgrimes 1241553Srgrimes sec = ntohl(sec); 1251553Srgrimes if (sec < BU) { 12630642Scharnier warnx("%s says it is before 1970: %lu", 1271553Srgrimes hostname, sec); 1281553Srgrimes return 0; 1291553Srgrimes } 1301553Srgrimes sec -= BU; 1311553Srgrimes 132239991Sed (void)gettimeofday(&now, NULL); 1331553Srgrimes return (sec - now.tv_sec); 1341553Srgrimes } 1351553Srgrimes } 1361553Srgrimes 1371553Srgrimes /* if we get here, we tried too many times */ 13830642Scharnier warnx("%s will not tell us the date", hostname); 1391553Srgrimes return 0; 1401553Srgrimes} 1411553Srgrimes 1421553Srgrimes 1431553Srgrimes/* 1441553Srgrimes * Clockdiff computes the difference between the time of the machine on 1451553Srgrimes * which it is called and the time of the machines given as argument. 1461553Srgrimes * The time differences measured by clockdiff are obtained using a sequence 1471553Srgrimes * of ICMP TSTAMP messages which are returned to the sender by the IP module 1481553Srgrimes * in the remote machine. 1491553Srgrimes * In order to compare clocks of machines in different time zones, the time 1501553Srgrimes * is transmitted (as a 32-bit value) in milliseconds since midnight UT. 1511553Srgrimes * If a hosts uses a different time format, it should set the high order 1521553Srgrimes * bit of the 32-bit quantity it transmits. 1531553Srgrimes * However, VMS apparently transmits the time in milliseconds since midnight 1541553Srgrimes * local time (rather than GMT) without setting the high order bit. 1551553Srgrimes * Furthermore, it does not understand daylight-saving time. This makes 1561553Srgrimes * clockdiff behaving inconsistently with hosts running VMS. 1571553Srgrimes * 1581553Srgrimes * In order to reduce the sensitivity to the variance of message transmission 1591553Srgrimes * time, clockdiff sends a sequence of messages. Yet, measures between 1601553Srgrimes * two `distant' hosts can be affected by a small error. The error can, 1611553Srgrimes * however, be reduced by increasing the number of messages sent in each 1621553Srgrimes * measurement. 1631553Srgrimes */ 1641553Srgrimesvoid 165246209Scharnierclockdiff(int argc, char *argv[]) 1661553Srgrimes{ 1671553Srgrimes int measure_status; 1681553Srgrimes extern int measure(u_long, u_long, char *, struct sockaddr_in*, int); 1691553Srgrimes register int avg_cnt; 1701553Srgrimes register long avg; 1711553Srgrimes struct servent *sp; 1721553Srgrimes 1731553Srgrimes if (argc < 2) { 17430642Scharnier printf("usage: timedc clockdiff host ...\n"); 1751553Srgrimes return; 1761553Srgrimes } 1771553Srgrimes 17830831Scharnier if (gethostname(myname, sizeof(myname) - 1) < 0) 17930831Scharnier err(1, "gethostname"); 1801553Srgrimes 1811553Srgrimes /* get the address for the date ready */ 1821553Srgrimes sp = getservbyname(DATE_PORT, DATE_PROTO); 1831553Srgrimes if (!sp) { 184117278Scharnier warnx("%s/%s: unknown service", DATE_PORT, DATE_PROTO); 1851553Srgrimes dayaddr.sin_port = 0; 1861553Srgrimes } else { 1871553Srgrimes dayaddr.sin_port = sp->s_port; 1881553Srgrimes } 1891553Srgrimes 1901553Srgrimes while (argc > 1) { 1911553Srgrimes argc--; argv++; 1921553Srgrimes hp = gethostbyname(*argv); 1931553Srgrimes if (hp == NULL) { 19430642Scharnier warnx("%s: %s", *argv, hstrerror(h_errno)); 1951553Srgrimes continue; 1961553Srgrimes } 1971553Srgrimes 1981553Srgrimes server.sin_family = hp->h_addrtype; 1991553Srgrimes bcopy(hp->h_addr, &server.sin_addr.s_addr, hp->h_length); 2001553Srgrimes for (avg_cnt = 0, avg = 0; avg_cnt < 16; avg_cnt++) { 2011553Srgrimes measure_status = measure(10000,100, *argv, &server, 1); 2021553Srgrimes if (measure_status != GOOD) 2031553Srgrimes break; 2041553Srgrimes avg += measure_delta; 2051553Srgrimes } 2061553Srgrimes if (measure_status == GOOD) 2071553Srgrimes measure_delta = avg/avg_cnt; 2081553Srgrimes 2091553Srgrimes switch (measure_status) { 2101553Srgrimes case HOSTDOWN: 2111553Srgrimes printf("%s is down\n", hp->h_name); 2121553Srgrimes continue; 2131553Srgrimes case NONSTDTIME: 214125456Sjohan printf("%s transmits a non-standard time format\n", 2151553Srgrimes hp->h_name); 2161553Srgrimes continue; 2171553Srgrimes case UNREACHABLE: 2181553Srgrimes printf("%s is unreachable\n", hp->h_name); 2191553Srgrimes continue; 2201553Srgrimes } 2211553Srgrimes 2221553Srgrimes /* 2231553Srgrimes * Try to get the date only after using ICMP timestamps to 2241553Srgrimes * get the time. This is because the date protocol 2251553Srgrimes * is optional. 2261553Srgrimes */ 2271553Srgrimes if (dayaddr.sin_port != 0) { 2281553Srgrimes dayaddr.sin_family = hp->h_addrtype; 2291553Srgrimes bcopy(hp->h_addr, &dayaddr.sin_addr.s_addr, 2301553Srgrimes hp->h_length); 2311553Srgrimes avg = daydiff(*argv); 2321553Srgrimes if (avg > SECDAY) { 2331553Srgrimes printf("time on %s is %ld days ahead %s\n", 2341553Srgrimes hp->h_name, avg/SECDAY, myname); 2351553Srgrimes continue; 2361553Srgrimes } else if (avg < -SECDAY) { 2371553Srgrimes printf("time on %s is %ld days behind %s\n", 2381553Srgrimes hp->h_name, -avg/SECDAY, myname); 2391553Srgrimes continue; 2401553Srgrimes } 2411553Srgrimes } 2421553Srgrimes 2431553Srgrimes if (measure_delta > 0) { 2441553Srgrimes printf("time on %s is %d ms. ahead of time on %s\n", 2451553Srgrimes hp->h_name, measure_delta, myname); 2461553Srgrimes } else if (measure_delta == 0) { 2471553Srgrimes printf("%s and %s have the same time\n", 2481553Srgrimes hp->h_name, myname); 2491553Srgrimes } else { 2501553Srgrimes printf("time on %s is %d ms. behind time on %s\n", 2511553Srgrimes hp->h_name, -measure_delta, myname); 2521553Srgrimes } 2531553Srgrimes } 2541553Srgrimes return; 2551553Srgrimes} 2561553Srgrimes 2571553Srgrimes 2581553Srgrimes/* 2591553Srgrimes * finds location of master timedaemon 2601553Srgrimes */ 2611553Srgrimesvoid 262246209Scharniermsite(int argc, char *argv[]) 2631553Srgrimes{ 264228714Sdim ssize_t cc; 2651553Srgrimes fd_set ready; 2661553Srgrimes struct sockaddr_in dest; 2671553Srgrimes int i, length; 26876403Skris struct sockaddr_in from; 2691553Srgrimes struct timeval tout; 2701553Srgrimes struct tsp msg; 2711553Srgrimes struct servent *srvp; 2721553Srgrimes char *tgtname; 2731553Srgrimes 2741553Srgrimes if (argc < 1) { 27530642Scharnier printf("usage: timedc msite [host ...]\n"); 2761553Srgrimes return; 2771553Srgrimes } 2781553Srgrimes 2791553Srgrimes srvp = getservbyname("timed", "udp"); 2801553Srgrimes if (srvp == 0) { 281117278Scharnier warnx("timed/udp: unknown service"); 2821553Srgrimes return; 2831553Srgrimes } 2841553Srgrimes dest.sin_port = srvp->s_port; 2851553Srgrimes dest.sin_family = AF_INET; 2861553Srgrimes 28730831Scharnier if (gethostname(myname, sizeof(myname) - 1) < 0) 28830831Scharnier err(1, "gethostname"); 2891553Srgrimes i = 1; 2901553Srgrimes do { 2911553Srgrimes tgtname = (i >= argc) ? myname : argv[i]; 2921553Srgrimes hp = gethostbyname(tgtname); 2931553Srgrimes if (hp == 0) { 29430642Scharnier warnx("%s: %s", tgtname, hstrerror(h_errno)); 2951553Srgrimes continue; 2961553Srgrimes } 2971553Srgrimes bcopy(hp->h_addr, &dest.sin_addr.s_addr, hp->h_length); 2981553Srgrimes 29976403Skris (void)strlcpy(msg.tsp_name, myname, sizeof(msg.tsp_name)); 3001553Srgrimes msg.tsp_type = TSP_MSITE; 3011553Srgrimes msg.tsp_vers = TSPVERSION; 3021553Srgrimes bytenetorder(&msg); 3031553Srgrimes if (sendto(sock, &msg, sizeof(struct tsp), 0, 3041553Srgrimes (struct sockaddr*)&dest, 3051553Srgrimes sizeof(struct sockaddr)) < 0) { 30630642Scharnier warn("sendto"); 3071553Srgrimes continue; 3081553Srgrimes } 3091553Srgrimes 3101553Srgrimes tout.tv_sec = 15; 3111553Srgrimes tout.tv_usec = 0; 3121553Srgrimes FD_ZERO(&ready); 3131553Srgrimes FD_SET(sock, &ready); 3141553Srgrimes if (select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0, 3151553Srgrimes &tout)) { 31676403Skris length = sizeof(from); 3171553Srgrimes cc = recvfrom(sock, &msg, sizeof(struct tsp), 0, 31876403Skris (struct sockaddr *)&from, &length); 3191553Srgrimes if (cc < 0) { 32030642Scharnier warn("recvfrom"); 3211553Srgrimes continue; 3221553Srgrimes } 32381946Skris /* 32481946Skris * The 4.3BSD protocol spec had a 32-byte tsp_name field, and 32581946Skris * this is still OS-dependent. Demand that the packet is at 32681946Skris * least long enough to hold a 4.3BSD packet. 32781946Skris */ 32881946Skris if (cc < (sizeof(struct tsp) - MAXHOSTNAMELEN + 32)) { 32976403Skris fprintf(stderr, 330228714Sdim "short packet (%zd/%zu bytes) from %s\n", 33181946Skris cc, sizeof(struct tsp) - MAXHOSTNAMELEN + 32, 33276403Skris inet_ntoa(from.sin_addr)); 33376403Skris continue; 33476403Skris } 3351553Srgrimes bytehostorder(&msg); 3361553Srgrimes if (msg.tsp_type == TSP_ACK) { 3371553Srgrimes printf("master timedaemon at %s is %s\n", 3381553Srgrimes tgtname, msg.tsp_name); 3391553Srgrimes } else { 34076403Skris if (msg.tsp_type >= TSPTYPENUMBER) 34176403Skris printf("unknown ack received: %u\n", 34276403Skris msg.tsp_type); 34376403Skris else 34476403Skris printf("wrong ack received: %s\n", 34576403Skris tsptype[msg.tsp_type]); 3461553Srgrimes } 3471553Srgrimes } else { 3481553Srgrimes printf("communication error with %s\n", tgtname); 3491553Srgrimes } 3501553Srgrimes } while (++i < argc); 3511553Srgrimes} 3521553Srgrimes 3531553Srgrimes/* 3541553Srgrimes * quits timedc 3551553Srgrimes */ 3561553Srgrimesvoid 357246209Scharnierquit(void) 3581553Srgrimes{ 3591553Srgrimes exit(0); 3601553Srgrimes} 3611553Srgrimes 3621553Srgrimes 3631553Srgrimes/* 3641553Srgrimes * Causes the election timer to expire on the selected hosts 3651553Srgrimes * It sends just one udp message per machine, relying on 3661553Srgrimes * reliability of communication channel. 3671553Srgrimes */ 3681553Srgrimesvoid 369246209Scharniertesting(int argc, char *argv[]) 3701553Srgrimes{ 3711553Srgrimes struct servent *srvp; 3721553Srgrimes struct sockaddr_in sin; 3731553Srgrimes struct tsp msg; 3741553Srgrimes 3751553Srgrimes if (argc < 2) { 37630642Scharnier printf("usage: timedc election host1 [host2 ...]\n"); 3771553Srgrimes return; 3781553Srgrimes } 3791553Srgrimes 3801553Srgrimes srvp = getservbyname("timed", "udp"); 3811553Srgrimes if (srvp == 0) { 382117278Scharnier warnx("timed/udp: unknown service"); 3831553Srgrimes return; 3841553Srgrimes } 3851553Srgrimes 3861553Srgrimes while (argc > 1) { 3871553Srgrimes argc--; argv++; 3881553Srgrimes hp = gethostbyname(*argv); 3891553Srgrimes if (hp == NULL) { 39030642Scharnier warnx("%s: %s", *argv, hstrerror(h_errno)); 3911553Srgrimes argc--; argv++; 3921553Srgrimes continue; 3931553Srgrimes } 3941553Srgrimes sin.sin_port = srvp->s_port; 3951553Srgrimes sin.sin_family = hp->h_addrtype; 3961553Srgrimes bcopy(hp->h_addr, &sin.sin_addr.s_addr, hp->h_length); 3971553Srgrimes 3981553Srgrimes msg.tsp_type = TSP_TEST; 3991553Srgrimes msg.tsp_vers = TSPVERSION; 40030831Scharnier if (gethostname(myname, sizeof(myname) - 1) < 0) 40130831Scharnier err(1, "gethostname"); 40276403Skris (void)strlcpy(msg.tsp_name, myname, sizeof(msg.tsp_name)); 4031553Srgrimes bytenetorder(&msg); 4041553Srgrimes if (sendto(sock, &msg, sizeof(struct tsp), 0, 4051553Srgrimes (struct sockaddr*)&sin, 4061553Srgrimes sizeof(struct sockaddr)) < 0) { 40730642Scharnier warn("sendto"); 4081553Srgrimes } 4091553Srgrimes } 4101553Srgrimes} 4111553Srgrimes 4121553Srgrimes 4131553Srgrimes/* 4141553Srgrimes * Enables or disables tracing on local timedaemon 4151553Srgrimes */ 4161553Srgrimesvoid 417246209Scharniertracing(int argc, char *argv[]) 4181553Srgrimes{ 4191553Srgrimes int onflag; 4201553Srgrimes int length; 421228714Sdim ssize_t cc; 4221553Srgrimes fd_set ready; 4231553Srgrimes struct sockaddr_in dest; 42476403Skris struct sockaddr_in from; 4251553Srgrimes struct timeval tout; 4261553Srgrimes struct tsp msg; 4271553Srgrimes struct servent *srvp; 4281553Srgrimes 4291553Srgrimes if (argc != 2) { 43030642Scharnier printf("usage: timedc trace { on | off }\n"); 4311553Srgrimes return; 4321553Srgrimes } 4331553Srgrimes 4341553Srgrimes srvp = getservbyname("timed", "udp"); 4351553Srgrimes if (srvp == 0) { 436117278Scharnier warnx("timed/udp: unknown service"); 4371553Srgrimes return; 4381553Srgrimes } 4391553Srgrimes dest.sin_port = srvp->s_port; 4401553Srgrimes dest.sin_family = AF_INET; 4411553Srgrimes 44230831Scharnier if (gethostname(myname, sizeof(myname) - 1) < 0) 44330831Scharnier err(1, "gethostname"); 4441553Srgrimes hp = gethostbyname(myname); 4451553Srgrimes bcopy(hp->h_addr, &dest.sin_addr.s_addr, hp->h_length); 4461553Srgrimes 4471553Srgrimes if (strcmp(argv[1], "on") == 0) { 4481553Srgrimes msg.tsp_type = TSP_TRACEON; 4491553Srgrimes onflag = ON; 4501553Srgrimes } else { 4511553Srgrimes msg.tsp_type = TSP_TRACEOFF; 4521553Srgrimes onflag = OFF; 4531553Srgrimes } 4541553Srgrimes 45530831Scharnier (void)strcpy(msg.tsp_name, myname); 4561553Srgrimes msg.tsp_vers = TSPVERSION; 4571553Srgrimes bytenetorder(&msg); 4581553Srgrimes if (sendto(sock, &msg, sizeof(struct tsp), 0, 4591553Srgrimes (struct sockaddr*)&dest, sizeof(struct sockaddr)) < 0) { 46030642Scharnier warn("sendto"); 4611553Srgrimes return; 4621553Srgrimes } 4631553Srgrimes 4641553Srgrimes tout.tv_sec = 5; 4651553Srgrimes tout.tv_usec = 0; 4661553Srgrimes FD_ZERO(&ready); 4671553Srgrimes FD_SET(sock, &ready); 4681553Srgrimes if (select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0, &tout)) { 46976403Skris length = sizeof(from); 4701553Srgrimes cc = recvfrom(sock, &msg, sizeof(struct tsp), 0, 47176403Skris (struct sockaddr *)&from, &length); 4721553Srgrimes if (cc < 0) { 47330642Scharnier warn("recvfrom"); 4741553Srgrimes return; 4751553Srgrimes } 47681946Skris /* 47781946Skris * The 4.3BSD protocol spec had a 32-byte tsp_name field, and 47881946Skris * this is still OS-dependent. Demand that the packet is at 47981946Skris * least long enough to hold a 4.3BSD packet. 48081946Skris */ 48181946Skris if (cc < (sizeof(struct tsp) - MAXHOSTNAMELEN + 32)) { 482228714Sdim fprintf(stderr, "short packet (%zd/%zu bytes) from %s\n", 48381946Skris cc, sizeof(struct tsp) - MAXHOSTNAMELEN + 32, 48481946Skris inet_ntoa(from.sin_addr)); 48576403Skris return; 48676403Skris } 4871553Srgrimes bytehostorder(&msg); 4881553Srgrimes if (msg.tsp_type == TSP_ACK) 4891553Srgrimes if (onflag) 4901553Srgrimes printf("timed tracing enabled\n"); 4911553Srgrimes else 4921553Srgrimes printf("timed tracing disabled\n"); 49376403Skris else { 49476403Skris if (msg.tsp_type >= TSPTYPENUMBER) 49576403Skris printf("unknown ack received: %u\n", 49676403Skris msg.tsp_type); 49776403Skris else 49876403Skris printf("wrong ack received: %s\n", 4991553Srgrimes tsptype[msg.tsp_type]); 50076403Skris } 5011553Srgrimes } else 5021553Srgrimes printf("communication error\n"); 5031553Srgrimes} 5041553Srgrimes 5051553Srgrimesint 506246209Scharnierpriv_resources(void) 5071553Srgrimes{ 5081553Srgrimes int port; 5091553Srgrimes struct sockaddr_in sin; 5101553Srgrimes 5111553Srgrimes sock = socket(AF_INET, SOCK_DGRAM, 0); 5121553Srgrimes if (sock < 0) { 51330642Scharnier warn("opening socket"); 5141553Srgrimes return(-1); 5151553Srgrimes } 5161553Srgrimes 5171553Srgrimes sin.sin_family = AF_INET; 5181553Srgrimes sin.sin_addr.s_addr = 0; 5191553Srgrimes for (port = IPPORT_RESERVED - 1; port > IPPORT_RESERVED / 2; port--) { 5201553Srgrimes sin.sin_port = htons((u_short)port); 5211553Srgrimes if (bind(sock, (struct sockaddr*)&sin, sizeof (sin)) >= 0) 5221553Srgrimes break; 5231553Srgrimes if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) { 52430642Scharnier warn("bind"); 5251553Srgrimes (void) close(sock); 5261553Srgrimes return(-1); 5271553Srgrimes } 5281553Srgrimes } 5291553Srgrimes if (port == IPPORT_RESERVED / 2) { 53030642Scharnier warnx("all reserved ports in use"); 5311553Srgrimes (void) close(sock); 5321553Srgrimes return(-1); 5331553Srgrimes } 5341553Srgrimes 5351553Srgrimes sock_raw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); 5361553Srgrimes if (sock_raw < 0) { 53730642Scharnier warn("opening raw socket"); 5381553Srgrimes (void) close(sock); 5391553Srgrimes return(-1); 5401553Srgrimes } 5411553Srgrimes return(1); 5421553Srgrimes} 543