net/icmp and icmpv6: Bind icmp callback from device to connection. Resolves the issue that bind() could not be called before send()
This commit is contained in:
parent
b161682adc
commit
c9b73f5139
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/devif/devif_poll.c
|
* net/devif/devif_poll.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2010, 2012, 2014, 2016-2018 Gregory Nutt. All rights
|
* Copyright (C) 2007-2010, 2012, 2014, 2016-2019 Gregory Nutt. All rights
|
||||||
* reserved.
|
* reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
@ -324,17 +324,27 @@ static int devif_poll_ieee802154_connections(FAR struct net_driver_s *dev,
|
|||||||
static inline int devif_poll_icmp(FAR struct net_driver_s *dev,
|
static inline int devif_poll_icmp(FAR struct net_driver_s *dev,
|
||||||
devif_poll_callback_t callback)
|
devif_poll_callback_t callback)
|
||||||
{
|
{
|
||||||
/* Perform the ICMP poll */
|
FAR struct icmp_conn_s *conn = NULL;
|
||||||
|
int bstop = 0;
|
||||||
|
|
||||||
icmp_poll(dev);
|
/* Traverse all of the allocated ICMP connections and perform the poll action */
|
||||||
|
|
||||||
/* Perform any necessary conversions on outgoing packets */
|
while (!bstop && (conn = icmp_nextconn(conn)) != NULL)
|
||||||
|
{
|
||||||
|
/* Perform the ICMP poll */
|
||||||
|
|
||||||
devif_packet_conversion(dev, DEVIF_ICMP);
|
icmp_poll(dev, conn);
|
||||||
|
|
||||||
/* Call back into the driver */
|
/* Perform any necessary conversions on outgoing packets */
|
||||||
|
|
||||||
return callback(dev);
|
devif_packet_conversion(dev, DEVIF_ICMP);
|
||||||
|
|
||||||
|
/* Call back into the driver */
|
||||||
|
|
||||||
|
bstop = callback(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bstop;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_ICMP && CONFIG_NET_ICMP_SOCKET */
|
#endif /* CONFIG_NET_ICMP && CONFIG_NET_ICMP_SOCKET */
|
||||||
|
|
||||||
@ -350,17 +360,27 @@ static inline int devif_poll_icmp(FAR struct net_driver_s *dev,
|
|||||||
static inline int devif_poll_icmpv6(FAR struct net_driver_s *dev,
|
static inline int devif_poll_icmpv6(FAR struct net_driver_s *dev,
|
||||||
devif_poll_callback_t callback)
|
devif_poll_callback_t callback)
|
||||||
{
|
{
|
||||||
/* Perform the ICMPv6 poll */
|
FAR struct icmpv6_conn_s *conn = NULL;
|
||||||
|
int bstop = 0;
|
||||||
|
|
||||||
icmpv6_poll(dev);
|
/* Traverse all of the allocated ICMPV6 connections and perform the poll action */
|
||||||
|
|
||||||
/* Perform any necessary conversions on outgoing packets */
|
while (!bstop && (conn = icmpv6_nextconn(conn)) != NULL)
|
||||||
|
{
|
||||||
|
/* Perform the ICMPV6 poll */
|
||||||
|
|
||||||
devif_packet_conversion(dev, DEVIF_ICMP6);
|
icmpv6_poll(dev, conn);
|
||||||
|
|
||||||
/* Call back into the driver */
|
/* Perform any necessary conversions on outgoing packets */
|
||||||
|
|
||||||
return callback(dev);
|
devif_packet_conversion(dev, DEVIF_ICMPV6);
|
||||||
|
|
||||||
|
/* Call back into the driver */
|
||||||
|
|
||||||
|
bstop = callback(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bstop;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_ICMPv6_SOCKET || CONFIG_NET_ICMPv6_NEIGHBOR*/
|
#endif /* CONFIG_NET_ICMPv6_SOCKET || CONFIG_NET_ICMPv6_NEIGHBOR*/
|
||||||
|
|
||||||
|
@ -61,8 +61,10 @@
|
|||||||
|
|
||||||
/* Allocate/free an ICMP data callback */
|
/* Allocate/free an ICMP data callback */
|
||||||
|
|
||||||
#define icmp_callback_alloc(dev) devif_callback_alloc(dev, &(dev)->d_conncb)
|
#define icmp_callback_alloc(dev, conn) \
|
||||||
#define icmp_callback_free(dev,cb) devif_dev_callback_free(dev, cb)
|
devif_callback_alloc((dev), &(conn)->list)
|
||||||
|
#define icmp_callback_free(dev, conn, cb) \
|
||||||
|
devif_conn_callback_free((dev), (cb), &(conn)->list)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public types
|
* Public types
|
||||||
@ -71,14 +73,14 @@
|
|||||||
#ifdef CONFIG_NET_ICMP_SOCKET
|
#ifdef CONFIG_NET_ICMP_SOCKET
|
||||||
/* Representation of a IPPROTO_ICMP socket connection */
|
/* Representation of a IPPROTO_ICMP socket connection */
|
||||||
|
|
||||||
struct devif_callback_s; /* Forward reference */
|
struct devif_callback_s; /* Forward reference */
|
||||||
|
|
||||||
struct icmp_conn_s
|
struct icmp_conn_s
|
||||||
{
|
{
|
||||||
dq_entry_t node; /* Supports a double linked list */
|
dq_entry_t node; /* Supports a double linked list */
|
||||||
uint16_t id; /* ICMP ECHO request ID */
|
uint16_t id; /* ICMP ECHO request ID */
|
||||||
uint8_t nreqs; /* Number of requests with no response received */
|
uint8_t nreqs; /* Number of requests with no response received */
|
||||||
uint8_t crefs; /* Reference counts on this instance */
|
uint8_t crefs; /* Reference counts on this instance */
|
||||||
|
|
||||||
/* The device that the ICMP request was sent on */
|
/* The device that the ICMP request was sent on */
|
||||||
|
|
||||||
@ -92,6 +94,10 @@ struct icmp_conn_s
|
|||||||
|
|
||||||
struct iob_queue_s readahead; /* Read-ahead buffering */
|
struct iob_queue_s readahead; /* Read-ahead buffering */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Defines the list of ICMP callbacks */
|
||||||
|
|
||||||
|
FAR struct devif_callback_s *list;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -236,7 +242,8 @@ FAR struct icmp_conn_s *icmp_findconn(FAR struct net_driver_s *dev,
|
|||||||
* Poll a device "connection" structure for availability of ICMP TX data
|
* Poll a device "connection" structure for availability of ICMP TX data
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* dev - The device driver structure to use in the send operation
|
* dev - The device driver structure to use in the send operation
|
||||||
|
* conn - A pointer to the ICMP connection structure
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
@ -247,7 +254,7 @@ FAR struct icmp_conn_s *icmp_findconn(FAR struct net_driver_s *dev,
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_NET_ICMP_SOCKET
|
#ifdef CONFIG_NET_ICMP_SOCKET
|
||||||
void icmp_poll(FAR struct net_driver_s *dev);
|
void icmp_poll(FAR struct net_driver_s *dev, FAR struct icmp_conn_s *conn);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
* net/icmp/icmp_input.c
|
* net/icmp/icmp_input.c
|
||||||
* Handling incoming ICMP input
|
* Handling incoming ICMP input
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009, 2012, 2014-2015, 2017 Gregory Nutt. All rights
|
* Copyright (C) 2007-2009, 2012, 2014-2015, 2017, 2019 Gregory Nutt. All
|
||||||
* reserved.
|
* rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
|
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
|
||||||
@ -289,29 +289,29 @@ void icmp_input(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
else if (ipicmp->type == ICMP_ECHO_REPLY)
|
else if (ipicmp->type == ICMP_ECHO_REPLY)
|
||||||
{
|
{
|
||||||
|
FAR struct icmp_conn_s *conn;
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
|
|
||||||
flags = devif_conn_event(dev, NULL, ICMP_ECHOREPLY, dev->d_conncb);
|
/* Nothing consumed the ICMP reply. That might because this is
|
||||||
|
* an old, invalid reply or simply because the ping application
|
||||||
|
* has not yet put its poll or recv in place.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Is there any connection that might expect this reply? */
|
||||||
|
|
||||||
|
conn = icmp_findconn(dev, ipicmp->id);
|
||||||
|
if (conn == NULL)
|
||||||
|
{
|
||||||
|
/* No.. drop the packet */
|
||||||
|
|
||||||
|
goto drop;
|
||||||
|
}
|
||||||
|
|
||||||
|
flags = devif_conn_event(dev, conn, ICMP_ECHOREPLY, conn->list);
|
||||||
if ((flags & ICMP_ECHOREPLY) != 0)
|
if ((flags & ICMP_ECHOREPLY) != 0)
|
||||||
{
|
{
|
||||||
FAR struct icmp_conn_s *conn;
|
|
||||||
uint16_t nbuffered;
|
uint16_t nbuffered;
|
||||||
|
|
||||||
/* Nothing consumed the ICMP reply. That might because this is
|
|
||||||
* an old, invalid reply or simply because the ping application
|
|
||||||
* has not yet put its poll or recv in place.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Is there any connection that might expect this reply? */
|
|
||||||
|
|
||||||
conn = icmp_findconn(dev, ipicmp->id);
|
|
||||||
if (conn == NULL)
|
|
||||||
{
|
|
||||||
/* No.. drop the packet */
|
|
||||||
|
|
||||||
goto drop;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the ICMP echo reply to the IPPROTO_ICMP socket read-ahead
|
/* Add the ICMP echo reply to the IPPROTO_ICMP socket read-ahead
|
||||||
* buffer.
|
* buffer.
|
||||||
*/
|
*/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/icmp/icmp_netpoll.c
|
* net/icmp/icmp_netpoll.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017-2018 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2017-2019 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -197,19 +197,9 @@ int icmp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
|
|||||||
|
|
||||||
net_lock();
|
net_lock();
|
||||||
|
|
||||||
/* Get the device that will provide the provide the NETDEV_DOWN event.
|
|
||||||
* NOTE: in the event that the local socket is bound to INADDR_ANY, the
|
|
||||||
* dev value will be zero and there will be no NETDEV_DOWN notifications.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (conn->dev == NULL)
|
|
||||||
{
|
|
||||||
conn->dev = netdev_default();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate a ICMP callback structure */
|
/* Allocate a ICMP callback structure */
|
||||||
|
|
||||||
cb = icmp_callback_alloc(conn->dev);
|
cb = icmp_callback_alloc(conn->dev, conn);
|
||||||
if (cb == NULL)
|
if (cb == NULL)
|
||||||
{
|
{
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
@ -315,7 +305,7 @@ int icmp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds)
|
|||||||
/* Release the callback */
|
/* Release the callback */
|
||||||
|
|
||||||
net_lock();
|
net_lock();
|
||||||
icmp_callback_free(conn->dev, info->cb);
|
icmp_callback_free(conn->dev, conn, info->cb);
|
||||||
net_unlock();
|
net_unlock();
|
||||||
|
|
||||||
/* Release the poll/select data slot */
|
/* Release the poll/select data slot */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/icmp/icmp_poll.c
|
* net/icmp/icmp_poll.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008-2009, 2014 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2008-2009, 2014, 2019 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -38,7 +38,8 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
#if defined(CONFIG_NET) && defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_SOCKET)
|
#if defined(CONFIG_NET) && defined(CONFIG_NET_ICMP) && \
|
||||||
|
defined(CONFIG_NET_ICMP_SOCKET)
|
||||||
|
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
@ -60,7 +61,8 @@
|
|||||||
* Poll a device "connection" structure for availability of ICMP TX data
|
* Poll a device "connection" structure for availability of ICMP TX data
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* dev - The device driver structure to use in the send operation
|
* dev - The device driver structure to use in the send operation
|
||||||
|
* conn - A pointer to the ICMP connection structure
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
@ -70,7 +72,7 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void icmp_poll(FAR struct net_driver_s *dev)
|
void icmp_poll(FAR struct net_driver_s *dev, FAR struct icmp_conn_s *conn)
|
||||||
{
|
{
|
||||||
/* Setup for the application callback */
|
/* Setup for the application callback */
|
||||||
|
|
||||||
@ -80,7 +82,7 @@ void icmp_poll(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
/* Perform the application callback */
|
/* Perform the application callback */
|
||||||
|
|
||||||
(void)devif_conn_event(dev, NULL, ICMP_POLL, dev->d_conncb);
|
(void)devif_conn_event(dev, conn, ICMP_POLL, conn->list);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_NET && CONFIG_NET_ICMP && CONFIG_NET_ICMP_SOCKET */
|
#endif /* CONFIG_NET && CONFIG_NET_ICMP && CONFIG_NET_ICMP_SOCKET */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/icmp/icmp_recvfrom.c
|
* net/icmp/icmp_recvfrom.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2017, 2019 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -488,8 +488,8 @@ ssize_t icmp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
|||||||
|
|
||||||
/* Set up the callback */
|
/* Set up the callback */
|
||||||
|
|
||||||
state.recv_cb = icmp_callback_alloc(dev);
|
state.recv_cb = icmp_callback_alloc(dev, conn);
|
||||||
if (state.recv_cb)
|
if (state.recv_cb != NULL)
|
||||||
{
|
{
|
||||||
state.recv_cb->flags = (ICMP_ECHOREPLY | NETDEV_DOWN);
|
state.recv_cb->flags = (ICMP_ECHOREPLY | NETDEV_DOWN);
|
||||||
state.recv_cb->priv = (FAR void *)&state;
|
state.recv_cb->priv = (FAR void *)&state;
|
||||||
@ -503,7 +503,7 @@ ssize_t icmp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
|||||||
ninfo("Start time: 0x%08x\n", state.recv_time);
|
ninfo("Start time: 0x%08x\n", state.recv_time);
|
||||||
net_lockedwait(&state.recv_sem);
|
net_lockedwait(&state.recv_sem);
|
||||||
|
|
||||||
icmp_callback_free(dev, state.recv_cb);
|
icmp_callback_free(dev, conn, state.recv_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
net_unlock();
|
net_unlock();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/icmp/icmp_sendto.c
|
* net/icmp/icmp_sendto.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2017, 2019 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -455,8 +455,8 @@ ssize_t icmp_sendto(FAR struct socket *psock, FAR const void *buf, size_t len,
|
|||||||
|
|
||||||
/* Set up the callback */
|
/* Set up the callback */
|
||||||
|
|
||||||
state.snd_cb = icmp_callback_alloc(dev);
|
state.snd_cb = icmp_callback_alloc(dev, conn);
|
||||||
if (state.snd_cb)
|
if (state.snd_cb != NULL)
|
||||||
{
|
{
|
||||||
state.snd_cb->flags = (ICMP_POLL | NETDEV_DOWN);
|
state.snd_cb->flags = (ICMP_POLL | NETDEV_DOWN);
|
||||||
state.snd_cb->priv = (FAR void *)&state;
|
state.snd_cb->priv = (FAR void *)&state;
|
||||||
@ -484,7 +484,7 @@ ssize_t icmp_sendto(FAR struct socket *psock, FAR const void *buf, size_t len,
|
|||||||
ninfo("Start time: 0x%08x\n", state.snd_time);
|
ninfo("Start time: 0x%08x\n", state.snd_time);
|
||||||
net_lockedwait(&state.snd_sem);
|
net_lockedwait(&state.snd_sem);
|
||||||
|
|
||||||
icmp_callback_free(dev, state.snd_cb);
|
icmp_callback_free(dev, conn, state.snd_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
net_unlock();
|
net_unlock();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/icmpv6/icmpv6.h
|
* net/icmpv6/icmpv6.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015, 2017-2018 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2015, 2017-2019 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -62,10 +62,10 @@
|
|||||||
|
|
||||||
/* Allocate a new ICMPv6 data callback */
|
/* Allocate a new ICMPv6 data callback */
|
||||||
|
|
||||||
#define icmpv6_callback_alloc(dev) \
|
#define icmpv6_callback_alloc(dev, conn) \
|
||||||
devif_callback_alloc((dev), &(dev)->d_conncb)
|
devif_callback_alloc((dev), &(conn)->list)
|
||||||
#define icmpv6_callback_free(dev,cb) \
|
#define icmpv6_callback_free(dev, conn, cb) \
|
||||||
devif_dev_callback_free((dev), (cb))
|
devif_conn_callback_free((dev), (cb), &(conn)->list)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Type Definitions
|
* Public Type Definitions
|
||||||
@ -95,6 +95,10 @@ struct icmpv6_conn_s
|
|||||||
|
|
||||||
struct iob_queue_s readahead; /* Read-ahead buffering */
|
struct iob_queue_s readahead; /* Read-ahead buffering */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Defines the list of ICMPV6 callbacks */
|
||||||
|
|
||||||
|
FAR struct devif_callback_s *list;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -228,7 +232,8 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr);
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_NET_ICMPv6_SOCKET) || defined(CONFIG_NET_ICMPv6_NEIGHBOR)
|
#if defined(CONFIG_NET_ICMPv6_SOCKET) || defined(CONFIG_NET_ICMPv6_NEIGHBOR)
|
||||||
void icmpv6_poll(FAR struct net_driver_s *dev);
|
void icmpv6_poll(FAR struct net_driver_s *dev,
|
||||||
|
FAR struct icmpv6_conn_s *conn);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -238,7 +243,7 @@ void icmpv6_poll(FAR struct net_driver_s *dev);
|
|||||||
* Set up to send an ICMPv6 Neighbor Solicitation message
|
* Set up to send an ICMPv6 Neighbor Solicitation message
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* dev - Reference to a device driver structure
|
* dev - Reference to a device driver structure
|
||||||
* ipaddr - IP address of Neighbor to be solicited
|
* ipaddr - IP address of Neighbor to be solicited
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@ -408,7 +413,8 @@ void icmpv6_notify(net_ipv6addr_t ipaddr);
|
|||||||
* device.
|
* device.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* dev - The device driver structure to assign the address to
|
* dev - The device driver structure to assign the address to
|
||||||
|
* psock - A pointer to a NuttX-specific, internal socket structure
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Zero (OK) is returned on success; A negated errno value is returned on
|
* Zero (OK) is returned on success; A negated errno value is returned on
|
||||||
@ -417,7 +423,8 @@ void icmpv6_notify(net_ipv6addr_t ipaddr);
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_NET_ICMPv6_AUTOCONF
|
#ifdef CONFIG_NET_ICMPv6_AUTOCONF
|
||||||
int icmpv6_autoconfig(FAR struct net_driver_s *dev);
|
int icmpv6_autoconfig(FAR struct net_driver_s *dev,
|
||||||
|
FAR struct socket *psock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/icmpv6/icmpv6_autoconfig.c
|
* net/icmpv6/icmpv6_autoconfig.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2016, 2018 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2015-2016, 2018-2019 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -184,6 +184,7 @@ static uint16_t icmpv6_router_eventhandler(FAR struct net_driver_s *dev,
|
|||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* dev - The device to use to send the solicitation
|
* dev - The device to use to send the solicitation
|
||||||
|
* conn - A pointer to the ICMPv6 connection structure
|
||||||
* advertise - True: Send the Neighbor Advertisement message
|
* advertise - True: Send the Neighbor Advertisement message
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@ -195,7 +196,9 @@ static uint16_t icmpv6_router_eventhandler(FAR struct net_driver_s *dev,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int icmpv6_send_message(FAR struct net_driver_s *dev, bool advertise)
|
static int icmpv6_send_message(FAR struct net_driver_s *dev,
|
||||||
|
FAR struct icmpv6_conn_s *conn,
|
||||||
|
bool advertise)
|
||||||
{
|
{
|
||||||
struct icmpv6_router_s state;
|
struct icmpv6_router_s state;
|
||||||
int ret;
|
int ret;
|
||||||
@ -220,7 +223,7 @@ static int icmpv6_send_message(FAR struct net_driver_s *dev, bool advertise)
|
|||||||
* want anything to happen until we are ready.
|
* want anything to happen until we are ready.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
state.snd_cb = icmpv6_callback_alloc(dev);
|
state.snd_cb = icmpv6_callback_alloc(dev, conn);
|
||||||
if (!state.snd_cb)
|
if (!state.snd_cb)
|
||||||
{
|
{
|
||||||
nerr("ERROR: Failed to allocate a cllback\n");
|
nerr("ERROR: Failed to allocate a cllback\n");
|
||||||
@ -252,7 +255,7 @@ static int icmpv6_send_message(FAR struct net_driver_s *dev, bool advertise)
|
|||||||
while (!state.snd_sent);
|
while (!state.snd_sent);
|
||||||
|
|
||||||
ret = state.snd_result;
|
ret = state.snd_result;
|
||||||
icmpv6_callback_free(dev, state.snd_cb);
|
icmpv6_callback_free(dev, conn, state.snd_cb);
|
||||||
|
|
||||||
errout_with_semaphore:
|
errout_with_semaphore:
|
||||||
nxsem_destroy(&state.snd_sem);
|
nxsem_destroy(&state.snd_sem);
|
||||||
@ -279,7 +282,8 @@ errout_with_semaphore:
|
|||||||
* address it can use based on that information.
|
* address it can use based on that information.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* dev - The device driver structure to assign the address to
|
* dev - The device driver structure to assign the address to
|
||||||
|
* psock - A pointer to a NuttX-specific, internal socket structure
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Zero (OK) is returned on success; A negated errno value is returned on
|
* Zero (OK) is returned on success; A negated errno value is returned on
|
||||||
@ -287,8 +291,9 @@ errout_with_semaphore:
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int icmpv6_autoconfig(FAR struct net_driver_s *dev)
|
int icmpv6_autoconfig(FAR struct net_driver_s *dev, FAR struct socket *psock)
|
||||||
{
|
{
|
||||||
|
FAR struct icmpv6_conn_s *conn = psock->s_conn;
|
||||||
struct icmpv6_rnotify_s notify;
|
struct icmpv6_rnotify_s notify;
|
||||||
struct timespec delay;
|
struct timespec delay;
|
||||||
net_ipv6addr_t lladdr;
|
net_ipv6addr_t lladdr;
|
||||||
@ -393,7 +398,7 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
/* Send the ICMPv6 Router solicitation message */
|
/* Send the ICMPv6 Router solicitation message */
|
||||||
|
|
||||||
ret = icmpv6_send_message(dev, false);
|
ret = icmpv6_send_message(dev, conn, false);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nerr("ERROR: Failed send router solicitation: %d\n", ret);
|
nerr("ERROR: Failed send router solicitation: %d\n", ret);
|
||||||
@ -429,7 +434,7 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
|
|||||||
* Advertisement message.
|
* Advertisement message.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = icmpv6_send_message(dev, true);
|
ret = icmpv6_send_message(dev, conn, true);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nerr("ERROR: Failed send neighbor advertisement: %d\n", ret);
|
nerr("ERROR: Failed send neighbor advertisement: %d\n", ret);
|
||||||
|
@ -450,36 +450,36 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen)
|
|||||||
|
|
||||||
case ICMPv6_ECHO_REPLY:
|
case ICMPv6_ECHO_REPLY:
|
||||||
{
|
{
|
||||||
|
FAR struct icmpv6_echo_reply_s *reply;
|
||||||
|
FAR struct icmpv6_conn_s *conn;
|
||||||
uint16_t flags = ICMPv6_ECHOREPLY;
|
uint16_t flags = ICMPv6_ECHOREPLY;
|
||||||
|
|
||||||
|
/* Nothing consumed the ICMP reply. That might be because this is
|
||||||
|
* an old, invalid reply or simply because the ping application
|
||||||
|
* has not yet put its poll or recv in place.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Is there any connection that might expect this reply? */
|
||||||
|
|
||||||
|
reply = ICMPv6REPLY;
|
||||||
|
conn = icmpv6_findconn(dev, reply->id);
|
||||||
|
if (conn == NULL)
|
||||||
|
{
|
||||||
|
/* No.. drop the packet */
|
||||||
|
|
||||||
|
goto icmpv6_drop_packet;
|
||||||
|
}
|
||||||
|
|
||||||
/* Dispatch the ECHO reply to the waiting thread */
|
/* Dispatch the ECHO reply to the waiting thread */
|
||||||
|
|
||||||
flags = devif_conn_event(dev, NULL, flags, dev->d_conncb);
|
flags = devif_conn_event(dev, conn, flags, conn->list);
|
||||||
|
|
||||||
/* Was the ECHO reply consumed by any waiting thread? */
|
/* Was the ECHO reply consumed by any waiting thread? */
|
||||||
|
|
||||||
if ((flags & ICMPv6_ECHOREPLY) != 0)
|
if ((flags & ICMPv6_ECHOREPLY) != 0)
|
||||||
{
|
{
|
||||||
FAR struct icmpv6_echo_reply_s *reply;
|
|
||||||
FAR struct icmpv6_conn_s *conn;
|
|
||||||
uint16_t nbuffered;
|
uint16_t nbuffered;
|
||||||
|
|
||||||
/* Nothing consumed the ICMP reply. That might because this is
|
|
||||||
* an old, invalid reply or simply because the ping application
|
|
||||||
* has not yet put its poll or recv in place.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Is there any connection that might expect this reply? */
|
|
||||||
|
|
||||||
reply = ICMPv6REPLY;
|
|
||||||
conn = icmpv6_findconn(dev, reply->id);
|
|
||||||
if (conn == NULL)
|
|
||||||
{
|
|
||||||
/* No.. drop the packet */
|
|
||||||
|
|
||||||
goto icmpv6_drop_packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Yes.. Add the ICMP echo reply to the IPPROTO_ICMP socket read
|
/* Yes.. Add the ICMP echo reply to the IPPROTO_ICMP socket read
|
||||||
* ahead buffer.
|
* ahead buffer.
|
||||||
*/
|
*/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/icmpv6/icmpv6_neighbor.c
|
* net/icmpv6/icmpv6_neighbor.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2015-2016, 2019 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -266,7 +266,7 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
net_lock();
|
net_lock();
|
||||||
state.snd_cb = icmpv6_callback_alloc(dev);
|
state.snd_cb = devif_callback_alloc((dev), &(dev)->d_conncb);
|
||||||
if (!state.snd_cb)
|
if (!state.snd_cb)
|
||||||
{
|
{
|
||||||
nerr("ERROR: Failed to allocate a callback\n");
|
nerr("ERROR: Failed to allocate a callback\n");
|
||||||
@ -366,7 +366,7 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nxsem_destroy(&state.snd_sem);
|
nxsem_destroy(&state.snd_sem);
|
||||||
icmpv6_callback_free(dev, state.snd_cb);
|
devif_dev_callback_free(dev, state.snd_cb);
|
||||||
|
|
||||||
errout_with_lock:
|
errout_with_lock:
|
||||||
net_unlock();
|
net_unlock();
|
||||||
|
@ -193,23 +193,11 @@ int icmpv6_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Some of the following must be atomic */
|
/* Some of the following must be atomic */
|
||||||
|
|
||||||
net_lock();
|
net_lock();
|
||||||
|
|
||||||
/* Get the device that will provide the provide the NETDEV_DOWN event.
|
cb = icmpv6_callback_alloc(conn->dev, conn);
|
||||||
* NOTE: in the event that the local socket is bound to IN6ADDR_ANY, the
|
|
||||||
* dev value will be zero and there will be no NETDEV_DOWN notifications.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Allocate a ICMP callback structure */
|
|
||||||
|
|
||||||
if (conn->dev == NULL)
|
|
||||||
{
|
|
||||||
conn->dev = netdev_default();
|
|
||||||
}
|
|
||||||
|
|
||||||
cb = icmpv6_callback_alloc(conn->dev);
|
|
||||||
if (cb == NULL)
|
if (cb == NULL)
|
||||||
{
|
{
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
@ -315,7 +303,7 @@ int icmpv6_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds)
|
|||||||
/* Release the callback */
|
/* Release the callback */
|
||||||
|
|
||||||
net_lock();
|
net_lock();
|
||||||
icmpv6_callback_free(conn->dev, info->cb);
|
icmpv6_callback_free(conn->dev, conn, info->cb);
|
||||||
net_unlock();
|
net_unlock();
|
||||||
|
|
||||||
/* Release the poll/select data slot */
|
/* Release the poll/select data slot */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/icmpv6/icmpv6_poll.c
|
* net/icmpv6/icmpv6_poll.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2015, 2019 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -61,7 +61,8 @@
|
|||||||
* Poll a UDP "connection" structure for availability of TX data
|
* Poll a UDP "connection" structure for availability of TX data
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* dev - The device driver structure to use in the send operation
|
* dev - The device driver structure to use in the send operation
|
||||||
|
* conn - A pointer to the ICMPv6 connection structure
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
@ -71,7 +72,8 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void icmpv6_poll(FAR struct net_driver_s *dev)
|
void icmpv6_poll(FAR struct net_driver_s *dev,
|
||||||
|
FAR struct icmpv6_conn_s *conn)
|
||||||
{
|
{
|
||||||
/* Setup for the application callback */
|
/* Setup for the application callback */
|
||||||
|
|
||||||
@ -81,7 +83,7 @@ void icmpv6_poll(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
/* Perform the application callback */
|
/* Perform the application callback */
|
||||||
|
|
||||||
(void)devif_conn_event(dev, NULL, ICMPv6_POLL, dev->d_conncb);
|
(void)devif_conn_event(dev, conn, ICMPv6_POLL, conn->list);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_NET_ICMPv6_SOCKET || CONFIG_NET_ICMPv6_NEIGHBOR */
|
#endif /* CONFIG_NET_ICMPv6_SOCKET || CONFIG_NET_ICMPv6_NEIGHBOR */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/icmpv6/icmpv6_recvfrom.c
|
* net/icmpv6/icmpv6_recvfrom.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2017, 2019 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -495,7 +495,7 @@ ssize_t icmpv6_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
|||||||
|
|
||||||
/* Set up the callback */
|
/* Set up the callback */
|
||||||
|
|
||||||
state.recv_cb = icmpv6_callback_alloc(dev);
|
state.recv_cb = icmpv6_callback_alloc(dev, conn);
|
||||||
if (state.recv_cb)
|
if (state.recv_cb)
|
||||||
{
|
{
|
||||||
state.recv_cb->flags = (ICMPv6_ECHOREPLY | NETDEV_DOWN);
|
state.recv_cb->flags = (ICMPv6_ECHOREPLY | NETDEV_DOWN);
|
||||||
@ -513,7 +513,7 @@ ssize_t icmpv6_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
|||||||
ninfo("Start time: 0x%08x\n", state.recv_time);
|
ninfo("Start time: 0x%08x\n", state.recv_time);
|
||||||
net_lockedwait(&state.recv_sem);
|
net_lockedwait(&state.recv_sem);
|
||||||
|
|
||||||
icmpv6_callback_free(dev, state.recv_cb);
|
icmpv6_callback_free(dev, conn, state.recv_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
net_unlock();
|
net_unlock();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/icmpv6/icmpv6_sendto.c
|
* net/icmpv6/icmpv6_sendto.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2017, 2019 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -449,7 +449,7 @@ ssize_t icmpv6_sendto(FAR struct socket *psock, FAR const void *buf, size_t len,
|
|||||||
|
|
||||||
/* Set up the callback */
|
/* Set up the callback */
|
||||||
|
|
||||||
state.snd_cb = icmpv6_callback_alloc(dev);
|
state.snd_cb = icmpv6_callback_alloc(dev, conn);
|
||||||
if (state.snd_cb)
|
if (state.snd_cb)
|
||||||
{
|
{
|
||||||
state.snd_cb->flags = (ICMPv6_POLL | NETDEV_DOWN);
|
state.snd_cb->flags = (ICMPv6_POLL | NETDEV_DOWN);
|
||||||
@ -478,7 +478,7 @@ ssize_t icmpv6_sendto(FAR struct socket *psock, FAR const void *buf, size_t len,
|
|||||||
ninfo("Start time: 0x%08x\n", state.snd_time);
|
ninfo("Start time: 0x%08x\n", state.snd_time);
|
||||||
net_lockedwait(&state.snd_sem);
|
net_lockedwait(&state.snd_sem);
|
||||||
|
|
||||||
icmpv6_callback_free(dev, state.snd_cb);
|
icmpv6_callback_free(dev, conn, state.snd_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
net_unlock();
|
net_unlock();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/netdev/netdev_ioctl.c
|
* net/netdev/netdev_ioctl.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2012, 2015-2018 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2012, 2015-2019 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -897,7 +897,7 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
|
|||||||
dev = netdev_ifr_dev(req);
|
dev = netdev_ifr_dev(req);
|
||||||
if (dev)
|
if (dev)
|
||||||
{
|
{
|
||||||
ret = icmpv6_autoconfig(dev);
|
ret = icmpv6_autoconfig(dev, psock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user