@@ -81,6 +81,35 @@ void NTPClient::begin(unsigned int port) {
81
81
this ->_udpSetup = true ;
82
82
}
83
83
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
+
84
113
bool NTPClient::forceUpdate () {
85
114
#ifdef DEBUG_NTPClient
86
115
Serial.println (" Update from NTP Server" );
@@ -102,19 +131,26 @@ bool NTPClient::forceUpdate() {
102
131
timeout++;
103
132
} while (cb == 0 );
104
133
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
108
139
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;
114
145
115
- this ->_currentEpoc = secsSince1900 - SEVENTYYEARS;
146
+ this ->_currentEpoc = secsSince1900 - SEVENTYYEARS;
116
147
117
- return true ; // return true after successful update
148
+ return true ; // return true after successful update
149
+ }
150
+ else
151
+ {
152
+ return false ;
153
+ }
118
154
}
119
155
120
156
bool NTPClient::update () {
0 commit comments