Пример #1
0
static inline int dhcpd_openlistener(void)
{
  struct sockaddr_in addr;
  struct ifreq req;
  int sockfd;
  int ret;

  /* Create a socket to listen for requests from DHCP clients */

  sockfd = dhcpd_socket();
  if (sockfd < 0)
    {
      ndbg("socket failed: %d\n", errno);
      return ERROR;
    }

  /* Get the IP address of the selected device */

  strncpy(req.ifr_name, CONFIG_NETUTILS_DHCPD_INTERFACE, IFNAMSIZ);
  ret = ioctl(sockfd, SIOCGIFADDR, (unsigned long)&req);
  if (ret < 0)
    {
      ndbg("setsockopt SIOCGIFADDR failed: %d\n", errno);
      close(sockfd);
      return ERROR;
    }

  g_state.ds_serverip = ((struct sockaddr_in*)&req.ifr_addr)->sin_addr.s_addr;
  nvdbg("serverip: %08lx\n", ntohl(g_state.ds_serverip));

  /* Bind the socket to a local port. We have to bind to INADDRY_ANY to
   * receive broadcast messages.
   */

  addr.sin_family      = AF_INET;
  addr.sin_port        = htons(DHCP_SERVER_PORT);
  addr.sin_addr.s_addr = INADDR_ANY;

  ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
  if (ret < 0)
    {
      ndbg("bind failed, port=%d addr=%08lx: %d\n",
           addr.sin_port, (long)addr.sin_addr.s_addr, errno);
      close(sockfd);
      return ERROR;
    }

  return sockfd;
}
Пример #2
0
int ftpc_sockinit(FAR struct ftpc_socket_s *sock)
{
	/* Initialize the socket structure */

	memset(sock, 0, sizeof(struct ftpc_socket_s));

	/* Create a socket descriptor */

	sock->sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sock->sd < 0) {
		ndbg("socket() failed: %d\n", errno);
		goto errout;
	}

	/* Call fdopen to "wrap" the socket descriptor as an input stream using C
	 * buffered I/O.
	 */

	sock->instream = fdopen(sock->sd, "r");
	if (!sock->instream) {
		ndbg("fdopen() failed: %d\n", errno);
		goto errout_with_sd;
	}

	/* Call fdopen to "wrap" the socket descriptor as an output stream using C
	 * buffered I/O.
	 */

	sock->outstream = fdopen(sock->sd, "w");
	if (!sock->outstream) {
		ndbg("fdopen() failed: %d\n", errno);
		goto errout_with_instream;
	}

	return OK;

	/* Close the instream.  NOTE:  Since the underlying socket descriptor is
	 * *not* dup'ed, the following close should fail harmlessly.
	 */

errout_with_instream:
	fclose(sock->instream);
	sock->instream = NULL;
errout_with_sd:
	close(sock->sd);
	sock->sd = -1;
errout:
	return ERROR;
}
Пример #3
0
static uint16_t socket_event(FAR struct net_driver_s *dev, FAR void *pvconn,
                             FAR void *pvpriv, uint16_t flags)
{
  FAR struct usrsock_reqstate_s *pstate = pvpriv;
  FAR struct usrsock_conn_s *conn = pvconn;

  if (flags & USRSOCK_EVENT_ABORT)
    {
      ndbg("socket aborted.\n");

      pstate->result = -ENETDOWN;

      /* Stop further callbacks */

      pstate->cb->flags   = 0;
      pstate->cb->priv    = NULL;
      pstate->cb->event   = NULL;

      /* Wake up the waiting thread */

      sem_post(&pstate->recvsem);
    }
  else if (flags & USRSOCK_EVENT_REQ_COMPLETE)
    {
      ndbg("request completed.\n");

      pstate->result = conn->resp.result;
      if (pstate->result >= 0)
        {
          /* We might start getting events for this socket right after
           * returning to daemon, so setup 'conn' already here. */

          conn->state   = USRSOCK_CONN_STATE_READY;
          conn->usockid = pstate->result;
        }

      /* Stop further callbacks */

      pstate->cb->flags   = 0;
      pstate->cb->priv    = NULL;
      pstate->cb->event   = NULL;

      /* Wake up the waiting thread */

      sem_post(&pstate->recvsem);
    }

  return flags;
}
Пример #4
0
int xmlrpc_main(int argc, char *argv[])
#endif
{
  int listenfd, connfd, on = 1;
  socklen_t clilen;
  struct sockaddr_in cliaddr, servaddr;

  if (xmlrpc_netinit() < 0)
    {
      ndbg("Could not initialize the network interface\n");
      return ERROR;
    }

  /* Register RPC functions. */

  calls_register();

  listenfd = socket(AF_INET, SOCK_STREAM, 0);

  setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

  bzero((void *)&servaddr, sizeof(servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  servaddr.sin_port = htons(80);

  bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

  listen(listenfd, 5);

  for (;;)
    {
      clilen = sizeof(cliaddr);
      connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
      if (connfd <= 0)
        {
          break;
        }
      ndbg("Connection accepted: %d\n", connfd);

      xmlrpc_handler(connfd);
      close(connfd);
      ndbg("[%d] connection closed\n", connfd);
    }

  close(listenfd);
  return (0);
}
Пример #5
0
static inline ssize_t tftp_write(int fd, const uint8_t *buf, size_t len)
{
    size_t left = len;
    ssize_t nbyteswritten;

    while (left > 0)
    {
        /* Write the data... repeating the write in the event that it was
         * interrupted by a signal.
         */

        do
        {
            nbyteswritten = write(fd, buf, left);
        }
        while (nbyteswritten < 0 && errno == EINTR);

        /* Check for non-EINTR errors */

        if (nbyteswritten < 0)
        {
            ndbg("write failed: %d\n", errno);
            return ERROR;
        }

        /* Handle partial writes */

        nvdbg("Wrote %d bytes to file\n", nbyteswritten);
        left -= nbyteswritten;
        buf  += nbyteswritten;
    }
    return len;
}
Пример #6
0
FAR struct tcp_wrbuffer_s *tcp_wrbuffer_alloc(void)
{
  FAR struct tcp_wrbuffer_s *wrb;

  /* We need to allocate two things:  (1) A write buffer structure and (2)
   * at least one I/O buffer to start the chain.
   *
   * Allocate the write buffer structure first then the IOBG.  In order to
   * avoid deadlocks, we will need to free the IOB first, then the write
   * buffer
   */

  DEBUGVERIFY(net_lockedwait(&g_wrbuffer.sem));

  /* Now, we are guaranteed to have a write buffer structure reserved
   * for us in the free list.
   */

  wrb = (FAR struct tcp_wrbuffer_s *)sq_remfirst(&g_wrbuffer.freebuffers);
  DEBUGASSERT(wrb);
  memset(wrb, 0, sizeof(struct tcp_wrbuffer_s));

  /* Now get the first I/O buffer for the write buffer structure */

  wrb->wb_iob = iob_alloc(false);
  if (!wrb->wb_iob)
    {
      ndbg("ERROR: Failed to allocate I/O buffer\n");
      tcp_wrbuffer_release(wrb);
      return NULL;
    }

  return wrb;
}
Пример #7
0
int tftp_mkdatapacket(int fd, off_t offset, uint8_t *packet, uint16_t blockno)
{
  off_t tmp;
  int nbytesread;

  /* Format the DATA message header */

  packet[0] = TFTP_DATA >> 8;
  packet[1] = TFTP_DATA & 0xff;
  packet[2] = blockno >> 8;
  packet[3] = blockno & 0xff;

  /* Seek to the correct offset in the file */

  tmp = lseek(fd, offset, SEEK_SET);
  if (tmp == (off_t)-1)
    {
      ndbg("lseek failed: %d\n", errno);
      return ERROR;
    }

  /* Read the file data into the packet buffer */

  nbytesread = tftp_read(fd, &packet[TFTP_DATAHEADERSIZE], TFTP_DATASIZE);
  if (nbytesread < 0)
    {
      return ERROR;
    }
  return nbytesread + TFTP_DATAHEADERSIZE;
}
Пример #8
0
int ftpc_socklisten(struct ftpc_socket_s *sock)
{
  unsigned int addrlen = sizeof(sock->laddr);
  int ret;

  /* Bind the local socket to the local address */

  sock->laddr.sin_port = 0;
  ret = bind(sock->sd, (struct sockaddr *)&sock->laddr, addrlen);
  if (ret < 0)
    {
      ndbg("bind() failed: %d\n", errno);
      return ERROR;
    }

  /* Wait for the connection to the server */

  if (listen(sock->sd, 1) == -1)
    {
      return ERROR;
    }

  /* Then get the local address selected by NuttX */

  ret = ftpc_sockgetsockname(sock, &sock->laddr);
  return ret;
}
Пример #9
0
static int local_tx_open(FAR struct local_conn_s *conn, FAR const char *path,
                         bool nonblock)
{
  int oflags = nonblock ? O_WRONLY | O_NONBLOCK : O_WRONLY;

  conn->lc_outfd = open(path, oflags);
  if (conn->lc_outfd < 0)
    {
      int errcode = errno;
      DEBUGASSERT(errcode > 0);

      ndbg("ERROR: Failed on open %s for writing: %d\n",
           path, errcode);

      /* Map the errcode to something consistent with the return
       * error codes from connect():
       *
       * If errcode is ENOENT, meaning that the FIFO does exist,
       * return EFAULT meaning that the socket structure address is
       * outside the user's address space.
       */

      return errcode == ENOENT ? -EFAULT : -errcode;
    }

  return OK;
}
Пример #10
0
/****************************************************************************
 * Name: dhcp_client_stop
 ****************************************************************************/
void dhcp_client_stop(const char *intf)
{
	struct in_addr in = { .s_addr = INADDR_NONE };
	DHCPC_SET_IP4ADDR(intf, in, in, in);
	ndbg("[DHCPC] dhcpc_stop -release IP address (app)\n");
	return;
}
Пример #11
0
/****************************************************************************
 * Name: local_release_fifo
 *
 * Description:
 *   Release a reference from one of the FIFOs used in a connection.
 *
 ****************************************************************************/

#ifdef CONFIG_NET_LOCAL_STREAM /* Currently not used by datagram code */
static int local_release_fifo(FAR const char *path)
{
  int ret;

  /* Unlink the client-to-server FIFO if it exists. */

  if (local_fifo_exists(path))
    {
      /* Un-linking the FIFO removes the FIFO from the namespace.  It will
       * also mark the FIFO device "unlinked".  When all of the open
       * references to the FIFO device are closed, the resources consumed
       * by the device instance will also be freed.
       */

      ret = unlink(path);
      if (ret < 0)
        {
          int errcode = errno;
          DEBUGASSERT(errcode > 0);

          ndbg("ERROR: Failed to unlink FIFO %s: %d\n", path, errcode);
          return -errcode;
        }
    }

  /* The FIFO does not exist or we successfully unlinked it. */

  return OK;
}
Пример #12
0
static int local_create_fifo(FAR const char *path)
{
  int ret;

  /* Create the client-to-server FIFO if it does not already exist. */

  if (!local_fifo_exists(path))
    {
      ret = mkfifo(path, 0644);
      if (ret < 0)
        {
          int errcode = errno;
          DEBUGASSERT(errcode > 0);

          ndbg("ERROR: Failed to create FIFO %s: %d\n", path, errcode);
          return -errcode;
        }
    }

  /* The FIFO (or some character driver) exists at PATH or we successfully
   * created the FIFO at that location.
   */

  return OK;
}
int net_addroute(uip_ipaddr_t target, uip_ipaddr_t netmask,
                 uip_ipaddr_t router)
{
  FAR struct net_route_s *route;
  uip_lock_t save;

  /* Allocate a route entry */

  route = net_allocroute();
  if (!route)
    {
      ndbg("ERROR:  Failed to allocate a route\n");
      return -ENOMEM;
    }

  /* Format the new route table entry */

  uip_ipaddr_copy(route->target, target);
  uip_ipaddr_copy(route->netmask, netmask);
  uip_ipaddr_copy(route->router, router);

  /* Get exclusive address to the networking data structures */

  save = uip_lock();

  /* Then add the new entry to the table */

  sq_addlast((FAR sq_entry_t *)route, (FAR sq_queue_t *)&g_routes);
  uip_unlock(save);
  return OK;
}
Пример #14
0
static inline void recvfrom_newtcpdata(FAR struct uip_driver_s *dev,
                                       FAR struct recvfrom_s *pstate)
{
  /* Take as much data from the packet as we can */

  size_t recvlen = recvfrom_newdata(dev, pstate);

  /* If there is more data left in the packet that we could not buffer, than
   * add it to the read-ahead buffers.
   */

 if (recvlen < dev->d_len)
   {
#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
      FAR struct uip_conn *conn   = (FAR struct uip_conn *)pstate->rf_sock->s_conn;
      FAR uint8_t         *buffer = (FAR uint8_t *)dev->d_appdata + recvlen;
      uint16_t             buflen = dev->d_len - recvlen;
      uint16_t             nsaved;

      nsaved = uip_datahandler(conn, buffer, buflen);

      /* There are complicated buffering issues that are not addressed fully
       * here.  For example, what if up_datahandler() cannot buffer the
       * remainder of the packet?  In that case, the data will be dropped but
       * still ACKed.  Therefore it would not be resent.
       * 
       * This is probably not an issue here because we only get here if the
       * read-ahead buffers are empty and there would have to be something
       * serioulsy wrong with the configuration not to be able to buffer a
       * partial packet in this context.
       */

#ifdef CONFIG_DEBUG_NET
      if (nsaved < buflen)
        {
          ndbg("ERROR: packet data not saved (%d bytes)\n", buflen - nsaved);
        }
#endif
#else
      ndbg("ERROR: packet data lost (%d bytes)\n", dev->d_len - recvlen);
#endif
   }

  /* Indicate no data in the buffer */

  dev->d_len = 0;
}
Пример #15
0
int net_clone(FAR struct socket *psock1, FAR struct socket *psock2)
{
  net_lock_t flags;
  int ret = OK;

  /* Parts of this operation need to be atomic */

  flags = net_lock();

  /* Duplicate the socket state */

  psock2->s_type     = psock1->s_type;      /* Protocol type: Only SOCK_STREAM or SOCK_DGRAM */
  psock2->s_flags    = psock1->s_flags;     /* See _SF_* definitions */
#ifdef CONFIG_NET_SOCKOPTS
  psock2->s_options  = psock1->s_options;   /* Selected socket options */
  psock2->s_rcvtimeo = psock1->s_rcvtimeo;  /* Receive timeout value (in deciseconds) */
  psock2->s_sndtimeo = psock1->s_sndtimeo;  /* Send timeout value (in deciseconds) */
#ifdef CONFIG_NET_SOLINGER
  psock2->s_linger   = psock1->s_linger;    /* Linger timeout value (in deciseconds) */
#endif
#endif
  psock2->s_conn     = psock1->s_conn;      /* UDP or TCP connection structure */
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
  psock2->s_sndcb    = NULL;                /* Force allocation of new callback
                                             * instance for TCP send */
#endif

  /* Increment the reference count on the connection */

  DEBUGASSERT(psock2->s_conn);
  psock2->s_crefs    = 1;                   /* One reference on the new socket itself */

#ifdef CONFIG_NET_TCP
  if (psock2->s_type == SOCK_STREAM)
    {
      FAR struct tcp_conn_s *conn = psock2->s_conn;
      DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
      conn->crefs++;
    }
  else
#endif
#ifdef CONFIG_NET_UDP
  if (psock2->s_type == SOCK_DGRAM)
    {
      FAR struct udp_conn_s *conn = psock2->s_conn;
      DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
      conn->crefs++;
    }
  else
#endif
    {
      ndbg("Unsupported type: %d\n", psock2->s_type);
      ret = -EBADF;
    }

  net_unlock(flags);
  return ret;
}
Пример #16
0
void *dhcpc_open(const void *macaddr, int maclen)
{
  struct dhcpc_state_s *pdhcpc;
  struct sockaddr_in addr;
  struct timeval tv;

  ndbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
       ((uint8_t*)macaddr)[0], ((uint8_t*)macaddr)[1], ((uint8_t*)macaddr)[2],
       ((uint8_t*)macaddr)[3], ((uint8_t*)macaddr)[4], ((uint8_t*)macaddr)[5]);

  /* Allocate an internal DHCP structure */

  pdhcpc = (struct dhcpc_state_s *)malloc(sizeof(struct dhcpc_state_s));
  if (pdhcpc)
    {
      /* Initialize the allocated structure */

      memset(pdhcpc, 0, sizeof(struct dhcpc_state_s));
      pdhcpc->ds_macaddr = macaddr;
      pdhcpc->ds_maclen  = maclen;

      /* Create a UDP socket */

      pdhcpc->sockfd    = socket(PF_INET, SOCK_DGRAM, 0);
      if (pdhcpc->sockfd < 0)
        {
          free(pdhcpc);
          return NULL;
        }

      /* bind the socket */

      addr.sin_family      = AF_INET;
      addr.sin_port        = HTONS(DHCPC_CLIENT_PORT);
      addr.sin_addr.s_addr = INADDR_ANY;

      if (bind(pdhcpc->sockfd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) < 0)
        {
          close(pdhcpc->sockfd);
          free(pdhcpc);
          return NULL;
        }

      /* Configure for read timeouts */

      tv.tv_sec  = 10;
      tv.tv_usec = 0;
      if (setsockopt(pdhcpc->sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)) < 0)
        {
          close(pdhcpc->sockfd);
          free(pdhcpc);
          return NULL;
        }
    }

  return (void*)pdhcpc;
}
Пример #17
0
static inline int dhcpd_socket(void)
{
  int sockfd;
#if defined(HAVE_SO_REUSEADDR) || defined(HAVE_SO_BROADCAST)
  int optval;
  int ret;
#endif

  /* Create a socket to listen for requests from DHCP clients */

  sockfd = socket(PF_INET, SOCK_DGRAM, 0);
  if (sockfd < 0)
    {
      ndbg("socket failed: %d\n", errno);
      return ERROR;
    }

  /* Configure the socket */

#ifdef HAVE_SO_REUSEADDR
  optval = 1;
  ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, sizeof(int));
  if (ret < 0)
    {
      ndbg("setsockopt SO_REUSEADDR failed: %d\n", errno);
      close(sockfd);
      return ERROR;
    }
#endif

#ifdef HAVE_SO_BROADCAST
  optval = 1;
  ret = setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (void*)&optval, sizeof(int));
  if (ret < 0)
    {
      ndbg("setsockopt SO_BROADCAST failed: %d\n", errno);
      close(sockfd);
      return ERROR;
    }
#endif

  return sockfd;

}
Пример #18
0
int usrsock_setsockopt(FAR struct usrsock_conn_s *conn, int level, int option,
                       FAR const void *value, FAR socklen_t value_len)
{
  struct usrsock_reqstate_s state = {};
  net_lock_t save;
  ssize_t ret;

  DEBUGASSERT(conn);

  save = net_lock();

  if (conn->state == USRSOCK_CONN_STATE_UNINITIALIZED ||
      conn->state == USRSOCK_CONN_STATE_ABORTED)
    {
      /* Invalid state or closed by daemon. */

      nlldbg("usockid=%d; connect() with uninitialized usrsock.\n",
             conn->usockid);

      ret = (conn->state == USRSOCK_CONN_STATE_ABORTED) ? -EPIPE : -ECONNRESET;
      goto errout_unlock;
    }

  /* Set up event callback for usrsock. */

  ret = usrsock_setup_request_callback(conn, &state, setsockopt_event,
                                       USRSOCK_EVENT_ABORT |
                                       USRSOCK_EVENT_REQ_COMPLETE);
  if (ret < 0)
    {
      ndbg("usrsock_setup_request_callback failed: %d\n", ret);
      goto errout_unlock;
    }

  /* Request user-space daemon to close socket. */

  ret = do_setsockopt_request(conn, level, option, value, value_len);
  if (ret >= 0)
    {
      /* Wait for completion of request. */

      while (net_lockedwait(&state.recvsem) != OK)
        {
          DEBUGASSERT(*get_errno_ptr() == EINTR);
        }

      ret = state.result;
    }

  usrsock_teardown_request_callback(&state);

errout_unlock:
  net_unlock(save);
  return ret;
}
Пример #19
0
static uint16_t setsockopt_event(FAR struct net_driver_s *dev, FAR void *pvconn,
                                 FAR void *pvpriv, uint16_t flags)
{
  FAR struct usrsock_reqstate_s *pstate = pvpriv;
  FAR struct usrsock_conn_s *conn = pvconn;

  if (flags & USRSOCK_EVENT_ABORT)
    {
      ndbg("socket aborted.\n");

      pstate->result = -ECONNABORTED;

      /* Stop further callbacks */

      pstate->cb->flags   = 0;
      pstate->cb->priv    = NULL;
      pstate->cb->event   = NULL;

      /* Wake up the waiting thread */

      sem_post(&pstate->recvsem);
    }
  else if (flags & USRSOCK_EVENT_REQ_COMPLETE)
    {
      ndbg("request completed.\n");

      pstate->result = conn->resp.result;

      /* Stop further callbacks */

      pstate->cb->flags   = 0;
      pstate->cb->priv    = NULL;
      pstate->cb->event   = NULL;

      /* Wake up the waiting thread */

      sem_post(&pstate->recvsem);
    }

  return flags;
}
Пример #20
0
int net_clone(FAR struct socket *psock1, FAR struct socket *psock2)
{
  uip_lock_t flags;
  int ret = OK;

  /* Parts of this operation need to be atomic */

  flags = uip_lock();

  /* Duplicate the socket state */

  psock2->s_type     = psock1->s_type;      /* Protocol type: Only SOCK_STREAM or SOCK_DGRAM */
  psock2->s_flags    = psock1->s_flags;     /* See _SF_* definitions */
#ifdef CONFIG_NET_SOCKOPTS
  psock2->s_options  = psock1->s_options;   /* Selected socket options */
#endif
#ifndef CONFIG_DISABLE_CLOCK
  psock2->s_rcvtimeo = psock1->s_rcvtimeo;  /* Receive timeout value (in deciseconds) */
  psock2->s_sndtimeo = psock1->s_sndtimeo;  /* Send timeout value (in deciseconds) */
#endif
  psock2->s_conn     = psock1->s_conn;      /* UDP or TCP connection structure */

  /* Increment the reference count on the connection */

  DEBUGASSERT(psock2->s_conn);
  psock2->s_crefs    = 1;                   /* One reference on the new socket itself */

#ifdef CONFIG_NET_TCP
  if (psock2->s_type == SOCK_STREAM)
    {
      struct uip_conn *conn = psock2->s_conn;
      DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
      conn->crefs++;
    }
  else
#endif
#ifdef CONFIG_NET_UDP
  if (psock2->s_type == SOCK_DGRAM)
    {
      struct uip_udp_conn *conn = psock2->s_conn;
      DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
      conn->crefs++;
    }
  else
#endif
    {
      ndbg("Unsupported type: %d\n", psock2->s_type);
      ret = -EBADF;
    }

  uip_unlock(flags);
  return ret;
}
Пример #21
0
int ftpc_sockgetsockname(FAR struct ftpc_socket_s *sock, FAR struct sockaddr_in *addr)
{
	socklen_t len = sizeof(struct sockaddr_in);
	int ret;

	ret = getsockname(sock->sd, (FAR struct sockaddr *)addr, &len);
	if (ret < 0) {
		ndbg("getsockname failed: %d\n", errno);
		return ERROR;
	}
	return OK;
}
Пример #22
0
static int lo_txpoll(FAR struct net_driver_s *dev)
{
  FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)dev->d_private;

  /* Loop while there is data "sent", i.e., while d_len > 0.  That should be
   * the case upon entry here and while the processing of the IPv4/6 packet
   * generates a new packet to be sent.  Sending, of course, just means
   * relaying back through the network for this driver.
   */

  while (priv->lo_dev.d_len > 0)
    {
       NETDEV_TXPACKETS(&priv->lo_dev);
       NETDEV_RXPACKETS(&priv->lo_dev);

#ifdef CONFIG_NET_PKT
      /* When packet sockets are enabled, feed the frame into the packet tap */

       pkt_input(&priv->lo_dev);
#endif

      /* We only accept IP packets of the configured type and ARP packets */

#ifdef CONFIG_NET_IPv4
      if ((IPv4BUF->vhl & IP_VERSION_MASK) == IPv4_VERSION)
        {
          nllvdbg("IPv4 frame\n");
          NETDEV_RXIPV4(&priv->lo_dev);
          ipv4_input(&priv->lo_dev);
        }
      else
#endif
#ifdef CONFIG_NET_IPv6
      if ((IPv6BUF->vtc & IP_VERSION_MASK) == IPv6_VERSION)
        {
          nllvdbg("Iv6 frame\n");
          NETDEV_RXIPV6(&priv->lo_dev);
          ipv6_input(&priv->lo_dev);
        }
      else
#endif
        {
          ndbg("WARNING: Unrecognized packet type dropped: %02x\n", IPv4BUF->vhl);
          NETDEV_RXDROPPED(&priv->lo_dev);
          priv->lo_dev.d_len = 0;
        }

      priv->lo_txdone = true;
      NETDEV_TXDONE(&priv->lo_dev);
    }

  return 0;
}
static void clear_connection(struct connect_s *conn, struct timeval *tv)
{
  ClientData client_data;

  if (conn->wakeup_timer != NULL)
    {
      tmr_cancel(conn->wakeup_timer);
      conn->wakeup_timer = 0;
    }

  /* This is our version of Apache's lingering_close() routine, which is
   * their version of the often-broken SO_LINGER socket option.  For why
   * this is necessary, see http://www.apache.org/docs/misc/fin_wait_2.html
   * What we do is delay the actual closing for a few seconds, while reading
   * any bytes that come over the connection.  However, we don't want to do
   * this unless it's necessary, because it ties up a connection slot and
   * file descriptor which means our maximum connection-handling rateis
   * lower.  So, elsewhere we set a flag when we detect the few
   * circumstances that make a lingering close necessary.  If the flag isn't
   * set we do the real close now.
   */

  if (conn->conn_state == CNST_LINGERING)
    {
      /* If we were already lingering, shut down for real */

      tmr_cancel(conn->linger_timer);
      conn->linger_timer      = NULL;
      conn->hc->should_linger = false;
    }
  else if (conn->hc->should_linger)
    {
      fdwatch_del_fd(fw, conn->hc->conn_fd);
      conn->conn_state = CNST_LINGERING;
      fdwatch_add_fd(fw, conn->hc->conn_fd, conn);
      client_data.p = conn;

      conn->linger_timer = tmr_create(tv, linger_clear_connection, client_data,
                                      CONFIG_THTTPD_LINGER_MSEC, 0);
      if (conn->linger_timer != NULL)
        {
          return;
        }
      ndbg("tmr_create(linger_clear_connection) failed\n");
    }

  /* Either we are done lingering, we shouldn't linger, or we failed to setup the linger */

  really_clear_connection(conn);
}
Пример #24
0
int ftpc_sockconnect(struct ftpc_socket_s *sock, struct sockaddr_in *addr)
{
	int ret;

	/* Connect to the server */

	ret = connect(sock->sd, (struct sockaddr *)addr, sizeof(struct sockaddr));
	if (ret < 0) {
		ndbg("connect() failed: %d\n", errno);
		return ERROR;
	}

	/* Get the local address of the socket */

	ret = ftpc_sockgetsockname(sock, &sock->laddr);
	if (ret < 0) {
		ndbg("ftpc_sockgetsockname() failed: %d\n", errno);
		return ERROR;
	}

	sock->connected = true;
	return OK;
}
Пример #25
0
int cc3000_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
#ifdef CONFIG_CC3000_MT
{
  short non_blocking = CC3000_SOCK_ON;
  if (setsockopt(sockfd, CC3000_SOL_SOCKET, CC3000_SOCKOPT_ACCEPT_NONBLOCK,
                 &non_blocking, sizeof(non_blocking)) < 0)
   {
     ndbg("setsockopt failure %d\n", errno);
     return -errno;
   }

  memset(addr, 0, *addrlen);
  return cc3000_accept_socket(sockfd, addr, addrlen);
}
Пример #26
0
int iob_tryadd_queue(FAR struct iob_s *iob, FAR struct iob_queue_s *iobq)
{
  FAR struct iob_qentry_s *qentry;

  /* Allocate a container to hold the I/O buffer chain */

  qentry = iob_tryalloc_qentry();
  if (!qentry)
    {
      ndbg("ERROR: Failed to allocate a container\n");
      return -ENOMEM;
    }

  return iob_add_queue_internal(iob, iobq, qentry);
}
Пример #27
0
/****************************************************************************
 * Name: dhcp_client_start
 ****************************************************************************/
int dhcp_client_start(const char *intf)
{
	struct dhcpc_state state;
	int ret;
	void *dhcp_hnd = NULL;
	ndbg("[DHCPC] External DHCPC application started\n");
	dhcp_hnd = dhcpc_open(intf);
	if (dhcp_hnd) {
		ret = dhcpc_request(dhcp_hnd, &state);
		if (ret != OK) {
			ndbg("[DHCPC] get IP address fail\n");
			dhcpc_close(dhcp_hnd);
			return -1;
		}
		DHCPC_SET_IP4ADDR(intf, state.ipaddr, state.netmask, state.default_router);
		ndbg("[DHCPC] IP address : %s ----\n", inet_ntoa(state.ipaddr));
		dhcpc_close(dhcp_hnd);
	} else {
		ndbg("[DHCPC] Invalid dhcp handle\n");
		return -1;
	}

	return OK;
}
Пример #28
0
static void slip_txtask(int argc, char *argv[])
{
  FAR struct slip_driver_s *priv;
  unsigned int index = *(argv[1]) - '0';
  uip_lock_t flags;

  ndbg("index: %d\n", index);
  DEBUGASSERT(index < CONFIG_SLIP_NINTERFACES);

  /* Get our private data structure instance and wake up the waiting
   * initialization logic.
   */

  priv = &g_slip[index];
  slip_semgive(priv);

  /* Loop forever */

  for (;;)
    {
      /* Wait for the timeout to expire (or until we are signaled by by  */

      usleep(SLIP_WDDELAY);

      /* Is the interface up? */

      if (priv->bifup)
        {
          /* Get exclusive access to uIP (if it it is already being used
           * slip_rxtask, then we have to wait).
           */

          slip_semtake(priv);

          /* Poll uIP for new XMIT data. BUG:  We really need to calculate
           * the number of hsecs!  When we are awakened by slip_txavail, the
           * number will be smaller; when we have to wait for the semaphore
           * (above), it may be larger.
           */

          flags = uip_lock();
          priv->dev.d_buf = priv->txbuf;
          (void)uip_timer(&priv->dev, slip_uiptxpoll, SLIP_POLLHSEC);
          uip_unlock(flags);
          slip_semgive(priv);
        }
    }
}
Пример #29
0
static int local_set_policy(int fd, unsigned long policy)
{
  int ret;

  /* Set the buffer policy */

  ret = ioctl(fd, PIPEIOC_POLICY, policy);
  if (ret < 0)
    {
      int errcode = get_errno();
      DEBUGASSERT(errcode > 0);

      ndbg("ERROR: Failed to set FIFO buffer policty: %d\n", errcode);
      return -errcode;
    }

  return OK;
}
Пример #30
0
static inline ssize_t tftp_read(int fd, uint8_t *buf, size_t buflen)
{
  ssize_t nbytesread;
  ssize_t totalread = 0;

  while (totalread < buflen)
    {
      /* Read the data... repeating the read in the event that it was
       * interrupted by a signal.
       */

      do
        {
          nbytesread = read(fd, buf, buflen - totalread);
        }
      while (nbytesread < 0 && errno == EINTR);

      /* Check for non-EINTR errors */

      if (nbytesread < 0)
        {
          ndbg("read failed: %d\n", errno);
          return ERROR;
        }

      /* Check for end of file */

      else if (nbytesread == 0)
        {
          break;
        }

      /* Handle partial reads.  Partial reads can happen normally
       * when the source is some device driver that returns data
       * in bits and pieces as received (such as a pipe)
       */

      totalread += nbytesread;
      buf       += nbytesread;
    }
  return totalread;
}