예제 #1
0
파일: tcp_conn.c 프로젝트: a1ien/nuttx
static inline FAR struct tcp_conn_s *
  tcp_ipv4_active(FAR struct net_driver_s *dev, FAR struct tcp_hdr_s *tcp)
{
  FAR struct ipv4_hdr_s *ip = IPv4BUF;
  FAR struct tcp_conn_s *conn;
  in_addr_t srcipaddr;
#ifdef CONFIG_NETDEV_MULTINIC
  in_addr_t destipaddr;
#endif

  conn       = (FAR struct tcp_conn_s *)g_active_tcp_connections.head;
  srcipaddr  = net_ip4addr_conv32(ip->srcipaddr);
#ifdef CONFIG_NETDEV_MULTINIC
  destipaddr = net_ip4addr_conv32(ip->destipaddr);
#endif

  while (conn)
    {
      /* Find an open connection matching the TCP input. The following
       * checks are performed:
       *
       * - The local port number is checked against the destination port
       *   number in the received packet.
       * - The remote port number is checked if the connection is bound
       *   to a remote port.
       * - If multiple network interfaces are supported, then the local
       *   IP address is available and we will insist that the
       *   destination IP matches the bound address. If a socket is
       *   bound to INADDRY_ANY, then it should receive all packets
       *   directed to the port.
       * - Finally, if the connection is bound to a remote IP address,
       *   the source IP address of the packet is checked.
       *
       * If all of the above are true then the newly received TCP packet
       * is destined for this TCP connection.
       */

      if (conn->tcpstateflags != TCP_CLOSED &&
          tcp->destport == conn->lport &&
          tcp->srcport  == conn->rport &&
#ifdef CONFIG_NETDEV_MULTINIC
          (net_ipv4addr_cmp(conn->u.ipv4.laddr, INADDR_ANY) ||
           net_ipv4addr_cmp(destipaddr, conn->u.ipv4.laddr)) &&
#endif
          net_ipv4addr_cmp(srcipaddr, conn->u.ipv4.raddr))
        {
          /* Matching connection found.. break out of the loop and return a
           * reference to it.
           */

          break;
        }

      /* Look at the next active connection */

      conn = (FAR struct tcp_conn_s *)conn->node.flink;
    }

  return conn;
}
예제 #2
0
파일: tcp_conn.c 프로젝트: KimMui/i2sTest
FAR struct tcp_conn_s *tcp_active(struct tcp_iphdr_s *buf)
{
  FAR struct tcp_conn_s *conn = (struct tcp_conn_s *)g_active_tcp_connections.head;
  in_addr_t srcipaddr = net_ip4addr_conv32(buf->srcipaddr);

  while (conn)
    {
      /* Find an open connection matching the tcp input */

      if (conn->tcpstateflags != TCP_CLOSED &&
          buf->destport == conn->lport && buf->srcport == conn->rport &&
          net_ipaddr_cmp(srcipaddr, conn->ripaddr))
        {
          /* Matching connection found.. break out of the loop and return a
           * reference to it.
           */

          break;
        }

      /* Look at the next active connection */

      conn = (FAR struct tcp_conn_s *)conn->node.flink;
    }

  return conn;
}
예제 #3
0
파일: arp_table.c 프로젝트: a1ien/nuttx
void arp_hdr_update(FAR uint16_t *pipaddr, FAR uint8_t *ethaddr)
{
  in_addr_t ipaddr = net_ip4addr_conv32(pipaddr);

  /* Update the ARP table */

  (void)arp_update(ipaddr, ethaddr);
}
예제 #4
0
파일: tcp_conn.c 프로젝트: KimMui/i2sTest
FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct tcp_iphdr_s *buf)
{
  FAR struct tcp_conn_s *conn = tcp_alloc();
  if (conn)
    {
      /* Fill in the necessary fields for the new connection. */

      conn->rto           = TCP_RTO;
      conn->timer         = TCP_RTO;
      conn->sa            = 0;
      conn->sv            = 4;
      conn->nrtx          = 0;
      conn->lport         = buf->destport;
      conn->rport         = buf->srcport;
      conn->mss           = TCP_INITIAL_MSS;
      net_ipaddr_copy(conn->ripaddr, net_ip4addr_conv32(buf->srcipaddr));
      conn->tcpstateflags = TCP_SYN_RCVD;

      tcp_initsequence(conn->sndseq);
      conn->unacked       = 1;
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
      conn->expired       = 0;
      conn->isn           = 0;
      conn->sent          = 0;
#endif

      /* rcvseq should be the seqno from the incoming packet + 1. */

      memcpy(conn->rcvseq, buf->seqno, 4);

#ifdef CONFIG_NET_TCP_READAHEAD
      /* Initialize the list of TCP read-ahead buffers */

      IOB_QINIT(&conn->readahead);
#endif

#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
      /* Initialize the write buffer lists */

      sq_init(&conn->write_q);
      sq_init(&conn->unacked_q);
#endif

      /* And, finally, put the connection structure into the active list.
       * Interrupts should already be disabled in this context.
       */

      dq_addlast(&conn->node, &g_active_tcp_connections);
    }

  return conn;
}
예제 #5
0
void arp_ipin(FAR struct net_driver_s *dev)
{
  in_addr_t srcipaddr;

  /* Only insert/update an entry if the source IP address of the incoming IP
   * packet comes from a host on the local network.
   */

  srcipaddr = net_ip4addr_conv32(IPBUF->eh_srcipaddr);
  if (net_ipv4addr_maskcmp(srcipaddr, dev->d_ipaddr, dev->d_netmask))
    {
      arp_hdr_update(IPBUF->eh_srcipaddr, ETHBUF->src);
    }
}
예제 #6
0
파일: udp_callback.c 프로젝트: dagar/NuttX
static uint16_t udp_datahandler(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn,
                                FAR uint8_t *buffer, uint16_t buflen)
{
  FAR struct iob_s *iob;
  int ret;
#ifdef CONFIG_NET_IPv6
  FAR struct sockaddr_in6 src_addr6;
#endif
#ifdef CONFIG_NET_IPv4
  FAR struct sockaddr_in src_addr4;
#endif
  FAR void  *src_addr;
  uint8_t src_addr_size;

  /* Allocate on I/O buffer to start the chain (throttling as necessary).
   * We will not wait for an I/O buffer to become available in this context.
   */

  iob = iob_tryalloc(true);
  if (iob == NULL)
    {
      nerr("ERROR: Failed to create new I/O buffer chain\n");
      return 0;
    }

#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
  if (IFF_IS_IPv6(dev->d_flags))
#endif
    {
      FAR struct udp_hdr_s *udp   = UDPIPv6BUF;
      FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;

      src_addr6.sin6_family = AF_INET6;
      src_addr6.sin6_port   = udp->srcport;

      net_ipv6addr_copy(src_addr6.sin6_addr.s6_addr, ipv6->srcipaddr);

      src_addr_size = sizeof(src_addr6);
      src_addr = &src_addr6;
    }
#endif /* CONFIG_NET_IPv6 */

#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
  else
#endif
    {
#ifdef CONFIG_NET_IPv6
      /* Hybrid dual-stack IPv6/IPv4 implementations recognize a special
       * class of addresses, the IPv4-mapped IPv6 addresses.
       */

      if (conn->domain == PF_INET6)
        {
          FAR struct udp_hdr_s *udp   = UDPIPv6BUF;
          FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
          in_addr_t ipv4addr;

          /* Encode the IPv4 address as an IPv-mapped IPv6 address */

          src_addr6.sin6_family = AF_INET6;
          src_addr6.sin6_port = udp->srcport;

          ipv4addr = net_ip4addr_conv32(ipv6->srcipaddr);
          ip6_map_ipv4addr(ipv4addr, src_addr6.sin6_addr.s6_addr16);

          src_addr_size = sizeof(src_addr6);
          src_addr = &src_addr6;
        }
      else
#endif
        {
          FAR struct udp_hdr_s *udp   = UDPIPv4BUF;
          FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;

          src_addr4.sin_family = AF_INET;
          src_addr4.sin_port   = udp->srcport;

          net_ipv4addr_copy(src_addr4.sin_addr.s_addr,
                            net_ip4addr_conv32(ipv4->srcipaddr));

          src_addr_size = sizeof(src_addr4);
          src_addr = &src_addr4;
        }
    }
#endif /* CONFIG_NET_IPv4 */

  /* Copy the src address info into the I/O buffer chain.  We will not wait
   * for an I/O buffer to become available in this context.  It there is
   * any failure to allocated, the entire I/O buffer chain will be discarded.
   */

  ret = iob_trycopyin(iob, (FAR const uint8_t *)&src_addr_size,
                      sizeof(uint8_t), 0, true);
  if (ret < 0)
    {
      /* On a failure, iob_trycopyin return a negated error value but does
       * not free any I/O buffers.
       */

      nerr("ERROR: Failed to add data to the I/O buffer chain: %d\n", ret);
      (void)iob_free_chain(iob);
      return 0;
    }

  ret = iob_trycopyin(iob, (FAR const uint8_t *)src_addr, src_addr_size,
                      sizeof(uint8_t), true);
  if (ret < 0)
    {
      /* On a failure, iob_trycopyin return a negated error value but does
       * not free any I/O buffers.
       */

      nerr("ERROR: Failed to add data to the I/O buffer chain: %d\n", ret);
      (void)iob_free_chain(iob);
      return 0;
    }

  if (buflen > 0)
    {
      /* Copy the new appdata into the I/O buffer chain */

      ret = iob_trycopyin(iob, buffer, buflen,
                          src_addr_size + sizeof(uint8_t), true);
      if (ret < 0)
        {
          /* On a failure, iob_trycopyin return a negated error value but
           * does not free any I/O buffers.
           */

          nerr("ERROR: Failed to add data to the I/O buffer chain: %d\n",
               ret);
          (void)iob_free_chain(iob);
          return 0;
        }
    }

  /* Add the new I/O buffer chain to the tail of the read-ahead queue */

  ret = iob_tryadd_queue(iob, &conn->readahead);
  if (ret < 0)
    {
      nerr("ERROR: Failed to queue the I/O buffer chain: %d\n", ret);
      (void)iob_free_chain(iob);
      return 0;
    }

#ifdef CONFIG_UDP_READAHEAD_NOTIFIER
  /* Provided notification(s) that additional UDP read-ahead data is
   * available.
   */

  udp_notifier_signal(conn);
#endif

  ninfo("Buffered %d bytes\n", buflen);
  return buflen;
}
예제 #7
0
파일: arp_out.c 프로젝트: dagar/NuttX
void arp_out(FAR struct net_driver_s *dev)
{
  struct ether_addr ethaddr;
  FAR struct eth_hdr_s *peth = ETHBUF;
  FAR struct arp_iphdr_s *pip = IPBUF;
  in_addr_t ipaddr;
  in_addr_t destipaddr;
  int ret;

#if defined(CONFIG_NET_PKT) || defined(CONFIG_NET_ARP_SEND)
  /* Skip sending ARP requests when the frame to be transmitted was
   * written into a packet socket.
   */

  if (IFF_IS_NOARP(dev->d_flags))
    {
      /* Clear the indication and let the packet continue on its way. */

      IFF_CLR_NOARP(dev->d_flags);
      return;
    }
#endif

  /* Find the destination IP address in the ARP table and construct
   * the Ethernet header. If the destination IP address isn't on the
   * local network, we use the default router's IP address instead.
   *
   * If not ARP table entry is found, we overwrite the original IP
   * packet with an ARP request for the IP address.
   */

  /* First check if destination is a local broadcast. */

  if (net_ipv4addr_hdrcmp(pip->eh_destipaddr, g_broadcast_ipaddr))
    {
      memcpy(peth->dest, g_broadcast_ethaddr.ether_addr_octet, ETHER_ADDR_LEN);
      goto finish_header;
    }

#ifdef CONFIG_NET_IGMP
  /* Check if the destination address is a multicast address
   *
   * - IPv4: multicast addresses lie in the class D group -- The address range
   *   224.0.0.0 to 239.255.255.255 (224.0.0.0/4)
   *
   * - IPv6 multicast addresses are have the high-order octet of the
   *   addresses=0xff (ff00::/8.)
   */

  if (NTOHS(pip->eh_destipaddr[0]) >= 0xe000 &&
      NTOHS(pip->eh_destipaddr[0]) <= 0xefff)
    {
      /* Build the well-known IPv4 IGMP Ethernet address.  The first
       * three bytes are fixed; the final three variable come from the
       * last three bytes of the IPv4 address (network order).
       *
       * Address range : 01:00:5e:00:00:00 to 01:00:5e:7f:ff:ff
       */

      FAR const uint8_t *ip = (FAR uint8_t *)pip->eh_destipaddr;

      peth->dest[0] = g_multicast_ethaddr[0];
      peth->dest[1] = g_multicast_ethaddr[1];
      peth->dest[2] = g_multicast_ethaddr[2];
      peth->dest[3] = ip[1] & 0x7f;
      peth->dest[4] = ip[2];
      peth->dest[5] = ip[3];

      goto finish_header;
    }
#endif

  /* Check if the destination address is on the local network. */

  destipaddr = net_ip4addr_conv32(pip->eh_destipaddr);
  if (!net_ipv4addr_maskcmp(destipaddr, dev->d_ipaddr, dev->d_netmask))
    {
      /* Destination address is not on the local network */

#ifdef CONFIG_NET_ROUTE
      /* We have a routing table.. find the correct router to use in
       * this case (or, as a fall-back, use the device's default router
       * address).  We will use the router IP address instead of the
       * destination address when determining the MAC address.
       */

      netdev_ipv4_router(dev, destipaddr, &ipaddr);
#else
      /* Use the device's default router IP address instead of the
       * destination address when determining the MAC address.
       */

      net_ipv4addr_copy(ipaddr, dev->d_draddr);
#endif
    }

  /* The destination address is on the local network.  Check if it is
   * the sub-net broadcast address.
   */

  else if (net_ipv4addr_broadcast(destipaddr, dev->d_netmask))
    {
      /* Yes.. then we won't need to know the destination MAC address */

      memcpy(peth->dest, g_broadcast_ethaddr.ether_addr_octet, ETHER_ADDR_LEN);
      goto finish_header;
    }
  else
    {
      /* Else, we use the destination IP address. */

      net_ipv4addr_copy(ipaddr, destipaddr);
    }

  /* Check if we already have this destination address in the ARP table */

  ret = arp_find(ipaddr, &ethaddr);
  if (ret < 0)
    {
      ninfo("ARP request for IP %08lx\n", (unsigned long)ipaddr);

      /* The destination address was not in our ARP table, so we overwrite
       * the IP packet with an ARP request.
       */

      arp_format(dev, ipaddr);
      arp_dump(ARPBUF);
      return;
    }

  /* Build an Ethernet header. */

  memcpy(peth->dest, ethaddr.ether_addr_octet, ETHER_ADDR_LEN);

  /* Finish populating the Ethernet header */

finish_header:
  memcpy(peth->src, dev->d_mac.ether.ether_addr_octet, ETHER_ADDR_LEN);
  peth->type  = HTONS(ETHTYPE_IP);
  dev->d_len += ETH_HDRLEN;
}
예제 #8
0
int ipv4_input(FAR struct net_driver_s *dev)
{
  FAR struct ipv4_hdr_s *pbuf = BUF;
  uint16_t iplen;

  /* This is where the input processing starts. */

#ifdef CONFIG_NET_STATISTICS
  g_netstats.ipv4.recv++;
#endif

  /* Start of IP input header processing code. */
  /* Check validity of the IP header. */

  if (pbuf->vhl != 0x45)
    {
      /* IP version and header length. */

#ifdef CONFIG_NET_STATISTICS
      g_netstats.ipv4.drop++;
      g_netstats.ipv4.vhlerr++;
#endif
      nlldbg("Invalid IP version or header length: %02x\n", pbuf->vhl);
      goto drop;
    }

  /* Check the size of the packet. If the size reported to us in d_len is
   * smaller the size reported in the IP header, we assume that the packet
   * has been corrupted in transit. If the size of d_len is larger than the
   * size reported in the IP packet header, the packet has been padded and
   * we set d_len to the correct value.
   */

  iplen = (pbuf->len[0] << 8) + pbuf->len[1];
  if (iplen <= dev->d_len)
    {
      dev->d_len = iplen;
    }
  else
    {
      nlldbg("IP packet shorter than length in IP header\n");
      goto drop;
    }

  /* Check the fragment flag. */

  if ((pbuf->ipoffset[0] & 0x3f) != 0 || pbuf->ipoffset[1] != 0)
    {
#if defined(CONFIG_NET_TCP_REASSEMBLY)
      dev->d_len = devif_reassembly();
      if (dev->d_len == 0)
        {
          goto drop;
        }
#else /* CONFIG_NET_TCP_REASSEMBLY */
#ifdef CONFIG_NET_STATISTICS
      g_netstats.ipv4.drop++;
      g_netstats.ipv4.fragerr++;
#endif
      nlldbg("IP fragment dropped\n");
      goto drop;
#endif /* CONFIG_NET_TCP_REASSEMBLY */
    }

   /* If IP broadcast support is configured, we check for a broadcast
    * UDP packet, which may be destined to us (even if there is no IP
    * address yet assigned to the device as is the case when we are
    * negotiating over DHCP for an address).
    */

#if defined(CONFIG_NET_BROADCAST) && defined(CONFIG_NET_UDP_STACK)
  if (pbuf->proto == IP_PROTO_UDP &&
      net_ipv4addr_cmp(net_ip4addr_conv32(pbuf->destipaddr),
                       g_ipv4_alloneaddr))
    {
      return udp_ipv4_input(dev);
    }

  /* In most other cases, the device must be assigned a non-zero IP
   * address.  Another exception is when CONFIG_NET_PINGADDRCONF is
   * enabled...
   */

  else
#endif
#ifdef CONFIG_NET_ICMP
  if (net_ipv4addr_cmp(dev->d_ipaddr, g_ipv4_allzeroaddr))
    {
      /* If we are configured to use ping IP address configuration and
       * hasn't been assigned an IP address yet, we accept all ICMP
       * packets.
       */

#ifdef CONFIG_NET_PINGADDRCONF
      if (pbuf->proto == IP_PROTO_ICMP)
        {
          nlldbg("Possible ping config packet received\n");
          icmp_input(dev);
          goto drop;
        }
      else
#endif
        {
          nlldbg("No IP address assigned\n");
          goto drop;
        }
    }

  /* Check if the packet is destined for out IP address */
  else
#endif
    {
      /* Check if the packet is destined for our IP address. */

      if (!net_ipv4addr_cmp(net_ip4addr_conv32(pbuf->destipaddr), dev->d_ipaddr))
        {
#ifdef CONFIG_NET_IGMP
          in_addr_t destip = net_ip4addr_conv32(pbuf->destipaddr);
          if (igmp_grpfind(dev, &destip) == NULL)
#endif
            {
#ifdef CONFIG_NET_STATISTICS
              g_netstats.ipv4.drop++;
#endif
              goto drop;
            }
        }
    }

  if (ipv4_chksum(dev) != 0xffff)
    {
      /* Compute and check the IP header checksum. */

#ifdef CONFIG_NET_STATISTICS
      g_netstats.ipv4.drop++;
      g_netstats.ipv4.chkerr++;
#endif
      nlldbg("Bad IP checksum\n");
      goto drop;
    }

  /* Make sure that all packet processing logic knows that there is an IPv4
   * packet in the device buffer.
   */

  IFF_SET_IPv4(dev->d_flags);

  /* Now process the incoming packet according to the protocol. */

  switch (pbuf->proto)
    {
#ifdef CONFIG_NET_TCP_STACK
      case IP_PROTO_TCP:   /* TCP input */
        tcp_ipv4_input(dev);
        break;
#endif

#ifdef CONFIG_NET_UDP_STACK
      case IP_PROTO_UDP:   /* UDP input */
        udp_ipv4_input(dev);
        break;
#endif

  /* Check for ICMP input */

#ifdef CONFIG_NET_ICMP
      case IP_PROTO_ICMP:  /* ICMP input */
        icmp_input(dev);
        break;
#endif

  /* Check for IGMP input */

#ifdef CONFIG_NET_IGMP
      case IP_PROTO_IGMP:  /* IGMP input */
        igmp_input(dev);
        break;
#endif

      default:              /* Unrecognized/unsupported protocol */
#ifdef CONFIG_NET_STATISTICS
        g_netstats.ipv4.drop++;
        g_netstats.ipv4.protoerr++;
#endif

        nlldbg("Unrecognized IP protocol\n");
        goto drop;
    }

  /* Return and let the caller do any pending transmission. */

  return OK;

  /* Drop the packet.  NOTE that OK is returned meaning that the
   * packet has been processed (although processed unsuccessfully).
   */

drop:
  dev->d_len = 0;
  return OK;
}
예제 #9
0
파일: tcp_conn.c 프로젝트: a1ien/nuttx
FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
                                        FAR struct tcp_hdr_s *tcp)
{
  FAR struct tcp_conn_s *conn;
  uint8_t domain;
  int ret;

  /* Get the appropriate IP domain */

#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv4)
  bool ipv6 = IFF_IS_IPv6(dev->d_flags);
  domain = ipv6 ? PF_INET6 : PF_INET;
#elif defined(CONFIG_NET_IPv4)
  domain = PF_INET;
#else /* defined(CONFIG_NET_IPv6) */
  domain = PF_INET6;
#endif

  /* Allocate the connection structure */

  conn = tcp_alloc(domain);
  if (conn)
    {
      /* Set up the local address (laddr) and the remote address (raddr)
       * that describes the TCP connection.
       */

#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
      if (ipv6)
#endif
        {
          FAR struct ipv6_hdr_s *ip = IPv6BUF;

          /* Set the IPv6 specific MSS and the IPv6 locally bound address */

          conn->mss = TCP_IPv6_INITIAL_MSS(dev);
          net_ipv6addr_copy(conn->u.ipv6.raddr, ip->srcipaddr);
#ifdef CONFIG_NETDEV_MULTINIC
          net_ipv6addr_copy(conn->u.ipv6.laddr, ip->destipaddr);

          /* We now have to filter all outgoing transfers so that they use
           * only the MSS of this device.
           */

          DEBUGASSERT(conn->dev == NULL || conn->dev == dev);
          conn->dev = dev;
#endif

          /* Find the device that can receive packets on the network
           * associated with this local address.
           */

          ret = tcp_remote_ipv6_device(conn);
        }
#endif /* CONFIG_NET_IPv6 */

#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
      else
#endif
        {
          FAR struct ipv4_hdr_s *ip = IPv4BUF;

          /* Set the IPv6 specific MSS and the IPv4 bound remote address. */

          conn->mss = TCP_IPv4_INITIAL_MSS(dev);
          net_ipv4addr_copy(conn->u.ipv4.raddr,
                            net_ip4addr_conv32(ip->srcipaddr));

#ifdef CONFIG_NETDEV_MULTINIC
          /* Set the local address as well */

          net_ipv4addr_copy(conn->u.ipv4.laddr,
                            net_ip4addr_conv32(ip->destipaddr));

          /* We now have to filter all outgoing transfers so that they use
           * only the MSS of this device.
           */

          DEBUGASSERT(conn->dev == NULL || conn->dev == dev);
          conn->dev = dev;
#endif

          /* Find the device that can receive packets on the network
           * associated with this local address.
           */

          ret = tcp_remote_ipv4_device(conn);
        }
#endif /* CONFIG_NET_IPv4 */

      /* Verify that a network device that can provide packets to this
       * local address was found.
       */

      if (ret < 0)
        {
          /* If no device is found, then the address is not reachable.
           * That should be impossible in this context and we should
           * probably really just assert here.
           */

          nerr("ERROR: Failed to find network device: %d\n", ret);
          tcp_free(conn);
          return NULL;
        }

      /* Fill in the necessary fields for the new connection. */

      conn->rto           = TCP_RTO;
      conn->timer         = TCP_RTO;
      conn->sa            = 0;
      conn->sv            = 4;
      conn->nrtx          = 0;
      conn->lport         = tcp->destport;
      conn->rport         = tcp->srcport;
      conn->tcpstateflags = TCP_SYN_RCVD;

      tcp_initsequence(conn->sndseq);
      conn->unacked       = 1;
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
      conn->expired       = 0;
      conn->isn           = 0;
      conn->sent          = 0;
      conn->sndseq_max    = 0;
#endif

      /* rcvseq should be the seqno from the incoming packet + 1. */

      memcpy(conn->rcvseq, tcp->seqno, 4);

#ifdef CONFIG_NET_TCP_READAHEAD
      /* Initialize the list of TCP read-ahead buffers */

      IOB_QINIT(&conn->readahead);
#endif

#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
      /* Initialize the write buffer lists */

      sq_init(&conn->write_q);
      sq_init(&conn->unacked_q);
#endif

      /* And, finally, put the connection structure into the active list.
       * Interrupts should already be disabled in this context.
       */

      dq_addlast(&conn->node, &g_active_tcp_connections);
    }

  return conn;
}
예제 #10
0
파일: arp_arpin.c 프로젝트: KimMui/i2sTest
void arp_arpin(FAR struct net_driver_s *dev)
{
  FAR struct arp_hdr_s *parp = ARPBUF;
  in_addr_t ipaddr;

  if (dev->d_len < (sizeof(struct arp_hdr_s) + NET_LL_HDRLEN))
    {
      nlldbg("Too small\n");
      dev->d_len = 0;
      return;
    }

  dev->d_len = 0;

  ipaddr = net_ip4addr_conv32(parp->ah_dipaddr);
  switch(parp->ah_opcode)
    {
      case HTONS(ARP_REQUEST):
        nllvdbg("ARP request for IP %04lx\n", (long)ipaddr);

        /* ARP request. If it asked for our address, we send out a reply. */

        if (net_ipaddr_cmp(ipaddr, dev->d_ipaddr))
          {
            struct eth_hdr_s *peth = ETHBUF;

            /* First, we register the one who made the request in our ARP
             * table, since it is likely that we will do more communication
             * with this host in the future.
             */

            arp_update(parp->ah_sipaddr, parp->ah_shwaddr);

            parp->ah_opcode = HTONS(ARP_REPLY);
            memcpy(parp->ah_dhwaddr, parp->ah_shwaddr, ETHER_ADDR_LEN);
            memcpy(parp->ah_shwaddr, dev->d_mac.ether_addr_octet, ETHER_ADDR_LEN);
            memcpy(peth->src, dev->d_mac.ether_addr_octet, ETHER_ADDR_LEN);
            memcpy(peth->dest, parp->ah_dhwaddr, ETHER_ADDR_LEN);

            parp->ah_dipaddr[0] = parp->ah_sipaddr[0];
            parp->ah_dipaddr[1] = parp->ah_sipaddr[1];
            net_ipaddr_hdrcopy(parp->ah_sipaddr, &dev->d_ipaddr);
            arp_dump(parp);

            peth->type          = HTONS(ETHTYPE_ARP);
            dev->d_len          = sizeof(struct arp_hdr_s) + NET_LL_HDRLEN;
          }
        break;

      case HTONS(ARP_REPLY):
        nllvdbg("ARP reply for IP %04lx\n", (long)ipaddr);

        /* ARP reply. We insert or update the ARP table if it was meant
         * for us.
         */

        if (net_ipaddr_cmp(ipaddr, dev->d_ipaddr))
          {
            /* Yes... Insert the address mapping in the ARP table */

            arp_update(parp->ah_sipaddr, parp->ah_shwaddr);

            /* Then notify any logic waiting for the ARP result */

            arp_notify(net_ip4addr_conv32(parp->ah_sipaddr));
          }
        break;
    }
}