1 1.1 kardel #!/usr/bin/perl -w 2 1.1 kardel ;# 3 1.1 kardel ;# ntp.pl,v 3.1 1993/07/06 01:09:09 jbj Exp 4 1.1 kardel ;# 5 1.1 kardel ;# process loop filter statistics file and either 6 1.1 kardel ;# - show statistics periodically using gnuplot 7 1.1 kardel ;# - or print a single plot 8 1.1 kardel ;# 9 1.1 kardel ;# Copyright (c) 1992 10 1.1 kardel ;# Rainer Pruy Friedrich-Alexander Universitaet Erlangen-Nuernberg 11 1.1 kardel ;# 12 1.1 kardel ;# 13 1.1 kardel ;############################################################# 14 1.1 kardel 15 1.1 kardel package ntp; 16 1.1 kardel 17 1.1 kardel $NTP_version = 2; 18 1.1 kardel $ctrl_mode=6; 19 1.1 kardel 20 1.1 kardel $byte1 = (($NTP_version & 0x7)<< 3) & 0x34 | ($ctrl_mode & 0x7); 21 1.1 kardel $MAX_DATA = 468; 22 1.1 kardel 23 1.1 kardel $sequence = 0; # initial sequence number incred before used 24 1.1 kardel $pad=4; 25 1.1 kardel $do_auth=0; # no possibility today 26 1.1 kardel $keyid=0; 27 1.1 kardel ;#list if known keys (passwords) 28 1.1 kardel %KEYS = ( 0, "\200\200\200\200\200\200\200\200", 29 1.1 kardel ); 30 1.1 kardel 31 1.1 kardel ;#----------------------------------------------------------------------------- 32 1.1 kardel ;# access routines for ntp control packet 33 1.1 kardel ;# NTP control message format 34 1.1 kardel ;# C LI|VN|MODE LI 2bit=00 VN 3bit=2(3) MODE 3bit=6 : $byte1 35 1.1 kardel ;# C R|E|M|Op R response E error M more Op opcode 36 1.1 kardel ;# n sequence 37 1.1 kardel ;# n status 38 1.1 kardel ;# n associd 39 1.1 kardel ;# n offset 40 1.1 kardel ;# n count 41 1.1 kardel ;# a+ data (+ padding) 42 1.1 kardel ;# optional authentication data 43 1.1 kardel ;# N key 44 1.1 kardel ;# N2 checksum 45 1.1 kardel 46 1.1 kardel ;# first byte of packet 47 1.1 kardel sub pkt_LI { return ($_[$[] >> 6) & 0x3; } 48 1.1 kardel sub pkt_VN { return ($_[$[] >> 3) & 0x7; } 49 1.1 kardel sub pkt_MODE { return ($_[$[] ) & 0x7; } 50 1.1 kardel 51 1.1 kardel ;# second byte of packet 52 1.1 kardel sub pkt_R { return ($_[$[] & 0x80) == 0x80; } 53 1.1 kardel sub pkt_E { return ($_[$[] & 0x40) == 0x40; } 54 1.1 kardel sub pkt_M { return ($_[$[] & 0x20) == 0x20; } 55 1.1 kardel sub pkt_OP { return $_[$[] & 0x1f; } 56 1.1 kardel 57 1.1 kardel ;#----------------------------------------------------------------------------- 58 1.1 kardel 59 1.1 kardel sub setkey 60 1.1 kardel { 61 1.1 kardel local($id,$key) = @_; 62 1.1 kardel 63 1.1 kardel $KEYS{$id} = $key if (defined($key)); 64 1.1 kardel if (! defined($KEYS{$id})) 65 1.1 kardel { 66 1.1 kardel warn "Key $id not yet specified - key not changed\n"; 67 1.1 kardel return undef; 68 1.1 kardel } 69 1.1 kardel return ($keyid,$keyid = $id)[$[]; 70 1.1 kardel } 71 1.1 kardel 72 1.1 kardel ;#----------------------------------------------------------------------------- 73 1.1 kardel sub numerical { $a <=> $b; } 74 1.1 kardel 75 1.1 kardel ;#----------------------------------------------------------------------------- 76 1.1 kardel 77 1.1 kardel sub send #' 78 1.1 kardel { 79 1.1 kardel local($fh,$opcode, $associd, $data,$address) = @_; 80 1.1 kardel $fh = caller(0)."'$fh"; 81 1.1 kardel 82 1.1 kardel local($junksize,$junk,$packet,$offset,$ret); 83 1.1 kardel $offset = 0; 84 1.1 kardel 85 1.1 kardel $sequence++; 86 1.1 kardel while(1) 87 1.1 kardel { 88 1.1 kardel $junksize = length($data); 89 1.1 kardel $junksize = $MAX_DATA if $junksize > $MAX_DATA; 90 1.1 kardel 91 1.1 kardel ($junk,$data) = $data =~ /^(.{$junksize})(.*)$/; 92 1.1 kardel $packet 93 1.1 kardel = pack("C2n5a".(($junk eq "") ? 0 : &pad($junksize+12,$pad)-12), 94 1.1 kardel $byte1, 95 1.1 kardel ($opcode & 0x1f) | ($data ? 0x20 : 0), 96 1.1 kardel $sequence, 97 1.1 kardel 0, $associd, 98 1.1 kardel $offset, $junksize, $junk); 99 1.1 kardel if ($do_auth) 100 1.1 kardel { 101 1.1 kardel ;# not yet 102 1.1 kardel } 103 1.1 kardel $offset += $junksize; 104 1.1 kardel 105 1.1 kardel if (defined($address)) 106 1.1 kardel { 107 1.1 kardel $ret = send($fh, $packet, 0, $address); 108 1.1 kardel } 109 1.1 kardel else 110 1.1 kardel { 111 1.1 kardel $ret = send($fh, $packet, 0); 112 1.1 kardel } 113 1.1 kardel 114 1.1 kardel if (! defined($ret)) 115 1.1 kardel { 116 1.1 kardel warn "send failed: $!\n"; 117 1.1 kardel return undef; 118 1.1 kardel } 119 1.1 kardel elsif ($ret != length($packet)) 120 1.1 kardel { 121 1.1 kardel warn "send failed: sent only $ret from ".length($packet). "bytes\n"; 122 1.1 kardel return undef; 123 1.1 kardel } 124 1.1 kardel return $sequence unless $data; 125 1.1 kardel } 126 1.1 kardel } 127 1.1 kardel 128 1.1 kardel ;#----------------------------------------------------------------------------- 129 1.1 kardel ;# status interpretation 130 1.1 kardel ;# 131 1.1 kardel sub getval 132 1.1 kardel { 133 1.1 kardel local($val,*list) = @_; 134 1.1 kardel 135 1.1 kardel return $list{$val} if defined($list{$val}); 136 1.1 kardel return sprintf("%s#%d",$list{"-"},$val) if defined($list{"-"}); 137 1.1 kardel return "unknown-$val"; 138 1.1 kardel } 139 1.1 kardel 140 1.1 kardel ;#--------------------------------- 141 1.1 kardel ;# system status 142 1.1 kardel ;# 143 1.1 kardel ;# format: |LI|CS|SECnt|SECode| LI=2bit CS=6bit SECnt=4bit SECode=4bit 144 1.1 kardel sub ssw_LI { return ($_[$[] >> 14) & 0x3; } 145 1.1 kardel sub ssw_CS { return ($_[$[] >> 8) & 0x3f; } 146 1.1 kardel sub ssw_SECnt { return ($_[$[] >> 4) & 0xf; } 147 1.1 kardel sub ssw_SECode { return $_[$[] & 0xf; } 148 1.1 kardel 149 1.1 kardel %LI = ( 0, "leap_none", 1, "leap_add_sec", 2, "leap_del_sec", 3, "sync_alarm", "-", "leap"); 150 1.1 kardel %ClockSource = (0, "sync_unspec", 151 1.1.1.2 christos 1, "sync_pps", 152 1.1.1.2 christos 2, "sync_lf_clock", 153 1.1 kardel 3, "sync_hf_clock", 154 1.1.1.2 christos 4, "sync_uhf_clock", 155 1.1.1.2 christos 5, "sync_local_proto", 156 1.1.1.2 christos 6, "sync_ntp", 157 1.1.1.2 christos 7, "sync_udp/time", 158 1.1.1.2 christos 8, "sync_wristwatch", 159 1.1.1.2 christos 9, "sync_telephone", 160 1.1 kardel "-", "ClockSource", 161 1.1 kardel ); 162 1.1 kardel 163 1.1 kardel %SystemEvent = (0, "event_unspec", 164 1.1.1.2 christos 1, "event_freq_not_set", 165 1.1.1.2 christos 2, "event_freq_set", 166 1.1.1.2 christos 3, "event_spike_detect", 167 1.1.1.2 christos 4, "event_freq_mode", 168 1.1.1.2 christos 5, "event_clock_sync", 169 1.1.1.2 christos 6, "event_restart", 170 1.1.1.2 christos 7, "event_panic_stop", 171 1.1.1.2 christos 8, "event_no_sys_peer", 172 1.1.1.2 christos 9, "event_leap_armed", 173 1.1.1.2 christos 10, "event_leap_disarmed", 174 1.1.1.2 christos 11, "event_leap_event", 175 1.1.1.2 christos 12, "event_clock_step", 176 1.1.1.2 christos 13, "event_kern", 177 1.1.1.2 christos 14, "event_loaded_leaps", 178 1.1.1.2 christos 15, "event_stale_leaps", 179 1.1 kardel "-", "event", 180 1.1 kardel ); 181 1.1 kardel sub LI 182 1.1 kardel { 183 1.1 kardel &getval(&ssw_LI($_[$[]),*LI); 184 1.1 kardel } 185 1.1 kardel sub ClockSource 186 1.1 kardel { 187 1.1 kardel &getval(&ssw_CS($_[$[]),*ClockSource); 188 1.1 kardel } 189 1.1 kardel 190 1.1 kardel sub SystemEvent 191 1.1 kardel { 192 1.1 kardel &getval(&ssw_SECode($_[$[]),*SystemEvent); 193 1.1 kardel } 194 1.1 kardel 195 1.1 kardel sub system_status 196 1.1 kardel { 197 1.1 kardel return sprintf("%s, %s, %d event%s, %s", &LI($_[$[]), &ClockSource($_[$[]), 198 1.1 kardel &ssw_SECnt($_[$[]), ((&ssw_SECnt($_[$[])==1) ? "" : "s"), 199 1.1 kardel &SystemEvent($_[$[])); 200 1.1 kardel } 201 1.1 kardel ;#--------------------------------- 202 1.1 kardel ;# peer status 203 1.1 kardel ;# 204 1.1 kardel ;# format: |PStat|PSel|PCnt|PCode| Pstat=6bit PSel=2bit PCnt=4bit PCode=4bit 205 1.1 kardel sub psw_PStat_config { return ($_[$[] & 0x8000) == 0x8000; } 206 1.1 kardel sub psw_PStat_authenable { return ($_[$[] & 0x4000) == 0x4000; } 207 1.1 kardel sub psw_PStat_authentic { return ($_[$[] & 0x2000) == 0x2000; } 208 1.1 kardel sub psw_PStat_reach { return ($_[$[] & 0x1000) == 0x1000; } 209 1.1.1.2 christos sub psw_PStat_bcast { return ($_[$[] & 0x0800) == 0x0800; } 210 1.1 kardel sub psw_PStat { return ($_[$[] >> 10) & 0x3f; } 211 1.1 kardel sub psw_PSel { return ($_[$[] >> 8) & 0x3; } 212 1.1 kardel sub psw_PCnt { return ($_[$[] >> 4) & 0xf; } 213 1.1 kardel sub psw_PCode { return $_[$[] & 0xf; } 214 1.1 kardel 215 1.1 kardel %PeerSelection = (0, "sel_reject", 216 1.1.1.2 christos 1, "sel_falsetick", 217 1.1.1.2 christos 2, "sel_excess", 218 1.1.1.2 christos 3, "sel_outlier", 219 1.1.1.2 christos 4, "sel_candidate", 220 1.1.1.2 christos 5, "sel_backup", 221 1.1.1.2 christos 6, "sel_sys.peer", 222 1.1.1.2 christos 6, "sel_pps.peer", 223 1.1 kardel "-", "PeerSel", 224 1.1 kardel ); 225 1.1 kardel %PeerEvent = (0, "event_unspec", 226 1.1.1.2 christos 1, "event_mobilize", 227 1.1.1.2 christos 2, "event_demobilize", 228 1.1 kardel 3, "event_unreach", 229 1.1 kardel 4, "event_reach", 230 1.1.1.2 christos 5, "event_restart", 231 1.1.1.2 christos 6, "event_no_reply", 232 1.1.1.2 christos 7, "event_rate_exceed", 233 1.1.1.2 christos 8, "event_denied", 234 1.1.1.2 christos 9, "event_leap_armed", 235 1.1.1.2 christos 10, "event_sys_peer", 236 1.1.1.2 christos 11, "event_clock_event", 237 1.1.1.2 christos 12, "event_bad_auth", 238 1.1.1.2 christos 13, "event_popcorn", 239 1.1.1.2 christos 14, "event_intlv_mode", 240 1.1.1.2 christos 15, "event_intlv_err", 241 1.1 kardel "-", "event", 242 1.1 kardel ); 243 1.1 kardel 244 1.1 kardel sub PeerSelection 245 1.1 kardel { 246 1.1 kardel &getval(&psw_PSel($_[$[]),*PeerSelection); 247 1.1 kardel } 248 1.1 kardel 249 1.1 kardel sub PeerEvent 250 1.1 kardel { 251 1.1 kardel &getval(&psw_PCode($_[$[]),*PeerEvent); 252 1.1 kardel } 253 1.1 kardel 254 1.1 kardel sub peer_status 255 1.1 kardel { 256 1.1 kardel local($x) = (""); 257 1.1 kardel $x .= "config," if &psw_PStat_config($_[$[]); 258 1.1 kardel $x .= "authenable," if &psw_PStat_authenable($_[$[]); 259 1.1 kardel $x .= "authentic," if &psw_PStat_authentic($_[$[]); 260 1.1 kardel $x .= "reach," if &psw_PStat_reach($_[$[]); 261 1.1.1.2 christos $x .= "bcast," if &psw_PStat_bcast($_[$[]); 262 1.1 kardel 263 1.1 kardel $x .= sprintf(" %s, %d event%s, %s", &PeerSelection($_[$[]), 264 1.1 kardel &psw_PCnt($_[$[]), ((&psw_PCnt($_[$[]) == 1) ? "" : "s"), 265 1.1 kardel &PeerEvent($_[$[])); 266 1.1 kardel return $x; 267 1.1 kardel } 268 1.1 kardel 269 1.1 kardel ;#--------------------------------- 270 1.1 kardel ;# clock status 271 1.1 kardel ;# 272 1.1 kardel ;# format: |CStat|CEvnt| CStat=8bit CEvnt=8bit 273 1.1 kardel sub csw_CStat { return ($_[$[] >> 8) & 0xff; } 274 1.1 kardel sub csw_CEvnt { return $_[$[] & 0xff; } 275 1.1 kardel 276 1.1 kardel %ClockStatus = (0, "clk_nominal", 277 1.1 kardel 1, "clk_timeout", 278 1.1 kardel 2, "clk_badreply", 279 1.1 kardel 3, "clk_fault", 280 1.1.1.2 christos 4, "clk_badsig", 281 1.1 kardel 5, "clk_baddate", 282 1.1 kardel 6, "clk_badtime", 283 1.1 kardel "-", "clk", 284 1.1 kardel ); 285 1.1 kardel 286 1.1 kardel sub clock_status 287 1.1 kardel { 288 1.1 kardel return sprintf("%s, last %s", 289 1.1 kardel &getval(&csw_CStat($_[$[]),*ClockStatus), 290 1.1 kardel &getval(&csw_CEvnt($_[$[]),*ClockStatus)); 291 1.1 kardel } 292 1.1 kardel 293 1.1 kardel ;#--------------------------------- 294 1.1 kardel ;# error status 295 1.1 kardel ;# 296 1.1 kardel ;# format: |Err|reserved| Err=8bit 297 1.1 kardel ;# 298 1.1 kardel sub esw_Err { return ($_[$[] >> 8) & 0xff; } 299 1.1 kardel 300 1.1 kardel %ErrorStatus = (0, "err_unspec", 301 1.1 kardel 1, "err_auth_fail", 302 1.1 kardel 2, "err_invalid_fmt", 303 1.1 kardel 3, "err_invalid_opcode", 304 1.1 kardel 4, "err_unknown_assoc", 305 1.1 kardel 5, "err_unknown_var", 306 1.1 kardel 6, "err_invalid_value", 307 1.1 kardel 7, "err_adm_prohibit", 308 1.1 kardel ); 309 1.1 kardel 310 1.1 kardel sub error_status 311 1.1 kardel { 312 1.1 kardel return sprintf("%s", &getval(&esw_Err($_[$[]),*ErrorStatus)); 313 1.1 kardel } 314 1.1 kardel 315 1.1 kardel ;#----------------------------------------------------------------------------- 316 1.1 kardel ;# 317 1.1 kardel ;# cntrl op name translation 318 1.1 kardel 319 1.1.1.2 christos %CntrlOpName = (0, "reserved", 320 1.1.1.2 christos 1, "read_status", 321 1.1 kardel 2, "read_variables", 322 1.1 kardel 3, "write_variables", 323 1.1 kardel 4, "read_clock_variables", 324 1.1 kardel 5, "write_clock_variables", 325 1.1 kardel 6, "set_trap", 326 1.1 kardel 7, "trap_response", 327 1.1.1.2 christos 8, "configure", 328 1.1.1.2 christos 9, "saveconf", 329 1.1.1.2 christos 10, "read_mru", 330 1.1.1.2 christos 11, "read_ordlist", 331 1.1.1.2 christos 12, "rqst_nonce", 332 1.1 kardel 31, "unset_trap", # !!! unofficial !!! 333 1.1 kardel "-", "cntrlop", 334 1.1 kardel ); 335 1.1 kardel 336 1.1 kardel sub cntrlop_name 337 1.1 kardel { 338 1.1 kardel return &getval($_[$[],*CntrlOpName); 339 1.1 kardel } 340 1.1 kardel 341 1.1 kardel ;#----------------------------------------------------------------------------- 342 1.1 kardel 343 1.1 kardel $STAT_short_pkt = 0; 344 1.1 kardel $STAT_pkt = 0; 345 1.1 kardel 346 1.1 kardel ;# process a NTP control message (response) packet 347 1.1 kardel ;# returns a list ($ret,$data,$status,$associd,$op,$seq,$auth_keyid) 348 1.1 kardel ;# $ret: undef --> not yet complete 349 1.1 kardel ;# "" --> complete packet received 350 1.1 kardel ;# "ERROR" --> error during receive, bad packet, ... 351 1.1 kardel ;# else --> error packet - list may contain useful info 352 1.1 kardel 353 1.1 kardel 354 1.1 kardel sub handle_packet 355 1.1 kardel { 356 1.1 kardel local($pkt,$from) = @_; # parameters 357 1.1 kardel local($len_pkt) = (length($pkt)); 358 1.1 kardel ;# local(*FRAGS,*lastseen); 359 1.1 kardel local($li_vn_mode,$r_e_m_op,$seq,$status,$associd,$offset,$count,$data); 360 1.1 kardel local($autch_keyid,$auth_cksum); 361 1.1 kardel 362 1.1 kardel $STAT_pkt++; 363 1.1 kardel if ($len_pkt < 12) 364 1.1 kardel { 365 1.1 kardel $STAT_short_pkt++; 366 1.1 kardel return ("ERROR","short packet received"); 367 1.1 kardel } 368 1.1 kardel 369 1.1 kardel ;# now break packet apart 370 1.1 kardel ($li_vn_mode,$r_e_m_op,$seq,$status,$associd,$offset,$count,$data) = 371 1.1 kardel unpack("C2n5a".($len_pkt-12),$pkt); 372 1.1 kardel $data=substr($data,$[,$count); 373 1.1 kardel if ((($len_pkt - 12) - &pad($count,4)) >= 12) 374 1.1 kardel { 375 1.1 kardel ;# looks like an authenticator 376 1.1 kardel ($auth_keyid,$auth_cksum) = 377 1.1 kardel unpack("Na8",substr($pkt,$len_pkt-12+$[,12)); 378 1.1 kardel $STAT_auth++; 379 1.1 kardel ;# no checking of auth_cksum (yet ?) 380 1.1 kardel } 381 1.1 kardel 382 1.1 kardel if (&pkt_VN($li_vn_mode) != $NTP_version) 383 1.1 kardel { 384 1.1 kardel $STAT_bad_version++; 385 1.1 kardel return ("ERROR","version ".&pkt_VN($li_vn_mode)."packet ignored"); 386 1.1 kardel } 387 1.1 kardel 388 1.1 kardel if (&pkt_MODE($li_vn_mode) != $ctrl_mode) 389 1.1 kardel { 390 1.1 kardel $STAT_bad_mode++; 391 1.1 kardel return ("ERROR", "mode ".&pkt_MODE($li_vn_mode)." packet ignored"); 392 1.1 kardel } 393 1.1 kardel 394 1.1 kardel ;# handle single fragment fast 395 1.1 kardel if ($offset == 0 && &pkt_M($r_e_m_op) == 0) 396 1.1 kardel { 397 1.1 kardel $STAT_single_frag++; 398 1.1 kardel if (&pkt_E($r_e_m_op)) 399 1.1 kardel { 400 1.1 kardel $STAT_err_pkt++; 401 1.1 kardel return (&error_status($status), 402 1.1 kardel $data,$status,$associd,&pkt_OP($r_e_m_op),$seq, 403 1.1 kardel $auth_keyid); 404 1.1 kardel } 405 1.1 kardel else 406 1.1 kardel { 407 1.1 kardel return ("", 408 1.1 kardel $data,$status,$associd,&pkt_OP($r_e_m_op),$seq, 409 1.1 kardel $auth_keyid); 410 1.1 kardel } 411 1.1 kardel } 412 1.1 kardel else 413 1.1 kardel { 414 1.1 kardel ;# fragment - set up local name space 415 1.1 kardel $id = "$from$seq".&pkt_OP($r_e_m_op); 416 1.1 kardel $ID{$id} = 1; 417 1.1 kardel *FRAGS = "$id FRAGS"; 418 1.1 kardel *lastseen = "$id lastseen"; 419 1.1 kardel 420 1.1 kardel $STAT_frag++; 421 1.1 kardel 422 1.1 kardel $lastseen = 1 if !&pkt_M($r_e_m_op); 423 1.1.1.2 christos if (!%FRAGS) 424 1.1 kardel { 425 1.1 kardel print((&pkt_M($r_e_m_op) ? " more" : "")."\n"); 426 1.1 kardel $FRAGS{$offset} = $data; 427 1.1 kardel ;# save other info 428 1.1 kardel @FRAGS = ($status,$associd,&pkt_OP($r_e_m_op),$seq,$auth_keyid,$r_e_m_op); 429 1.1 kardel } 430 1.1 kardel else 431 1.1 kardel { 432 1.1 kardel print((&pkt_M($r_e_m_op) ? " more" : "")."\n"); 433 1.1 kardel ;# add frag to previous - combine on the fly 434 1.1 kardel if (defined($FRAGS{$offset})) 435 1.1 kardel { 436 1.1 kardel $STAT_dup_frag++; 437 1.1 kardel return ("ERROR","duplicate fragment at $offset seq=$seq"); 438 1.1 kardel } 439 1.1 kardel 440 1.1 kardel $FRAGS{$offset} = $data; 441 1.1 kardel 442 1.1 kardel undef($loff); 443 1.1 kardel foreach $off (sort numerical keys(%FRAGS)) 444 1.1 kardel { 445 1.1 kardel next unless defined($FRAGS{$off}); 446 1.1 kardel if (defined($loff) && 447 1.1 kardel ($loff + length($FRAGS{$loff})) == $off) 448 1.1 kardel { 449 1.1 kardel $FRAGS{$loff} .= $FRAGS{$off}; 450 1.1 kardel delete $FRAGS{$off}; 451 1.1 kardel last; 452 1.1 kardel } 453 1.1 kardel $loff = $off; 454 1.1 kardel } 455 1.1 kardel 456 1.1 kardel ;# return packet if all frags arrived 457 1.1 kardel ;# at most two frags with possible padding ??? 458 1.1 kardel if ($lastseen && defined($FRAGS{0}) && 459 1.1 kardel (((scalar(@x=sort numerical keys(%FRAGS)) == 2) && 460 1.1 kardel (length($FRAGS{0}) + 8) > $x[$[+1]) || 461 1.1 kardel (scalar(@x=sort numerical keys(%FRAGS)) < 2))) 462 1.1 kardel { 463 1.1 kardel @x=((&pkt_E($r_e_m_op) ? &error_status($status) : ""), 464 1.1 kardel $FRAGS{0},@FRAGS); 465 1.1 kardel &pkt_E($r_e_m_op) ? $STAT_err_frag++ : $STAT_frag_all++; 466 1.1 kardel undef(%FRAGS); 467 1.1 kardel undef(@FRAGS); 468 1.1 kardel undef($lastseen); 469 1.1 kardel delete $ID{$id}; 470 1.1 kardel &main'clear_timeout($id); 471 1.1 kardel return @x; 472 1.1 kardel } 473 1.1 kardel else 474 1.1 kardel { 475 1.1 kardel &main'set_timeout($id,time+$timeout,"&ntp'handle_packet_timeout(\"".unpack("H*",$id)."\");"); #'"; 476 1.1 kardel } 477 1.1 kardel } 478 1.1 kardel return (undef); 479 1.1 kardel } 480 1.1 kardel } 481 1.1 kardel 482 1.1 kardel sub handle_packet_timeout 483 1.1 kardel { 484 1.1 kardel local($id) = @_; 485 1.1 kardel local($r_e_m_op,*FRAGS,*lastseen,@x) = (@FRAGS[$[+5]); 486 1.1 kardel 487 1.1 kardel *FRAGS = "$id FRAGS"; 488 1.1 kardel *lastseen = "$id lastseen"; 489 1.1 kardel 490 1.1 kardel @x=((&pkt_E($r_e_m_op) ? &error_status($status) : "TIMEOUT"), 491 1.1 kardel $FRAGS{0},@FRAGS[$[ .. $[+4]); 492 1.1 kardel $STAT_frag_timeout++; 493 1.1 kardel undef(%FRAGS); 494 1.1 kardel undef(@FRAGS); 495 1.1 kardel undef($lastseen); 496 1.1 kardel delete $ID{$id}; 497 1.1 kardel return @x; 498 1.1 kardel } 499 1.1 kardel 500 1.1 kardel 501 1.1 kardel sub pad 502 1.1 kardel { 503 1.1 kardel return $_[$[+1] * int(($_[$[] + $_[$[+1] - 1) / $_[$[+1]); 504 1.1 kardel } 505 1.1 kardel 506 1.1 kardel 1; 507