@@ -81,6 +81,34 @@ 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 ) || (refTimeFrac != 0 ))
109+ );
110+ }
111+
84112bool NTPClient::forceUpdate () {
85113 #ifdef DEBUG_NTPClient
86114 Serial.println (" Update from NTP Server" );
@@ -102,19 +130,26 @@ bool NTPClient::forceUpdate() {
102130 timeout++;
103131 } while (cb == 0 );
104132
105- this ->_lastUpdate = millis () - (10 * (timeout + 1 )); // Account for delay in reading the time
106-
107- this ->_udp ->read (this ->_packetBuffer , NTP_PACKET_SIZE);
133+ if ((cb >= NTP_PACKET_SIZE) &&
134+ (this ->_udp ->read (this ->_packetBuffer , NTP_PACKET_SIZE) == NTP_PACKET_SIZE) &&
135+ isValid (this ->_packetBuffer ))
136+ {
137+ this ->_lastUpdate = millis () - (10 * (timeout + 1 )); // Account for delay in reading the time
108138
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;
139+ unsigned long highWord = word (this ->_packetBuffer [40 ], this ->_packetBuffer [41 ]);
140+ unsigned long lowWord = word (this ->_packetBuffer [42 ], this ->_packetBuffer [43 ]);
141+ // combine the four bytes (two words) into a long integer
142+ // this is NTP time (seconds since Jan 1 1900):
143+ unsigned long secsSince1900 = highWord << 16 | lowWord;
114144
115- this ->_currentEpoc = secsSince1900 - SEVENTYYEARS;
145+ this ->_currentEpoc = secsSince1900 - SEVENTYYEARS;
116146
117- return true ; // return true after successful update
147+ return true ; // return true after successful update
148+ }
149+ else
150+ {
151+ return false ;
152+ }
118153}
119154
120155bool NTPClient::update () {
0 commit comments