Having the correct time on your module is critical for all kinds of activities including log synchronization and security certificate validation. Starting in release 15.1 VOS shipped with a port of the Network Time Protocol daemon (ntpd) and it is strongly recommend that you run it.

Typically, to run ntpd you need to provide it with a list of time servers, hosts on the network that also run ntpd and will provide the time to any host that asks. There are a large number of time servers available on the internet that you can use. Take a look at http://www.pool.ntp.org/en/ which organizes the servers by region.

I suggest listing one or three (or more) servers, never two. ntpd attempts to figure out which server is best to use by comparing the servers’ responses. If only two servers are listed it is possible that ntpd will not be able to make a determination and end up not using either.

But what should you do if your company’s policies prevent you from accessing time servers on the Internet and you do not have a company designated time server? In that case you may be able to use a local Microsoft Windows domain controller (DC) or backup domain controller (BDC). Most DCs and BDCs will provide time services.

So as a VOS administrator how can you find the local DC or BDC? The simplest way is to ask but assuming that is not an option you can run packet monitor and look for yourself. Both workstations and domain controllers broadcast periodically on UDP port 138.

The command

>system>stcp>command_library>packet_monitor -interface #INTERFACE -numeric
-time_stamp -verbose -pkt_hdr -hex_header -hex_dump -length 1500 -filter -port 138
Figure 1 – packet_monitor command

will display these broadcasts (be sure to replace INTERFACE with the name of your IP interface). Unfortunately, in order to find the time servers you need to look at the hex data in the packet and since there will probably be a lot of packets to go through you need to dump the packets into a file. My pm.cm, command macro (you can find the macro here) will automatically create an out file and run the trace as a started process. The out file will have the name pm.(date).(time).out. The command would be

pm #INTERFACE -no_arp -no_icmp -port 138
Figure 2 – pm command macro

However you start the trace, let it run for 15 to 20 minutes and you should get a broadcast from each DC and BDC on your network. Next search for lines with the string ‘c0    3’ and ‘c0    2’ in them; that is lower case C, zero, four spaces and either a three or a two. The number corresponds to the upper nibble of the byte at offset c0. That byte can be decoded as

ABCD EFGH
^^^^ ^^^^
|||| ||||-- host is a workstation
|||| |||--- host is a server
|||| ||---- host is NOT an SQL server
|||| |----- host is NOT a domain controller
||||------- host is a backup domain controller
|||-------- host is a time server
||--------- host is NOT an Apple host
|---------- host is NOT a Novell host
Figure 3 – Server type byte decode

As you can see searching for that first three or two may not get all of the time servers but unless you run an exclusive Novel or Apple site it should get at least one DC or BDC.

d pm.11-02-06.17:25:06.out -match 'c0    2'
ready  17:47:13

d pm.11-02-06.17:25:06.out -match 'c0    3'

%phx_vos#m15_mas>SysAdmin>Noah_Davids>pm.11-02-06.17:25:06.out  11-02-06 17:47

     c0    33 10 82  0  f  1 55 aa   0                       3 <<U*
     c0    33 10 84  0  f  1 55 aa   0                       3 <<U*
     c0    33 10 84  0  f  1 55 aa   0                       3 <<U*
     c0    33 10 82  0  f  1 55 aa   0                       3 <<U*
     c0    33 10 84  0  f  1 55 aa   0                       3 <<U*
     c0    33 10 84  0  f  1 55 aa   0                       3 <<U*
     c0    33 10 84  0  f  1 55 aa   0                       3 <<U*
     c0    33 10 82  0  f  1 55 aa   0                       3 <<U*
     c0    33 10 84  0  f  1 55 aa   0                       3 <<U*
     c0    33 10 82  0  f  1 55 aa   0                       3 <<U*
     c0    33 10 84  0  f  1 55 aa   0                       3 <<U*

ready  17:47:29
Figure 4 – packet_monitor lines matching time server and backup domain controller

Just finding the “c0” lines is not enough. You need to also find the address of the host that sent the packet. The grep command which can be found in the >system>gnu_library>bin directory can match on multiple lines

grep -e 'c0    3' -e 'c0    2' -e UDP pm.11-02-06.17:25:06.out
. . . .
UDP from 192.168.33.180.138 to 192.168.33.255.138 Cksum 7ca3, 220 data bytes.
UDP from 192.168.33.249.138 to 192.168.33.255.138 Cksum c89a, 209 data bytes.
     c0    33 10 82  0  f  1 55 aa   0                       3 <<U*
. . . .
UDP from 192.168.33.50.138 to 192.168.33.255.138 Cksum 9526, 193 data bytes.
UDP from 192.168.33.248.138 to 192.168.33.255.138 Cksum d05f, 209 data bytes.
     c0    33 10 84  0  f  1 55 aa   0                       3 <<U*
. . . .
UDP from 192.168.33.202.138 to 192.168.33.255.138 Cksum cf35, 219 data bytes.
UDP from 192.168.33.253.138 to 192.168.33.255.138 Cksum 9505, 209 data bytes.
     c0    33 10 82  0  f  1 55 aa   0                       3 <<U*
. . . .
UDP from 192.168.33.131.138 to 192.168.33.255.138 Cksum aa35, 222 data bytes.
UDP from 192.168.33.252.138 to 192.168.33.255.138 Cksum 7343, 209 data bytes.
     c0    33 10 84  0  f  1 55 aa   0                       3 <<U*
. . . . .
Figure 5 – packet_monitor lines showing discovered time servers

The address of the time servers appears on the lines immediately above the “c0” line. In the above figure we have identified 192.168.33.249, 192.168.33.248, 192.168.33.253, and 192.168.33.252.

Now that we have identified hosts that advertise themselves as time servers how can we be sure that they will work? The ntpdate command can be used to manually query each time server. Use the “-q” argument to only query the time server, at this point we do not want ntpdate to also set the module’s time.

ntpdate -q 192.168.33.248
Looking for host 192.168.33.248 and service ntp
host found : dc48.noahslab.stratus.com
server 192.168.33.248, stratum 4, offset -0.117418, delay 0.04202
6 Feb 17:53:10 ntpdate[1427079382]: adjust time server 192.168.33.248 offset -0
+.117418 sec
ready  17:53:10

ntpdate -q 192.168.33.249
Looking for host 192.168.33.249 and service ntp
host found : dc49.noahslab.stratus.com
server 192.168.33.249, stratum 4, offset -0.038709, delay 0.04355
6 Feb 17:53:25 ntpdate[1427079382]: adjust time server 192.168.33.249 offset -0
+.038709 sec
ready  17:53:25

ntpdate -q 192.168.33.252
Looking for host 192.168.33.252 and service ntp
host found : dc52.noahslab.stratus.com
server 192.168.33.252, stratum 3, offset 0.015733, delay 0.04216
6 Feb 17:53:38 ntpdate[1427079382]: adjust time server 192.168.33.252 offset 0.
+015733 sec
ready  17:53:38
Figure 6 – using ntpdate to test discovered time servers — working servers

Lets say that one of the servers has a firewall policy that prevents it from giving out the time even though it advetrtises it, ntpdate will show the following.

ntpdate -q 192.168.33.254
Looking for host 192.168.33.254 and service ntp
host found : dc54.noahslab.stratus.com
server 192.168.33.254, stratum 0, offset 0.000000, delay 0.00000
6 Feb 17:54:00 ntpdate[1427079382]: no server suitable for synchronization foun
+d
ready  17:54:00
Figure 7 – using ntpdate to test discovered time servers — nonworking server

Now that you know what time servers you can use you can write the >system>ntp>ntp.conf file as follows. Everything in black comes from the sample_ntp.conf.17.0 file, new characters are in green. Note the comment character that was added in front of the “server foo.bar.somewhere.com” line. The restrict statements improve the security position of the system by preventing other hosts from making non-time queries against the ntp daemon.

# server directives indicate where to get time from.
# They may be DNS or IP values, one per directive.
# server foo.bar.somewhere.com

server 192.168.33.248 burst iburst
server 192.168.33.249 burst iburst
server 192.168.33.252 burst iburst

# Home for the logile.  Pick a good relative path - VOS absolute
# pathnames can't be parsed correctly.
logfile >system>ntp>ntp.logfile

# Home for the driftfile.
driftfile >system>ntp>ntp.drift

# These statements will prevent non-time queries from any host but local host
restrict default noquery
restrict 127.0.0.1
Figure 8 – updated >system>ntp>ntp.conf file

Start the ntpd command (there is a sample_start_ntpd.17.0 in the >system>ntp directory) and after a few minutes you should see something like the following. The “*” in front of 192.168.33.252 indicates that that is the server that ntpd has choose to take its time from. The “+” in front of 192.168.33.248 indicates another good choice in case there is no response from 192.168.33.252. As long one of the lines as an “*” in column one you know that the module’s time will be synchronized with a time server. Remember however, that it may take a while for the times to converge when the initial difference between the module and the time server is large.

ntpq -n
ntpq> peer
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
+192.168.33.248  192.168.33.252   4 u    - 1024  377    1.312  -1549.3 639.489
 192.168.33.249  192.168.33.252   4 u  626 1024  377  132.423   15.202  27.797
*192.168.33.252  192.168.33.51    3 u  802 1024  377    0.964  -27.486   2.993
Figure 9 – using ntpq to confirm time synchronization

Finally, ntpd acts as both a client and a server so once it is running on one VOS module it can act as the time server for other modules or anything else on your network.