@@ -81,6 +81,34 @@ 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 ) || (refTimeFrac != 0 ))
109
+ );
110
+ }
111
+
84
112
bool NTPClient::forceUpdate () {
85
113
#ifdef DEBUG_NTPClient
86
114
Serial.println (" Update from NTP Server" );
@@ -102,19 +130,26 @@ bool NTPClient::forceUpdate() {
102
130
timeout++;
103
131
} while (cb == 0 );
104
132
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
108
138
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;
114
144
115
- this ->_currentEpoc = secsSince1900 - SEVENTYYEARS;
145
+ this ->_currentEpoc = secsSince1900 - SEVENTYYEARS;
116
146
117
- return true ; // return true after successful update
147
+ return true ; // return true after successful update
148
+ }
149
+ else
150
+ {
151
+ return false ;
152
+ }
118
153
}
119
154
120
155
bool NTPClient::update () {
0 commit comments