示例#1
0
void icmp_send(FAR struct net_driver_s *dev, FAR in_addr_t *destaddr)
{
  FAR struct icmp_iphdr_s *picmp = ICMPBUF;

  if (dev->d_sndlen > 0)
    {
      IFF_SET_IPv4(dev->d_flags);

      /* The total length to send is the size of the application data plus
       * the IP and ICMP headers (and, eventually, the Ethernet header)
       */

      dev->d_len = dev->d_sndlen + IPICMP_HDRLEN;

      /* The total size of the data (for ICMP checksum calculation) includes
       * the size of the ICMP header
       */

      dev->d_sndlen += ICMP_HDRLEN;

      /* Initialize the IP header. */

      picmp->vhl         = 0x45;
      picmp->tos         = 0;
      picmp->len[0]      = (dev->d_len >> 8);
      picmp->len[1]      = (dev->d_len & 0xff);
      ++g_ipid;
      picmp->ipid[0]     = g_ipid >> 8;
      picmp->ipid[1]     = g_ipid & 0xff;
      picmp->ipoffset[0] = IP_FLAG_DONTFRAG >> 8;
      picmp->ipoffset[1] = IP_FLAG_DONTFRAG & 0xff;
      picmp->ttl         = IP_TTL;
      picmp->proto       = IP_PROTO_ICMP;

      net_ipv4addr_hdrcopy(picmp->srcipaddr, &dev->d_ipaddr);
      net_ipv4addr_hdrcopy(picmp->destipaddr, destaddr);

      /* Calculate IP checksum. */

      picmp->ipchksum    = 0;
      picmp->ipchksum    = ~(ipv4_chksum(dev));

      /* Calculate the ICMP checksum. */

      picmp->icmpchksum  = 0;
      picmp->icmpchksum  = ~(icmp_chksum(dev, dev->d_sndlen));
      if (picmp->icmpchksum == 0)
        {
          picmp->icmpchksum = 0xffff;
        }

      nllvdbg("Outgoing ICMP packet length: %d (%d)\n",
              dev->d_len, (picmp->len[0] << 8) | picmp->len[1]);

#ifdef CONFIG_NET_STATISTICS
      g_netstats.icmp.sent++;
      g_netstats.ipv4.sent++;
#endif
    }
示例#2
0
static void tcp_sendcommon(FAR struct net_driver_s *dev,
                           FAR struct tcp_conn_s *conn,
                           FAR struct tcp_hdr_s *tcp)
{
  /* Copy the IP address into the IPv6 header */

#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
  if (IFF_IS_IPv6(dev->d_flags))
#endif
    {
      FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
      net_ipv6addr_hdrcopy(ipv6->srcipaddr, dev->d_ipv6addr);
      net_ipv6addr_hdrcopy(ipv6->destipaddr, conn->u.ipv6.raddr);
    }
#endif /* CONFIG_NET_IPv6 */

#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
  else
#endif
    {
      FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
      net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr);
      net_ipv4addr_hdrcopy(ipv4->destipaddr, &conn->u.ipv4.raddr);
    }
#endif /* CONFIG_NET_IPv4 */

  /* Set TCP sequence numbers and port numbers */

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

  tcp->srcport  = conn->lport;
  tcp->destport = conn->rport;

  /* Set the TCP window */

  if (conn->tcpstateflags & TCP_STOPPED)
    {
      /* If the connection has issued TCP_STOPPED, we advertise a zero
       * window so that the remote host will stop sending data.
       */

      tcp->wnd[0] = 0;
      tcp->wnd[1] = 0;
    }
  else
    {
      tcp->wnd[0] = ((NET_DEV_RCVWNDO(dev)) >> 8);
      tcp->wnd[1] = ((NET_DEV_RCVWNDO(dev)) & 0xff);
    }

  /* Finish the IP portion of the message and calculate checksums */

  tcp_sendcomplete(dev, tcp);
}
示例#3
0
void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn)
{
  FAR struct udp_hdr_s *udp;

  nllvdbg("UDP payload: %d (%d) bytes\n", dev->d_sndlen, dev->d_len);

  if (dev->d_sndlen > 0)
    {
      /* Initialize the IP header. */

#ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6
      if (conn->domain == PF_INET ||
          (conn->domain == PF_INET6 &&
           ip6_is_ipv4addr((FAR struct in6_addr *)conn->u.ipv6.raddr)))
#endif
        {
          /* Get pointers to the IPv4 header and the offset TCP header */

          FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;

          DEBUGASSERT(IFF_IS_IPv4(dev->d_flags));
          udp = UDPIPv4BUF;

          /* Initialize the IPv4 header. */

          ipv4->vhl         = 0x45;
          ipv4->tos         = 0;
          ++g_ipid;
          ipv4->ipid[0]     = g_ipid >> 8;
          ipv4->ipid[1]     = g_ipid & 0xff;
          ipv4->ipoffset[0] = 0;
          ipv4->ipoffset[1] = 0;
          ipv4->ttl         = conn->ttl;
          ipv4->proto       = IP_PROTO_UDP;

          net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr);

#ifdef CONFIG_NET_IPv6
          if (conn->domain == PF_INET6 &&
              ip6_is_ipv4addr((FAR struct in6_addr *)conn->u.ipv6.raddr))
            {
              in_addr_t raddr = ip6_get_ipv4addr((FAR struct in6_addr *)conn->u.ipv6.raddr);
              net_ipv4addr_hdrcopy(ipv4->destipaddr, &raddr);
            }
          else
#endif
            {
              net_ipv4addr_hdrcopy(ipv4->destipaddr, &conn->u.ipv4.raddr);
            }

          /* The total length to send is the size of the application data
           * plus the IPv4 and UDP headers (and, eventually, the link layer
           * header)
           */

          dev->d_len        = dev->d_sndlen + IPv4UDP_HDRLEN;

          /* The IPv4 length includes the size of the IPv4 header */

          ipv4->len[0]      = (dev->d_len >> 8);
          ipv4->len[1]      = (dev->d_len & 0xff);

          /* Calculate IP checksum. */

          ipv4->ipchksum    = 0;
          ipv4->ipchksum    = ~ipv4_chksum(dev);

#ifdef CONFIG_NET_STATISTICS
          g_netstats.ipv4.sent++;
#endif
        }
#endif /* CONFIG_NET_IPv4 */

#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
      else
#endif
        {
示例#4
0
static void icmp_echo_request(FAR struct net_driver_s *dev,
                              FAR in_addr_t *destaddr)
{
  FAR struct icmp_iphdr_s *picmp = ICMPBUF;
  FAR uint8_t *ptr;
  size_t sendlen;
  size_t icmplen;
  size_t pktlen;
  int i;

  /* The total length to send is the size of the application data plus the
   * IPv4 and ICMP headers (and, eventually, the Ethernet header)
   */

  pktlen = IPv4_PAYLOAD_SIZE + IPICMP_HDRLEN;

  /* The total size of the data (for ICMP checksum calculation) includes the
   * size of the ICMP header
   */

  icmplen = IPv4_PAYLOAD_SIZE + ICMP_HDRLEN;

  /* Initialize the IP header. */

  picmp->vhl         = 0x45;
  picmp->tos         = 0;
  picmp->len[0]      = (pktlen >> 8);
  picmp->len[1]      = (pktlen & 0xff);
  ++g_ipid;
  picmp->ipid[0]     = g_ipid >> 8;
  picmp->ipid[1]     = g_ipid & 0xff;
  picmp->ipoffset[0] = IP_FLAG_DONTFRAG >> 8;
  picmp->ipoffset[1] = IP_FLAG_DONTFRAG & 0xff;
  picmp->ttl         = IP_TTL;
  picmp->proto       = IP_PROTO_ICMP;

  net_ipv4addr_hdrcopy(picmp->srcipaddr, &dev->d_ipaddr);
  net_ipv4addr_hdrcopy(picmp->destipaddr, destaddr);

  /* Format the ICMP ECHO request packet */

  picmp->type  = ICMP_ECHO_REQUEST;
  picmp->icode = 0;
  picmp->id    = htons(pstate->png_id);
  picmp->seqno = htons(pstate->png_seqno);

  /* Insert some recognizable data into the packet */

  for (i = 0, ptr = ICMPDAT; i < ICMP_DATALEN; i++)
    {
      *ptr++ = i;
    }

  /* Calculate IP checksum. */

  picmp->ipchksum    = 0;
  picmp->ipchksum    = ~(ipv4_chksum(dev));

  /* Calculate the ICMP checksum. */

  picmp->icmpchksum  = 0;
  picmp->icmpchksum  = ~(icmp_chksum(dev, icmplen));
  if (picmp->icmpchksum == 0)
    {
      picmp->icmpchksum = 0xffff;
    }
}
示例#5
0
void tcp_reset(FAR struct net_driver_s *dev)
{
  FAR struct tcp_hdr_s *tcp = tcp_header(dev);
  uint16_t tmp16;
  uint8_t seqbyte;

#ifdef CONFIG_NET_STATISTICS
  g_netstats.tcp.rst++;
#endif

  /* TCP setup */

  tcp->flags     = TCP_RST | TCP_ACK;
  tcp->tcpoffset = 5 << 4;

  /* Flip the seqno and ackno fields in the TCP header. */

  seqbyte        = tcp->seqno[3];
  tcp->seqno[3]  = tcp->ackno[3];
  tcp->ackno[3]  = seqbyte;

  seqbyte        = tcp->seqno[2];
  tcp->seqno[2]  = tcp->ackno[2];
  tcp->ackno[2]  = seqbyte;

  seqbyte        = tcp->seqno[1];
  tcp->seqno[1]  = tcp->ackno[1];
  tcp->ackno[1]  = seqbyte;

  seqbyte        = tcp->seqno[0];
  tcp->seqno[0]  = tcp->ackno[0];
  tcp->ackno[0]  = seqbyte;

  /* We also have to increase the sequence number we are
   * acknowledging. If the least significant byte overflowed, we need
   * to propagate the carry to the other bytes as well.
   */

  if (++(tcp->ackno[3]) == 0)
    {
      if (++(tcp->ackno[2]) == 0)
        {
          if (++(tcp->ackno[1]) == 0)
            {
              ++(tcp->ackno[0]);
            }
        }
    }

  /* Swap port numbers. */

  tmp16         = tcp->srcport;
  tcp->srcport  = tcp->destport;
  tcp->destport = tmp16;

  /* Set the packet length and swap IP addresses. */

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

      /* Set the packet length to the size of the IPv6 + TCP headers */

      dev->d_len = IPv6TCP_HDRLEN;

      /* Swap IPv6 addresses */

      net_ipv6addr_hdrcopy(ipv6->destipaddr, ipv6->srcipaddr);
      net_ipv6addr_hdrcopy(ipv6->srcipaddr, dev->d_ipv6addr);
    }
#endif /* CONFIG_NET_IPv6 */

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

      /* Set the packet length to the size of the IPv4 + TCP headers */

      dev->d_len = IPv4TCP_HDRLEN;

      /* Swap IPv4 addresses */

      net_ipv4addr_hdrcopy(ipv4->destipaddr, ipv4->srcipaddr);
      net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr);
    }
#endif /* CONFIG_NET_IPv4 */

  /* And send out the RST packet */

  tcp_sendcomplete(dev, tcp);
}