Changeset View
Changeset View
Standalone View
Standalone View
head/contrib/ntp/ntpd/ntp_proto.c
Show All 9 Lines | |||||
#include "ntpd.h" | #include "ntpd.h" | ||||
#include "ntp_stdlib.h" | #include "ntp_stdlib.h" | ||||
#include "ntp_unixtime.h" | #include "ntp_unixtime.h" | ||||
#include "ntp_control.h" | #include "ntp_control.h" | ||||
#include "ntp_string.h" | #include "ntp_string.h" | ||||
#include "ntp_leapsec.h" | #include "ntp_leapsec.h" | ||||
#include "refidsmear.h" | #include "refidsmear.h" | ||||
#include "lib_strbuf.h" | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#ifdef HAVE_LIBSCF_H | #ifdef HAVE_LIBSCF_H | ||||
#include <libscf.h> | #include <libscf.h> | ||||
#endif | #endif | ||||
#ifdef HAVE_UNISTD_H | #ifdef HAVE_UNISTD_H | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 141 Lines • ▼ Show 20 Lines | |||||
static int group_test (char *, char *); | static int group_test (char *, char *); | ||||
#endif /* AUTOKEY */ | #endif /* AUTOKEY */ | ||||
#ifdef WORKER | #ifdef WORKER | ||||
void pool_name_resolved (int, int, void *, const char *, | void pool_name_resolved (int, int, void *, const char *, | ||||
const char *, const struct addrinfo *, | const char *, const struct addrinfo *, | ||||
const struct addrinfo *); | const struct addrinfo *); | ||||
#endif /* WORKER */ | #endif /* WORKER */ | ||||
const char * amtoa (int am); | |||||
void | void | ||||
set_sys_leap(u_char new_sys_leap) { | set_sys_leap( | ||||
u_char new_sys_leap | |||||
) | |||||
{ | |||||
sys_leap = new_sys_leap; | sys_leap = new_sys_leap; | ||||
xmt_leap = sys_leap; | xmt_leap = sys_leap; | ||||
/* | /* | ||||
* Under certain conditions we send faked leap bits to clients, so | * Under certain conditions we send faked leap bits to clients, so | ||||
* eventually change xmt_leap below, but never change LEAP_NOTINSYNC. | * eventually change xmt_leap below, but never change LEAP_NOTINSYNC. | ||||
*/ | */ | ||||
if (xmt_leap != LEAP_NOTINSYNC) { | if (xmt_leap != LEAP_NOTINSYNC) { | ||||
if (leap_sec_in_progress) { | if (leap_sec_in_progress) { | ||||
/* always send "not sync" */ | /* always send "not sync" */ | ||||
xmt_leap = LEAP_NOTINSYNC; | xmt_leap = LEAP_NOTINSYNC; | ||||
} | } | ||||
#ifdef LEAP_SMEAR | #ifdef LEAP_SMEAR | ||||
else { | else { | ||||
/* | /* | ||||
* If leap smear is enabled in general we must never send a leap second warning | * If leap smear is enabled in general we must | ||||
* to clients, so make sure we only send "in sync". | * never send a leap second warning to clients, | ||||
* so make sure we only send "in sync". | |||||
*/ | */ | ||||
if (leap_smear.enabled) | if (leap_smear.enabled) | ||||
xmt_leap = LEAP_NOWARNING; | xmt_leap = LEAP_NOWARNING; | ||||
} | } | ||||
#endif /* LEAP_SMEAR */ | #endif /* LEAP_SMEAR */ | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Kiss Code check | * Kiss Code check | ||||
*/ | */ | ||||
int kiss_code_check(u_char hisleap, u_char hisstratum, u_char hismode, u_int32 refid) { | int | ||||
kiss_code_check( | |||||
u_char hisleap, | |||||
u_char hisstratum, | |||||
u_char hismode, | |||||
u_int32 refid | |||||
) | |||||
{ | |||||
if ( hismode == MODE_SERVER | if ( hismode == MODE_SERVER | ||||
&& hisleap == LEAP_NOTINSYNC | && hisleap == LEAP_NOTINSYNC | ||||
&& hisstratum == STRATUM_UNSPEC) { | && hisstratum == STRATUM_UNSPEC) { | ||||
if(memcmp(&refid,"RATE", 4) == 0) { | if(memcmp(&refid,"RATE", 4) == 0) { | ||||
return (RATEKISS); | return (RATEKISS); | ||||
} | } else if(memcmp(&refid,"DENY", 4) == 0) { | ||||
else if(memcmp(&refid,"DENY", 4) == 0) { | |||||
return (DENYKISS); | return (DENYKISS); | ||||
} | } else if(memcmp(&refid,"RSTR", 4) == 0) { | ||||
else if(memcmp(&refid,"RSTR", 4) == 0) { | |||||
return (RSTRKISS); | return (RSTRKISS); | ||||
} | } else if(memcmp(&refid,"X", 1) == 0) { | ||||
else if(memcmp(&refid,"X", 1) == 0) { | |||||
return (XKISS); | return (XKISS); | ||||
} | } else { | ||||
else { | |||||
return (UNKNOWNKISS); | return (UNKNOWNKISS); | ||||
} | } | ||||
} | } else { | ||||
else { | |||||
return (NOKISS); | return (NOKISS); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* transmit - transmit procedure called by poll timeout | * transmit - transmit procedure called by poll timeout | ||||
*/ | */ | ||||
void | void | ||||
transmit( | transmit( | ||||
struct peer *peer /* peer structure pointer */ | struct peer *peer /* peer structure pointer */ | ||||
) | ) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | transmit( | ||||
* resulted in 60 associations without the hard limit. A | * resulted in 60 associations without the hard limit. A | ||||
* similar hard limit on manycastclient ephemeral associations | * similar hard limit on manycastclient ephemeral associations | ||||
* may be appropriate. | * may be appropriate. | ||||
*/ | */ | ||||
if (peer->cast_flags & MDF_POOL) { | if (peer->cast_flags & MDF_POOL) { | ||||
peer->outdate = current_time; | peer->outdate = current_time; | ||||
if ( (peer_associations <= 2 * sys_maxclock) | if ( (peer_associations <= 2 * sys_maxclock) | ||||
&& ( peer_associations < sys_maxclock | && ( peer_associations < sys_maxclock | ||||
|| sys_survivors < sys_minclock)) | || sys_survivors < sys_minclock)) | ||||
pool_xmit(peer); | pool_xmit(peer); | ||||
poll_update(peer, hpoll); | poll_update(peer, hpoll); | ||||
return; | return; | ||||
} | } | ||||
/* | /* | ||||
* In unicast modes the dance is much more intricate. It is | * In unicast modes the dance is much more intricate. It is | ||||
* designed to back off whenever possible to minimize network | * designed to back off whenever possible to minimize network | ||||
▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | if (peer->retry > 0) | ||||
peer->retry--; | peer->retry--; | ||||
/* | /* | ||||
* Do not transmit if in broadcast client mode. | * Do not transmit if in broadcast client mode. | ||||
*/ | */ | ||||
if (peer->hmode != MODE_BCLIENT) | if (peer->hmode != MODE_BCLIENT) | ||||
peer_xmit(peer); | peer_xmit(peer); | ||||
poll_update(peer, hpoll); | poll_update(peer, hpoll); | ||||
return; | |||||
} | } | ||||
const char * | |||||
amtoa( | |||||
int am | |||||
) | |||||
{ | |||||
char *bp; | |||||
switch(am) { | |||||
case AM_ERR: return "AM_ERR"; | |||||
case AM_NOMATCH: return "AM_NOMATCH"; | |||||
case AM_PROCPKT: return "AM_PROCPKT"; | |||||
case AM_BCST: return "AM_BCST"; | |||||
case AM_FXMIT: return "AM_FXMIT"; | |||||
case AM_MANYCAST: return "AM_MANYCAST"; | |||||
case AM_NEWPASS: return "AM_NEWPASS"; | |||||
case AM_NEWBCL: return "AM_NEWBCL"; | |||||
case AM_POSSBCL: return "AM_POSSBCL"; | |||||
default: | |||||
LIB_GETBUF(bp); | |||||
snprintf(bp, LIB_BUFLENGTH, "AM_#%d", am); | |||||
return bp; | |||||
} | |||||
} | |||||
/* | /* | ||||
* receive - receive procedure called for each packet received | * receive - receive procedure called for each packet received | ||||
*/ | */ | ||||
void | void | ||||
receive( | receive( | ||||
struct recvbuf *rbufp | struct recvbuf *rbufp | ||||
) | ) | ||||
{ | { | ||||
register struct peer *peer; /* peer structure pointer */ | register struct peer *peer; /* peer structure pointer */ | ||||
register struct pkt *pkt; /* receive packet pointer */ | register struct pkt *pkt; /* receive packet pointer */ | ||||
u_char hisversion; /* packet version */ | u_char hisversion; /* packet version */ | ||||
u_char hisleap; /* packet leap indicator */ | u_char hisleap; /* packet leap indicator */ | ||||
u_char hismode; /* packet mode */ | u_char hismode; /* packet mode */ | ||||
u_char hisstratum; /* packet stratum */ | u_char hisstratum; /* packet stratum */ | ||||
u_short restrict_mask; /* restrict bits */ | u_short restrict_mask; /* restrict bits */ | ||||
const char *hm_str; /* hismode string */ | |||||
const char *am_str; /* association match string */ | |||||
int kissCode = NOKISS; /* Kiss Code */ | int kissCode = NOKISS; /* Kiss Code */ | ||||
int has_mac; /* length of MAC field */ | int has_mac; /* length of MAC field */ | ||||
int authlen; /* offset of MAC field */ | int authlen; /* offset of MAC field */ | ||||
int is_authentic = 0; /* cryptosum ok */ | int is_authentic = 0; /* cryptosum ok */ | ||||
int retcode = AM_NOMATCH; /* match code */ | int retcode = AM_NOMATCH; /* match code */ | ||||
keyid_t skeyid = 0; /* key IDs */ | keyid_t skeyid = 0; /* key IDs */ | ||||
u_int32 opcode = 0; /* extension field opcode */ | u_int32 opcode = 0; /* extension field opcode */ | ||||
sockaddr_u *dstadr_sin; /* active runway */ | sockaddr_u *dstadr_sin; /* active runway */ | ||||
struct peer *peer2; /* aux peer structure pointer */ | struct peer *peer2; /* aux peer structure pointer */ | ||||
endpt * match_ep; /* newpeer() local address */ | endpt *match_ep; /* newpeer() local address */ | ||||
l_fp p_org; /* origin timestamp */ | l_fp p_org; /* origin timestamp */ | ||||
l_fp p_rec; /* receive timestamp */ | l_fp p_rec; /* receive timestamp */ | ||||
l_fp p_xmt; /* transmit timestamp */ | l_fp p_xmt; /* transmit timestamp */ | ||||
#ifdef AUTOKEY | #ifdef AUTOKEY | ||||
char hostname[NTP_MAXSTRLEN + 1]; | char hostname[NTP_MAXSTRLEN + 1]; | ||||
char *groupname = NULL; | char *groupname = NULL; | ||||
struct autokey *ap; /* autokey structure pointer */ | struct autokey *ap; /* autokey structure pointer */ | ||||
int rval; /* cookie snatcher */ | int rval; /* cookie snatcher */ | ||||
Show All 14 Lines | #endif /* HAVE_NTP_SIGND */ | ||||
* reveals a clogging attack. | * reveals a clogging attack. | ||||
*/ | */ | ||||
sys_received++; | sys_received++; | ||||
if (0 == SRCPORT(&rbufp->recv_srcadr)) { | if (0 == SRCPORT(&rbufp->recv_srcadr)) { | ||||
sys_badlength++; | sys_badlength++; | ||||
return; /* bogus port */ | return; /* bogus port */ | ||||
} | } | ||||
restrict_mask = restrictions(&rbufp->recv_srcadr); | restrict_mask = restrictions(&rbufp->recv_srcadr); | ||||
DPRINTF(2, ("receive: at %ld %s<-%s flags %x restrict %03x\n", | |||||
current_time, stoa(&rbufp->dstadr->sin), | |||||
stoa(&rbufp->recv_srcadr), | |||||
rbufp->dstadr->flags, restrict_mask)); | |||||
pkt = &rbufp->recv_pkt; | pkt = &rbufp->recv_pkt; | ||||
DPRINTF(2, ("receive: at %ld %s<-%s flags %x restrict %03x org %#010x.%08x xmt %#010x.%08x\n", | |||||
current_time, stoa(&rbufp->dstadr->sin), | |||||
stoa(&rbufp->recv_srcadr), rbufp->dstadr->flags, | |||||
restrict_mask, ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf), | |||||
ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf))); | |||||
hisversion = PKT_VERSION(pkt->li_vn_mode); | hisversion = PKT_VERSION(pkt->li_vn_mode); | ||||
hisleap = PKT_LEAP(pkt->li_vn_mode); | hisleap = PKT_LEAP(pkt->li_vn_mode); | ||||
hismode = (int)PKT_MODE(pkt->li_vn_mode); | hismode = (int)PKT_MODE(pkt->li_vn_mode); | ||||
hisstratum = PKT_TO_STRATUM(pkt->stratum); | hisstratum = PKT_TO_STRATUM(pkt->stratum); | ||||
if (restrict_mask & RES_IGNORE) { | if (restrict_mask & RES_IGNORE) { | ||||
sys_restricted++; | sys_restricted++; | ||||
return; /* ignore everything */ | return; /* ignore everything */ | ||||
} | } | ||||
▲ Show 20 Lines • Show All 190 Lines • ▼ Show 20 Lines | #endif /* AUTOKEY */ | ||||
* multicaster, the broadcast address is null, so we use the | * multicaster, the broadcast address is null, so we use the | ||||
* unicast address anyway. Don't ask. | * unicast address anyway. Don't ask. | ||||
*/ | */ | ||||
peer = findpeer(rbufp, hismode, &retcode); | peer = findpeer(rbufp, hismode, &retcode); | ||||
dstadr_sin = &rbufp->dstadr->sin; | dstadr_sin = &rbufp->dstadr->sin; | ||||
NTOHL_FP(&pkt->org, &p_org); | NTOHL_FP(&pkt->org, &p_org); | ||||
NTOHL_FP(&pkt->rec, &p_rec); | NTOHL_FP(&pkt->rec, &p_rec); | ||||
NTOHL_FP(&pkt->xmt, &p_xmt); | NTOHL_FP(&pkt->xmt, &p_xmt); | ||||
hm_str = modetoa(hismode); | |||||
am_str = amtoa(retcode); | |||||
/* | /* | ||||
* Authentication is conditioned by three switches: | * Authentication is conditioned by three switches: | ||||
* | * | ||||
* NOPEER (RES_NOPEER) do not mobilize an association unless | * NOPEER (RES_NOPEER) do not mobilize an association unless | ||||
* authenticated | * authenticated | ||||
* NOTRUST (RES_DONTTRUST) do not allow access unless | * NOTRUST (RES_DONTTRUST) do not allow access unless | ||||
* authenticated (implies NOPEER) | * authenticated (implies NOPEER) | ||||
Show All 12 Lines | #endif /* AUTOKEY */ | ||||
* Note: The AUTH(x, y) macro is used to filter outcomes. If x | * Note: The AUTH(x, y) macro is used to filter outcomes. If x | ||||
* is zero, acceptable outcomes of y are NONE and OK. If x is | * is zero, acceptable outcomes of y are NONE and OK. If x is | ||||
* one, the only acceptable outcome of y is OK. | * one, the only acceptable outcome of y is OK. | ||||
*/ | */ | ||||
if (has_mac == 0) { | if (has_mac == 0) { | ||||
restrict_mask &= ~RES_MSSNTP; | restrict_mask &= ~RES_MSSNTP; | ||||
is_authentic = AUTH_NONE; /* not required */ | is_authentic = AUTH_NONE; /* not required */ | ||||
#ifdef DEBUG | DPRINTF(2, ("receive: at %ld %s<-%s mode %d/%s:%s len %d org %#010x.%08x xmt %#010x.%08x NOMAC\n", | ||||
if (debug) | |||||
printf( | |||||
"receive: at %ld %s<-%s mode %d len %d\n", | |||||
current_time, stoa(dstadr_sin), | current_time, stoa(dstadr_sin), | ||||
stoa(&rbufp->recv_srcadr), hismode, | stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str, | ||||
authlen); | authlen, | ||||
#endif | ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf), | ||||
ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf))); | |||||
} else if (has_mac == 4) { | } else if (has_mac == 4) { | ||||
restrict_mask &= ~RES_MSSNTP; | restrict_mask &= ~RES_MSSNTP; | ||||
is_authentic = AUTH_CRYPTO; /* crypto-NAK */ | is_authentic = AUTH_CRYPTO; /* crypto-NAK */ | ||||
#ifdef DEBUG | DPRINTF(2, ("receive: at %ld %s<-%s mode %d/%s:%s keyid %08x len %d auth %d org %#010x.%08x xmt %#010x.%08x MAC4\n", | ||||
if (debug) | |||||
printf( | |||||
"receive: at %ld %s<-%s mode %d keyid %08x len %d auth %d\n", | |||||
current_time, stoa(dstadr_sin), | current_time, stoa(dstadr_sin), | ||||
stoa(&rbufp->recv_srcadr), hismode, skeyid, | stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str, | ||||
authlen + has_mac, is_authentic); | skeyid, authlen + has_mac, is_authentic, | ||||
#endif | ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf), | ||||
ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf))); | |||||
#ifdef HAVE_NTP_SIGND | #ifdef HAVE_NTP_SIGND | ||||
/* | /* | ||||
* If the signature is 20 bytes long, the last 16 of | * If the signature is 20 bytes long, the last 16 of | ||||
* which are zero, then this is a Microsoft client | * which are zero, then this is a Microsoft client | ||||
* wanting AD-style authentication of the server's | * wanting AD-style authentication of the server's | ||||
* reply. | * reply. | ||||
* | * | ||||
* This is described in Microsoft's WSPP docs, in MS-SNTP: | * This is described in Microsoft's WSPP docs, in MS-SNTP: | ||||
* http://msdn.microsoft.com/en-us/library/cc212930.aspx | * http://msdn.microsoft.com/en-us/library/cc212930.aspx | ||||
*/ | */ | ||||
} else if ( has_mac == MAX_MD5_LEN | } else if ( has_mac == MAX_MD5_LEN | ||||
&& (restrict_mask & RES_MSSNTP) | && (restrict_mask & RES_MSSNTP) | ||||
&& (retcode == AM_FXMIT || retcode == AM_NEWPASS) | && (retcode == AM_FXMIT || retcode == AM_NEWPASS) | ||||
&& (memcmp(zero_key, (char *)pkt + authlen + 4, | && (memcmp(zero_key, (char *)pkt + authlen + 4, | ||||
MAX_MD5_LEN - 4) == 0)) { | MAX_MD5_LEN - 4) == 0)) { | ||||
is_authentic = AUTH_NONE; | is_authentic = AUTH_NONE; | ||||
#endif /* HAVE_NTP_SIGND */ | #endif /* HAVE_NTP_SIGND */ | ||||
} else { | } else { | ||||
restrict_mask &= ~RES_MSSNTP; | restrict_mask &= ~RES_MSSNTP; | ||||
#ifdef AUTOKEY | #ifdef AUTOKEY | ||||
/* | /* | ||||
* For autokey modes, generate the session key | * For autokey modes, generate the session key | ||||
▲ Show 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | if (!authdecrypt(skeyid, (u_int32 *)pkt, authlen, | ||||
has_mac)) | has_mac)) | ||||
is_authentic = AUTH_ERROR; | is_authentic = AUTH_ERROR; | ||||
else | else | ||||
is_authentic = AUTH_OK; | is_authentic = AUTH_OK; | ||||
#ifdef AUTOKEY | #ifdef AUTOKEY | ||||
if (crypto_flags && skeyid > NTP_MAXKEY) | if (crypto_flags && skeyid > NTP_MAXKEY) | ||||
authtrust(skeyid, 0); | authtrust(skeyid, 0); | ||||
#endif /* AUTOKEY */ | #endif /* AUTOKEY */ | ||||
#ifdef DEBUG | DPRINTF(2, ("receive: at %ld %s<-%s mode %d/%s:%s keyid %08x len %d auth %d org %#010x.%08x xmt %#010x.%08x\n", | ||||
if (debug) | |||||
printf( | |||||
"receive: at %ld %s<-%s mode %d keyid %08x len %d auth %d\n", | |||||
current_time, stoa(dstadr_sin), | current_time, stoa(dstadr_sin), | ||||
stoa(&rbufp->recv_srcadr), hismode, skeyid, | stoa(&rbufp->recv_srcadr), hismode, hm_str, am_str, | ||||
authlen + has_mac, is_authentic); | skeyid, authlen + has_mac, is_authentic, | ||||
#endif | ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf), | ||||
ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf))); | |||||
} | } | ||||
/* | /* | ||||
* The association matching rules are implemented by a set of | * The association matching rules are implemented by a set of | ||||
* routines and an association table. A packet matching an | * routines and an association table. A packet matching an | ||||
* association is processed by the peer process for that | * association is processed by the peer process for that | ||||
* association. If there are no errors, an ephemeral association | * association. If there are no errors, an ephemeral association | ||||
* is mobilized: a broadcast packet mobilizes a broadcast client | * is mobilized: a broadcast packet mobilizes a broadcast client | ||||
▲ Show 20 Lines • Show All 314 Lines • ▼ Show 20 Lines | if (!AUTH(sys_authenticate | (restrict_mask & | ||||
* authenticated, and it didn't meet either of | * authenticated, and it didn't meet either of | ||||
* the previous two special cases so we should | * the previous two special cases so we should | ||||
* just drop it on the floor. For example, | * just drop it on the floor. For example, | ||||
* crypto-NAKs (is_authentic == AUTH_CRYPTO) | * crypto-NAKs (is_authentic == AUTH_CRYPTO) | ||||
* will make it this far. This is just | * will make it this far. This is just | ||||
* debug-printed and not logged to avoid log | * debug-printed and not logged to avoid log | ||||
* flooding. | * flooding. | ||||
*/ | */ | ||||
DPRINTF(1, ("receive: at %ld refusing to mobilize passive association" | DPRINTF(2, ("receive: at %ld refusing to mobilize passive association" | ||||
" with unknown peer %s mode %d keyid %08x len %d auth %d\n", | " with unknown peer %s mode %d/%s:%s keyid %08x len %d auth %d\n", | ||||
current_time, stoa(&rbufp->recv_srcadr), | current_time, stoa(&rbufp->recv_srcadr), | ||||
hismode, skeyid, (authlen + has_mac), | hismode, hm_str, am_str, skeyid, | ||||
is_authentic)); | (authlen + has_mac), is_authentic)); | ||||
sys_declined++; | sys_declined++; | ||||
return; | return; | ||||
} | } | ||||
/* | /* | ||||
* Do not respond if synchronized and if stratum is | * Do not respond if synchronized and if stratum is | ||||
* below the floor or at or above the ceiling. Note, | * below the floor or at or above the ceiling. Note, | ||||
* this allows an unsynchronized peer to synchronize to | * this allows an unsynchronized peer to synchronize to | ||||
▲ Show 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | if (!L_ISZERO(&p_org) && !(peer->flags & FLAG_XB)) { | ||||
peer->flags |= FLAG_XB; | peer->flags |= FLAG_XB; | ||||
peer->aorg = p_xmt; | peer->aorg = p_xmt; | ||||
peer->borg = rbufp->recv_time; | peer->borg = rbufp->recv_time; | ||||
report_event(PEVNT_XLEAVE, peer, NULL); | report_event(PEVNT_XLEAVE, peer, NULL); | ||||
return; | return; | ||||
} | } | ||||
/* | /* | ||||
* Check for bogus packet in basic mode. If found, switch to | * Basic mode checks: | ||||
* interleaved mode and resynchronize, but only after confirming | |||||
* the packet is not bogus in symmetric interleaved mode. | |||||
* | * | ||||
* If there is no origin timestamp, it's an initial packet. | |||||
* | |||||
* Otherwise, check for bogus packet in basic mode. | |||||
* If it is bogus, switch to interleaved mode and resynchronize, | |||||
* but only after confirming the packet is not bogus in | |||||
* symmetric interleaved mode. | |||||
* | |||||
* This could also mean somebody is forging packets claiming to | * This could also mean somebody is forging packets claiming to | ||||
* be from us, attempting to cause our server to KoD us. | * be from us, attempting to cause our server to KoD us. | ||||
*/ | */ | ||||
} else if (peer->flip == 0) { | } else if (peer->flip == 0) { | ||||
if (!L_ISEQU(&p_org, &peer->aorg)) { | if (0 < hisstratum && L_ISZERO(&p_org)) { | ||||
L_CLR(&peer->aorg); | |||||
} else if (!L_ISEQU(&p_org, &peer->aorg)) { | |||||
peer->bogusorg++; | peer->bogusorg++; | ||||
peer->flash |= TEST2; /* bogus */ | peer->flash |= TEST2; /* bogus */ | ||||
msyslog(LOG_INFO, | msyslog(LOG_INFO, | ||||
"receive: Unexpected origin timestamp from %s", | "receive: Unexpected origin timestamp %#010x.%08x from %s xmt %#010x.%08x", | ||||
ntoa(&peer->srcadr)); | ntohl(pkt->org.l_ui), ntohl(pkt->org.l_uf), | ||||
ntoa(&peer->srcadr), | |||||
ntohl(pkt->xmt.l_ui), ntohl(pkt->xmt.l_uf)); | |||||
if ( !L_ISZERO(&peer->dst) | if ( !L_ISZERO(&peer->dst) | ||||
&& L_ISEQU(&p_org, &peer->dst)) { | && L_ISEQU(&p_org, &peer->dst)) { | ||||
/* Might be the start of an interleave */ | |||||
peer->flip = 1; | peer->flip = 1; | ||||
report_event(PEVNT_XLEAVE, peer, NULL); | report_event(PEVNT_XLEAVE, peer, NULL); | ||||
} | } | ||||
return; /* Bogus packet, we are done */ | return; /* Bogus or possible interleave packet */ | ||||
} else { | } else { | ||||
L_CLR(&peer->aorg); | L_CLR(&peer->aorg); | ||||
} | } | ||||
/* | /* | ||||
* Check for valid nonzero timestamp fields. | * Check for valid nonzero timestamp fields. | ||||
*/ | */ | ||||
} else if (L_ISZERO(&p_org) || L_ISZERO(&p_rec) || | } else if (L_ISZERO(&p_org) || L_ISZERO(&p_rec) || | ||||
▲ Show 20 Lines • Show All 337 Lines • ▼ Show 20 Lines | #endif /* ASSYM */ | ||||
/* | /* | ||||
* If any tests fail at this point, the packet is discarded. | * If any tests fail at this point, the packet is discarded. | ||||
* Note that some flashers may have already been set in the | * Note that some flashers may have already been set in the | ||||
* receive() routine. | * receive() routine. | ||||
*/ | */ | ||||
if (peer->flash & PKT_TEST_MASK) { | if (peer->flash & PKT_TEST_MASK) { | ||||
peer->seldisptoolarge++; | peer->seldisptoolarge++; | ||||
#ifdef DEBUG | DPRINTF(1, ("packet: flash header %04x\n", | ||||
if (debug) | peer->flash)); | ||||
printf("packet: flash header %04x\n", | |||||
peer->flash); | |||||
#endif | |||||
return; | return; | ||||
} | } | ||||
/* | /* | ||||
* If the peer was previously unreachable, raise a trap. In any | * If the peer was previously unreachable, raise a trap. In any | ||||
* case, mark it reachable. | * case, mark it reachable. | ||||
*/ | */ | ||||
if (!peer->reach) { | if (!peer->reach) { | ||||
▲ Show 20 Lines • Show All 156 Lines • ▼ Show 20 Lines | #if ASSYM | ||||
/* | /* | ||||
* The following section compensates for different data rates on | * The following section compensates for different data rates on | ||||
* the outbound (d21) and inbound (t34) directions. To do this, | * the outbound (d21) and inbound (t34) directions. To do this, | ||||
* it finds t such that r21 * t - r34 * (d - t) = 0, where d is | * it finds t such that r21 * t - r34 * (d - t) = 0, where d is | ||||
* the roundtrip delay. Then it calculates the correction as a | * the roundtrip delay. Then it calculates the correction as a | ||||
* fraction of d. | * fraction of d. | ||||
*/ | */ | ||||
peer->t21 = t21; | peer->t21 = t21; | ||||
peer->t21_last = peer->t21_bytes; | peer->t21_last = peer->t21_bytes; | ||||
peer->t34 = -t34; | peer->t34 = -t34; | ||||
peer->t34_bytes = len; | peer->t34_bytes = len; | ||||
#ifdef DEBUG | DPRINTF(2, ("packet: t21 %.9lf %d t34 %.9lf %d\n", peer->t21, | ||||
if (debug > 1) | peer->t21_bytes, peer->t34, peer->t34_bytes)); | ||||
printf("packet: t21 %.9lf %d t34 %.9lf %d\n", peer->t21, | |||||
peer->t21_bytes, peer->t34, peer->t34_bytes); | |||||
#endif | |||||
if (peer->r21 > 0 && peer->r34 > 0 && p_del > 0) { | if (peer->r21 > 0 && peer->r34 > 0 && p_del > 0) { | ||||
if (peer->pmode != MODE_BROADCAST) | if (peer->pmode != MODE_BROADCAST) | ||||
td = (peer->r34 / (peer->r21 + peer->r34) - | td = (peer->r34 / (peer->r21 + peer->r34) - | ||||
.5) * p_del; | .5) * p_del; | ||||
else | else | ||||
td = 0; | td = 0; | ||||
/* | /* | ||||
* Unfortunately, in many cases the errors are | * Unfortunately, in many cases the errors are | ||||
* unacceptable, so for the present the rates are not | * unacceptable, so for the present the rates are not | ||||
* used. In future, we might find conditions where the | * used. In future, we might find conditions where the | ||||
* calculations are useful, so this should be considered | * calculations are useful, so this should be considered | ||||
* a work in progress. | * a work in progress. | ||||
*/ | */ | ||||
t21 -= td; | t21 -= td; | ||||
t34 -= td; | t34 -= td; | ||||
#ifdef DEBUG | DPRINTF(2, ("packet: del %.6lf r21 %.1lf r34 %.1lf %.6lf\n", | ||||
if (debug > 1) | |||||
printf("packet: del %.6lf r21 %.1lf r34 %.1lf %.6lf\n", | |||||
p_del, peer->r21 / 1e3, peer->r34 / 1e3, | p_del, peer->r21 / 1e3, peer->r34 / 1e3, | ||||
td); | td)); | ||||
#endif | |||||
} | } | ||||
#endif /* ASSYM */ | #endif /* ASSYM */ | ||||
/* | /* | ||||
* That was awesome. Now hand off to the clock filter. | * That was awesome. Now hand off to the clock filter. | ||||
*/ | */ | ||||
clock_filter(peer, p_offset + peer->bias, p_del, p_disp); | clock_filter(peer, p_offset + peer->bias, p_del, p_disp); | ||||
▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | #endif /* HAVE_LIBSCF_H */ | ||||
if (dtemp > sys_mindisp) | if (dtemp > sys_mindisp) | ||||
sys_rootdisp = dtemp; | sys_rootdisp = dtemp; | ||||
else | else | ||||
sys_rootdisp = sys_mindisp; | sys_rootdisp = sys_mindisp; | ||||
sys_rootdelay = peer->delay + peer->rootdelay; | sys_rootdelay = peer->delay + peer->rootdelay; | ||||
sys_reftime = peer->dst; | sys_reftime = peer->dst; | ||||
#ifdef DEBUG | DPRINTF(1, ("clock_update: at %lu sample %lu associd %d\n", | ||||
if (debug) | current_time, peer->epoch, peer->associd)); | ||||
printf( | |||||
"clock_update: at %lu sample %lu associd %d\n", | |||||
current_time, peer->epoch, peer->associd); | |||||
#endif | |||||
/* | /* | ||||
* Comes now the moment of truth. Crank the clock discipline and | * Comes now the moment of truth. Crank the clock discipline and | ||||
* see what comes out. | * see what comes out. | ||||
*/ | */ | ||||
switch (local_clock(peer, sys_offset)) { | switch (local_clock(peer, sys_offset)) { | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 292 Lines • ▼ Show 20 Lines | #endif | ||||
} else if (MODE_PASSIVE == peer->hmode) { | } else if (MODE_PASSIVE == peer->hmode) { | ||||
peer->nextdate += ntp_minpkt; | peer->nextdate += ntp_minpkt; | ||||
} else { | } else { | ||||
peer->nextdate += ntp_random() % peer->minpoll; | peer->nextdate += ntp_random() % peer->minpoll; | ||||
} | } | ||||
#ifdef AUTOKEY | #ifdef AUTOKEY | ||||
peer->refresh = current_time + (1 << NTP_REFRESH); | peer->refresh = current_time + (1 << NTP_REFRESH); | ||||
#endif /* AUTOKEY */ | #endif /* AUTOKEY */ | ||||
#ifdef DEBUG | DPRINTF(1, ("peer_clear: at %ld next %ld associd %d refid %s\n", | ||||
if (debug) | |||||
printf( | |||||
"peer_clear: at %ld next %ld associd %d refid %s\n", | |||||
current_time, peer->nextdate, peer->associd, | current_time, peer->nextdate, peer->associd, | ||||
ident); | ident)); | ||||
#endif | |||||
} | } | ||||
/* | /* | ||||
* clock_filter - add incoming clock sample to filter register and run | * clock_filter - add incoming clock sample to filter register and run | ||||
* the filter procedure to find the best sample. | * the filter procedure to find the best sample. | ||||
*/ | */ | ||||
void | void | ||||
▲ Show 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | clock_filter( | ||||
/* | /* | ||||
* A new minimum sample is useful only if it is later than the | * A new minimum sample is useful only if it is later than the | ||||
* last one used. In this design the maximum lifetime of any | * last one used. In this design the maximum lifetime of any | ||||
* sample is not greater than eight times the poll interval, so | * sample is not greater than eight times the poll interval, so | ||||
* the maximum interval between minimum samples is eight | * the maximum interval between minimum samples is eight | ||||
* packets. | * packets. | ||||
*/ | */ | ||||
if (peer->filter_epoch[k] <= peer->epoch) { | if (peer->filter_epoch[k] <= peer->epoch) { | ||||
#if DEBUG | DPRINTF(2, ("clock_filter: old sample %lu\n", current_time - | ||||
if (debug > 1) | peer->filter_epoch[k])); | ||||
printf("clock_filter: old sample %lu\n", current_time - | |||||
peer->filter_epoch[k]); | |||||
#endif | |||||
return; | return; | ||||
} | } | ||||
peer->epoch = peer->filter_epoch[k]; | peer->epoch = peer->filter_epoch[k]; | ||||
/* | /* | ||||
* The mitigated sample statistics are saved for later | * The mitigated sample statistics are saved for later | ||||
* processing. If not synchronized or not in a burst, tickle the | * processing. If not synchronized or not in a burst, tickle the | ||||
* clock select algorithm. | * clock select algorithm. | ||||
*/ | */ | ||||
record_peer_stats(&peer->srcadr, ctlpeerstatus(peer), | record_peer_stats(&peer->srcadr, ctlpeerstatus(peer), | ||||
peer->offset, peer->delay, peer->disp, peer->jitter); | peer->offset, peer->delay, peer->disp, peer->jitter); | ||||
#ifdef DEBUG | DPRINTF(1, ("clock_filter: n %d off %.6f del %.6f dsp %.6f jit %.6f\n", | ||||
if (debug) | |||||
printf( | |||||
"clock_filter: n %d off %.6f del %.6f dsp %.6f jit %.6f\n", | |||||
m, peer->offset, peer->delay, peer->disp, | m, peer->offset, peer->delay, peer->disp, | ||||
peer->jitter); | peer->jitter)); | ||||
#endif | |||||
if (peer->burst == 0 || sys_leap == LEAP_NOTINSYNC) | if (peer->burst == 0 || sys_leap == LEAP_NOTINSYNC) | ||||
clock_select(); | clock_select(); | ||||
} | } | ||||
/* | /* | ||||
* clock_select - find the pick-of-the-litter clock | * clock_select - find the pick-of-the-litter clock | ||||
* | * | ||||
▲ Show 20 Lines • Show All 487 Lines • ▼ Show 20 Lines | if ( typepps != NULL | ||||
&& fabs(sys_offset) < 0.4 | && fabs(sys_offset) < 0.4 | ||||
&& ( typepps->refclktype != REFCLK_ATOM_PPS | && ( typepps->refclktype != REFCLK_ATOM_PPS | ||||
|| ( typepps->refclktype == REFCLK_ATOM_PPS | || ( typepps->refclktype == REFCLK_ATOM_PPS | ||||
&& ( sys_prefer != NULL | && ( sys_prefer != NULL | ||||
|| (typesystem == NULL && sys_minsane == 0))))) { | || (typesystem == NULL && sys_minsane == 0))))) { | ||||
typesystem = typepps; | typesystem = typepps; | ||||
sys_clockhop = 0; | sys_clockhop = 0; | ||||
typesystem->new_status = CTL_PST_SEL_PPS; | typesystem->new_status = CTL_PST_SEL_PPS; | ||||
sys_offset = typesystem->offset; | sys_offset = typesystem->offset; | ||||
sys_jitter = typesystem->jitter; | sys_jitter = typesystem->jitter; | ||||
DPRINTF(1, ("select: pps offset %.9f jitter %.9f\n", | DPRINTF(1, ("select: pps offset %.9f jitter %.9f\n", | ||||
sys_offset, sys_jitter)); | sys_offset, sys_jitter)); | ||||
} | } | ||||
#endif /* REFCLOCK */ | #endif /* REFCLOCK */ | ||||
/* | /* | ||||
* If there are no survivors at this point, there is no | * If there are no survivors at this point, there is no | ||||
▲ Show 20 Lines • Show All 136 Lines • ▼ Show 20 Lines | peer_xmit( | ||||
* It is most important when autokey is in use that the local | * It is most important when autokey is in use that the local | ||||
* interface IP address be known before the first packet is | * interface IP address be known before the first packet is | ||||
* sent. Otherwise, it is not possible to compute a correct MAC | * sent. Otherwise, it is not possible to compute a correct MAC | ||||
* the recipient will accept. Thus, the I/O semantics have to do | * the recipient will accept. Thus, the I/O semantics have to do | ||||
* a little more work. In particular, the wildcard interface | * a little more work. In particular, the wildcard interface | ||||
* might not be usable. | * might not be usable. | ||||
*/ | */ | ||||
sendlen = LEN_PKT_NOMAC; | sendlen = LEN_PKT_NOMAC; | ||||
if ( | |||||
#ifdef AUTOKEY | #ifdef AUTOKEY | ||||
if (!(peer->flags & FLAG_SKEY) && peer->keyid == 0) { | !(peer->flags & FLAG_SKEY) && | ||||
#else /* !AUTOKEY follows */ | |||||
if (peer->keyid == 0) { | |||||
#endif /* !AUTOKEY */ | #endif /* !AUTOKEY */ | ||||
peer->keyid == 0) { | |||||
/* | /* | ||||
* Transmit a-priori timestamps | * Transmit a-priori timestamps | ||||
*/ | */ | ||||
get_systime(&xmt_tx); | get_systime(&xmt_tx); | ||||
if (peer->flip == 0) { /* basic mode */ | if (peer->flip == 0) { /* basic mode */ | ||||
peer->aorg = xmt_tx; | peer->aorg = xmt_tx; | ||||
HTONL_FP(&xmt_tx, &xpkt.xmt); | HTONL_FP(&xmt_tx, &xpkt.xmt); | ||||
Show All 29 Lines | if (peer->flip != 0) { /* interleaved modes */ | ||||
if (peer->flip > 0) | if (peer->flip > 0) | ||||
peer->aorg = xmt_ty; | peer->aorg = xmt_ty; | ||||
else | else | ||||
peer->borg = xmt_ty; | peer->borg = xmt_ty; | ||||
peer->flip = -peer->flip; | peer->flip = -peer->flip; | ||||
} | } | ||||
L_SUB(&xmt_ty, &xmt_tx); | L_SUB(&xmt_ty, &xmt_tx); | ||||
LFPTOD(&xmt_ty, peer->xleave); | LFPTOD(&xmt_ty, peer->xleave); | ||||
#ifdef DEBUG | DPRINTF(1, ("peer_xmit: at %ld %s->%s mode %d len %zu xmt %#010x.%08x\n", | ||||
if (debug) | current_time, | ||||
printf("transmit: at %ld %s->%s mode %d len %zu\n", | peer->dstadr ? stoa(&peer->dstadr->sin) : "-", | ||||
current_time, peer->dstadr ? | stoa(&peer->srcadr), peer->hmode, sendlen, | ||||
stoa(&peer->dstadr->sin) : "-", | xmt_tx.l_ui, xmt_tx.l_uf)); | ||||
stoa(&peer->srcadr), peer->hmode, sendlen); | |||||
#endif | |||||
return; | return; | ||||
} | } | ||||
/* | /* | ||||
* Authentication is enabled, so the transmitted packet must be | * Authentication is enabled, so the transmitted packet must be | ||||
* authenticated. If autokey is enabled, fuss with the various | * authenticated. If autokey is enabled, fuss with the various | ||||
* modes; otherwise, symmetric key cryptography is used. | * modes; otherwise, symmetric key cryptography is used. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 268 Lines • ▼ Show 20 Lines | if (authlen == 0) { | ||||
return; | return; | ||||
} | } | ||||
sendlen += authlen; | sendlen += authlen; | ||||
#ifdef AUTOKEY | #ifdef AUTOKEY | ||||
if (xkeyid > NTP_MAXKEY) | if (xkeyid > NTP_MAXKEY) | ||||
authtrust(xkeyid, 0); | authtrust(xkeyid, 0); | ||||
#endif /* AUTOKEY */ | #endif /* AUTOKEY */ | ||||
if (sendlen > sizeof(xpkt)) { | if (sendlen > sizeof(xpkt)) { | ||||
msyslog(LOG_ERR, "proto: buffer overflow %zu", sendlen); | msyslog(LOG_ERR, "peer_xmit: buffer overflow %zu", sendlen); | ||||
exit (-1); | exit (-1); | ||||
} | } | ||||
peer->t21_bytes = sendlen; | peer->t21_bytes = sendlen; | ||||
sendpkt(&peer->srcadr, peer->dstadr, sys_ttl[peer->ttl], &xpkt, | sendpkt(&peer->srcadr, peer->dstadr, sys_ttl[peer->ttl], &xpkt, | ||||
sendlen); | sendlen); | ||||
peer->sent++; | peer->sent++; | ||||
peer->throttle += (1 << peer->minpoll) - 2; | peer->throttle += (1 << peer->minpoll) - 2; | ||||
/* | /* | ||||
* Capture a-posteriori timestamps | * Capture a-posteriori timestamps | ||||
*/ | */ | ||||
get_systime(&xmt_ty); | get_systime(&xmt_ty); | ||||
if (peer->flip != 0) { /* interleaved modes */ | if (peer->flip != 0) { /* interleaved modes */ | ||||
if (peer->flip > 0) | if (peer->flip > 0) | ||||
peer->aorg = xmt_ty; | peer->aorg = xmt_ty; | ||||
else | else | ||||
peer->borg = xmt_ty; | peer->borg = xmt_ty; | ||||
peer->flip = -peer->flip; | peer->flip = -peer->flip; | ||||
} | } | ||||
L_SUB(&xmt_ty, &xmt_tx); | L_SUB(&xmt_ty, &xmt_tx); | ||||
LFPTOD(&xmt_ty, peer->xleave); | LFPTOD(&xmt_ty, peer->xleave); | ||||
#ifdef AUTOKEY | #ifdef AUTOKEY | ||||
#ifdef DEBUG | DPRINTF(1, ("peer_xmit: at %ld %s->%s mode %d keyid %08x len %zu index %d\n", | ||||
if (debug) | |||||
printf("transmit: at %ld %s->%s mode %d keyid %08x len %zu index %d\n", | |||||
current_time, latoa(peer->dstadr), | current_time, latoa(peer->dstadr), | ||||
ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen, | ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen, | ||||
peer->keynumber); | peer->keynumber)); | ||||
#endif | |||||
#else /* !AUTOKEY follows */ | #else /* !AUTOKEY follows */ | ||||
#ifdef DEBUG | DPRINTF(1, ("peer_xmit: at %ld %s->%s mode %d keyid %08x len %d\n", | ||||
if (debug) | |||||
printf("transmit: at %ld %s->%s mode %d keyid %08x len %d\n", | |||||
current_time, peer->dstadr ? | current_time, peer->dstadr ? | ||||
ntoa(&peer->dstadr->sin) : "-", | ntoa(&peer->dstadr->sin) : "-", | ||||
ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen); | ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen)); | ||||
#endif | |||||
#endif /* !AUTOKEY */ | #endif /* !AUTOKEY */ | ||||
return; | |||||
} | } | ||||
#ifdef LEAP_SMEAR | #ifdef LEAP_SMEAR | ||||
static void | static void | ||||
leap_smear_add_offs(l_fp *t, l_fp *t_recv) { | leap_smear_add_offs( | ||||
l_fp *t, | |||||
l_fp *t_recv | |||||
) | |||||
{ | |||||
L_ADD(t, &leap_smear.offset); | L_ADD(t, &leap_smear.offset); | ||||
return; | |||||
} | } | ||||
#endif /* LEAP_SMEAR */ | #endif /* LEAP_SMEAR */ | ||||
/* | /* | ||||
* fast_xmit - Send packet for nonpersistent association. Note that | * fast_xmit - Send packet for nonpersistent association. Note that | ||||
* neither the source or destination can be a broadcast address. | * neither the source or destination can be a broadcast address. | ||||
*/ | */ | ||||
static void | static void | ||||
fast_xmit( | fast_xmit( | ||||
struct recvbuf *rbufp, /* receive packet pointer */ | struct recvbuf *rbufp, /* receive packet pointer */ | ||||
int xmode, /* receive mode */ | int xmode, /* receive mode */ | ||||
keyid_t xkeyid, /* transmit key ID */ | keyid_t xkeyid, /* transmit key ID */ | ||||
int flags /* restrict mask */ | int flags /* restrict mask */ | ||||
) | ) | ||||
{ | { | ||||
struct pkt xpkt; /* transmit packet structure */ | struct pkt xpkt; /* transmit packet structure */ | ||||
struct pkt *rpkt; /* receive packet structure */ | struct pkt *rpkt; /* receive packet structure */ | ||||
l_fp xmt_tx, xmt_ty; | l_fp xmt_tx, xmt_ty; | ||||
int sendlen; | size_t sendlen; | ||||
#ifdef AUTOKEY | #ifdef AUTOKEY | ||||
u_int32 temp32; | u_int32 temp32; | ||||
#endif | #endif | ||||
/* | /* | ||||
* Initialize transmit packet header fields from the receive | * Initialize transmit packet header fields from the receive | ||||
* buffer provided. We leave the fields intact as received, but | * buffer provided. We leave the fields intact as received, but | ||||
* set the peer poll at the maximum of the receive peer poll and | * set the peer poll at the maximum of the receive peer poll and | ||||
▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | #endif /* HAVE_NTP_SIGND */ | ||||
* If the received packet contains a MAC, the transmitted packet | * If the received packet contains a MAC, the transmitted packet | ||||
* is authenticated and contains a MAC. If not, the transmitted | * is authenticated and contains a MAC. If not, the transmitted | ||||
* packet is not authenticated. | * packet is not authenticated. | ||||
*/ | */ | ||||
sendlen = LEN_PKT_NOMAC; | sendlen = LEN_PKT_NOMAC; | ||||
if (rbufp->recv_length == sendlen) { | if (rbufp->recv_length == sendlen) { | ||||
sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt, | sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt, | ||||
sendlen); | sendlen); | ||||
#ifdef DEBUG | DPRINTF(1, ("fast_xmit: at %ld %s->%s mode %d len %lu\n", | ||||
if (debug) | |||||
printf( | |||||
"transmit: at %ld %s->%s mode %d len %d\n", | |||||
current_time, stoa(&rbufp->dstadr->sin), | current_time, stoa(&rbufp->dstadr->sin), | ||||
stoa(&rbufp->recv_srcadr), xmode, sendlen); | stoa(&rbufp->recv_srcadr), xmode, | ||||
#endif | (u_long)sendlen)); | ||||
return; | return; | ||||
} | } | ||||
/* | /* | ||||
* The received packet contains a MAC, so the transmitted packet | * The received packet contains a MAC, so the transmitted packet | ||||
* must be authenticated. For symmetric key cryptography, use | * must be authenticated. For symmetric key cryptography, use | ||||
* the predefined and trusted symmetric keys to generate the | * the predefined and trusted symmetric keys to generate the | ||||
* cryptosum. For autokey cryptography, use the server private | * cryptosum. For autokey cryptography, use the server private | ||||
Show All 10 Lines | if (xkeyid > NTP_MAXKEY) { | ||||
* MODE_SERVER. If an extension field is present, there | * MODE_SERVER. If an extension field is present, there | ||||
* can be only one and that must be a command. Do what | * can be only one and that must be a command. Do what | ||||
* needs, but with private value of zero so the poor | * needs, but with private value of zero so the poor | ||||
* jerk can decode it. If no extension field is present, | * jerk can decode it. If no extension field is present, | ||||
* use the cookie to generate the session key. | * use the cookie to generate the session key. | ||||
*/ | */ | ||||
cookie = session_key(&rbufp->recv_srcadr, | cookie = session_key(&rbufp->recv_srcadr, | ||||
&rbufp->dstadr->sin, 0, sys_private, 0); | &rbufp->dstadr->sin, 0, sys_private, 0); | ||||
if (rbufp->recv_length > sendlen + (int)MAX_MAC_LEN) { | if ((size_t)rbufp->recv_length > sendlen + MAX_MAC_LEN) { | ||||
session_key(&rbufp->dstadr->sin, | session_key(&rbufp->dstadr->sin, | ||||
&rbufp->recv_srcadr, xkeyid, 0, 2); | &rbufp->recv_srcadr, xkeyid, 0, 2); | ||||
temp32 = CRYPTO_RESP; | temp32 = CRYPTO_RESP; | ||||
rpkt->exten[0] |= htonl(temp32); | rpkt->exten[0] |= htonl(temp32); | ||||
sendlen += crypto_xmit(NULL, &xpkt, rbufp, | sendlen += crypto_xmit(NULL, &xpkt, rbufp, | ||||
sendlen, (struct exten *)rpkt->exten, | sendlen, (struct exten *)rpkt->exten, | ||||
cookie); | cookie); | ||||
} else { | } else { | ||||
session_key(&rbufp->dstadr->sin, | session_key(&rbufp->dstadr->sin, | ||||
&rbufp->recv_srcadr, xkeyid, cookie, 2); | &rbufp->recv_srcadr, xkeyid, cookie, 2); | ||||
} | } | ||||
} | } | ||||
#endif /* AUTOKEY */ | #endif /* AUTOKEY */ | ||||
get_systime(&xmt_tx); | get_systime(&xmt_tx); | ||||
sendlen += authencrypt(xkeyid, (u_int32 *)&xpkt, sendlen); | sendlen += authencrypt(xkeyid, (u_int32 *)&xpkt, sendlen); | ||||
#ifdef AUTOKEY | #ifdef AUTOKEY | ||||
if (xkeyid > NTP_MAXKEY) | if (xkeyid > NTP_MAXKEY) | ||||
authtrust(xkeyid, 0); | authtrust(xkeyid, 0); | ||||
#endif /* AUTOKEY */ | #endif /* AUTOKEY */ | ||||
sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt, sendlen); | sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt, sendlen); | ||||
get_systime(&xmt_ty); | get_systime(&xmt_ty); | ||||
L_SUB(&xmt_ty, &xmt_tx); | L_SUB(&xmt_ty, &xmt_tx); | ||||
sys_authdelay = xmt_ty; | sys_authdelay = xmt_ty; | ||||
#ifdef DEBUG | DPRINTF(1, ("fast_xmit: at %ld %s->%s mode %d keyid %08x len %lu\n", | ||||
if (debug) | |||||
printf( | |||||
"transmit: at %ld %s->%s mode %d keyid %08x len %d\n", | |||||
current_time, ntoa(&rbufp->dstadr->sin), | current_time, ntoa(&rbufp->dstadr->sin), | ||||
ntoa(&rbufp->recv_srcadr), xmode, xkeyid, sendlen); | ntoa(&rbufp->recv_srcadr), xmode, xkeyid, | ||||
#endif | (u_long)sendlen)); | ||||
} | } | ||||
/* | /* | ||||
* pool_xmit - resolve hostname or send unicast solicitation for pool. | * pool_xmit - resolve hostname or send unicast solicitation for pool. | ||||
*/ | */ | ||||
static void | static void | ||||
pool_xmit( | pool_xmit( | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | #ifdef WORKER | ||||
HTONL_FP(&sys_reftime, &xpkt.reftime); | HTONL_FP(&sys_reftime, &xpkt.reftime); | ||||
get_systime(&xmt_tx); | get_systime(&xmt_tx); | ||||
pool->aorg = xmt_tx; | pool->aorg = xmt_tx; | ||||
HTONL_FP(&xmt_tx, &xpkt.xmt); | HTONL_FP(&xmt_tx, &xpkt.xmt); | ||||
sendpkt(rmtadr, lcladr, sys_ttl[pool->ttl], &xpkt, | sendpkt(rmtadr, lcladr, sys_ttl[pool->ttl], &xpkt, | ||||
LEN_PKT_NOMAC); | LEN_PKT_NOMAC); | ||||
pool->sent++; | pool->sent++; | ||||
pool->throttle += (1 << pool->minpoll) - 2; | pool->throttle += (1 << pool->minpoll) - 2; | ||||
#ifdef DEBUG | DPRINTF(1, ("pool_xmit: at %ld %s->%s pool\n", | ||||
if (debug) | current_time, latoa(lcladr), stoa(rmtadr))); | ||||
printf("transmit: at %ld %s->%s pool\n", | |||||
current_time, latoa(lcladr), stoa(rmtadr)); | |||||
#endif | |||||
msyslog(LOG_INFO, "Soliciting pool server %s", stoa(rmtadr)); | msyslog(LOG_INFO, "Soliciting pool server %s", stoa(rmtadr)); | ||||
#endif /* WORKER */ | #endif /* WORKER */ | ||||
} | } | ||||
#ifdef AUTOKEY | #ifdef AUTOKEY | ||||
/* | /* | ||||
* group_test - test if this is the same group | * group_test - test if this is the same group | ||||
* | * | ||||
* host assoc return action | * host assoc return action | ||||
* none none 0 mobilize * | * none none 0 mobilize * | ||||
* none group 0 mobilize * | * none group 0 mobilize * | ||||
* group none 0 mobilize * | * group none 0 mobilize * | ||||
* group group 1 mobilize | * group group 1 mobilize | ||||
* group different 1 ignore | * group different 1 ignore | ||||
* * ignore if notrust | * * ignore if notrust | ||||
*/ | */ | ||||
int group_test( | int | ||||
group_test( | |||||
char *grp, | char *grp, | ||||
char *ident | char *ident | ||||
) | ) | ||||
{ | { | ||||
if (grp == NULL) | if (grp == NULL) | ||||
return (0); | return (0); | ||||
if (strcmp(grp, sys_groupname) == 0) | if (strcmp(grp, sys_groupname) == 0) | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | if (peer->keylist != NULL) { | ||||
for (i = 0; i <= peer->keynumber; i++) | for (i = 0; i <= peer->keynumber; i++) | ||||
authtrust(peer->keylist[i], 0); | authtrust(peer->keylist[i], 0); | ||||
free(peer->keylist); | free(peer->keylist); | ||||
peer->keylist = NULL; | peer->keylist = NULL; | ||||
} | } | ||||
value_free(&peer->sndval); | value_free(&peer->sndval); | ||||
peer->keynumber = 0; | peer->keynumber = 0; | ||||
peer->flags &= ~FLAG_ASSOC; | peer->flags &= ~FLAG_ASSOC; | ||||
#ifdef DEBUG | DPRINTF(1, ("key_expire: at %lu associd %d\n", current_time, | ||||
if (debug) | peer->associd)); | ||||
printf("key_expire: at %lu associd %d\n", current_time, | |||||
peer->associd); | |||||
#endif | |||||
} | } | ||||
#endif /* AUTOKEY */ | #endif /* AUTOKEY */ | ||||
/* | /* | ||||
* local_refid(peer) - check peer refid to avoid selecting peers | * local_refid(peer) - check peer refid to avoid selecting peers | ||||
* currently synced to this ntpd. | * currently synced to this ntpd. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 426 Lines • Show Last 20 Lines |