1#!/bin/sh
2
3/usr/bin/awk '
4#
5# Based on a perl script by
6# John Hay -- John.Hay@icomtek.csir.co.za / jhay@FreeBSD.org
7#
8# awk version by Frederick Bruckman <bruckman@ntp.org>
9
10
11function usage() {
12    print "usage: ntptrace [-nv] [-r retries] [host]"
13    exit 1
14}
15
16function getargs( command, i, argc, argv, done) {
17    host = "localhost."
18    retries = 1
19
20    command = "getopt nr:v"
21    for (i = 2; i <= ARGC; i++)
22	command = command " " ARGV[i-1]
23    command | getline
24    argc = split($0, argv)
25    for (i = 1; i <= argc; i++) {
26	if (argv[i] == "-n") use_numeric = 1
27	if (argv[i] == "-v") do_verbose = 1
28	if (argv[i] == "-r") retries = argv[++i]
29	if (done == 1) host = argv[i]
30	if (argv[i] == "--") done = 1
31    }
32
33    if (retries != retries + 0)
34	usage()
35}
36
37function do_one_server( command, i, nvars, vars, stratum, peer, offset,
38	rootdelay, rootdispersion, refid, srcadr) {
39    rootdelay = 0
40    rootdispersion = 0
41    srcadr = ""
42    stratum = 255
43
44    command = "ntpq -n -c rv " host
45    while (command | getline) {
46	gsub(/,/,"")
47	nvars = split($0, vars)
48	for (i = 1; i <= nvars; i++) {
49	    if (vars[i] ~ /stratum=/) {
50		stratum = vars[i]
51		sub(/stratum=/, "", stratum)
52	    }
53	    if (vars[i] ~ /peer=/) {
54		peer = vars[i]
55		sub(/peer=/, "", peer)
56	    }
57	    if (vars[i] ~ /offset=/) {
58		offset = vars[i]
59		sub(/offset=/, "", offset)
60	    }
61	    if (vars[i] ~ /phase=/) {
62		offset = vars[i]
63		sub(/phase=/, "", offset)
64	    }
65	    if (vars[i] ~ /rootdelay=/) {
66		rootdelay = vars[i]
67		sub(/rootdelay=/, "", rootdelay)
68	    }
69	    if (vars[i] ~ /rootdispersion=/) {
70		rootdispersion = vars[i]
71		sub(/rootdispersion=/, "", rootdispersion)
72	    }
73	    if (vars[i] ~ /refid=/) {
74		refid = vars[i]
75		sub(/refid=/, "", refid)
76	    }
77	}
78    }
79
80    if (stratum == 255)
81	exit 1
82
83    offset = offset / 1000
84    syncdistance = (rootdispersion + (rootdelay / 2)) / 1000
85
86    printf("%s: stratum %d, offset %f, synch distance %f",
87	dhost(host), stratum, offset, syncdistance)
88    if (stratum == 1) printf(", refid '\''%s'\''", refid)
89    printf("\n")
90
91    if (stratum == 0 || stratum == 1 || stratum == 16)
92	exit 0
93    if (refid ~ /127\.127\.[0-9]{1,3}\.[0-9]{1,3}/)
94	exit 0
95
96    command = "ntpq -n -c '\''pstat " peer "'\'' " host
97    while (command | getline) {
98	gsub(/,/,"")
99	nvars = split($0, vars)
100	for (i = 1; i <= nvars; i++) {
101	    if (vars[i] ~ /srcadr=/) {
102		srcadr = vars[i]
103		sub(/srcadr=/, "", srcadr)
104	    }
105	}
106    }
107
108    if (srcadr ~ /127\.127\.[0-9]{1,3}\.[0-9]{1,3}/ || srcadr == "")
109	exit 0
110
111    host = srcadr
112    do_one_server()
113}
114
115function dhost(myhost,  command) {
116	command = "host " myhost
117	while (command | getline) {
118	    if (use_numeric) {
119		if (/address/) return $NF
120	    } else {
121		if (/pointer/) return $NF
122	    }
123	}
124	return myhost
125}
126
127BEGIN {
128    getargs()
129    do_one_server()
130}
131' $@
132