While most modern systems rely on NTP (Network Time Protocol), certain legacy equipment - particularly in cable networks - still requires the archaic RFC 868 Time Protocol. This 32-bit time format running on port 37 (both TCP/UDP) is essential for DOCSIS 3.0 compliance in CMTS deployments.
The traditional implementation comes bundled with inetd/xinetd:
# Debian/Ubuntu sudo apt install xinetd # CentOS/RHEL sudo yum install xinetd # FreeBSD (pfSense) pkg install xinetd
Edit /etc/xinetd.d/time
to enable the service:
service time { disable = no type = INTERNAL id = time-stream socket_type = stream protocol = tcp user = root wait = no flags = IPv4 } service time { disable = no type = INTERNAL id = time-dgram socket_type = dgram protocol = udp user = root wait = yes flags = IPv4 }
Verify service availability with these methods:
# Check if port 37 is listening netstat -tuln | grep 37 # Manual TCP test (returns 32-bit binary) nc localhost 37 | od -An -t d4 # UDP test (requires custom script) import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.sendto(b'', ('localhost', 37)) print(int.from_bytes(s.recv(4), 'big'))
For DOCSIS 3.0 deployments:
- Ensure CMTS can reach the ToD server on port 37
- Configure firewall rules (both host and network level)
- Monitor time drift as RFC 868 lacks NTP's precision
For systems without xinetd, consider these options:
# Python minimalist server from socketserver import TCPServer, StreamRequestHandler import time class TimeHandler(StreamRequestHandler): def handle(self): self.wfile.write(int(time.time() + 2208988800).to_bytes(4, 'big')) TCPServer(('', 37), TimeHandler).serve_forever()
The RFC 868 epoch (1900-01-01) requires adding 2,208,988,800 seconds to Unix timestamps for proper conversion.
While NTP dominates modern time synchronization, some legacy systems still rely on the RFC 868 Time Protocol (commonly called ToD in DOCSIS contexts). This 32-bit timestamp format running on port 37 remains crucial for:
- DOCSIS 3 cable modem provisioning
- Industrial control systems
- Retro computing environments
Debian/Ubuntu Setup
# Install xinetd
sudo apt install xinetd
# Enable time service
sudo nano /etc/xinetd.d/time
---------------------------------
service time
{
disable = no
type = INTERNAL
id = time-stream
socket_type = stream
protocol = tcp
user = root
wait = no
}
service time
{
disable = no
type = INTERNAL
id = time-dgram
socket_type = dgram
protocol = udp
user = root
wait = yes
}
---------------------------------
sudo systemctl restart xinetd
CentOS/RHEL Configuration
# Enable via inetd
sudo yum install inetd
echo "time stream tcp nowait root internal" | sudo tee -a /etc/inetd.conf
echo "time dgram udp wait root internal" | sudo tee -a /etc/inetd.conf
sudo systemctl restart inetd
FreeBSD/pfSense Method
# Enable in inetd
sudo nano /etc/inetd.conf
---------------------------------
time stream tcp nowait root internal
time dgram udp wait root internal
---------------------------------
service inetd restart
Confirm your ToD server is operational:
# Test TCP connection
nc -zv localhost 37
# Verify UDP response (requires special client)
todtest -h yourserver -p 37 -u
# Check running services
ss -tulnp | grep 37
netstat -an | grep 37
For cable modem environments:
- Ensure port 37 is forwarded through firewalls
- Configure CMTS to point to your ToD server IP
- Account for network latency (DOCSIS requires ±5 seconds accuracy)
Example CMTS configuration snippet:
cable time-server 192.168.100.1
cable time-server priority 1
For custom solutions, here's a minimal Python implementation:
import socket
import time
def tod_server():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('0.0.0.0', 37))
s.listen()
while True:
conn, addr = s.accept()
seconds = int(time.time()) + 2208988800 # Unix to RFC868
conn.sendall(seconds.to_bytes(4, 'big'))
conn.close()
if __name__ == "__main__":
tod_server()