@@ -248,6 +248,39 @@ static bool icmp_deliver(FAR struct net_driver_s *dev, uint16_t iphdrlen)
248248}
249249#endif
250250
251+ /****************************************************************************
252+ * Name: icmp_timestamp
253+ *
254+ * Description:
255+ * Return milliseconds since midnight.
256+ *
257+ ****************************************************************************/
258+
259+ static uint32_t icmp_timestamp (void )
260+ {
261+ struct timespec ts ;
262+ uint32_t secs ;
263+ uint32_t msecs ;
264+
265+ nxclock_gettime (CLOCK_REALTIME , & ts );
266+
267+ /* Get secs since midnight. */
268+
269+ secs = ts .tv_sec % 86400 ;
270+
271+ /* Convert to msecs. */
272+
273+ msecs = secs * MSEC_PER_SEC ;
274+
275+ /* Convert nsec to msec. */
276+
277+ msecs += ts .tv_nsec / NSEC_PER_MSEC ;
278+
279+ /* Convert to network byte order. */
280+
281+ return msecs ;
282+ }
283+
251284/****************************************************************************
252285 * Public Functions
253286 ****************************************************************************/
@@ -412,6 +445,61 @@ void icmp_input(FAR struct net_driver_s *dev)
412445 }
413446 }
414447#endif
448+ else if (icmp -> type == ICMP_TIMESTAMP_REQUEST )
449+ {
450+ uint16_t len = iphdrlen + sizeof (struct icmp_hdr_s ) + 3 * sizeof (uint32_t );
451+ uint32_t timestamp ;
452+ FAR uint8_t * buf ;
453+
454+ /* Change the ICMP type */
455+
456+ icmp -> type = ICMP_TIMESTAMP_REPLY ;
457+
458+ /* Swap IP addresses. */
459+
460+ net_ipv4addr_hdrcopy (ipv4 -> destipaddr , ipv4 -> srcipaddr );
461+ net_ipv4addr_hdrcopy (ipv4 -> srcipaddr , & dev -> d_ipaddr );
462+
463+ ipv4 -> len [0 ] = (len >> 8 );
464+ ipv4 -> len [1 ] = (len & 0xff );
465+
466+ ipv4 -> ipchksum = 0 ;
467+ #ifdef CONFIG_NET_IPV4_CHECKSUMS
468+ ipv4 -> ipchksum = ~ipv4_chksum (ipv4 );
469+ #endif
470+
471+ dev -> d_len = len ;
472+
473+ /* Update device buffer length */
474+
475+ iob_update_pktlen (dev -> d_iob , dev -> d_len , false);
476+
477+ /* Set Receive Timestamp and Transmit Timestamp */
478+
479+ buf = (FAR uint8_t * )(icmp + 1 );
480+ timestamp = htonl (icmp_timestamp ());
481+ memcpy (buf + 4 , & timestamp , 4 );
482+ memcpy (buf + 8 , & timestamp , 4 );
483+
484+ /* Recalculate the ICMP checksum */
485+
486+ icmp -> icmpchksum = 0 ;
487+ #ifdef CONFIG_NET_ICMP_CHECKSUMS
488+ icmp -> icmpchksum = ~icmp_chksum_iob (dev -> d_iob );
489+ if (icmp -> icmpchksum == 0 )
490+ {
491+ icmp -> icmpchksum = 0xffff ;
492+ }
493+ #endif
494+
495+ ninfo ("Outgoing ICMP packet length: %d (%d)\n" ,
496+ dev -> d_len , (ipv4 -> len [0 ] << 8 ) | ipv4 -> len [1 ]);
497+
498+ #ifdef CONFIG_NET_STATISTICS
499+ g_netstats .icmp .sent ++ ;
500+ g_netstats .ipv4 .sent ++ ;
501+ #endif
502+ }
415503
416504 /* Otherwise the ICMP input was not processed */
417505
0 commit comments