Skip to content

Commit 6545792

Browse files
author
wenquan1
committed
net/icmp: Support icmp timestamp request
When received a icmp timestamp request, send a icmp timestamp reply. Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
1 parent 6addf24 commit 6545792

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed

net/icmp/icmp_input.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)