printf("found request in tables\n");
#endif
- if (temp_size != proc->sizeofitem && temp_size != proc->v6_sizeofitem){
+ /*
+ * If we need data, check to see if we have some. If we
+ * don't, check to see that there is none (picky, picky).
+ */
+
+ /* This part is a bit tricky, we want to be sure that the size
+ * returned is either the old or the new size. We also can find
+ * out if the client can accept both types of messages this way.
++ *
++ * Handle the exception of REQ_CONFIG. It can have two data sizes.
+ */
+ temp_size = INFO_ITEMSIZE(inpkt->mbz_itemsize);
++ if ((temp_size != proc->sizeofitem &&
++ temp_size != proc->v6_sizeofitem) &&
++ !(inpkt->implementation == IMPL_XNTPD &&
++ inpkt->request == REQ_CONFIG &&
++ temp_size == sizeof(struct old_conf_peer))) {
+ if (debug > 2)
+ printf("process_private: wrong item size, received %d, should be %d or %d\n",
+ temp_size, proc->sizeofitem, proc->v6_sizeofitem);
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+ if ((proc->sizeofitem != 0) &&
+ ((temp_size * INFO_NITEMS(inpkt->err_nitems)) >
+ (rbufp->recv_length - REQ_LEN_HDR))) {
+ if (debug > 2)
+ printf("process_private: not enough data\n");
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ switch (inpkt->implementation) {
+ case IMPL_XNTPD:
+ client_v6_capable = 1;
+ break;
+ case IMPL_XNTPD_OLD:
+ client_v6_capable = 0;
+ break;
+ default:
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
/*
* If we need to authenticate, do so. Note that an
* authenticatable packet must include a mac field, must
/*
* So far so good. See if decryption works out okay.
*/
- printf("process_private: rbufp->recv_length %d\n",
- rbufp->recv_length);
- printf("process_private: l1 %d, l2 %d, l3 %d, l4 %d\n",
- rbufp->recv_length - sizeof(*tailinpkt),
- sizeof(struct req_pkt_tail),
- REQ_LEN_NOMAC,
- (int)(rbufp->recv_length - REQ_LEN_NOMAC));
if (!authdecrypt(info_auth_keyid, (u_int32 *)inpkt,
- REQ_LEN_NOMAC, (int)(rbufp->recv_length - REQ_LEN_NOMAC))) {
+ rbufp->recv_length - sizeof(struct req_pkt_tail) +
+ REQ_LEN_HDR, sizeof(struct req_pkt_tail) - REQ_LEN_HDR)) {
req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
return;
}
struct req_pkt *inpkt
)
{
- register struct conf_peer *cp;
- u_int fl;
- struct conf_peer *cp;
- struct old_conf_peer *ocp;
+ int items;
- struct sockaddr_in peeraddr;
++ u_int fl;
++ struct conf_peer *cp;
+ struct conf_peer temp_cp;
- register int items;
+ struct sockaddr_storage peeraddr;
+ struct sockaddr_in tmp_clock;
- int fl;
/*
* Do a check of everything to see that it looks
* Looks okay, try it out
*/
items = INFO_NITEMS(inpkt->err_nitems);
- cp = (struct conf_peer *)inpkt->data;
- if (ocp)
- ocp = (struct old_conf_peer *)inpkt->data;
- memset((char *)&peeraddr, 0, sizeof(struct sockaddr_in));
- peeraddr.sin_family = AF_INET;
- peeraddr.sin_port = htons(NTP_PORT);
+ cp = (struct conf_peer *)inpkt->data;
- /*
- * Make sure the address is valid
- */
- if (
+ while (items-- > 0) {
+ memset(&temp_cp, 0, sizeof(struct conf_peer));
+ memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
+ memset((char *)&peeraddr, 0, sizeof(struct sockaddr_storage));
+
+ fl = 0;
+ if (temp_cp.flags & CONF_FLAG_AUTHENABLE)
+ fl |= FLAG_AUTHENABLE;
+ if (temp_cp.flags & CONF_FLAG_PREFER)
+ fl |= FLAG_PREFER;
+ if (temp_cp.flags & CONF_FLAG_BURST)
+ fl |= FLAG_BURST;
+ if (temp_cp.flags & CONF_FLAG_SKEY)
+ fl |= FLAG_SKEY;
+ if (client_v6_capable && temp_cp.v6_flag != 0) {
+ peeraddr.ss_family = AF_INET6;
+ GET_INADDR6(peeraddr) = temp_cp.peeraddr6;
+ } else {
+ peeraddr.ss_family = AF_INET;
+ GET_INADDR(peeraddr) = temp_cp.peeraddr;
+ /*
+ * Make sure the address is valid
+ */
+ tmp_clock = *CAST_V4(peeraddr);
+ if (
#ifdef REFCLOCK
- !ISREFCLOCKADR(&peeraddr) &&
+ !ISREFCLOCKADR(&tmp_clock) &&
#endif
- ISBADADR(&peeraddr)) {
-#ifdef REFCLOCK
- msyslog(LOG_ERR, "do_conf: !ISREFCLOCK && ISBADADR");
-#else
- msyslog(LOG_ERR, "do_conf: ISBADADR");
+ ISBADADR(&tmp_clock)) {
+ req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+ return;
+ }
+
+ }
+ NSRCPORT(&peeraddr) = htons(NTP_PORT);
+#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
+ peeraddr.ss_len = SOCKLEN(&peeraddr);
#endif
- req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
- return;
- }
- while (items-- > 0) {
- fl = 0;
- if (cp->flags & CONF_FLAG_AUTHENABLE)
- fl |= FLAG_AUTHENABLE;
- if (cp->flags & CONF_FLAG_PREFER)
- fl |= FLAG_PREFER;
- if (cp->flags & CONF_FLAG_NOSELECT)
- fl |= FLAG_NOSELECT;
- if (cp->flags & CONF_FLAG_BURST)
- fl |= FLAG_BURST;
- if (cp->flags & CONF_FLAG_IBURST)
- fl |= FLAG_IBURST;
- if (cp->flags & CONF_FLAG_SKEY)
- fl |= FLAG_SKEY;
- peeraddr.sin_addr.s_addr = cp->peeraddr;
/* XXX W2DO? minpoll/maxpoll arguments ??? */
- if (peer_config(&peeraddr, any_interface, cp->hmode,
- cp->version, cp->minpoll, cp->maxpoll, fl, cp->ttl,
- cp->keyid, NULL) == 0) {
+ if (peer_config(&peeraddr, (struct interface *)0,
- temp_cp.hmode, temp_cp.version, temp_cp.minpoll,
- temp_cp.maxpoll, fl, temp_cp.ttl, temp_cp.keyid,
- temp_cp.keystr) == 0) {
++ temp_cp.hmode, temp_cp.version, temp_cp.minpoll,
++ temp_cp.maxpoll, fl, temp_cp.ttl, temp_cp.keyid,
++ NULL) == 0) {
req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
return;
}
cpeer.flags = (u_char)flags;
cpeer.ttl = cmode;
- res = doquery(IMPL_XNTPD, REQ_CONFIG, 1, 1,
- sizeof(struct conf_peer), (char *)&cpeer, &items,
- &itemsize, &dummy, 0);
+ res = doquery(impl_ver, REQ_CONFIG, 1, 1,
+ sendsize, (char *)&cpeer, &items,
+ &itemsize, &dummy, 0, sizeof(struct conf_peer));
- &items, &itemsize, &dummy, 0);
+ if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
+ impl_ver = IMPL_XNTPD_OLD;
+ goto again;
+ }
+
+ if (res == INFO_ERR_FMT) {
+ (void) fprintf(fp,
+ "***Retrying command with old conf_peer size\n");
+ res = doquery(IMPL_XNTPD, REQ_CONFIG, 1, 1,
+ sizeof(struct old_conf_peer), (char *)&cpeer,
++ &items, &itemsize, &dummy, 0,
++ sizeof(struct conf_peer));
+ }
if (res == 0)
(void) fprintf(fp, "done!\n");
return;