From: John Hay Date: Fri, 4 Jan 2002 08:02:57 +0000 (+0200) Subject: merge (x)ntpdc compatibilty changes. X-Git-Tag: NTP_4_1_73~205 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=98b8f3b8fe9bd41ab87f0f376bd90f821fcf5a86;p=thirdparty%2Fntp.git merge (x)ntpdc compatibilty changes. bk: 3c3561b1skanBTQ67Q52IMFp4Eoggg --- 98b8f3b8fe9bd41ab87f0f376bd90f821fcf5a86 diff --cc ntpd/ntp_request.c index 18f66f0f06,9d8d1d4d38..564361f1fc --- a/ntpd/ntp_request.c +++ b/ntpd/ntp_request.c @@@ -475,44 -451,6 +475,50 @@@ process_private printf("found request in tables\n"); #endif + /* + * 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){ ++ 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 @@@ -587,8 -526,16 +594,9 @@@ /* * 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; } @@@ -1293,12 -1157,11 +1301,12 @@@ do_conf 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 @@@ -1334,52 -1204,49 +1342,52 @@@ * 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; } diff --cc ntpdc/ntpdc_ops.c index 743430e6f9,b1634017c9..f6416abfd0 --- a/ntpdc/ntpdc_ops.c +++ b/ntpdc/ntpdc_ops.c @@@ -1380,15 -1170,17 +1380,23 @@@ again 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)); + 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); ++ &items, &itemsize, &dummy, 0, ++ sizeof(struct conf_peer)); + } if (res == 0) (void) fprintf(fp, "done!\n"); return;