mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 08:36:24 +08:00
Networking: First cut at ICMPv6 ping logic
This commit is contained in:
@@ -175,6 +175,36 @@ struct icmpv6_neighbor_advertise_s
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* This the message format for the ICMPv6 Echo Request message */
|
||||||
|
|
||||||
|
struct icmpv6_echo_request_s
|
||||||
|
{
|
||||||
|
uint8_t type; /* Message Type: ICMPv6_ECHO_REQUEST */
|
||||||
|
uint8_t code; /* Further qualifies the ICMP messages */
|
||||||
|
uint16_t chksum; /* Checksum of ICMP header and data */
|
||||||
|
uint16_t id; /* Identifier */
|
||||||
|
uint16_t seqno; /* Sequence Number */
|
||||||
|
uint8_t data[1]; /* Data follows */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SIZEOF_ICMPV6_ECHO_REQUEST_S(n) \
|
||||||
|
(sizeof(struct icmpv6_echo_request_s) - 1 + (n))
|
||||||
|
|
||||||
|
/* This the message format for the ICMPv6 Echo Reply message */
|
||||||
|
|
||||||
|
struct icmpv6_echo_reply_s
|
||||||
|
{
|
||||||
|
uint8_t type; /* Message Type: ICMPv6_ECHO_REQUEST */
|
||||||
|
uint8_t code; /* Further qualifies the ICMP messages */
|
||||||
|
uint16_t chksum; /* Checksum of ICMP header and data */
|
||||||
|
uint16_t id; /* Identifier */
|
||||||
|
uint16_t seqno; /* Sequence Number */
|
||||||
|
uint8_t data[1]; /* Data follows */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SIZEOF_ICMPV6_ECHO_REPLY_S(n) \
|
||||||
|
(sizeof(struct icmpv6_echo_reply_s) - 1 + (n))
|
||||||
|
|
||||||
/* The structure holding the ICMP statistics that are gathered if
|
/* The structure holding the ICMP statistics that are gathered if
|
||||||
* CONFIG_NET_STATISTICS is defined.
|
* CONFIG_NET_STATISTICS is defined.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+62
-60
@@ -61,78 +61,80 @@
|
|||||||
* TCP_ACKDATA, XYZ_NEWDATA, and TCP_CLOSE flags may be set at the same time,
|
* TCP_ACKDATA, XYZ_NEWDATA, and TCP_CLOSE flags may be set at the same time,
|
||||||
* whereas the others are mutually exclusive.
|
* whereas the others are mutually exclusive.
|
||||||
*
|
*
|
||||||
* TCP_ACKDATA IN: Signifies that the outstanding data was ACKed and
|
* TCP_ACKDATA IN: Signifies that the outstanding data was ACKed and
|
||||||
* the socket layer should send out new data instead
|
* the socket layer should send out new data instead
|
||||||
* of retransmitting the last data (TCP only)
|
* of retransmitting the last data (TCP only)
|
||||||
* OUT: Input state must be preserved on output.
|
* OUT: Input state must be preserved on output.
|
||||||
*
|
*
|
||||||
* TCP_NEWDATA IN: Set to indicate that the peer has sent us new data.
|
* TCP_NEWDATA IN: Set to indicate that the peer has sent us new data.
|
||||||
* UDP_NEWDATA OUT: Cleared (only) by the socket layer logic to indicate
|
* UDP_NEWDATA OUT: Cleared (only) by the socket layer logic to indicate
|
||||||
* PKT_NEWDATA that the new data was consumed, suppressing further
|
* PKT_NEWDATA that the new data was consumed, suppressing further
|
||||||
* ICMP_NEWDATA attempts to process the new data.
|
* ICMP_NEWDATA attempts to process the new data.
|
||||||
*
|
*
|
||||||
* TCP_SNDACK IN: Not used; always zero
|
* TCP_SNDACK IN: Not used; always zero
|
||||||
* OUT: Set by the socket layer if the new data was consumed
|
* OUT: Set by the socket layer if the new data was consumed
|
||||||
* and an ACK should be sent in the response. (TCP only)
|
* and an ACK should be sent in the response. (TCP only)
|
||||||
*
|
*
|
||||||
* TCP_REXMIT IN: Tells the socket layer to retransmit the data that
|
* TCP_REXMIT IN: Tells the socket layer to retransmit the data that
|
||||||
* was last sent. (TCP only)
|
* was last sent. (TCP only)
|
||||||
* OUT: Not used
|
* OUT: Not used
|
||||||
*
|
*
|
||||||
* TCP_POLL IN: Used for polling the socket layer. This is provided
|
* TCP_POLL IN: Used for polling the socket layer. This is provided
|
||||||
* UDP_POLL periodically from the drivers to support (1) timed
|
* UDP_POLL periodically from the drivers to support (1) timed
|
||||||
* PKT_POLL operations, and (2) to check if the socket layer has
|
* PKT_POLL operations, and (2) to check if the socket layer has
|
||||||
* ICMP_POLL data that it wants to send
|
* ICMP_POLL data that it wants to send
|
||||||
* ICMPv6_POLL OUT: Not used
|
* ICMPv6_POLL OUT: Not used
|
||||||
*
|
*
|
||||||
* TCP_BACKLOG IN: There is a new connection in the backlog list set
|
* TCP_BACKLOG IN: There is a new connection in the backlog list set
|
||||||
* up by the listen() command. (TCP only)
|
* up by the listen() command. (TCP only)
|
||||||
* OUT: Not used
|
* OUT: Not used
|
||||||
*
|
*
|
||||||
* TCP_CLOSE IN: The remote host has closed the connection, thus the
|
* TCP_CLOSE IN: The remote host has closed the connection, thus the
|
||||||
* connection has gone away. (TCP only)
|
* connection has gone away. (TCP only)
|
||||||
* OUT: The socket layer signals that it wants to close the
|
* OUT: The socket layer signals that it wants to close the
|
||||||
* connection. (TCP only)
|
* connection. (TCP only)
|
||||||
*
|
*
|
||||||
* TCP_ABORT IN: The remote host has aborted the connection, thus the
|
* TCP_ABORT IN: The remote host has aborted the connection, thus the
|
||||||
* connection has gone away. (TCP only)
|
* connection has gone away. (TCP only)
|
||||||
* OUT: The socket layer signals that it wants to abort the
|
* OUT: The socket layer signals that it wants to abort the
|
||||||
* connection. (TCP only)
|
* connection. (TCP only)
|
||||||
*
|
*
|
||||||
* TCP_CONNECTED IN: We have got a connection from a remote host and have
|
* TCP_CONNECTED IN: We have got a connection from a remote host and have
|
||||||
* set up a new connection for it, or an active connection
|
* set up a new connection for it, or an active connection
|
||||||
* has been successfully established. (TCP only)
|
* has been successfully established. (TCP only)
|
||||||
* OUT: Not used
|
* OUT: Not used
|
||||||
*
|
*
|
||||||
* TCP_TIMEDOUT IN: The connection has been aborted due to too many
|
* TCP_TIMEDOUT IN: The connection has been aborted due to too many
|
||||||
* retransmissions. (TCP only)
|
* retransmissions. (TCP only)
|
||||||
* OUT: Not used
|
* OUT: Not used
|
||||||
*
|
*
|
||||||
* ICMP_ECHOREPLY IN: An ICMP Echo Reply has been received. Used to support
|
* ICMP_ECHOREPLY IN: An ICMP Echo Reply has been received. Used to support
|
||||||
* ICMP ping from the socket layer. (ICMP only)
|
* ICMPv6_ECHOREPLY ICMP ping from the socket layer. (ICMP only)
|
||||||
* OUT: Cleared (only) by the socket layer logic to indicate
|
* OUT: Cleared (only) by the socket layer logic to indicate
|
||||||
* that the reply was processed, suppressing further
|
* that the reply was processed, suppressing further
|
||||||
* attempts to process the reply.
|
* attempts to process the reply.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define TCP_ACKDATA (1 << 0)
|
#define TCP_ACKDATA (1 << 0)
|
||||||
#define TCP_NEWDATA (1 << 1)
|
#define TCP_NEWDATA (1 << 1)
|
||||||
#define UDP_NEWDATA TCP_NEWDATA
|
#define UDP_NEWDATA TCP_NEWDATA
|
||||||
#define PKT_NEWDATA TCP_NEWDATA
|
#define PKT_NEWDATA TCP_NEWDATA
|
||||||
#define ICMP_NEWDATA TCP_NEWDATA
|
#define ICMP_NEWDATA TCP_NEWDATA
|
||||||
#define TCP_SNDACK (1 << 2)
|
#define ICMPv6_NEWDATA TCP_NEWDATA
|
||||||
#define TCP_REXMIT (1 << 3)
|
#define TCP_SNDACK (1 << 2)
|
||||||
#define TCP_POLL (1 << 4)
|
#define TCP_REXMIT (1 << 3)
|
||||||
#define UDP_POLL TCP_POLL
|
#define TCP_POLL (1 << 4)
|
||||||
#define PKT_POLL TCP_POLL
|
#define UDP_POLL TCP_POLL
|
||||||
#define ICMP_POLL TCP_POLL
|
#define PKT_POLL TCP_POLL
|
||||||
#define ICMPv6_POLL TCP_POLL
|
#define ICMP_POLL TCP_POLL
|
||||||
#define TCP_BACKLOG (1 << 5)
|
#define ICMPv6_POLL TCP_POLL
|
||||||
#define TCP_CLOSE (1 << 6)
|
#define TCP_BACKLOG (1 << 5)
|
||||||
#define TCP_ABORT (1 << 7)
|
#define TCP_CLOSE (1 << 6)
|
||||||
#define TCP_CONNECTED (1 << 8)
|
#define TCP_ABORT (1 << 7)
|
||||||
#define TCP_TIMEDOUT (1 << 9)
|
#define TCP_CONNECTED (1 << 8)
|
||||||
#define ICMP_ECHOREPLY (1 << 10)
|
#define TCP_TIMEDOUT (1 << 9)
|
||||||
|
#define ICMP_ECHOREPLY (1 << 10)
|
||||||
|
#define ICMPv6_ECHOREPLY ICMP_ECHOREPLY
|
||||||
|
|
||||||
#define TCP_CONN_EVENTS (TCP_CLOSE | TCP_ABORT | TCP_CONNECTED | TCP_TIMEDOUT)
|
#define TCP_CONN_EVENTS (TCP_CLOSE | TCP_ABORT | TCP_CONNECTED | TCP_TIMEDOUT)
|
||||||
|
|
||||||
|
|||||||
@@ -349,7 +349,7 @@ int icmp_ping(in_addr_t addr, uint16_t id, uint16_t seqno, uint16_t datalen,
|
|||||||
state.png_result = -ENOMEM; /* Assume allocation failure */
|
state.png_result = -ENOMEM; /* Assume allocation failure */
|
||||||
state.png_addr = addr; /* Address of the peer to be ping'ed */
|
state.png_addr = addr; /* Address of the peer to be ping'ed */
|
||||||
state.png_id = id; /* The ID to use in the ECHO request */
|
state.png_id = id; /* The ID to use in the ECHO request */
|
||||||
state.png_seqno = seqno; /* The seqno to use int the ECHO request */
|
state.png_seqno = seqno; /* The seqno to use in the ECHO request */
|
||||||
state.png_datlen = datalen; /* The length of data to send in the ECHO request */
|
state.png_datlen = datalen; /* The length of data to send in the ECHO request */
|
||||||
state.png_sent = false; /* ECHO request not yet sent */
|
state.png_sent = false; /* ECHO request not yet sent */
|
||||||
|
|
||||||
|
|||||||
+124
-46
@@ -39,11 +39,12 @@
|
|||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
#if defined(CONFIG_NET) && defined(CONFIG_NET_ICMPv6) && \
|
#if defined(CONFIG_NET) && defined(CONFIG_NET_ICMPv6) && \
|
||||||
defined(CONFIG_NET_ICMPv6v6_PING)
|
defined(CONFIG_NET_ICMPv6_PING)
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
@@ -55,24 +56,34 @@
|
|||||||
#include <nuttx/net/netdev.h>
|
#include <nuttx/net/netdev.h>
|
||||||
#include <nuttx/net/ip.h>
|
#include <nuttx/net/ip.h>
|
||||||
#include <nuttx/net/icmpv6.h>
|
#include <nuttx/net/icmpv6.h>
|
||||||
|
#include <nuttx/net/netstats.h>
|
||||||
|
|
||||||
#include "netdev/netdev.h"
|
#include "netdev/netdev.h"
|
||||||
#include "devif/devif.h"
|
#include "devif/devif.h"
|
||||||
#include "arp/arp.h"
|
#include "arp/arp.h"
|
||||||
|
#include "utils/utils.h"
|
||||||
#include "icmpv6/icmpv6.h"
|
#include "icmpv6/icmpv6.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define ETHBUF ((struct eth_hdr_s *)&dev->d_buf[0])
|
||||||
#define ICMPv6BUF ((struct icmpv6_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
|
#define ICMPv6BUF ((struct icmpv6_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
|
||||||
#define ICMPv6DAT (&dev->d_buf[NET_LL_HDRLEN(dev) + sizeof(struct icmpv6_iphdr_s)])
|
#define ICMPv6ECHOREQ \
|
||||||
|
((struct icmpv6_echo_request_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN])
|
||||||
|
#define ICMPv6ECHOREPLY \
|
||||||
|
((struct icmpv6_echo_reply_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN])
|
||||||
|
|
||||||
/* Allocate a new ICMPv6 data callback */
|
/* Allocate a new ICMPv6 data callback */
|
||||||
|
|
||||||
#define icmpv6_callback_alloc() devif_callback_alloc(&g_icmpv6_echocallback)
|
#define icmpv6_callback_alloc() devif_callback_alloc(&g_icmpv6_echocallback)
|
||||||
#define icmpv6_callback_free(cb) devif_callback_free(cb, &g_icmpv6_echocallback)
|
#define icmpv6_callback_free(cb) devif_callback_free(cb, &g_icmpv6_echocallback)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -132,6 +143,96 @@ static inline int ping_timeout(FAR struct icmpv6_ping_s *pstate)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: icmpv6_echo_request
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Format an ICMPv6 Echo Request message.. This version
|
||||||
|
* is for a standalone solicitation. If formats:
|
||||||
|
*
|
||||||
|
* - The Ethernet header
|
||||||
|
* - The IPv6 header
|
||||||
|
* - The ICMPv6 Echo Request Message
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* dev - Reference to an Ethernet device driver structure
|
||||||
|
* pstate - Ping state structure
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void icmpv6_echo_request(FAR struct net_driver_s *dev,
|
||||||
|
FAR struct icmpv6_ping_s *pstate)
|
||||||
|
{
|
||||||
|
FAR struct icmpv6_iphdr_s *icmp;
|
||||||
|
FAR struct icmpv6_echo_request_s *req;
|
||||||
|
uint16_t reqlen;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
nllvdbg("Send ECHO request: seqno=%d\n", pstate->png_seqno);
|
||||||
|
|
||||||
|
/* Set up the IPv6 header (most is probably already in place) */
|
||||||
|
|
||||||
|
icmp = ICMPv6BUF;
|
||||||
|
icmp->vtc = 0x60; /* Version/traffic class (MS) */
|
||||||
|
icmp->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
|
||||||
|
icmp->flow = 0; /* Flow label (LS) */
|
||||||
|
|
||||||
|
/* Length excludes the IPv6 header */
|
||||||
|
|
||||||
|
reqlen = SIZEOF_ICMPV6_ECHO_REQUEST_S(pstate->png_datlen);
|
||||||
|
icmp->len[0] = (reqlen >> 8);
|
||||||
|
icmp->len[1] = (reqlen & 0xff);
|
||||||
|
|
||||||
|
icmp->proto = IP_PROTO_ICMP6; /* Next header */
|
||||||
|
icmp->ttl = 255; /* Hop limit */
|
||||||
|
|
||||||
|
/* Set the multicast destination IP address */
|
||||||
|
|
||||||
|
net_ipv6addr_copy(icmp->destipaddr, pstate->png_addr);
|
||||||
|
|
||||||
|
/* Add out IPv6 address as the source address */
|
||||||
|
|
||||||
|
net_ipv6addr_copy(icmp->srcipaddr, dev->d_ipv6addr);
|
||||||
|
|
||||||
|
/* Set up the ICMPv6 Echo Request message */
|
||||||
|
|
||||||
|
req = ICMPv6ECHOREQ;
|
||||||
|
req->type = ICMPv6_ECHO_REQUEST; /* Message type */
|
||||||
|
req->code = 0; /* Message qualifier */
|
||||||
|
req->id = htons(pstate->png_id);
|
||||||
|
req->seqno = htons(pstate->png_seqno);
|
||||||
|
|
||||||
|
/* Add some easily verifiable data */
|
||||||
|
|
||||||
|
for (i = 0; i < pstate->png_datlen; i++)
|
||||||
|
{
|
||||||
|
req->data[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the checksum over both the ICMP header and payload */
|
||||||
|
|
||||||
|
icmp->chksum = 0;
|
||||||
|
icmp->chksum = ~icmpv6_chksum(dev);
|
||||||
|
|
||||||
|
/* Set the size to the size of the IPv6 header and the payload size */
|
||||||
|
|
||||||
|
IFF_SET_IPv6(dev->d_flags);
|
||||||
|
|
||||||
|
dev->d_sndlen = reqlen;
|
||||||
|
dev->d_len = reqlen + IPv6_HDRLEN;
|
||||||
|
|
||||||
|
nllvdbg("Outgoing ICMPv6 Echo Request length: %d (%d)\n",
|
||||||
|
dev->d_len, (icmp->len[0] << 8) | icmp->len[1]);
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_STATISTICS
|
||||||
|
g_netstats.icmpv6.sent++;
|
||||||
|
g_netstats.ip.sent++;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: ping_interrupt
|
* Function: ping_interrupt
|
||||||
*
|
*
|
||||||
@@ -158,8 +259,6 @@ static uint16_t ping_interrupt(FAR struct net_driver_s *dev, FAR void *conn,
|
|||||||
FAR void *pvpriv, uint16_t flags)
|
FAR void *pvpriv, uint16_t flags)
|
||||||
{
|
{
|
||||||
FAR struct icmpv6_ping_s *pstate = (struct icmpv6_ping_s *)pvpriv;
|
FAR struct icmpv6_ping_s *pstate = (struct icmpv6_ping_s *)pvpriv;
|
||||||
FAR uint8_t *ptr;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
nllvdbg("flags: %04x\n", flags);
|
nllvdbg("flags: %04x\n", flags);
|
||||||
if (pstate)
|
if (pstate)
|
||||||
@@ -172,12 +271,12 @@ static uint16_t ping_interrupt(FAR struct net_driver_s *dev, FAR void *conn,
|
|||||||
|
|
||||||
if ((flags & ICMPv6_ECHOREPLY) != 0 && conn != NULL)
|
if ((flags & ICMPv6_ECHOREPLY) != 0 && conn != NULL)
|
||||||
{
|
{
|
||||||
FAR struct icmpv6_iphdr_s *icmpv6 = (FAR struct icmpv6_iphdr_s *)conn;
|
FAR struct icmpv6_echo_reply_s *reply = ICMPv6ECHOREPLY;
|
||||||
|
|
||||||
nllvdbg("ECHO reply: id=%d seqno=%d\n",
|
nllvdbg("ECHO reply: id=%d seqno=%d\n",
|
||||||
ntohs(icmpv6->id), ntohs(icmpv6->seqno));
|
ntohs(reply->id), reply(reply->seqno));
|
||||||
|
|
||||||
if (ntohs(icmpv6->id) == pstate->png_id)
|
if (ntohs(reply->id) == pstate->png_id)
|
||||||
{
|
{
|
||||||
/* Consume the ECHOREPLY */
|
/* Consume the ECHOREPLY */
|
||||||
|
|
||||||
@@ -187,7 +286,7 @@ static uint16_t ping_interrupt(FAR struct net_driver_s *dev, FAR void *conn,
|
|||||||
/* Return the result to the caller */
|
/* Return the result to the caller */
|
||||||
|
|
||||||
pstate->png_result = OK;
|
pstate->png_result = OK;
|
||||||
pstate->png_seqno = ntohs(icmpv6->seqno);
|
pstate->png_seqno = ntohs(reply->seqno);
|
||||||
goto end_wait;
|
goto end_wait;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -209,33 +308,9 @@ static uint16_t ping_interrupt(FAR struct net_driver_s *dev, FAR void *conn,
|
|||||||
(flags & ICMPv6_NEWDATA) == 0 && /* No incoming data */
|
(flags & ICMPv6_NEWDATA) == 0 && /* No incoming data */
|
||||||
!pstate->png_sent) /* Request not sent */
|
!pstate->png_sent) /* Request not sent */
|
||||||
{
|
{
|
||||||
FAR struct icmpv6_iphdr_s *picmpv6 = ICMPv6BUF;
|
/* Send the ECHO request now. */
|
||||||
|
|
||||||
/* We can send the ECHO request now.
|
icmpv6_echo_request(dev, pstate);
|
||||||
*
|
|
||||||
* Format the ICMPv6 ECHO request packet
|
|
||||||
*/
|
|
||||||
|
|
||||||
picmpv6->type = ICMPv6_ECHO_REQUEST;
|
|
||||||
picmpv6->icode = 0;
|
|
||||||
# error "IPv6 ECHO Request not implemented"
|
|
||||||
|
|
||||||
/* Add some easily verifiable data */
|
|
||||||
|
|
||||||
for (i = 0, ptr = ICMPv6DAT; i < pstate->png_datlen; i++)
|
|
||||||
{
|
|
||||||
*ptr++ = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send the ICMPv6 echo request. Note that d_sndlen is set to
|
|
||||||
* the size of the ICMPv6 payload and does not include the size
|
|
||||||
* of the ICMPv6 header.
|
|
||||||
*/
|
|
||||||
|
|
||||||
nllvdbg("Send ECHO request: seqno=%d\n", pstate->png_seqno);
|
|
||||||
|
|
||||||
dev->d_sndlen = pstate->png_datlen + 4;
|
|
||||||
icmpv6_send(dev, &pstate->png_addr);
|
|
||||||
pstate->png_sent = true;
|
pstate->png_sent = true;
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
@@ -250,7 +325,8 @@ static uint16_t ping_interrupt(FAR struct net_driver_s *dev, FAR void *conn,
|
|||||||
* device.
|
* device.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!net_ipv6addr_maskcmp(pstate->png_addr, dev->d_ipaddr, dev->d_netmask))
|
if (!net_ipv6addr_maskcmp(pstate->png_addr, dev->d_ipv6addr,
|
||||||
|
dev->d_ipv6netmask))
|
||||||
{
|
{
|
||||||
/* Destination address was not on the local network served by this
|
/* Destination address was not on the local network served by this
|
||||||
* device. If a timeout occurs, then the most likely reason is
|
* device. If a timeout occurs, then the most likely reason is
|
||||||
@@ -328,12 +404,13 @@ int icmpv6_ping(net_ipv6addr_t addr, uint16_t id, uint16_t seqno,
|
|||||||
{
|
{
|
||||||
struct icmpv6_ping_s state;
|
struct icmpv6_ping_s state;
|
||||||
net_lock_t save;
|
net_lock_t save;
|
||||||
#ifdef CONFIG_NET_ARP_SEND
|
|
||||||
|
#ifdef CONFIG_NET_ICMPv6_SEND
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Make sure that the IP address mapping is in the ARP table */
|
/* Make sure that the IP address mapping is in the Neighbor Table */
|
||||||
|
|
||||||
ret = arp_send(addr);
|
ret = neighbor_send(addr);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
ndbg("ERROR: Not reachable\n");
|
ndbg("ERROR: Not reachable\n");
|
||||||
@@ -344,13 +421,14 @@ int icmpv6_ping(net_ipv6addr_t addr, uint16_t id, uint16_t seqno,
|
|||||||
/* Initialize the state structure */
|
/* Initialize the state structure */
|
||||||
|
|
||||||
sem_init(&state.png_sem, 0, 0);
|
sem_init(&state.png_sem, 0, 0);
|
||||||
state.png_ticks = DSEC2TICK(dsecs); /* System ticks to wait */
|
state.png_ticks = DSEC2TICK(dsecs); /* System ticks to wait */
|
||||||
state.png_result = -ENOMEM; /* Assume allocation failure */
|
state.png_result = -ENOMEM; /* Assume allocation failure */
|
||||||
state.png_addr = addr; /* Address of the peer to be ping'ed */
|
state.png_id = id; /* The ID to use in the ECHO request */
|
||||||
state.png_id = id; /* The ID to use in the ECHO request */
|
state.png_seqno = seqno; /* The seqno to use in the ECHO request */
|
||||||
state.png_seqno = seqno; /* The seqno to use int the ECHO request */
|
state.png_datlen = datalen; /* The length of data to send in the ECHO request */
|
||||||
state.png_datlen = datalen; /* The length of data to send in the ECHO request */
|
state.png_sent = false; /* ECHO request not yet sent */
|
||||||
state.png_sent = false; /* ECHO request not yet sent */
|
|
||||||
|
net_ipv6addr_copy(state.png_addr, addr); /* Address of the peer to be ping'ed */
|
||||||
|
|
||||||
save = net_lock();
|
save = net_lock();
|
||||||
state.png_time = clock_systimer();
|
state.png_time = clock_systimer();
|
||||||
@@ -404,4 +482,4 @@ int icmpv6_ping(net_ipv6addr_t addr, uint16_t id, uint16_t seqno,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_NET_ICMPv6 && CONFIG_NET_ICMPv6v6_PING ... */
|
#endif /* CONFIG_NET_ICMPv6 && CONFIG_NET_ICMPv6_PING ... */
|
||||||
|
|||||||
@@ -80,7 +80,12 @@ static const uint16_t g_icmpv_mcastaddr[6] =
|
|||||||
* Name: icmpv6_solicit
|
* Name: icmpv6_solicit
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Set up to send an ICMPv6 Neighbor Solicitation message
|
* Set up to send an ICMPv6 Neighbor Solicitation message. This version
|
||||||
|
* is for a standalone solicitation. If formats:
|
||||||
|
*
|
||||||
|
* - The Ethernet header
|
||||||
|
* - The IPv6 header
|
||||||
|
* - The ICMPv6 Neighbor Solicitation Message
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* dev - Reference to an Ethernet device driver structure
|
* dev - Reference to an Ethernet device driver structure
|
||||||
|
|||||||
Reference in New Issue
Block a user