Skip to content

Commit 38a7dff

Browse files
committed
Add NTP packet validity checks
1 parent 296b0b6 commit 38a7dff

File tree

1 file changed

+45
-10
lines changed

1 file changed

+45
-10
lines changed

NTPClient.cpp

+45-10
Original file line numberDiff line numberDiff line change
@@ -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+
84112
bool 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

120155
bool NTPClient::update() {

0 commit comments

Comments
 (0)