static char *rcsid
= "$Header: /f/osi/others/ntp/RCS/ntp_osi.c,v 7.2 91/02/22 09:33:47 mrose Interim $";
* Ntp OSI specific code (mainly)
* Revision 7.2 91/02/22 09:33:47 mrose
* Revision 7.1 90/12/10 23:15:45 mrose
* Revision 7.0 90/12/10 17:21:29 mrose
* *** empty log message ***
* Revision 1.3 90/08/14 10:13:54 jpo
* Revision 1.2 89/12/19 08:32:43 jpo
* Updated for ISODE 6.0ish
* Revision 1.1 89/06/15 20:36:56 jpo
void ros_advise (), acs_advise ();
extern unsigned long clock_watchdog
;
extern int trusting
, logstats
;
extern struct sysdata sys
;
extern struct list peer_list
;
extern struct ntp_peer
*check_peer();
extern unsigned int servport
;
extern char *malloc(), *ntoa();
extern double drift_comp
, compliance
; /* logical clock variables */
extern void make_new_peer(), tstamp(), clock_update (),
receive (), clear (), clock_filter (),
select_clock (), poll_update (), adios (), advise ();
extern struct ntp_peer
*find_peer ();
extern int demobilize ();
static double ul_fixed_to_doublep ();
static double ul2_fixed_to_double ();
static void tstamp_osi ();
static void ros_indication ();
static int acsap_retry ();
static int acsap_initial ();
static int bindfailed ();
static PE
build_bind_arg ();
static int check_accept ();
static int handle_reject ();
static int TMagic (vecp
, vec
, td
)
struct TSAPdisconnect
*td
;
register struct TSAPstart
*ts
= &tss
;
if (TInit (*vecp
, vec
, ts
, td
) == NOTOK
)
if (TConnResponse (sd
, &ts
-> ts_called
, ts
-> ts_expedited
, NULLCP
, 0,
if (TSaveState (sd
, vec
+ 1, td
) == NOTOK
)
void create_osilisten (addr
)
int result_func (), query_func ();
struct RoSAPindication rois
;
register struct RoSAPindication
*roi
= &rois
;
struct TSAPdisconnect tds
;
struct TSAPdisconnect
*td
= &tds
;
if ((pa
= str2paddr (addr
)) == NULLPA
)
adios (NULLCP
, "Address translation failed for %s", addr
);
if (TNetListenAux (&pa
-> pa_addr
.sa_addr
, TMagic
, td
) == NOTOK
)
adios (NULLCP
, "Address listen failed");
if (RyDispatch (NOTOK
, table_NTP_Operations
, operation_NTP_update
,
result_func
, roi
) == NOTOK
)
adios (NULLCP
, "RyDispatch failed");
if (RyDispatch (NOTOK
, table_NTP_Operations
, operation_NTP_query
,
query_func
, roi
) == NOTOK
)
adios (NULLCP
, "RyDispatch failed");
TRACE (1, ("Listening on address %s", addr
));
struct type_NTP_TimeStamp
*sstamp ();
struct type_NTP_SmallFixed
*sfixed ();
struct type_NTP_ClockIdentifier
*srclock ();
extern struct ntp_peer dummy_peer
;
extern struct list peer_list
;
extern struct sysdata sys
;
static void process_packet_osi ();
static void terminate ();
struct RoSAPindication rois
;
register struct RoSAPindication
*roi
= &rois
;
register struct RoSAPpreject
*rop
= &roi
-> roi_preject
;
struct type_NTP_Packet
*packet
;
struct type_NTP_Leap
*leap
;
ap
= peer
-> sock
< 0 ? addrs
: &addrs
[peer
->sock
];
TRACE (2, ("Sending OSI packet to %s fd %d if %d",
paddr(&ap
-> addr
), ap
-> fd
, ap
- addrs
));
if (ap
-> addr
.type
!= AF_OSI
) {
advise (LLOG_EXCEPTIONS
, NULLCP
,
"Wrong address family in send_osi!");
packet
= (struct type_NTP_Packet
*) malloc (sizeof *packet
);
leap
= (struct type_NTP_Leap
*) malloc (sizeof *leap
);
switch (sys
.leap
& LEAPMASK
) {
leap
-> parm
= int_NTP_Leap_nowarning
;
leap
-> parm
= int_NTP_Leap_plussecond
;
leap
-> parm
= int_NTP_Leap_minussecond
;
leap
-> parm
= int_NTP_Leap_alarm
;
packet
-> version
= peer
-> vers
== 1 ? 2 : peer
-> vers
;
packet
-> mode
= (struct type_NTP_Mode
*)
malloc (sizeof (struct type_NTP_Mode
));
packet
-> mode
-> parm
= peer
-> hmode
;
packet
-> stratum
= sys
.stratum
;
packet
-> pollInterval
= peer
-> hpoll
;
packet
-> precision
= sys
.precision
;
packet
-> synchDistance
= sfixed (&sys
.distance
);
packet
-> synchDispersion
= sfixed (&sys
.dispersion
);
packet
-> referenceClockIdentifier
= srclock (&sys
.refid
);
packet
-> referenceTimestamp
= sstamp (&sys
.reftime
);
packet
-> originateTimestamp
= sstamp (&peer
-> org
);
packet
-> receiveTimestamp
= sstamp (&peer
-> rec
);
(void) gettimeofday (&txtv
, (struct timezone
*)0);
tstamp_osi (&peer
->xmt
, &txtv
);
packet
-> transmitTimestamp
= sstamp (&peer
-> xmt
);
switch (RyStub (ap
-> fd
, table_NTP_Operations
, operation_NTP_update
,
RyGenID (ap
-> fd
), NULLIP
, (caddr_t
) packet
,
result_func
, NULLIFP
, ROS_ASYNC
, roi
)) {
ros_advise (rop
, "STUB");
if (ROS_FATAL (rop
-> rop_reason
))
free_NTP_Packet (packet
);
i
= peer
->reach
; /* save a copy */
peer
->reach
= (peer
->reach
<< 1) & NTP_WINDOW_SHIFT_MASK
;
if ((peer
->reach
== 0) &&
((peer
->flags
& PEER_FL_CONFIG
) == 0) &&
(peer
!= &dummy_peer
) && demobilize(&peer_list
, peer
))
if (i
&& peer
->reach
== 0) {
advise (LLOG_NOTICE
, NULLCP
,
"Lost reachability with %s",
clock_filter(peer
, 0.0, 0.0); /* call with invalid values */
select_clock(); /* and try to reselect clock */
poll_update(sys
.peer
, NTP_MINPOLL
);
peer
->timer
= 1<<(MAX(MIN(peer
->ppoll
, MIN(peer
->hpoll
, NTP_MAXPOLL
)),
peer
->backoff
= BACKOFF_COUNT
;
poll_update (peer
, (int)peer
->hpoll
+ 1);
else if (peer
->estdisp
> PEER_THRESHOLD
)
poll_update(peer
, (int)peer
->hpoll
- 1);
poll_update(peer
, (int)peer
->hpoll
+ 1);
struct s_fixedpt
gfixed ();
struct l_fixedpt
gstamp ();
int result_func (sd
, ryo
, rox
, in
, roi
)
struct RoSAPindication
*roi
;
struct type_NTP_Packet
*result
= (struct type_NTP_Packet
*)in
;
for (ap
= addrs
; ap
< &addrs
[nintf
]; ap
++)
if ((peer_mode
= result
-> mode
-> parm
) == int_NTP_Mode_client
) {
* Special case: Use the dummy peer item that we keep around
* just for this type of thing
peer
->hmode
= MODE_SYM_PAS
;
peer
= check_peer(dst
, sock
);
peer
= (struct ntp_peer
*) malloc(sizeof(struct ntp_peer
));
advise (LLOG_EXCEPTIONS
, "malloc", "peer");
peer
->sock
= sock
; /* remember which socket we heard
peer
->hmode
= MODE_SYM_PAS
;
* If we decide to consider any random NTP peer that might
* come as a peer we might sync to, then set the PEER_FL_SYNC
* flag in the peer structure.
* Alternatively, we could change the hmode to MODE_SERVER,
* but then the peer state wouldn't be persistant.
peer
->flags
|= PEER_FL_SYNC
;
enqueue(&peer_list
, peer
);
if (peer_mode
< MODE_SYM_ACT
|| peer_mode
> MODE_BROADCAST
) {
TRACE (1, ("Bogus peer_mode %d from %s", peer_mode
,
if (peer
->hmode
< MODE_SYM_ACT
|| peer
->hmode
> MODE_BROADCAST
) {
advise (LLOG_EXCEPTIONS
, NULLCP
,
"Bogus hmode %d for peer %s", peer
->hmode
,
switch (actions
[peer_mode
- 1][peer
->hmode
- 1]) {
if (!(((peer
->flags
& PEER_FL_CONFIG
) == 0) &&
STRMCMP(result
->stratum
, >, sys
.stratum
))) {
process_packet_osi(dst
, result
, osi_tvp
, peer
);
if (((peer
->flags
& PEER_FL_CONFIG
) == 0) &&
(peer
!= &dummy_peer
) && demobilize(&peer_list
, peer
))
if (!(((peer
->flags
& PEER_FL_CONFIG
) == 0) &&
STRMCMP(result
->stratum
, >, sys
.stratum
))) {
process_packet_osi(dst
, result
, osi_tvp
, peer
);
process_packet_osi(dst
, result
, osi_tvp
, peer
);
poll_update(peer
, (int)peer
->ppoll
);
/* 3.4.3 Packet procedure */
static void process_packet_osi (dst
, pkt
, tvp
, peer
)
struct type_NTP_Packet
*pkt
;
double t1
, t2
, t3
, t4
, offset
, delay
;
duplicate
= (pkt
->transmitTimestamp
->integer
== peer
->org
.int_part
) &&
(pkt
->transmitTimestamp
->fraction
== peer
->org
.fraction
);
bogus
= ((pkt
->originateTimestamp
-> integer
!= peer
->xmt
.int_part
) ||
(pkt
->originateTimestamp
-> fraction
!= peer
->xmt
.fraction
))
|| (peer
->xmt
.int_part
== 0);
switch (pkt
-> leap
-> parm
) {
case int_NTP_Leap_minussecond
:
case int_NTP_Leap_plussecond
:
case int_NTP_Leap_nowarning
:
peer
->stratum
= pkt
->stratum
;
peer
->ppoll
= pkt
-> pollInterval
;
peer
->precision
= pkt
->precision
;
peer
->distance
= gfixed (pkt
->synchDistance
);
peer
->dispersion
= gfixed (pkt
->synchDispersion
);
peer
->refid
= *gclock (pkt
-> referenceClockIdentifier
);
peer
->reftime
= gstamp (pkt
->referenceTimestamp
);
peer
->org
= gstamp (pkt
->transmitTimestamp
);
tstamp_osi (&peer
->rec
, tvp
);
poll_update(peer
, (int)peer
->hpoll
);
* may want to do something special here for Broadcast Mode peers to
if (bogus
|| duplicate
||
(pkt
->originateTimestamp
-> integer
== 0 &&
pkt
->originateTimestamp
-> fraction
== 0) ||
(pkt
->receiveTimestamp
-> integer
== 0 &&
pkt
->receiveTimestamp
-> fraction
== 0)) {
TRACE (3, ("process_packet_osi: dropped duplicate or bogus"));
* Now compute local adjusts
t1
= ul2_fixed_to_double(pkt
->originateTimestamp
);
t2
= ul2_fixed_to_double(pkt
->receiveTimestamp
);
t3
= ul2_fixed_to_double(pkt
->transmitTimestamp
);
t4
= ul_fixed_to_doublep(&peer
->rec
);
/* END Protocol specific stuff */
* although the delay computation looks different than the one in the
* specification, it is correct. Think about it.
delay
= (t2
- t1
) - (t3
- t4
);
offset
= ((t2
- t1
) + (t3
- t4
)) / 2.0;
delay
+= 1.0/(unsigned long)(1L << -sys
.precision
)
+ (peer
->flags
&PEER_FL_REFCLOCK
) ? NTP_REFMAXSKW
: NTP_MAXSKW
;
if (peer
->precision
< 0 && -peer
->precision
< sizeof(long)*NBBY
)
delay
+= 1.0/(unsigned long)(1L << -peer
->precision
);
delay
= MAX(delay
, NTP_MINDIST
);
delay
= MAX(delay
, (peer
->flags
& PEER_FL_REFCLOCK
) ?
NTP_REFMINDIST
: NTP_MINDIST
);
clock_filter(peer
, delay
, offset
); /* invoke clock filter procedure */
TRACE (1, ("host: %s : %f : %f : %f : %f : %f : %o",
dst
? paddr (dst
) : "refclock",
peer
->estdelay
, peer
->estoffset
, peer
->estdisp
,
clock_update(peer
); /* call clock update procedure */
struct l_fixedpt
gstamp (ts
)
struct type_NTP_TimeStamp
*ts
;
static struct l_fixedpt fp
;
fp
.int_part
= ts
-> integer
;
fp
.fraction
= ts
-> fraction
;
struct s_fixedpt
gfixed (ts
)
struct type_NTP_SmallFixed
*ts
;
static struct s_fixedpt fp
;
fp
.int_part
= ts
-> integer
;
fp
.fraction
= ts
-> fraction
;
struct type_NTP_ClockIdentifier
*ci
;
case type_NTP_ClockIdentifier_referenceClock
:
rid
.rid_type
= RID_STRING
;
p
= qb2str (ci
->un
.referenceClock
);
(void) strncpy (rid
.rid_string
, p
, 4);
case type_NTP_ClockIdentifier_inetaddr
:
p
= qb2str (ci
->un
.inetaddr
);
rid
.rid_inet
= inet_addr (p
);
case type_NTP_ClockIdentifier_psapaddr
:
p
= qb2str (ci
->un
.psapaddr
);
(void) strncpy (rid
.rid_string
, "????", 4);
rid
.rid_type
= RID_STRING
;
struct type_NTP_TimeStamp
*sstamp (ts
)
struct type_NTP_TimeStamp
*nts
;
nts
= (struct type_NTP_TimeStamp
*)malloc (sizeof (*nts
));
nts
-> integer
= ts
-> int_part
;
nts
-> fraction
= ts
-> fraction
;
struct type_NTP_SmallFixed
*sfixed (ts
)
struct type_NTP_SmallFixed
*nts
;
nts
= (struct type_NTP_SmallFixed
*)malloc (sizeof *nts
);
nts
-> integer
= ts
-> int_part
;
nts
-> fraction
= ts
-> fraction
;
struct type_NTP_ClockIdentifier
*srclock (rid
)
struct type_NTP_ClockIdentifier
*ci
;
ci
= (struct type_NTP_ClockIdentifier
*) malloc (sizeof *ci
);
switch (rid
-> rid_type
) {
ci
-> offset
= type_NTP_ClockIdentifier_referenceClock
;
if (rid
-> rid_type
== RID_STRING
)
ci
-> un
.referenceClock
=
str2qb (rid
->rid_string
, 4, 1);
ci
-> un
.referenceClock
= str2qb ("??", 2, 1);
ci
-> offset
= type_NTP_ClockIdentifier_inetaddr
;
in
.s_addr
= rid
-> rid_inet
;
ci
-> un
.inetaddr
= str2qb (p
, strlen (p
), 1);
ci
-> offset
= type_NTP_ClockIdentifier_psapaddr
;
p
= _paddr2str (&rid
->rid_psap
, NULLNA
, -1);
ci
-> un
.psapaddr
= str2qb (p
, strlen(p
), 1);
struct RoSAPindication rois
;
register struct RoSAPindication
*roi
= &rois
;
register struct RoSAPpreject
*rop
= &roi
-> roi_preject
;
TRACE (2, ("Received OSI packet from %s", paddr (&ap
->addr
)));
switch (RyWait (ap
-> fd
, NULLIP
, &out
, OK
, roi
)) {
if (rop
-> rop_reason
== ROS_TIMER
)
ros_indication (ap
-> fd
, ap
, roi
);
advise (LLOG_EXCEPTIONS
, NULLCP
, "Unknown return from RyWait");
static void ros_indication (fd
, ap
, roi
)
register struct RoSAPindication
*roi
;
switch (roi
-> roi_type
) {
advise (LLOG_EXCEPTIONS
, NULLCP
, "unexpected indication type=%d",
register struct RoSAPureject
*rou
= &roi
-> roi_ureject
;
advise (LLOG_EXCEPTIONS
, NULLCP
,
"RO-REJECT-U.INDICATION/%d: %s",
fd
, RoErrString (rou
-> rou_reason
));
advise (LLOG_EXCEPTIONS
, NULLCP
,
"RO-REJECT-U.INDICATION/%d: %s (id=%d)",
fd
, RoErrString (rou
-> rou_reason
),
register struct RoSAPpreject
*rop
= &roi
-> roi_preject
;
ros_advise (rop
, "RO-REJECT-P.INDICATION");
if (ROS_FATAL (rop
-> rop_reason
)) {
register struct AcSAPfinish
*acf
= &roi
-> roi_finish
;
struct AcSAPindication acis
;
register struct AcSAPabort
*aca
= &acis
.aci_abort
;
advise (LLOG_EXCEPTIONS
, NULLCP
, "A-RELEASE.INDICATION/%d: %d",
result
= AcRelResponse (fd
, ACS_ACCEPT
, ACR_NORMAL
, NULLPEP
, 0,
acs_advise (aca
, "A-RELEASE.RESPONSE");
advise (LLOG_EXCEPTIONS
, NULLCP
,
"unknown indication type=%d", roi
-> roi_type
);
static void terminate (ap
, roi
)
struct RoSAPindication
*roi
;
struct AcSAPindication acsis
;
extern struct list peer_list
;
(void) AcUAbortRequest (fd
, NULLPEP
, 0, &acsis
);
if ((peer
= find_peer (ap
- addrs
)) != NULL
) {
peer
-> flags
&= ~PEER_FL_CONNSTATE
;
advise (LLOG_NOTICE
, NULLCP
,
"Connection on %d if %d TERMINATED", ap
-> fd
, fd
);
void iso_init (vecp
, vec
, fd
)
ap
-> flags
= INTF_ACCEPTING
;
ap
-> vec
[0] = strdup (vec
[0]);
ap
-> vec
[1] = strdup (vec
[1]);
ap
-> vec
[2] = strdup (vec
[2]);
ap
-> vec
[3] = strdup (vec
[3]);
ap
-> vec
[vecp
] = NULLCP
;
TRACE (1, ("Incoming Connection pending on %d", fd
));
register struct AcSAPstart
*acs
= &acss
;
struct AcSAPindication acis
;
register struct AcSAPindication
*aci
= &acis
;
register struct AcSAPabort
*aca
= &aci
-> aci_abort
;
register struct PSAPstart
*ps
= &acs
-> acs_start
;
struct RoSAPindication rois
;
register struct RoSAPindication
*roi
= &rois
;
register struct RoSAPpreject
*rop
= &roi
-> roi_preject
;
struct type_NTP_BindArgument
*bindarg
;
struct type_NTP_BindResult
*bindresult
;
if (AcInit (ap
-> vecp
, ap
-> vec
, acs
, aci
) == NOTOK
) {
acs_advise (aca
, "Initialisation fails");
for (i
= 0; i
< ap
-> vecp
; i
++) {
TRACE (1,("A-ASSOCIATE.INDICATION: <%d, %s, %s, %s, %d>",
acs
-> acs_sd
, oid2ode (acs
-> acs_context
),
sprintaei (&acs
-> acs_callingtitle
),
sprintaei (&acs
-> acs_calledtitle
), acs
-> acs_ninfo
));
if (acs
-> acs_ninfo
> 0) {
PLOG (pgm_log
, print_NTP_BindArgument
, acs
-> acs_info
[0],
if (decode_NTP_BindArgument (acs
-> acs_info
[0], 1,
advise (LLOG_EXCEPTIONS
, NULLCP
,
"bind decode failed [%s]", PY_pepy
);
free_NTP_BindArgument(bindarg
);
return bindfailed (ap
, acs
, int_NTP_reason_badarg
,
if (bindarg
-> psap
== NULL
)
pa
= &acs
-> acs_start
.ps_calling
;
p
= qb2str(bindarg
-> psap
);
if ((pa
= str2paddr (p
)) == NULLPA
)
pa
= &acs
-> acs_start
.ps_calling
;
if (bit_test (bindarg
-> version
,
bit_NTP_version_version__2
))
else if (bit_test (bindarg
-> version
,
bit_NTP_version_version__1
))
free_NTP_BindArgument(bindarg
);
return bindfailed (ap
, acs
,
"No acceptable version");
if (bindarg
-> authentication
) {
"Connection specifies authentication");
free_NTP_BindArgument(bindarg
);
return bindfailed (ap
, acs
,
int_NTP_reason_validation
,
"Authentication not supported");
switch (bindarg
-> mode
-> parm
) {
case int_NTP_BindMode_normal
:
case int_NTP_BindMode_query
:
free_NTP_BindArgument(bindarg
);
return bindfailed (ap
, acs
, int_NTP_reason_badarg
,
free_NTP_BindArgument(bindarg
);
bindresult
= (struct type_NTP_BindResult
*)
calloc (1, sizeof *bindresult
);
bindresult
-> version
= version
;
bindresult
-> mode
= (struct type_NTP_BindMode
*)
calloc (1, sizeof *bindresult
-> mode
);
bindresult
-> mode
-> parm
=
if (encode_NTP_BindResult (&pe
, 1, NULLINT
, NULLCP
,
advise (LLOG_EXCEPTIONS
, NULLCP
,
"encode failed [%s]", PY_pepy
);
return bindfailed (ap
, acs
,
int_NTP_reason_congested
,
PLOG (pgm_log
, print_NTP_BindResult
, pe
,
free_NTP_BindResult (bindresult
);
pa
= &acs
-> acs_start
.ps_calling
;
mode
= int_NTP_BindMode_normal
;
result
= AcAssocResponse (sd
, ACS_ACCEPT
,
NULLOID
, NULLAEI
, NULLPA
, NULLPC
,
ps
-> ps_srequirements
, SERIAL_NONE
,
ps
-> ps_settings
, &ps
-> ps_connect
,
pep
, pep
== NULLPEP
? 0 : 1, aci
);
acs_advise (aca
, "Association response failed");
if (RoSetService (sd
, RoPService
, roi
) == NOTOK
) {
ros_advise (rop
, "set RO/PS fails");
ap
-> flags
|= INTF_VALID
;
for (peer
= peer_list
.head
; peer
; peer
= peer
->next
) {
if (peer
->src
.type
!= AF_OSI
)
if (psapaddr_cmp (pa
, &peer
->src
.psap_ad
)) {
peer
-> flags
|= PEER_FL_CONNECTED
;
peer
-> sock
= ap
-> inum
;
if (result
== 0 && mode
== int_NTP_BindMode_normal
) {
peer
= (struct ntp_peer
*) malloc(sizeof(struct ntp_peer
));
advise (LLOG_EXCEPTIONS
, "malloc", "peer");
peer
-> flags
|= PEER_FL_CONNECTED
;
peer
->hmode
= MODE_SYM_PAS
;
peer
-> flags
|= PEER_FL_SYNC
;
enqueue(&peer_list
, peer
);
peer
= find_peer (ap
-> inum
);
TRACE (2, ("Association accepted from %s sd %d if %d",
paddr (adr
), sd
, ap
-> inum
));
if (peer
&& peer
-> flags
& PEER_FL_CONFIG
)
static int bindfailed (ap
, acs
, type
, msg
)
register struct PSAPstart
*ps
= &acs
-> acs_start
;
struct type_NTP_BindError
*binderr
;
struct RoSAPindication rois
;
struct RoSAPindication
*roi
= &rois
;
struct AcSAPindication acis
;
register struct AcSAPindication
*aci
= &acis
;
binderr
= (struct type_NTP_BindError
*)
calloc (1, sizeof *binderr
);
binderr
-> reason
= type
;
binderr
-> supplementary
= str2qb (msg
, strlen (msg
), 1);
if (encode_NTP_BindError (&pe
, 1, NULLINT
, NULLCP
, binderr
) == NOTOK
) {
advise (LLOG_EXCEPTIONS
, NULLCP
, "ecode binderror failed [%s]",
PLOG (pgm_log
, print_NTP_BindError
, pe
, "NTP.BindError", 0);
free_NTP_BindError (binderr
);
AcAssocResponse (ap
-> fd
, ACS_REJECT
, ACS_USER_NULL
,
NULLOID
, NULLAEI
, NULLPA
, NULLPC
,
ps
-> ps_srequirements
, SERIAL_NONE
,
ps
-> ps_settings
, &ps
-> ps_connect
,
int make_osi_conn (peer
, addr
)
struct RoSAPindication rois
;
register struct RoSAPindication
*roi
= &rois
;
switch (peer
->flags
& PEER_FL_CONNSTATE
) {
switch (acsap_initial (peer
, addr
, roi
)) {
peer
-> flags
|= PEER_FL_CONINP1
;
FD_SET (ap
-> fd
, &globwmask
);
peer
-> flags
|= PEER_FL_CONINP2
;
FD_SET (ap
-> fd
, &globmask
);
peer
-> flags
&= ~ PEER_FL_CONNSTATE
;
peer
-> flags
|= PEER_FL_CONNECTED
;
FD_CLR (ap
-> fd
, &globwmask
);
FD_SET (ap
-> fd
, &globmask
);
ap
-> flags
= INTF_VALID
;
switch (result
= acsap_retry (peer
, roi
)) {
peer
-> flags
&= ~ PEER_FL_CONNSTATE
;
peer
-> flags
|= PEER_FL_CONINP1
;
FD_CLR (ap
-> fd
, &globmask
);
FD_SET (ap
-> fd
, &globwmask
);
peer
-> flags
&= ~ PEER_FL_CONNSTATE
;
peer
-> flags
|= PEER_FL_CONINP2
;
FD_CLR (ap
-> fd
, &globwmask
);
FD_SET (ap
-> fd
, &globmask
);
peer
-> flags
&= ~ PEER_FL_CONNSTATE
;
peer
-> flags
|= PEER_FL_CONNECTED
;
FD_CLR (ap
-> fd
, &globwmask
);
FD_SET (ap
-> fd
, &globmask
);
ap
-> flags
= INTF_VALID
;
switch( result
= acsap_retry (peer
, roi
)) {
peer
-> flags
&= ~ PEER_FL_CONNSTATE
;
peer
-> flags
|= PEER_FL_CONINP1
;
FD_CLR (ap
-> fd
, &globmask
);
FD_SET (ap
-> fd
, &globwmask
);
peer
-> flags
&= ~ PEER_FL_CONNSTATE
;
peer
-> flags
|= PEER_FL_CONINP2
;
FD_CLR (ap
-> fd
, &globwmask
);
FD_SET (ap
-> fd
, &globmask
);
peer
-> flags
&= ~ PEER_FL_CONNSTATE
;
peer
-> flags
|= PEER_FL_CONNECTED
;
FD_CLR (ap
-> fd
, &globwmask
);
FD_SET (ap
-> fd
, &globmask
);
ap
-> flags
= INTF_VALID
;
return result
== DONE
? OK
: NOTOK
;
static int acsap_initial (peer
, addr
, roi
)
struct RoSAPindication
*roi
;
register struct SSAPref
*sf
;
register struct PSAPaddr
*pa
, *pa2
;
struct AcSAPconnect accs
;
register struct AcSAPconnect
*acc
= &accs
;
struct AcSAPindication acis
;
register struct AcSAPindication
*aci
= &acis
;
register struct AcSAPabort
*aca
= &aci
-> aci_abort
;
register struct PSAPctxlist
*pc
= &pcs
;
if (peer
-> src
.type
!= AF_OSI
)
pa
= &ap
-> addr
.psap_ad
;
TRACE (2, ("Making connection to %s", paddr2str (pa
, NULLNA
)));
if ((pa2
= str2paddr (addr
)) == NULLPA
) {
advise (LLOG_EXCEPTIONS
, NULLCP
, "Can't translate %s", addr
);
pep
[0] = build_bind_arg (pa2
, peer
);
if ((ctx
= ode2oid (mycontext
)) == NULLOID
) {
advise (LLOG_EXCEPTIONS
, NULLCP
,
"%s: unknown object descriptor", mycontext
);
if ((ctx
= oid_cpy (ctx
)) == NULLOID
) {
advise (LLOG_EXCEPTIONS
, "memory", "out of");
if ((pci
= ode2oid (mypci
)) == NULLOID
) {
advise (LLOG_EXCEPTIONS
, NULLCP
,
"%s: unknown object descriptor", mypci
);
if ((pci
= oid_cpy (pci
)) == NULLOID
) {
advise (LLOG_EXCEPTIONS
, "memory", "out of");
pc
-> pc_ctx
[0].pc_id
= 1;
pc
-> pc_ctx
[0].pc_asn
= pci
;
pc
-> pc_ctx
[0].pc_atn
= NULLOID
;
if ((sf
= addr2ref (PLocalHostName ())) == NULL
) {
(void) bzero ((char *) sf
, sizeof *sf
);
result
= AcAsynAssocRequest (ctx
, NULLAEI
, NULLAEI
, pa2
, pa
,
0, ROS_MYREQUIRE
, SERIAL_NONE
, 0, sf
,
acs_advise (aca
, "A-ASSOCIATE.REQUEST");
ap
-> fd
= sd
= acc
-> acc_sd
;
ap
-> flags
|= INTF_PENDING
;
if (acc
-> acc_result
!= ACS_ACCEPT
)
return handle_reject (acc
, ap
);
return check_accept (acc
, ap
, peer
);
advise (LLOG_EXCEPTIONS
, NULLCP
, "Unknown response (%d)",
static int check_accept (acc
, ap
, peer
)
struct AcSAPconnect
*acc
;
struct RoSAPindication rois
;
struct RoSAPindication
*roi
= &rois
;
struct RoSAPpreject
*rop
= &roi
-> roi_preject
;
struct type_NTP_BindResult
*bindres
;
if (acc
-> acc_ninfo
> 0) {
PLOG (pgm_log
, print_NTP_BindResult
, acc
-> acc_info
[0],
if (decode_NTP_BindResult (acc
-> acc_info
[0], 1,
advise (LLOG_EXCEPTIONS
, NULLCP
,
"decode bindresult failed [%s]", PY_pepy
);
version
= bindres
-> version
;
mode
= bindres
-> mode
-> parm
;
free_NTP_BindResult (bindres
);
mode
= int_NTP_BindMode_normal
;
if (RoSetService (sd
, RoPService
, roi
) == NOTOK
) {
ros_advise (rop
, "set RO/PS fails");
peer
-> flags
|= PEER_FL_CONNECTED
;
TRACE (1, ("CONNECTED to %s on %d if %d",
paddr2str (&peer
->src
.psap_ad
, NULLNA
),
static PE
build_bind_arg (psap
, peer
)
struct type_NTP_BindArgument
*bindarg
;
bindarg
= (struct type_NTP_BindArgument
*)
calloc (1, sizeof *bindarg
);
str
= _paddr2str (psap
, NULLNA
, -1);
bindarg
-> psap
= str2qb (str
, strlen(str
), 1);
pe_alloc (PE_CLASS_UNIV
, PE_FORM_PRIM
,
bit_on (bindarg
-> version
,
bit_NTP_version_version__1
);
bit_on (bindarg
-> version
,
bit_NTP_version_version__2
);
bindarg
-> mode
= (struct type_NTP_BindMode
*)
calloc (1, sizeof *bindarg
-> mode
);
bindarg
-> mode
-> parm
=
if (encode_NTP_BindArgument (&pe
, 1, NULLINT
, NULLCP
,
advise (LLOG_EXCEPTIONS
, NULLCP
,
"encode Bindargument failed [%s]", PY_pepy
);
PLOG (pgm_log
, print_NTP_BindArgument
, pe
,
free_NTP_BindArgument (bindarg
);
static int acsap_retry (peer
, roi
)
struct RoSAPindication
*roi
;
struct AcSAPconnect accs
;
register struct AcSAPconnect
*acc
= &accs
;
struct AcSAPindication acis
;
register struct AcSAPindication
*aci
= &acis
;
register struct AcSAPabort
*aca
= &aci
-> aci_abort
;
TRACE (2, ("retry request on %s", paddr (&peer
->src
)));
switch (result
= AcAsynRetryRequest (ap
-> fd
, acc
, aci
)) {
acs_advise (aca
, "A-ASSOCIATE.REQUEST");
if (acc
-> acc_result
!= ACS_ACCEPT
)
return handle_reject (acc
, ap
);
return check_accept (acc
, ap
, peer
);
advise (LLOG_EXCEPTIONS
, NULLCP
,
"Bad response from retry %d", result
);
static int handle_reject (acc
, ap
)
struct AcSAPconnect
*acc
;
if (acc
-> acc_ninfo
> 0) {
struct type_NTP_BindError
*binderr
;
PLOG (pgm_log
, print_NTP_BindError
, acc
-> acc_info
[0],
if (decode_NTP_BindError (acc
-> acc_info
[0], 1,
if (binderr
-> supplementary
)
cp
= qb2str (binderr
-> supplementary
);
switch (binderr
-> reason
) {
case int_NTP_reason_refused
:
"connection refused: %s",
case int_NTP_reason_validation
:
"validation failure: %s",
case int_NTP_reason_version
:
case int_NTP_reason_badarg
:
"bad connect argument: %s",
case int_NTP_reason_congested
:
advise (LLOG_EXCEPTIONS
, NULLCP
,
"Unknown reason (%d) %s",
free_NTP_BindError (binderr
);
advise (LLOG_EXCEPTIONS
, NULLCP
,
"decode bind error failed [%s]", PY_pepy
);
advise (LLOG_EXCEPTIONS
, NULLCP
,
AcErrString (acc
-> acc_result
));
void ros_advise (rop
, event
)
register struct RoSAPpreject
*rop
;
(void) sprintf (buffer
, "[%s] %*.*s",
RoErrString (rop
-> rop_reason
),
rop
-> rop_cc
, rop
-> rop_cc
, rop
-> rop_data
);
(void) sprintf (buffer
, "[%s]",
RoErrString (rop
-> rop_reason
));
advise (LLOG_EXCEPTIONS
, NULLCP
, "%s: %s", event
, buffer
);
void acs_advise (aca
, event
)
register struct AcSAPabort
*aca
;
(void) sprintf (buffer
, "[%s] %*.*s",
AcErrString (aca
-> aca_reason
),
aca
-> aca_cc
, aca
-> aca_cc
, aca
-> aca_data
);
(void) sprintf (buffer
, "[%s]",
AcErrString (aca
-> aca_reason
));
advise (LLOG_EXCEPTIONS
, NULLCP
, "%s: %s (source %d)", event
, buffer
,
struct type_NTP_TimeStamp
*t
;
a
= (long)((i
>> 1) & 0x7fffffff);
a
= a
/ (4.294967296e9
); /* shift dec point over by 32 bits */
b
= (long)((i
>> 1) & 0x7fffffff);
#else /* GENERIC_UNS_BUG */
a
= (unsigned long) t
->fraction
;
#ifdef VAX_COMPILER_FLT_BUG
if (a
< 0.0) a
+= 4.294967296e9
;
a
= a
/ (4.294967296e9
);/* shift dec point over by 32 bits */
b
= (unsigned long) t
->integer
;
#ifdef VAX_COMPILER_FLT_BUG
if (b
< 0.0) b
+= 4.294967296e9
;
#endif /* GENERIC_UNS_BUG */
a
= (long)((i
>> 1) & 0x7fffffff);
a
= a
/ (4.294967296e9
); /* shift dec point over by 32 bits */
b
= (long)((i
>> 1) & 0x7fffffff);
#else /* GENERIC_UNS_BUG */
a
= (unsigned long) t
->fraction
;
#ifdef VAX_COMPILER_FLT_BUG
if (a
< 0.0) a
+= 4.294967296e9
;
a
= a
/ (4.294967296e9
);/* shift dec point over by 32 bits */
b
= (unsigned long) t
->int_part
;
#ifdef VAX_COMPILER_FLT_BUG
if (b
< 0.0) b
+= 4.294967296e9
;
#endif /* GENERIC_UNS_BUG */
struct l_fixedpt
*stampp
;
stampp
->int_part
= JAN_1970
+ tvp
->tv_sec
;
dd
= (float) tvp
->tv_usec
/ 1000000.0;
stampp
->fraction
= tt
<< 1;
struct l_fixedpt
*stampp
;
stampp
->int_part
= JAN_1970
+ tvp
->tv_sec
;
stampp
->fraction
= (float) tvp
->tv_usec
* 4294.967295;
struct type_NTP_ClockIdentifier
*cli_refid (refid
)
struct type_NTP_ClockIdentifier
*rid
;
rid
= (struct type_NTP_ClockIdentifier
*) malloc (sizeof *rid
);
switch (refid
.rid_type
) {
rid
-> offset
= type_NTP_ClockIdentifier_referenceClock
;
rid
-> un
.referenceClock
= str2qb (refid
.rid_string
,
strlen(refid
.rid_string
),
rid
-> offset
= type_NTP_ClockIdentifier_inetaddr
;
cp
= ntoa(&refid
.rid_inet
);
rid
-> un
.inetaddr
= str2qb(cp
, strlen(cp
), 1);
rid
-> offset
= type_NTP_ClockIdentifier_psapaddr
;
cp
= paddr2str (&refid
.rid_psap
, NULLNA
);
rid
-> un
.inetaddr
= str2qb (cp
, strlen (cp
), 1);
struct type_NTP_ClockInfo
*peer2clock (peer
)
struct type_NTP_ClockInfo
*ci
;
ci
= (struct type_NTP_ClockInfo
*) calloc (1, sizeof *ci
);
cp
= paddr (&addrs
[peer
->sock
].addr
);
ci
-> localAddress
= str2qb (cp
, strlen (cp
), 1);
cp
= paddr (&peer
-> src
);
ci
-> remoteAddress
= str2qb (cp
, strlen (cp
), 1);
ci
-> flags
= pe_alloc (PE_CLASS_UNIV
, PE_FORM_PRIM
, PE_PRIM_BITS
);
#define setflbit(x,y) if (peer -> flags & (x)) bit_on (ci -> flags, (y))
setflbit (PEER_FL_CONFIG
, bit_NTP_flags_configured
);
setflbit (PEER_FL_AUTHENABLE
, bit_NTP_flags_authentable
);
setflbit (PEER_FL_SANE
, bit_NTP_flags_sane
);
setflbit (PEER_FL_CANDIDATE
, bit_NTP_flags_candidate
);
setflbit (PEER_FL_SYNC
, bit_NTP_flags_sync
);
setflbit (PEER_FL_BCAST
, bit_NTP_flags_broadcast
);
setflbit (PEER_FL_REFCLOCK
, bit_NTP_flags_referenceClock
);
setflbit (PEER_FL_SELECTED
, bit_NTP_flags_selected
);
setflbit (PEER_FL_SNOOZE
, bit_NTP_flags_inactive
);
bit_on (ci
-> flags
, bit_NTP_flags_selected
);
ci
-> packetsSent
= peer
-> pkt_sent
;
ci
-> packetsReceived
= peer
-> pkt_rcvd
;
ci
-> packetsDropped
= peer
-> pkt_dropped
;
ci
-> timer
= peer
-> timer
;
ci
-> leap
= (struct type_NTP_Leap
*) calloc (1, sizeof *ci
-> leap
);
ci
-> leap
-> parm
= peer
-> leap
;
ci
-> stratum
= peer
-> stratum
;
ci
-> ppoll
= peer
-> ppoll
;
ci
-> hpoll
= peer
-> hpoll
;
ci
-> precision
= peer
-> precision
;
ci
-> reachability
= peer
-> reach
& NTP_WINDOW_SHIFT_MASK
;
ci
-> estdisp
= peer
-> estdisp
* 1000.0;
ci
-> estdelay
= peer
-> estdelay
* 1000.0;
ci
-> estoffset
= peer
-> estoffset
* 1000.0;
ci
-> reference
= cli_refid (peer
-> refid
);
ci
-> reftime
= sstamp (&peer
-> reftime
);
int query_func (sd
, ryo
, rox
, in
, roi
)
struct RoSAPindication
*roi
;
struct type_NTP_ClockInfoList
*clbase
, *cl
;
for (peer
= peer_list
.head
; peer
!= NULL
; peer
= peer
-> next
) {
clbase
= cl
= (struct type_NTP_ClockInfoList
*)
cl
-> next
= (struct type_NTP_ClockInfoList
*)
cl
-> ClockInfo
= peer2clock (peer
);
if (RyDsResult (sd
, rox
-> rox_id
, (caddr_t
) clbase
,
ROS_NOPRIO
, roi
) == NOTOK
)
ros_advise (&roi
-> roi_preject
, "RyDsResult failed");
free_NTP_ClockInfoList (clbase
);