1c0b746e5SOllivier Robert#!/local/bin/perl --*-perl-*- 2c0b746e5SOllivier Robert;# 3c0b746e5SOllivier Robert;# ntptrap,v 3.1 1993/07/06 01:09:15 jbj Exp 4c0b746e5SOllivier Robert;# 5c0b746e5SOllivier Robert;# a client for the xntp mode 6 trap mechanism 6c0b746e5SOllivier Robert;# 7c0b746e5SOllivier Robert;# Copyright (c) 1992 8c0b746e5SOllivier Robert;# Rainer Pruy Friedrich-Alexander Universitaet Erlangen-Nuernberg 9c0b746e5SOllivier Robert;# 10c0b746e5SOllivier Robert;# 11c0b746e5SOllivier Robert;############################################################# 12c0b746e5SOllivier Robert$0 =~ s!^.*/([^/]+)$!$1!; # strip to filename 13c0b746e5SOllivier Robert;# enforce STDOUT and STDERR to be line buffered 14c0b746e5SOllivier Robert$| = 1; 15c0b746e5SOllivier Robertselect((select(STDERR),$|=1)[$[]); 16c0b746e5SOllivier Robert 17c0b746e5SOllivier Robert;####################################### 18c0b746e5SOllivier Robert;# load utility routines and definitions 19c0b746e5SOllivier Robert;# 20c0b746e5SOllivier Robertrequire('ntp.pl'); # implementation of the NTP protocol 21c0b746e5SOllivier Robertuse Socket; 22c0b746e5SOllivier Robert 23c0b746e5SOllivier Robert#eval { require('sys/socket.ph'); require('netinet/in.ph') unless defined(&INADDR_ANY); } || 24c0b746e5SOllivier Robert#do { 25c0b746e5SOllivier Robert #die("$0: $@") unless $[ == index($@, "Can't locate "); 26c0b746e5SOllivier Robert #warn "$0: $@"; 27c0b746e5SOllivier Robert #warn "$0: supplying some default definitions\n"; 28c0b746e5SOllivier Robert #eval 'sub INADDR_ANY { 0; } sub AF_INET {2;} sub SOCK_DGRAM {2;} 1;' || die "$0: $@"; 29c0b746e5SOllivier Robert#}; 30c0b746e5SOllivier Robertrequire('getopts.pl'); # option parsing 31c0b746e5SOllivier Robertrequire('ctime.pl'); # date/time formatting 32c0b746e5SOllivier Robert 33c0b746e5SOllivier Robert;###################################### 34c0b746e5SOllivier Robert;# define some global constants 35c0b746e5SOllivier Robert;# 36c0b746e5SOllivier Robert$BASE_TIMEOUT=10; 37c0b746e5SOllivier Robert$FRAG_TIMEOUT=10; 38c0b746e5SOllivier Robert$MAX_TRY = 5; 39c0b746e5SOllivier Robert$REFRESH_TIME=60*15; # 15 minutes (server uses 1 hour) 40c0b746e5SOllivier Robert$ntp'timeout = $FRAG_TIMEOUT; #'; 41c0b746e5SOllivier Robert$ntp'timeout if 0; 42c0b746e5SOllivier Robert 43c0b746e5SOllivier Robert;###################################### 44c0b746e5SOllivier Robert;# now process options 45c0b746e5SOllivier Robert;# 46c0b746e5SOllivier Robertsub usage 47c0b746e5SOllivier Robert{ 48*2b15cb3dSCy Schubert die("usage: $0 [-p <port>] [-l <logfile>] [host] ...\n"); 49c0b746e5SOllivier Robert} 50c0b746e5SOllivier Robert 51c0b746e5SOllivier Robert&usage unless &Getopts('l:p:'); 52c0b746e5SOllivier Robert&Getopts if 0; # make -w happy 53c0b746e5SOllivier Robert 54*2b15cb3dSCy Schubert$opt_l = "/dev/null" # where to write debug messages to 55*2b15cb3dSCy Schubert if (!$opt_l); 56*2b15cb3dSCy Schubert$opt_p = 0 # port to use locally - (0 does mean: will be chosen by kernel) 57*2b15cb3dSCy Schubert if (!$opt_p); 58*2b15cb3dSCy Schubert 59c0b746e5SOllivier Robert@Hosts = ($#ARGV < $[) ? ("localhost") : @ARGV; 60c0b746e5SOllivier Robert 61c0b746e5SOllivier Robert;# setup for debug output 62c0b746e5SOllivier Robert$DEBUGFILE=$opt_l; 63c0b746e5SOllivier Robert$DEBUGFILE="&STDERR" if $DEBUGFILE eq '-'; 64c0b746e5SOllivier Robert 65c0b746e5SOllivier Robertopen(DEBUG,">>$DEBUGFILE") || die("Cannot open \"$DEBUGFILE\": $!\n"); 66c0b746e5SOllivier Robertselect((select(DEBUG),$|=1)[$[]); 67c0b746e5SOllivier Robert 68c0b746e5SOllivier Robert;# &log prints a single trap record (adding a (local) time stamp) 69c0b746e5SOllivier Robertsub log 70c0b746e5SOllivier Robert{ 71c0b746e5SOllivier Robert chop($date=&ctime(time)); 72c0b746e5SOllivier Robert print "$date ",@_,"\n"; 73c0b746e5SOllivier Robert} 74c0b746e5SOllivier Robert 75c0b746e5SOllivier Robertsub debug 76c0b746e5SOllivier Robert{ 77c0b746e5SOllivier Robert print DEBUG @_,"\n"; 78c0b746e5SOllivier Robert} 79c0b746e5SOllivier Robert;# 80c0b746e5SOllivier Robert$proto_udp = (getprotobyname('udp'))[$[+2] || 81c0b746e5SOllivier Robert (warn("$0: Could not get protocoll number for 'udp' using 17"), 17); 82c0b746e5SOllivier Robert 83c0b746e5SOllivier Robert$ntp_port = (getservbyname('ntp','udp'))[$[+2] || 84c0b746e5SOllivier Robert (warn("$0: Could not get port number for service ntp/udp using 123"), 123); 85c0b746e5SOllivier Robert 86c0b746e5SOllivier Robert;# 87c0b746e5SOllivier Robertsocket(S, &AF_INET, &SOCK_DGRAM, $proto_udp) || die("Cannot open socket: $!\n"); 88c0b746e5SOllivier Robert 89c0b746e5SOllivier Robert;# 90c0b746e5SOllivier Robertbind(S, pack("S n a4 x8", &AF_INET, $opt_p, &INADDR_ANY)) || 91c0b746e5SOllivier Robert die("Cannot bind: $!\n"); 92c0b746e5SOllivier Robert 93c0b746e5SOllivier Robert($my_port, $my_addr) = (unpack("S n a4 x8",getsockname(S)))[$[+1,$[+2]; 94c0b746e5SOllivier Robert&log(sprintf("Listening at address %d.%d.%d.%d port %d", 95c0b746e5SOllivier Robert unpack("C4",$my_addr), $my_port)); 96c0b746e5SOllivier Robert 97c0b746e5SOllivier Robert;# disregister with all servers in case of termination 98c0b746e5SOllivier Robertsub cleanup 99c0b746e5SOllivier Robert{ 100c0b746e5SOllivier Robert &log("Aborted by signal \"$_[$[]\"") if defined($_[$[]); 101c0b746e5SOllivier Robert 102c0b746e5SOllivier Robert foreach (@Hosts) 103c0b746e5SOllivier Robert { 104c0b746e5SOllivier Robert if ( ! defined($Host{$_}) ) 105c0b746e5SOllivier Robert { 106c0b746e5SOllivier Robert print "no info for host '$_'\n"; 107c0b746e5SOllivier Robert next; 108c0b746e5SOllivier Robert } 109c0b746e5SOllivier Robert &ntp'send(S,31,0,"",pack("Sna4x8",&AF_INET,$ntp_port,$Host{$_})); #'; 110c0b746e5SOllivier Robert } 111c0b746e5SOllivier Robert close(S); 112c0b746e5SOllivier Robert exit(2); 113c0b746e5SOllivier Robert} 114c0b746e5SOllivier Robert 115c0b746e5SOllivier Robert$SIG{'HUP'} = 'cleanup'; 116c0b746e5SOllivier Robert$SIG{'INT'} = 'cleanup'; 117c0b746e5SOllivier Robert$SIG{'QUIT'} = 'cleanup'; 118c0b746e5SOllivier Robert$SIG{'TERM'} = 'cleanup'; 119c0b746e5SOllivier Robert 120c0b746e5SOllivier Robert0 && $a && $b; 121c0b746e5SOllivier Robertsub timeouts # sort timeout id array 122c0b746e5SOllivier Robert{ 123c0b746e5SOllivier Robert $TIMEOUTS{$a} <=> $TIMEOUTS{$b}; 124c0b746e5SOllivier Robert} 125c0b746e5SOllivier Robert 126c0b746e5SOllivier Robert;# a Request element looks like: pack("a4SC",addr,associd,op) 127c0b746e5SOllivier Robert@Requests= (); 128c0b746e5SOllivier Robert 129c0b746e5SOllivier Robert;# compute requests for set trap control msgs to each host given 130c0b746e5SOllivier Robert{ 131c0b746e5SOllivier Robert local($name,$addr); 132c0b746e5SOllivier Robert 133c0b746e5SOllivier Robert foreach (@Hosts) 134c0b746e5SOllivier Robert { 135c0b746e5SOllivier Robert if (/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) 136c0b746e5SOllivier Robert { 137c0b746e5SOllivier Robert ($name,$addr) = 138c0b746e5SOllivier Robert (gethostbyaddr(pack("C4",$1,$2,$3,$4),&AF_INET))[$[,$[+4]; 139c0b746e5SOllivier Robert unless (defined($name)) 140c0b746e5SOllivier Robert { 141c0b746e5SOllivier Robert $name = sprintf("[[%d.%d.%d.%d]]",$1,$2,$3,$4); 142c0b746e5SOllivier Robert $addr = pack("C4",$1,$2,$3,$4); 143c0b746e5SOllivier Robert } 144c0b746e5SOllivier Robert } 145c0b746e5SOllivier Robert else 146c0b746e5SOllivier Robert { 147c0b746e5SOllivier Robert ($name,$addr) = (gethostbyname($_))[$[,$[+4]; 148c0b746e5SOllivier Robert unless (defined($name)) 149c0b746e5SOllivier Robert { 150c0b746e5SOllivier Robert warn "$0: unknown host \"$_\" - ignored\n"; 151c0b746e5SOllivier Robert next; 152c0b746e5SOllivier Robert } 153c0b746e5SOllivier Robert } 154c0b746e5SOllivier Robert next if defined($Host{$name}); 155c0b746e5SOllivier Robert $Host{$name} = $addr; 156c0b746e5SOllivier Robert $Host{$_} = $addr; 157c0b746e5SOllivier Robert push(@Requests,pack("a4SC",$addr,0,6)); # schedule a set trap request for $name 158c0b746e5SOllivier Robert } 159c0b746e5SOllivier Robert} 160c0b746e5SOllivier Robert 161c0b746e5SOllivier Robertsub hostname 162c0b746e5SOllivier Robert{ 163c0b746e5SOllivier Robert local($addr) = @_; 164c0b746e5SOllivier Robert return $HostName{$addr} if defined($HostName{$addr}); 165c0b746e5SOllivier Robert local($name) = gethostbyaddr($addr,&AF_INET); 166c0b746e5SOllivier Robert &debug(sprintf("hostname(%d.%d.%d.%d) = \"%s\"",unpack("C4",$addr),$name)) 167c0b746e5SOllivier Robert if defined($name); 168c0b746e5SOllivier Robert defined($name) && ($HostName{$addr} = $name) && (return $name); 169c0b746e5SOllivier Robert &debug(sprintf("Failed to get name for %d.%d.%d.%d",unpack("C4",$addr))); 170c0b746e5SOllivier Robert return sprintf("[%d.%d.%d.%d]",unpack("C4",$addr)); 171c0b746e5SOllivier Robert} 172c0b746e5SOllivier Robert 173c0b746e5SOllivier Robert;# when no hosts were given on the commandline no requests have been scheduled 174c0b746e5SOllivier Robert&usage unless (@Requests); 175c0b746e5SOllivier Robert 176c0b746e5SOllivier Robert&debug(sprintf("%d request(s) scheduled",scalar(@Requests))); 177c0b746e5SOllivier Robertgrep(&debug(" - ".$_),keys(%Host)); 178c0b746e5SOllivier Robert 179c0b746e5SOllivier Robert;# allocate variables; 180c0b746e5SOllivier Robert$addr=""; 181c0b746e5SOllivier Robert$assoc=0; 182c0b746e5SOllivier Robert$op = 0; 183c0b746e5SOllivier Robert$timeout = 0; 184c0b746e5SOllivier Robert$ret=""; 185c0b746e5SOllivier Robert%TIMEOUTS = (); 186c0b746e5SOllivier Robert%TIMEOUT_PROCS = (); 187c0b746e5SOllivier Robert@TIMEOUTS = (); 188c0b746e5SOllivier Robert 189c0b746e5SOllivier Robert$len = 512; 190c0b746e5SOllivier Robert$buf = " " x $len; 191c0b746e5SOllivier Robert 192c0b746e5SOllivier Robertwhile (1) 193c0b746e5SOllivier Robert{ 194c0b746e5SOllivier Robert if (@Requests || @TIMEOUTS) # if there is some work pending 195c0b746e5SOllivier Robert { 196c0b746e5SOllivier Robert if (@Requests) 197c0b746e5SOllivier Robert { 198c0b746e5SOllivier Robert ($addr,$assoc,$op) = unpack("a4SC",($req = shift(@Requests))); 199c0b746e5SOllivier Robert &debug(sprintf("Request: %s: %s(%d)",&hostname($addr), &ntp'cntrlop_name($op), $assoc)); #';)) 200c0b746e5SOllivier Robert $ret = &ntp'send(S,$op,$assoc,"", #'( 201c0b746e5SOllivier Robert pack("Sna4x8",&AF_INET,$ntp_port,$addr)); 202c0b746e5SOllivier Robert &set_timeout("retry-".unpack("H*",$req),time+$BASE_TIMEOUT, 203c0b746e5SOllivier Robert sprintf("&retry(\"%s\");",unpack("H*",$req))); 204c0b746e5SOllivier Robert 205c0b746e5SOllivier Robert last unless (defined($ret)); # warn called by ntp'send(); 206c0b746e5SOllivier Robert 207c0b746e5SOllivier Robert ;# if there are more requests just have a quick look for new messages 208c0b746e5SOllivier Robert ;# otherwise grant server time for a response 209c0b746e5SOllivier Robert $timeout = @Requests ? 0 : $BASE_TIMEOUT; 210c0b746e5SOllivier Robert } 211c0b746e5SOllivier Robert if ($timeout && @TIMEOUTS) 212c0b746e5SOllivier Robert { 213c0b746e5SOllivier Robert ;# ensure not to miss a timeout 214c0b746e5SOllivier Robert if ($timeout + time > $TIMEOUTS{$TIMEOUTS[$[]}) 215c0b746e5SOllivier Robert { 216c0b746e5SOllivier Robert $timeout = $TIMEOUTS{$TIMEOUTS[$[]} - time; 217c0b746e5SOllivier Robert $timeout = 0 if $timeout < 0; 218c0b746e5SOllivier Robert } 219c0b746e5SOllivier Robert } 220c0b746e5SOllivier Robert } 221c0b746e5SOllivier Robert else 222c0b746e5SOllivier Robert { 223c0b746e5SOllivier Robert ;# no work yet - wait for some messages dropping in 224c0b746e5SOllivier Robert ;# usually this will not hapen as the refresh semantic will 225c0b746e5SOllivier Robert ;# always have a pending timeout 226c0b746e5SOllivier Robert undef($timeout); 227c0b746e5SOllivier Robert } 228c0b746e5SOllivier Robert 229c0b746e5SOllivier Robert vec($mask="",fileno(S),1) = 1; 230c0b746e5SOllivier Robert $ret = select($mask,undef,undef,$timeout); 231c0b746e5SOllivier Robert 232c0b746e5SOllivier Robert warn("$0: select: $!\n"),last if $ret < 0; # give up on error return from select 233c0b746e5SOllivier Robert 234c0b746e5SOllivier Robert if ($ret == 0) 235c0b746e5SOllivier Robert { 236c0b746e5SOllivier Robert ;# timeout 237c0b746e5SOllivier Robert if (@TIMEOUTS && time > $TIMEOUTS{$TIMEOUTS[$[]}) 238c0b746e5SOllivier Robert { 239c0b746e5SOllivier Robert ;# handle timeout 240c0b746e5SOllivier Robert $timeout_proc = 241c0b746e5SOllivier Robert (delete $TIMEOUT_PROCS{$TIMEOUTS[$[]}, 242c0b746e5SOllivier Robert delete $TIMEOUTS{shift(@TIMEOUTS)})[$[]; 243c0b746e5SOllivier Robert eval $timeout_proc; 244c0b746e5SOllivier Robert die "timeout eval (\"$timeout_proc\"): $@\n" if $@; 245c0b746e5SOllivier Robert } 246c0b746e5SOllivier Robert ;# else: there may be something to be sent 247c0b746e5SOllivier Robert } 248c0b746e5SOllivier Robert else 249c0b746e5SOllivier Robert { 250c0b746e5SOllivier Robert ;# data avail 251c0b746e5SOllivier Robert $from = recv(S,$buf,$len,0); 252c0b746e5SOllivier Robert ;# give up on error return from recv 253c0b746e5SOllivier Robert warn("$0: recv: $!\n"), last unless (defined($from)); 254c0b746e5SOllivier Robert 255c0b746e5SOllivier Robert $from = (unpack("Sna4",$from))[$[+2]; # keep host addr only 256c0b746e5SOllivier Robert ;# could check for ntp_port - but who cares 257c0b746e5SOllivier Robert &debug("-Packet from ",&hostname($from)); 258c0b746e5SOllivier Robert 259c0b746e5SOllivier Robert ;# stuff packet into ntp mode 6 receive machinery 260c0b746e5SOllivier Robert ($ret,$data,$status,$associd,$op,$seq,$auth_keyid) = 261c0b746e5SOllivier Robert &ntp'handle_packet($buf,$from); # '; 262c0b746e5SOllivier Robert &debug(sprintf("%s uses auth_keyid %d",&hostname($from),$auth_keyid)) if defined($auth_keyid); 263c0b746e5SOllivier Robert next unless defined($ret); 264c0b746e5SOllivier Robert 265c0b746e5SOllivier Robert if ($ret eq "") 266c0b746e5SOllivier Robert { 267c0b746e5SOllivier Robert ;# handle packet 268c0b746e5SOllivier Robert ;# simple trap response messages have neither timeout nor retries 269c0b746e5SOllivier Robert &clear_timeout("retry-".unpack("H*",pack("a4SC",$from,$associd,$op))) unless $op == 7; 270c0b746e5SOllivier Robert delete $RETRY{pack("a4SC",$from,$associd,$op)} unless $op == 7; 271c0b746e5SOllivier Robert 272c0b746e5SOllivier Robert &process_response($from,$ret,$data,$status,$associd,$op,$seq,$auth_keyid); 273c0b746e5SOllivier Robert } 274c0b746e5SOllivier Robert else 275c0b746e5SOllivier Robert { 276c0b746e5SOllivier Robert ;# some kind of error 277c0b746e5SOllivier Robert &log(sprintf("%50s: %s: %s",(gethostbyaddr($from,&AF_INET))[$[],$ret,$data)); 278c0b746e5SOllivier Robert if ($ret ne "TIMEOUT" && $ret ne "ERROR") 279c0b746e5SOllivier Robert { 280c0b746e5SOllivier Robert &clear_timeout("retry-".unpack("H*",pack("a4SC",$from,$associd,$op))); 281c0b746e5SOllivier Robert } 282c0b746e5SOllivier Robert } 283c0b746e5SOllivier Robert } 284c0b746e5SOllivier Robert 285c0b746e5SOllivier Robert} 286c0b746e5SOllivier Robert 287c0b746e5SOllivier Robertwarn("$0: terminating\n"); 288c0b746e5SOllivier Robert&cleanup; 289c0b746e5SOllivier Robertexit 0; 290c0b746e5SOllivier Robert 291c0b746e5SOllivier Robert;################################################## 292c0b746e5SOllivier Robert;# timeout support 293c0b746e5SOllivier Robert;# 294c0b746e5SOllivier Robertsub set_timeout 295c0b746e5SOllivier Robert{ 296c0b746e5SOllivier Robert local($id,$time,$proc) = @_; 297c0b746e5SOllivier Robert 298c0b746e5SOllivier Robert $TIMEOUTS{$id} = $time; 299c0b746e5SOllivier Robert $TIMEOUT_PROCS{$id} = $proc; 300c0b746e5SOllivier Robert @TIMEOUTS = sort timeouts keys(%TIMEOUTS); 301c0b746e5SOllivier Robert chop($date=&ctime($time)); 302c0b746e5SOllivier Robert &debug(sprintf("Schedule timeout \"%s\" for %s", $id, $date)); 303c0b746e5SOllivier Robert} 304c0b746e5SOllivier Robert 305c0b746e5SOllivier Robertsub clear_timeout 306c0b746e5SOllivier Robert{ 307c0b746e5SOllivier Robert local($id) = @_; 308c0b746e5SOllivier Robert delete $TIMEOUTS{$id}; 309c0b746e5SOllivier Robert delete $TIMEOUT_PROCS{$id}; 310c0b746e5SOllivier Robert @TIMEOUTS = sort timeouts keys(%TIMEOUTS); 311c0b746e5SOllivier Robert &debug("Clear timeout \"$id\""); 312c0b746e5SOllivier Robert} 313c0b746e5SOllivier Robert 314c0b746e5SOllivier Robert0 && &refresh; 315c0b746e5SOllivier Robertsub refresh 316c0b746e5SOllivier Robert{ 317c0b746e5SOllivier Robert local($addr) = @_[$[]; 318c0b746e5SOllivier Robert $addr = pack("H*",$addr); 319c0b746e5SOllivier Robert &debug(sprintf("Refreshing trap for %s", &hostname($addr))); 320c0b746e5SOllivier Robert push(@Requests,pack("a4SC",$addr,0,6)); 321c0b746e5SOllivier Robert} 322c0b746e5SOllivier Robert 323c0b746e5SOllivier Robert0 && &retry; 324c0b746e5SOllivier Robertsub retry 325c0b746e5SOllivier Robert{ 326c0b746e5SOllivier Robert local($tag) = @_; 327c0b746e5SOllivier Robert $tag = pack("H*",$tag); 328c0b746e5SOllivier Robert $RETRY{$tag} = 0 if (!defined($RETRY{$tag})); 329c0b746e5SOllivier Robert 330c0b746e5SOllivier Robert if (++$RETRY{$tag} > $MAX_TRY) 331c0b746e5SOllivier Robert { 332c0b746e5SOllivier Robert &debug(sprintf("Retry failed: %s assoc %5d op %d", 333c0b746e5SOllivier Robert &hostname(substr($tag,$[,4)), 334c0b746e5SOllivier Robert unpack("x4SC",$tag))); 335c0b746e5SOllivier Robert return; 336c0b746e5SOllivier Robert } 337c0b746e5SOllivier Robert &debug(sprintf("Retrying: %s assoc %5d op %d", 338c0b746e5SOllivier Robert &hostname(substr($tag,$[,4)), 339c0b746e5SOllivier Robert unpack("x4SC",$tag))); 340c0b746e5SOllivier Robert push(@Requests,$tag); 341c0b746e5SOllivier Robert} 342c0b746e5SOllivier Robert 343c0b746e5SOllivier Robertsub process_response 344c0b746e5SOllivier Robert{ 345c0b746e5SOllivier Robert local($from,$ret,$data,$status,$associd,$op,$seq,$auth_keyid) = @_; 346c0b746e5SOllivier Robert 347c0b746e5SOllivier Robert $msg=""; 348c0b746e5SOllivier Robert if ($op == 7) # trap response 349c0b746e5SOllivier Robert { 350c0b746e5SOllivier Robert $msg .= sprintf("%40s trap#%-5d", 351c0b746e5SOllivier Robert &hostname($from),$seq); 352c0b746e5SOllivier Robert &debug (sprintf("\nTrap %d associd %d:\n%s\n===============\n",$seq,$associd,$data)); 353c0b746e5SOllivier Robert if ($associd == 0) # system event 354c0b746e5SOllivier Robert { 355c0b746e5SOllivier Robert $msg .= " SYSTEM "; 356c0b746e5SOllivier Robert $evnt = &ntp'SystemEvent($status); #'; 357c0b746e5SOllivier Robert $msg .= "$evnt "; 358c0b746e5SOllivier Robert ;# for special cases add additional info 359c0b746e5SOllivier Robert ($stratum) = ($data =~ /stratum=(\d+)/); 360c0b746e5SOllivier Robert ($refid) = ($data =~ /refid=([\w\.]+)/); 361c0b746e5SOllivier Robert $msg .= "stratum=$stratum refid=$refid"; 362c0b746e5SOllivier Robert if ($refid =~ /\[?(\d+)\.(\d+)\.(\d+)\.(\d+)/) 363c0b746e5SOllivier Robert { 364c0b746e5SOllivier Robert local($x) = (gethostbyaddr(pack("C4",$1,$2,$3,$4),&AF_INET)); 365c0b746e5SOllivier Robert $msg .= " " . $x if defined($x) 366c0b746e5SOllivier Robert } 367c0b746e5SOllivier Robert if ($evnt eq "event_sync_chg") 368c0b746e5SOllivier Robert { 369c0b746e5SOllivier Robert $msg .= sprintf("%s %s ", 370c0b746e5SOllivier Robert &ntp'LI($status), #', 371c0b746e5SOllivier Robert &ntp'ClockSource($status) #' 372c0b746e5SOllivier Robert ); 373c0b746e5SOllivier Robert } 374c0b746e5SOllivier Robert elsif ($evnt eq "event_sync/strat_chg") 375c0b746e5SOllivier Robert { 376c0b746e5SOllivier Robert ($peer) = ($data =~ /peer=([0-9]+)/); 377c0b746e5SOllivier Robert $msg .= " peer=$peer"; 378c0b746e5SOllivier Robert } 379c0b746e5SOllivier Robert elsif ($evnt eq "event_clock_excptn") 380c0b746e5SOllivier Robert { 381c0b746e5SOllivier Robert if (($device) = ($data =~ /device=\"([^\"]+)\"/)) 382c0b746e5SOllivier Robert { 383c0b746e5SOllivier Robert ($cstatus) = ($data =~ /refclockstatus=0?x?([\da-fA-F]+)/); 384c0b746e5SOllivier Robert $Cstatus = hex($cstatus); 385c0b746e5SOllivier Robert $msg .= sprintf("- %-32s",&ntp'clock_status($Cstatus)); #'); 386c0b746e5SOllivier Robert ($timecode) = ($data =~ /timecode=\"([^\"]+)\"/); 387c0b746e5SOllivier Robert $msg .= " \"$device\" \"$timecode\""; 388c0b746e5SOllivier Robert } 389c0b746e5SOllivier Robert else 390c0b746e5SOllivier Robert { 391c0b746e5SOllivier Robert push(@Requests,pack("a4SC",$from, $associd, 4)); 392c0b746e5SOllivier Robert } 393c0b746e5SOllivier Robert } 394c0b746e5SOllivier Robert } 395c0b746e5SOllivier Robert else # peer event 396c0b746e5SOllivier Robert { 397c0b746e5SOllivier Robert $msg .= sprintf("peer %5d ",$associd); 398c0b746e5SOllivier Robert ($srcadr) = ($data =~ /srcadr=\[?([\d\.]+)/); 399c0b746e5SOllivier Robert $msg .= sprintf("%-18s %40s ", "[$srcadr]", 400c0b746e5SOllivier Robert &hostname(pack("C4",split(/\./,$srcadr)))); 401c0b746e5SOllivier Robert $evnt = &ntp'PeerEvent($status); #'; 402c0b746e5SOllivier Robert $msg .= "$evnt "; 403c0b746e5SOllivier Robert ;# for special cases include additional info 404c0b746e5SOllivier Robert if ($evnt eq "event_clock_excptn") 405c0b746e5SOllivier Robert { 406c0b746e5SOllivier Robert if (($device) = ($data =~ /device=\"([^\"]+)\"/)) 407c0b746e5SOllivier Robert { 408c0b746e5SOllivier Robert ;#&debug("----\n$data\n====\n"); 409c0b746e5SOllivier Robert ($cstatus) = ($data =~ /refclockstatus=0?x?([\da-fA-F]+)/); 410c0b746e5SOllivier Robert $Cstatus = hex($cstatus); 411c0b746e5SOllivier Robert $msg .= sprintf("- %-32s",&ntp'clock_status($Cstatus)); #'); 412c0b746e5SOllivier Robert ($timecode) = ($data =~ /timecode=\"([^\"]+)\"/); 413c0b746e5SOllivier Robert $msg .= " \"$device\" \"$timecode\""; 414c0b746e5SOllivier Robert } 415c0b746e5SOllivier Robert else 416c0b746e5SOllivier Robert { 417c0b746e5SOllivier Robert ;# no clockvars included - post a cv request 418c0b746e5SOllivier Robert push(@Requests,pack("a4SC",$from, $associd, 4)); 419c0b746e5SOllivier Robert } 420c0b746e5SOllivier Robert } 421c0b746e5SOllivier Robert elsif ($evnt eq "event_stratum_chg") 422c0b746e5SOllivier Robert { 423c0b746e5SOllivier Robert ($stratum) = ($data =~ /stratum=(\d+)/); 424c0b746e5SOllivier Robert $msg .= "new stratum $stratum"; 425c0b746e5SOllivier Robert } 426c0b746e5SOllivier Robert } 427c0b746e5SOllivier Robert } 428c0b746e5SOllivier Robert elsif ($op == 6) # set trap resonse 429c0b746e5SOllivier Robert { 430c0b746e5SOllivier Robert &debug("Set trap ok from ",&hostname($from)); 431c0b746e5SOllivier Robert &set_timeout("refresh-".unpack("H*",$from),time+$REFRESH_TIME, 432c0b746e5SOllivier Robert sprintf("&refresh(\"%s\");",unpack("H*",$from))); 433c0b746e5SOllivier Robert return; 434c0b746e5SOllivier Robert } 435c0b746e5SOllivier Robert elsif ($op == 4) # read clock variables response 436c0b746e5SOllivier Robert { 437c0b746e5SOllivier Robert ;# status of clock 438c0b746e5SOllivier Robert $msg .= sprintf(" %40s ", &hostname($from)); 439c0b746e5SOllivier Robert if ($associd == 0) 440c0b746e5SOllivier Robert { 441c0b746e5SOllivier Robert $msg .= "system clock status: "; 442c0b746e5SOllivier Robert } 443c0b746e5SOllivier Robert else 444c0b746e5SOllivier Robert { 445c0b746e5SOllivier Robert $msg .= sprintf("peer %5d clock",$associd); 446c0b746e5SOllivier Robert } 447c0b746e5SOllivier Robert $msg .= sprintf("%-32s",&ntp'clock_status($status)); #'); 448c0b746e5SOllivier Robert ($device) = ($data =~ /device=\"([^\"]+)\"/); 449c0b746e5SOllivier Robert ($timecode) = ($data =~ /timecode=\"([^\"]+)\"/); 450c0b746e5SOllivier Robert $msg .= " \"$device\" \"$timecode\""; 451c0b746e5SOllivier Robert } 452c0b746e5SOllivier Robert elsif ($op == 31) # unset trap response (UNOFFICIAL op) 453c0b746e5SOllivier Robert { 454c0b746e5SOllivier Robert ;# clear timeout 455c0b746e5SOllivier Robert &debug("Clear Trap ok from ",&hostname($from)); 456c0b746e5SOllivier Robert &clear_timeout("refresh-".unpack("H*",$from)); 457c0b746e5SOllivier Robert return; 458c0b746e5SOllivier Robert } 459c0b746e5SOllivier Robert else # unexpected response 460c0b746e5SOllivier Robert { 461c0b746e5SOllivier Robert $msg .= "unexpected response to op $op assoc=$associd"; 462c0b746e5SOllivier Robert $msg .= sprintf(" status=%04x",$status); 463c0b746e5SOllivier Robert } 464c0b746e5SOllivier Robert &log($msg); 465c0b746e5SOllivier Robert} 466