Changeset View
Changeset View
Standalone View
Standalone View
head/contrib/ntp/ntpdc/ntpdc.c
Show All 26 Lines | |||||
#ifdef OPENSSL | #ifdef OPENSSL | ||||
#include "openssl/evp.h" | #include "openssl/evp.h" | ||||
#include "openssl/objects.h" | #include "openssl/objects.h" | ||||
#endif | #endif | ||||
#include <ssl_applink.c> | #include <ssl_applink.c> | ||||
#include "ntp_libopts.h" | #include "ntp_libopts.h" | ||||
#include "ntpdc-opts.h" | #include "ntpdc-opts.h" | ||||
#include "safecast.h" | |||||
#ifdef SYS_VXWORKS | #ifdef SYS_VXWORKS | ||||
/* vxWorks needs mode flag -casey*/ | /* vxWorks needs mode flag -casey*/ | ||||
# define open(name, flags) open(name, flags, 0777) | # define open(name, flags) open(name, flags, 0777) | ||||
# define SERVER_PORT_NUM 123 | # define SERVER_PORT_NUM 123 | ||||
#endif | #endif | ||||
/* We use COMMAND as an autogen keyword */ | /* We use COMMAND as an autogen keyword */ | ||||
Show All 26 Lines | |||||
int ntpdcmain (int, char **); | int ntpdcmain (int, char **); | ||||
/* | /* | ||||
* Built in command handler declarations | * Built in command handler declarations | ||||
*/ | */ | ||||
static int openhost (const char *); | static int openhost (const char *); | ||||
static int sendpkt (void *, size_t); | static int sendpkt (void *, size_t); | ||||
static void growpktdata (void); | static void growpktdata (void); | ||||
static int getresponse (int, int, int *, int *, char **, int); | static int getresponse (int, int, size_t *, size_t *, const char **, size_t); | ||||
static int sendrequest (int, int, int, u_int, size_t, char *); | static int sendrequest (int, int, int, size_t, size_t, const char *); | ||||
static void getcmds (void); | static void getcmds (void); | ||||
static RETSIGTYPE abortcmd (int); | static RETSIGTYPE abortcmd (int); | ||||
static void docmd (const char *); | static void docmd (const char *); | ||||
static void tokenize (const char *, char **, int *); | static void tokenize (const char *, char **, int *); | ||||
static int findcmd (char *, struct xcmd *, struct xcmd *, struct xcmd **); | static int findcmd (char *, struct xcmd *, struct xcmd *, struct xcmd **); | ||||
static int getarg (char *, int, arg_v *); | static int getarg (char *, int, arg_v *); | ||||
static int getnetnum (const char *, sockaddr_u *, char *, int); | static int getnetnum (const char *, sockaddr_u *, char *, int); | ||||
static void help (struct parse *, FILE *); | static void help (struct parse *, FILE *); | ||||
▲ Show 20 Lines • Show All 434 Lines • ▼ Show 20 Lines | if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, | ||||
&rbufsize, sizeof(int)) == -1) | &rbufsize, sizeof(int)) == -1) | ||||
error("setsockopt"); | error("setsockopt"); | ||||
} | } | ||||
# endif | # endif | ||||
#endif | #endif | ||||
#ifdef SYS_VXWORKS | #ifdef SYS_VXWORKS | ||||
if (connect(sockfd, (struct sockaddr *)&hostaddr, | if (connect(sockfd, (struct sockaddr *)&hostaddr, | ||||
sizeof(hostaddr)) == -1) { | sizeof(hostaddr)) == -1) | ||||
#else | #else | ||||
if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) == -1) { | if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) == -1) | ||||
#endif /* SYS_VXWORKS */ | #endif /* SYS_VXWORKS */ | ||||
{ | |||||
error("connect"); | error("connect"); | ||||
exit(-1); | exit(-1); | ||||
} | } | ||||
freeaddrinfo(ai); | freeaddrinfo(ai); | ||||
havehost = 1; | havehost = 1; | ||||
req_pkt_size = REQ_LEN_NOMAC; | req_pkt_size = REQ_LEN_NOMAC; | ||||
impl_ver = IMPL_XNTPD; | impl_ver = IMPL_XNTPD; | ||||
Show All 36 Lines | |||||
/* | /* | ||||
* getresponse - get a (series of) response packet(s) and return the data | * getresponse - get a (series of) response packet(s) and return the data | ||||
*/ | */ | ||||
static int | static int | ||||
getresponse( | getresponse( | ||||
int implcode, | int implcode, | ||||
int reqcode, | int reqcode, | ||||
int *ritems, | size_t *ritems, | ||||
int *rsize, | size_t *rsize, | ||||
char **rdata, | const char **rdata, | ||||
int esize | size_t esize | ||||
) | ) | ||||
{ | { | ||||
struct resp_pkt rpkt; | struct resp_pkt rpkt; | ||||
struct sock_timeval tvo; | struct sock_timeval tvo; | ||||
int items; | size_t items; | ||||
int i; | size_t i; | ||||
int size; | size_t size; | ||||
int datasize; | size_t datasize; | ||||
char *datap; | char *datap; | ||||
char *tmp_data; | char *tmp_data; | ||||
char haveseq[MAXSEQ+1]; | char haveseq[MAXSEQ+1]; | ||||
int firstpkt; | int firstpkt; | ||||
int lastseq; | int lastseq; | ||||
int numrecv; | int numrecv; | ||||
int seq; | int seq; | ||||
fd_set fds; | fd_set fds; | ||||
ssize_t n; | ssize_t n; | ||||
int pad; | size_t pad; | ||||
/* | /* | ||||
* This is pretty tricky. We may get between 1 and many packets | * This is pretty tricky. We may get between 1 and many packets | ||||
* back in response to the request. We peel the data out of | * back in response to the request. We peel the data out of | ||||
* each packet and collect it in one long block. When the last | * each packet and collect it in one long block. When the last | ||||
* packet in the sequence is received we'll know how many we | * packet in the sequence is received we'll know how many we | ||||
* should have had. Note we use one long time out, should reconsider. | * should have had. Note we use one long time out, should reconsider. | ||||
*/ | */ | ||||
*ritems = 0; | *ritems = 0; | ||||
*rsize = 0; | *rsize = 0; | ||||
firstpkt = 1; | firstpkt = 1; | ||||
numrecv = 0; | numrecv = 0; | ||||
*rdata = datap = pktdata; | *rdata = datap = pktdata; | ||||
lastseq = 999; /* too big to be a sequence number */ | lastseq = 999; /* too big to be a sequence number */ | ||||
ZERO(haveseq); | ZERO(haveseq); | ||||
FD_ZERO(&fds); | FD_ZERO(&fds); | ||||
again: | again: | ||||
if (firstpkt) | if (firstpkt) | ||||
tvo = tvout; | tvo = tvout; | ||||
else | else | ||||
tvo = tvsout; | tvo = tvsout; | ||||
FD_SET(sockfd, &fds); | FD_SET(sockfd, &fds); | ||||
n = select(sockfd+1, &fds, (fd_set *)0, (fd_set *)0, &tvo); | n = select(sockfd+1, &fds, NULL, NULL, &tvo); | ||||
if (n == -1) { | if (n == -1) { | ||||
warning("select fails"); | warning("select fails"); | ||||
return -1; | return -1; | ||||
} | } | ||||
if (n == 0) { | if (n == 0) { | ||||
/* | /* | ||||
* Timed out. Return what we have | * Timed out. Return what we have | ||||
*/ | */ | ||||
if (firstpkt) { | if (firstpkt) { | ||||
(void) fprintf(stderr, | (void) fprintf(stderr, | ||||
"%s: timed out, nothing received\n", currenthost); | "%s: timed out, nothing received\n", | ||||
currenthost); | |||||
return ERR_TIMEOUT; | return ERR_TIMEOUT; | ||||
} else { | } else { | ||||
(void) fprintf(stderr, | (void) fprintf(stderr, | ||||
"%s: timed out with incomplete data\n", | "%s: timed out with incomplete data\n", | ||||
currenthost); | currenthost); | ||||
if (debug) { | if (debug) { | ||||
printf("Received sequence numbers"); | printf("Received sequence numbers"); | ||||
for (n = 0; n <= MAXSEQ; n++) | for (n = 0; n <= MAXSEQ; n++) | ||||
▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | getresponse( | ||||
if (esize > size) | if (esize > size) | ||||
pad = esize - size; | pad = esize - size; | ||||
else | else | ||||
pad = 0; | pad = 0; | ||||
datasize = items * size; | datasize = items * size; | ||||
if ((size_t)datasize > (n-RESP_HEADER_SIZE)) { | if ((size_t)datasize > (n-RESP_HEADER_SIZE)) { | ||||
if (debug) | if (debug) | ||||
printf( | printf( | ||||
"Received items %d, size %d (total %d), data in packet is %zu\n", | "Received items %zu, size %zu (total %zu), data in packet is %zu\n", | ||||
items, size, datasize, n-RESP_HEADER_SIZE); | items, size, datasize, n-RESP_HEADER_SIZE); | ||||
goto again; | goto again; | ||||
} | } | ||||
/* | /* | ||||
* If this isn't our first packet, make sure the size matches | * If this isn't our first packet, make sure the size matches | ||||
* the other ones. | * the other ones. | ||||
*/ | */ | ||||
if (!firstpkt && size != *rsize) { | if (!firstpkt && size != *rsize) { | ||||
if (debug) | if (debug) | ||||
printf("Received itemsize %d, previous %d\n", | printf("Received itemsize %zu, previous %zu\n", | ||||
size, *rsize); | size, *rsize); | ||||
goto again; | goto again; | ||||
} | } | ||||
/* | /* | ||||
* If we've received this before, +toss it | * If we've received this before, +toss it | ||||
*/ | */ | ||||
seq = INFO_SEQ(rpkt.auth_seq); | seq = INFO_SEQ(rpkt.auth_seq); | ||||
if (haveseq[seq]) { | if (haveseq[seq]) { | ||||
Show All 13 Lines | if (!ISMORE(rpkt.rm_vn_mode)) { | ||||
} | } | ||||
lastseq = seq; | lastseq = seq; | ||||
} | } | ||||
/* | /* | ||||
* So far, so good. Copy this data into the output array. | * So far, so good. Copy this data into the output array. | ||||
*/ | */ | ||||
if ((datap + datasize + (pad * items)) > (pktdata + pktdatasize)) { | if ((datap + datasize + (pad * items)) > (pktdata + pktdatasize)) { | ||||
int offset = datap - pktdata; | size_t offset = datap - pktdata; | ||||
growpktdata(); | growpktdata(); | ||||
*rdata = pktdata; /* might have been realloced ! */ | *rdata = pktdata; /* might have been realloced ! */ | ||||
datap = pktdata + offset; | datap = pktdata + offset; | ||||
} | } | ||||
/* | /* | ||||
* We now move the pointer along according to size and number of | * We now move the pointer along according to size and number of | ||||
* items. This is so we can play nice with older implementations | * items. This is so we can play nice with older implementations | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | |||||
* packet, and the size of the digest is then implied by the packet | * packet, and the size of the digest is then implied by the packet | ||||
* size. | * size. | ||||
*/ | */ | ||||
static int | static int | ||||
sendrequest( | sendrequest( | ||||
int implcode, | int implcode, | ||||
int reqcode, | int reqcode, | ||||
int auth, | int auth, | ||||
u_int qitems, | size_t qitems, | ||||
size_t qsize, | size_t qsize, | ||||
char *qdata | const char *qdata | ||||
) | ) | ||||
{ | { | ||||
struct req_pkt qpkt; | struct req_pkt qpkt; | ||||
size_t datasize; | size_t datasize; | ||||
size_t reqsize; | size_t reqsize; | ||||
u_long key_id; | u_long key_id; | ||||
l_fp ts; | l_fp ts; | ||||
l_fp * ptstamp; | l_fp * ptstamp; | ||||
int maclen; | size_t maclen; | ||||
char * pass; | char * pass; | ||||
ZERO(qpkt); | ZERO(qpkt); | ||||
qpkt.rm_vn_mode = RM_VN_MODE(0, 0, 0); | qpkt.rm_vn_mode = RM_VN_MODE(0, 0, 0); | ||||
qpkt.implementation = (u_char)implcode; | qpkt.implementation = (u_char)implcode; | ||||
qpkt.request = (u_char)reqcode; | qpkt.request = (u_char)reqcode; | ||||
datasize = qitems * qsize; | datasize = qitems * qsize; | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | if (info_auth_hashlen > 16) { | ||||
reqsize = (reqsize + 3) & ~3; | reqsize = (reqsize + 3) & ~3; | ||||
} else | } else | ||||
reqsize = req_pkt_size; | reqsize = req_pkt_size; | ||||
ptstamp = (void *)((char *)&qpkt + reqsize); | ptstamp = (void *)((char *)&qpkt + reqsize); | ||||
ptstamp--; | ptstamp--; | ||||
get_systime(&ts); | get_systime(&ts); | ||||
L_ADD(&ts, &delay_time); | L_ADD(&ts, &delay_time); | ||||
HTONL_FP(&ts, ptstamp); | HTONL_FP(&ts, ptstamp); | ||||
maclen = authencrypt(info_auth_keyid, (void *)&qpkt, reqsize); | maclen = authencrypt( | ||||
info_auth_keyid, (void *)&qpkt, size2int_chk(reqsize)); | |||||
if (!maclen) { | if (!maclen) { | ||||
fprintf(stderr, "Key not found\n"); | fprintf(stderr, "Key not found\n"); | ||||
return 1; | return 1; | ||||
} else if (maclen != (int)(info_auth_hashlen + sizeof(keyid_t))) { | } else if (maclen != (int)(info_auth_hashlen + sizeof(keyid_t))) { | ||||
fprintf(stderr, | fprintf(stderr, | ||||
"%d octet MAC, %zu expected with %zu octet digest\n", | "%zu octet MAC, %zu expected with %zu octet digest\n", | ||||
maclen, (info_auth_hashlen + sizeof(keyid_t)), | maclen, (info_auth_hashlen + sizeof(keyid_t)), | ||||
info_auth_hashlen); | info_auth_hashlen); | ||||
return 1; | return 1; | ||||
} | } | ||||
return sendpkt(&qpkt, reqsize + maclen); | return sendpkt(&qpkt, reqsize + maclen); | ||||
} | } | ||||
/* | /* | ||||
* doquery - send a request and process the response | * doquery - send a request and process the response | ||||
*/ | */ | ||||
int | int | ||||
doquery( | doquery( | ||||
int implcode, | int implcode, | ||||
int reqcode, | int reqcode, | ||||
int auth, | int auth, | ||||
int qitems, | size_t qitems, | ||||
int qsize, | size_t qsize, | ||||
char *qdata, | const char *qdata, | ||||
int *ritems, | size_t *ritems, | ||||
int *rsize, | size_t *rsize, | ||||
char **rdata, | const char **rdata, | ||||
int quiet_mask, | int quiet_mask, | ||||
int esize | int esize | ||||
) | ) | ||||
{ | { | ||||
int res; | int res; | ||||
char junk[512]; | char junk[512]; | ||||
fd_set fds; | fd_set fds; | ||||
struct sock_timeval tvzero; | struct sock_timeval tvzero; | ||||
Show All 9 Lines | doquery( | ||||
/* | /* | ||||
* Poll the socket and clear out any pending data | * Poll the socket and clear out any pending data | ||||
*/ | */ | ||||
again: | again: | ||||
do { | do { | ||||
tvzero.tv_sec = tvzero.tv_usec = 0; | tvzero.tv_sec = tvzero.tv_usec = 0; | ||||
FD_ZERO(&fds); | FD_ZERO(&fds); | ||||
FD_SET(sockfd, &fds); | FD_SET(sockfd, &fds); | ||||
res = select(sockfd+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero); | res = select(sockfd+1, &fds, NULL, NULL, &tvzero); | ||||
if (res == -1) { | if (res == -1) { | ||||
warning("polling select"); | warning("polling select"); | ||||
return -1; | return -1; | ||||
} else if (res > 0) | } else if (res > 0) | ||||
(void) recv(sockfd, junk, sizeof junk, 0); | (void) recv(sockfd, junk, sizeof junk, 0); | ||||
} while (res > 0); | } while (res > 0); | ||||
▲ Show 20 Lines • Show All 281 Lines • ▼ Show 20 Lines | |||||
findcmd( | findcmd( | ||||
register char *str, | register char *str, | ||||
struct xcmd *clist1, | struct xcmd *clist1, | ||||
struct xcmd *clist2, | struct xcmd *clist2, | ||||
struct xcmd **cmd | struct xcmd **cmd | ||||
) | ) | ||||
{ | { | ||||
register struct xcmd *cl; | register struct xcmd *cl; | ||||
register int clen; | size_t clen; | ||||
int nmatch; | int nmatch; | ||||
struct xcmd *nearmatch = NULL; | struct xcmd *nearmatch = NULL; | ||||
struct xcmd *clist; | struct xcmd *clist; | ||||
clen = strlen(str); | clen = strlen(str); | ||||
nmatch = 0; | nmatch = 0; | ||||
if (clist1 != 0) | if (clist1 != 0) | ||||
clist = clist1; | clist = clist1; | ||||
▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | switch (argp->type) { | ||||
do { | do { | ||||
cp = strchr(digits, *np); | cp = strchr(digits, *np); | ||||
if (cp == NULL) { | if (cp == NULL) { | ||||
(void) fprintf(stderr, | (void) fprintf(stderr, | ||||
"***Illegal integer value %s\n", str); | "***Illegal integer value %s\n", str); | ||||
return 0; | return 0; | ||||
} | } | ||||
argp->uval *= 10; | argp->uval *= 10; | ||||
argp->uval += (cp - digits); | argp->uval += (u_long)(cp - digits); | ||||
} while (*(++np) != '\0'); | } while (*(++np) != '\0'); | ||||
if (isneg) { | if (isneg) { | ||||
if ((code & ~OPT) == NTP_UINT) { | if ((code & ~OPT) == NTP_UINT) { | ||||
(void) fprintf(stderr, | (void) fprintf(stderr, | ||||
"***Value %s should be unsigned\n", str); | "***Value %s should be unsigned\n", str); | ||||
return 0; | return 0; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 551 Lines • Show Last 20 Lines |