text: /****************************************************************************
   * net/icmp/icmp.h
   *
   *   Copyright (C) 2014 Gregory Nutt. All rights reserved.
   *   Author: Gregory Nutt <gnutt@nuttx.org>
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   * 3. Neither the name NuttX nor the names of its contributors may be
   *    used to endorse or promote products derived from this software
   *    without specific prior written permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
   * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
   * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   * POSSIBILITY OF SUCH DAMAGE.
   *
   ****************************************************************************/
  
  #ifndef __NET_ICMP_ICMP_H
  #define __NET_ICMP_ICMP_H
  
  /****************************************************************************
   * Included Files
   ****************************************************************************/
  
  #include <nuttx/config.h>
  
  #include <sys/types.h>
  #include <stdint.h>
  #include <queue.h>
  #include <assert.h>
  
  #include <nuttx/mm/iob.h>
  #include <nuttx/net/ip.h>
  #include <nuttx/net/netdev.h>
  
  #ifdef CONFIG_NET_ICMP
  
  /****************************************************************************
   * Pre-processor Definitions
   ****************************************************************************/
  
  /* Allocate/free an ICMP data callback */
  
  #define icmp_callback_alloc(dev)   devif_callback_alloc(dev, &(dev)->d_conncb)
  #define icmp_callback_free(dev,cb) devif_dev_callback_free(dev, cb)
  
  /****************************************************************************
   * Public types
   ****************************************************************************/
  
  #ifdef CONFIG_NET_ICMP_SOCKET
  /* Representation of a IPPROTO_ICMP socket connection */
  
  struct devif_callback_s; /* Forward reference */
  
  struct icmp_conn_s
  {
    dq_entry_t node;     /* Supports a double linked list */
    uint16_t   id;       /* ICMP ECHO request ID */
    uint8_t    nreqs;    /* Number of requests with no response received */
    uint8_t    crefs;    /* Reference counts on this instance */
  
    /* The device that the ICMP request was sent on */
  
    FAR struct net_driver_s *dev;  /* Needed to free the callback structure */
  
  #ifdef CONFIG_MM_IOB
    /* ICMP response read-ahead list.  A singly linked list of type struct
     * iob_qentry_s where the ICMP read-ahead data for the current ID is
     * retained.
     */
  
    struct iob_queue_s readahead;  /* Read-ahead buffering */
  #endif
  };
  #endif
  
  /****************************************************************************
   * Public Data
   ****************************************************************************/
  
  #ifdef __cplusplus
  #  define EXTERN extern "C"
  extern "C"
  {
  #else
  #  define EXTERN extern
  #endif
  
  #ifdef CONFIG_NET_ICMP_SOCKET
  /* PF_INET socket address family, IPPROTO_ICMP protocol interface */
  
  EXTERN const struct sock_intf_s g_icmp_sockif;
  #endif
  
  /****************************************************************************
   * Public Function Prototypes
   ****************************************************************************/
  
  struct socket;    /* Forward reference */
  struct sockaddr;  /* Forward reference */
  struct pollfd;    /* Forward reference */
  
  /****************************************************************************
   * Name: icmp_input
   *
   * Description:
   *   Handle incoming ICMP input
   *
   * Parameters:
   *   dev - The device driver structure containing the received ICMP
   *         packet
   *
   * Returned Value:
   *   None
   *
   * Assumptions:
   *   The network is locked.
   *
   ****************************************************************************/
  
  void icmp_input(FAR struct net_driver_s *dev);
  
  /****************************************************************************
   * Name: icmp_sock_initialize
   *
   * Description:
   *   Initialize the IPPROTO_ICMP socket connection structures.  Called once
   *   and only from the network initialization layer.
   *
   ****************************************************************************/
  
  #ifdef CONFIG_NET_ICMP_SOCKET
  void icmp_sock_initialize(void);
  #endif
  
  /****************************************************************************
   * Name: icmp_alloc
   *
   * Description:
   *   Allocate a new, uninitialized IPPROTO_ICMP socket connection structure.
   *   This is normally something done by the implementation of the socket()
   *   interface.
   *
   ****************************************************************************/
  
  #ifdef CONFIG_NET_ICMP_SOCKET
  FAR struct icmp_conn_s *icmp_alloc(void);
  #endif
  
  /****************************************************************************
   * Name: icmp_free
   *
   * Description:
   *   Free a IPPROTO_ICMP socket connection structure that is no longer in
   *   use.  This should be done by the implementation of close().
   *
   ****************************************************************************/
  
  #ifdef CONFIG_NET_ICMP_SOCKET
  void icmp_free(FAR struct icmp_conn_s *conn);
  #endif
  
  /****************************************************************************
   * Name: icmp_active()
   *
   * Description:
   *   Find a connection structure that is the appropriate connection to be
   *   used with the provided ECHO request ID.
   *
   * Assumptions:
   *   This function is called from network logic at with the network locked.
   *
   ****************************************************************************/
  
  #ifdef CONFIG_NET_ICMP_SOCKET
  FAR struct icmp_conn_s *icmp_active(uint16_t id);
  #endif
  
  /****************************************************************************
   * Name: icmp_nextconn
   *
   * Description:
   *   Traverse the list of allocated packet connections
   *
   * Assumptions:
   *   This function is called from network logic at with the network locked.
   *
   ****************************************************************************/
  
  #ifdef CONFIG_NET_ICMP_SOCKET
  FAR struct icmp_conn_s *icmp_nextconn(FAR struct icmp_conn_s *conn);
  #endif
  
  /****************************************************************************
   * Name: icmp_findconn
   *
   * Description:
   *   Find an ICMP connection structure that is expecting a ICMP ECHO response
   *   with this ID from this device
   *
   * Assumptions:
   *   This function is called from network logic at with the network locked.
   *
   ****************************************************************************/
  
  #ifdef CONFIG_NET_ICMP_SOCKET
  FAR struct icmp_conn_s *icmp_findconn(FAR struct net_driver_s *dev, uint8_t id);
  #endif
  
  /****************************************************************************
   * Name: icmp_poll
   *
   * Description:
   *   Poll a device "connection" structure for availability of ICMP TX data
   *
   * Parameters:
   *   dev - The device driver structure to use in the send operation
   *
   * Returned Value:
   *   None
   *
   * Assumptions:
   *   The network is locked.
   *
   ****************************************************************************/
  
  #ifdef CONFIG_NET_ICMP_SOCKET
  void icmp_poll(FAR struct net_driver_s *dev);
  #endif
  
  /****************************************************************************
   * Name: icmp_sendto
   *
   * Description:
   *   Implements the sendto() operation for the case of the IPPROTO_ICMP
   *   socket.  The 'buf' parameter points to a block of memory that includes
   *   an ICMP request header, followed by any payload that accompanies the
   *   request.  The 'len' parameter includes both the size of the ICMP header
   *   and the following payload.
   *
   * Input Parameters:
   *   psock    A pointer to a NuttX-specific, internal socket structure
   *   buf      Data to send
   *   len      Length of data to send
   *   flags    Send flags
   *   to       Address of recipient
   *   tolen    The length of the address structure
   *
   * Returned Value:
   *   On success, returns the number of characters sent.  On  error, a negated
   *   errno value is returned (see send_to() for the list of appropriate error
   *   values.
   *
   ****************************************************************************/
  
  #ifdef CONFIG_NET_ICMP_SOCKET
  ssize_t icmp_sendto(FAR struct socket *psock, FAR const void *buf, size_t len,
                      int flags, FAR const struct sockaddr *to, socklen_t tolen);
  #endif
  
  /****************************************************************************
   * Name: icmp_recvfrom
   *
   * Description:
   *   Implements the socket recvfrom interface for the case of the AF_INET
   *   data gram socket with the IPPROTO_ICMP protocol.  icmp_recvfrom()
   *   receives ICMP ECHO replies for the a socket.
   *
   *   If 'from' is not NULL, and the underlying protocol provides the source
   *   address, this source address is filled in.  The argument 'fromlen' is
   *   initialized to the size of the buffer associated with from, and
   *   modified on return to indicate the actual size of the address stored
   *   there.
   *
   * Input Parameters:
   *   psock    A pointer to a NuttX-specific, internal socket structure
   *   buf      Buffer to receive data
   *   len      Length of buffer
   *   flags    Receive flags
   *   from     Address of source (may be NULL)
   *   fromlen  The length of the address structure
   *
   * Returned Value:
   *   On success, returns the number of characters received.  If no data is
   *   available to be received and the peer has performed an orderly shutdown,
   *   recv() will return 0.  Otherwise, on errors, a negated errno value is
   *   returned (see recvfrom() for the list of appropriate error values).
   *
   ****************************************************************************/
  
  #ifdef CONFIG_NET_ICMP_SOCKET
  ssize_t icmp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
                        int flags, FAR struct sockaddr *from,
                        FAR socklen_t *fromlen);
  #endif
  
  /****************************************************************************
   * Name: icmp_pollsetup
   *
   * Description:
   *   Setup to monitor events on one ICMP socket
   *
   * Input Parameters:
   *   psock - The IPPROTO_ICMP socket of interest
   *   fds   - The structure describing the events to be monitored, OR NULL if
   *           this is a request to stop monitoring events.
   *
   * Returned Value:
   *  0: Success; Negated errno on failure
   *
   ****************************************************************************/
  
  #ifdef CONFIG_NET_ICMP_SOCKET
  int icmp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds);
  #endif
  
  /****************************************************************************
   * Name: icmp_pollteardown
   *
   * Description:
   *   Teardown monitoring of events on an ICMP socket
   *
   * Input Parameters:
   *   psock - The IPPROTO_ICMP socket of interest
   *   fds   - The structure describing the events to be monitored, OR NULL if
   *           this is a request to stop monitoring events.
   *
   * Returned Value:
   *  0: Success; Negated errno on failure
   *
   ****************************************************************************/
  
  #ifdef CONFIG_NET_ICMP_SOCKET
  int icmp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds);
  #endif
  
  #undef EXTERN
  #ifdef __cplusplus
  }
  #endif
  
  #endif /* CONFIG_NET_ICMP */
  #endif /* __NET_ICMP_ICMP_H */
  