int key_id;
struct timeval timeout;
struct key *key;
+ struct pkt x_pkt;
};
struct key *keys = NULL;
struct timeval timeout_tv;
+static union {
+ struct pkt pkt;
+ char buf[1500];
+} rbuf;
+
+#define r_pkt rbuf.pkt
+
void dns_cb (int errcode, struct evutil_addrinfo *addr, void *ptr);
void ntp_cb (evutil_socket_t, short, void *);
void set_li_vn_mode (struct pkt *spkt, char leap, char version, char mode);
hints.ai_protocol = IPPROTO_TCP;
dns_ctx = emalloc(sizeof(*dns_ctx));
+ memset(dns_ctx, 0, sizeof(*dns_ctx));
+
dns_ctx->name = argv[i];
dns_ctx->flags = CTX_UCST;
dns_ctx->timeout = timeout_tv;
ctx->key_id, ctx->key);
/* The current sendpkt does not return status */
- /* XXX: the 2nd arg may be wrong... */
- /* XXX: ... or it may need a cast*/
sendpkt(sock, (sockaddr_u *)ai->ai_addr,
&x_pkt, pkt_len);
+ /* Save the packet we sent... */
+ memcpy(&(ctx->x_pkt), &x_pkt, pkt_len);
#ifdef DEBUG
msyslog(LOG_DEBUG,
)
{
struct ntp_ctx *ctx = ptr;
+ int rpktl;
if (debug)
printf("Got an event on socket %d:%s%s%s%s [%s%s] <%s>\n",
);
/* Read in the packet */
+ rpktl = recvpkt(fd, &r_pkt, sizeof rbuf,
+ (ctx->flags & CTX_UCST) ? &(ctx->x_pkt) : 0);
/* If this is a Unicast packet, we're done ... */
if (ctx->flags & CTX_UCST) {
}
-
-static union {
- struct pkt pkt;
- char buf[1500];
-} rbuf;
-
-#define r_pkt rbuf.pkt
-
-
int
generate_pkt (
struct pkt *x_pkt,
}
-/*
-** The heart of (S)NTP:
-**
-** Exchange NTP packets and compute values to correct the local clock.
-*/
-int
-on_wire (
- struct addrinfo *host,
- struct addrinfo *bcast
- )
-{
- char addr_buf[INET6_ADDRSTRLEN];
- register int try;
- SOCKET sock;
- struct key *pkt_key = NULL;
- long l;
- int key_id = 0;
- struct timeval tv_xmt;
- struct pkt x_pkt;
- int error, rpktl, handle_pkt_res;
-
- if (ENABLED_OPT(AUTHENTICATION) &&
- atoint(OPT_ARG(AUTHENTICATION), &l)) {
- key_id = l;
- get_key(key_id, &pkt_key);
- }
- for (try = 0; try < 5; try++) {
- memset(&r_pkt, 0, sizeof rbuf);
-
- error = GETTIMEOFDAY(&tv_xmt, NULL);
- tv_xmt.tv_sec += JAN_1970;
-
-#ifdef DEBUG
- printf("sntp on_wire: Current time sec: %i msec: %i\n",
- (unsigned int) tv_xmt.tv_sec,
- (unsigned int) tv_xmt.tv_usec);
-#endif
-
- if (bcast) {
- create_socket(&sock, (sockaddr_u *)bcast->ai_addr);
- rpktl = recv_bcst_pkt(sock, &r_pkt, sizeof rbuf,
- (sockaddr_u *)bcast->ai_addr);
- closesocket(sock);
- } else {
- int pkt_len = generate_pkt(&x_pkt, &tv_xmt, key_id,
- pkt_key);
-
- create_socket(&sock, (sockaddr_u *)host->ai_addr);
- sendpkt(sock, (sockaddr_u *)host->ai_addr, &x_pkt,
- pkt_len);
- rpktl = recvpkt(sock, &r_pkt, sizeof rbuf, &x_pkt);
- closesocket(sock);
- }
-
- handle_pkt_res = handle_pkt(rpktl, &r_pkt, host);
- if (handle_pkt_res < 1)
- return handle_pkt_res;
- }
-
- getnameinfo(host->ai_addr, host->ai_addrlen, addr_buf,
- sizeof(addr_buf), NULL, 0, NI_NUMERICHOST);
- msyslog(LOG_DEBUG, "Received no useable packet from %s!", addr_buf);
-
- return -1;
-}
-
/* Compute the 8 bits for li_vn_mode */
void
#include <config.h>
#include "networking.h"
+#include "ntp_debug.h"
char adr_buf[INET6_ADDRSTRLEN];
}
-/* Creates a socket and returns. */
-void
-create_socket (
- SOCKET *rsock,
- sockaddr_u *dest
- )
-{
- *rsock = socket(AF(dest), SOCK_DGRAM, 0);
-
- if (-1 == *rsock && debug)
- printf("Failed to create UDP socket with family %d\n", AF(dest));
-}
-
-
/* Send a packet */
void
sendpkt (
GETSOCKNAME_SOCKLEN_TYPE slen;
int recvc;
-#ifdef DEBUG
- printf("sntp recvdata: Trying to receive data from...\n");
-#endif
slen = sizeof(*sender);
recvc = recvfrom(rsock, rdata, rdata_length, 0,
&sender->sa, &slen);
+ if (-1 == recvc) {
+ msyslog(LOG_ERR, "recvdata(%d) failed: %m", rsock);
+ return recvc;
+ }
#ifdef DEBUG
- if (recvc > 0) {
+ if (debug > 1) {
printf("Received %d bytes from %s:\n", recvc, sptoa(sender));
- pkt_output((struct pkt *) rdata, recvc, stdout);
- } else {
- // saved_errno = errno;
- printf("recvfrom error %d (%s)\n", errno, strerror(errno));
- // errno = saved_errno;
+ pkt_output((struct pkt *)rdata, recvc, stdout);
}
#endif
return recvc;
{
unsigned int key_id = 0;
struct key *pkt_key = NULL;
- int is_authentic = 0;
+ int is_authentic = -1;
unsigned int exten_words, exten_words_used = 0;
int mac_size;
*/
if (pkt_len < LEN_PKT_NOMAC || (pkt_len & 3) != 0) {
unusable:
- if (debug)
- printf("sntp %s: Funny packet length: %i. Discarding package.\n", func_name, pkt_len);
+ msyslog(LOG_ERR,
+ "%s: Funny packet length: %i. Discarding packet.",
+ func_name, pkt_len);
return PACKET_UNUSEABLE;
}
/* skip past the extensions, if any */
*/
mac_size = exten_words << 2;
if (!auth_md5((char *)rpkt, pkt_len - mac_size, mac_size - 4, pkt_key)) {
+ is_authentic = 0;
break;
}
/* Yay! Things worked out! */
if (debug) {
char *hostname = ss_to_str(sas);
+
printf("sntp %s: packet received from %s successfully authenticated using key id %i.\n",
func_name, hostname, key_id);
free(hostname);
goto unusable;
break;
}
- if (!is_authentic) {
- if (ENABLED_OPT(AUTHENTICATION)) {
- /* We want a authenticated packet */
- if (debug) {
- char *hostname = ss_to_str(sas);
- printf("sntp %s: packet received from %s is not authentic. Will discard it.\n",
- func_name, hostname);
- free(hostname);
- }
- return SERVER_AUTH_FAIL;
- }
- /*
- ** We don't know if the user wanted authentication so let's
- ** use it anyways
- */
- if (debug) {
- char *hostname = ss_to_str(sas);
- printf("sntp %s: packet received from %s is not authentic. Authentication not enforced.\n",
- func_name, hostname);
- free(hostname);
- }
+ switch (is_authentic) {
+ case -1: /* unknown */
+ break;
+ case 0: /* not authentic */
+ return SERVER_AUTH_FAIL;
+ break;
+ case 1: /* authentic */
+ break;
+ default: /* error */
+ break;
}
+
/* Check for server's ntp version */
if (PKT_VERSION(rpkt->li_vn_mode) < NTP_OLDVERSION ||
PKT_VERSION(rpkt->li_vn_mode) > NTP_VERSION) {
- if (debug)
- printf("sntp %s: Packet shows wrong version (%i)\n",
- func_name, PKT_VERSION(rpkt->li_vn_mode));
+ msyslog(LOG_ERR,
+ "%s: Packet shows wrong version (%i)",
+ func_name, PKT_VERSION(rpkt->li_vn_mode));
return SERVER_UNUSEABLE;
}
/* We want a server to sync with */
if (PKT_MODE(rpkt->li_vn_mode) != mode &&
PKT_MODE(rpkt->li_vn_mode) != MODE_PASSIVE) {
- if (debug)
- printf("sntp %s: mode %d stratum %i\n", func_name,
- PKT_MODE(rpkt->li_vn_mode), rpkt->stratum);
+ msyslog(LOG_ERR,
+ "%s: mode %d stratum %i", func_name,
+ PKT_MODE(rpkt->li_vn_mode), rpkt->stratum);
return SERVER_UNUSEABLE;
}
/* Stratum is unspecified (0) check what's going on */
if (STRATUM_PKT_UNSPEC == rpkt->stratum) {
char *ref_char;
- if (debug)
- printf("sntp %s: Stratum unspecified, going to check for KOD (stratum: %i)\n",
- func_name, rpkt->stratum);
+ DPRINTF(1, ("%s: Stratum unspecified, going to check for KOD (stratum: %i)\n",
+ func_name, rpkt->stratum));
ref_char = (char *) &rpkt->refid;
- if (debug)
- printf("sntp %s: Packet refid: %c%c%c%c\n", func_name,
- ref_char[0], ref_char[1], ref_char[2], ref_char[3]);
+ DPRINTF(1, ("%s: Packet refid: %c%c%c%c\n", func_name,
+ ref_char[0], ref_char[1], ref_char[2], ref_char[3]));
/* If it's a KOD packet we'll just use the KOD information */
if (ref_char[0] != 'X') {
if (strncmp(ref_char, "DENY", 4) == 0)
}
/* If the server is not synced it's not really useable for us */
if (LEAP_NOTINSYNC == PKT_LEAP(rpkt->li_vn_mode)) {
- if (debug)
- printf("sntp %s: Server not in sync, skipping this server\n", func_name);
+ msyslog(LOG_ERR,
+ "%s: Server not in sync, skipping this server", func_name);
return SERVER_UNUSEABLE;
}
l_fp_output(&spkt->xmt, stdout);
#endif
if (mode != MODE_BROADCAST && !L_ISEQU(&rpkt->org, &spkt->xmt)) {
- if (debug)
- printf("sntp process_pkt: pkt.org and peer.xmt differ\n");
+ msyslog(LOG_ERR,
+ "process_pkt: pkt.org and peer.xmt differ");
return PACKET_UNUSEABLE;
}