@@ -81,6 +81,35 @@ void NTPClient::begin(unsigned int port) {
8181 this ->_udpSetup = true ;
8282}
8383
84+ // Perform some validity checks on the packet
85+ // https://datatracker.ietf.org/doc/html/rfc4330#section-4
86+ // Check length before calling
87+ static bool isValid (byte const *ntpPacket)
88+ {
89+ unsigned long highWord = word (ntpPacket[16 ], ntpPacket[17 ]);
90+ unsigned long lowWord = word (ntpPacket[18 ], ntpPacket[19 ]);
91+ unsigned long refTimeInt = highWord << 16 | lowWord;
92+ highWord = word (ntpPacket[20 ], ntpPacket[21 ]);
93+ lowWord = word (ntpPacket[22 ], ntpPacket[23 ]);
94+ unsigned long refTimeFrac = highWord << 16 | lowWord;
95+
96+ byte leapIndicator = ((ntpPacket[0 ] & 0b11000000 ) >> 6 );
97+ byte version = ((ntpPacket[0 ] & 0b00111000 ) >> 3 );
98+ byte mode = ( ntpPacket[0 ] & 0b00000111 );
99+ byte stratum = ntpPacket[1 ];
100+
101+ return
102+ (
103+ (leapIndicator != 3 ) && // LI != UNSYNC
104+ (version >= 4 ) &&
105+ ((mode == 4 ) || (mode == 5 )) && // Mode == server or broadcast
106+ (stratum >= 1 ) &&
107+ (stratum <= 15 ) &&
108+ (refTimeInt != 0 ) &&
109+ (refTimeFrac != 0 )
110+ );
111+ }
112+
84113bool NTPClient::forceUpdate () {
85114 #ifdef DEBUG_NTPClient
86115 Serial.println (" Update from NTP Server" );
@@ -102,19 +131,26 @@ bool NTPClient::forceUpdate() {
102131 timeout++;
103132 } while (cb == 0 );
104133
105- this ->_lastUpdate = millis () - (10 * (timeout + 1 )); // Account for delay in reading the time
106-
107- this ->_udp ->read (this ->_packetBuffer , NTP_PACKET_SIZE);
134+ if ((cb >= NTP_PACKET_SIZE) &&
135+ (this ->_udp ->read (this ->_packetBuffer , NTP_PACKET_SIZE) == NTP_PACKET_SIZE) &&
136+ isValid (this ->_packetBuffer ))
137+ {
138+ this ->_lastUpdate = millis () - (10 * (timeout + 1 )); // Account for delay in reading the time
108139
109- unsigned long highWord = word (this ->_packetBuffer [40 ], this ->_packetBuffer [41 ]);
110- unsigned long lowWord = word (this ->_packetBuffer [42 ], this ->_packetBuffer [43 ]);
111- // combine the four bytes (two words) into a long integer
112- // this is NTP time (seconds since Jan 1 1900):
113- unsigned long secsSince1900 = highWord << 16 | lowWord;
140+ unsigned long highWord = word (this ->_packetBuffer [40 ], this ->_packetBuffer [41 ]);
141+ unsigned long lowWord = word (this ->_packetBuffer [42 ], this ->_packetBuffer [43 ]);
142+ // combine the four bytes (two words) into a long integer
143+ // this is NTP time (seconds since Jan 1 1900):
144+ unsigned long secsSince1900 = highWord << 16 | lowWord;
114145
115- this ->_currentEpoc = secsSince1900 - SEVENTYYEARS;
146+ this ->_currentEpoc = secsSince1900 - SEVENTYYEARS;
116147
117- return true ; // return true after successful update
148+ return true ; // return true after successful update
149+ }
150+ else
151+ {
152+ return false ;
153+ }
118154}
119155
120156bool NTPClient::update () {
0 commit comments