⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uip-tcpsend.c

📁 這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU
💻 C
字号:
/**************************************************************************** * net/uip/uip-tcpsend.c * *   Copyright (C) 2007 Gregory Nutt. All rights reserved. *   Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Adapted for NuttX from logic in uIP which also has a BSD-like license: * *   Original author Adam Dunkels <adam@dunkels.com> *   Copyright () 2001-2003, Adam Dunkels. *   All rights reserved. * * 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. The name of the author may not be used to endorse or promote *    products derived from this software without specific prior *    written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. * ****************************************************************************//**************************************************************************** * Included Files ****************************************************************************/#include <nuttx/config.h>#if defined(CONFIG_NET) && defined(CONFIG_NET_TCP)#include <sys/types.h>#include <string.h>#include <debug.h>#include <net/uip/uipopt.h>#include <net/uip/uip.h>#include <net/uip/uip-arch.h>#include "uip-internal.h"/**************************************************************************** * Definitions ****************************************************************************/#define BUF ((struct uip_tcpip_hdr *)&dev->d_buf[UIP_LLH_LEN])/**************************************************************************** * Public Variables ****************************************************************************//**************************************************************************** * Private Variables ****************************************************************************//**************************************************************************** * Private Functions ****************************************************************************//**************************************************************************** * Name: uip_tcpsendcomplete * * Description: *   Complete the final portions of the send operation.  This function sets *   up IP header and computes the TCP checksum * * Parameters: *   dev    - The device driver structure to use in the send operation * * Return: *   None * * Assumptions: *   Called from the interrupt level or with interrupts disabled. * ****************************************************************************/static void uip_tcpsendcomplete(struct uip_driver_s *dev){  BUF->ttl         = UIP_TTL;#ifdef CONFIG_NET_IPv6  /* For IPv6, the IP length field does not include the IPv6 IP header   * length.   */  BUF->len[0]      = ((dev->d_len - UIP_IPH_LEN) >> 8);  BUF->len[1]      = ((dev->d_len - UIP_IPH_LEN) & 0xff);#else /* CONFIG_NET_IPv6 */  BUF->len[0]      = (dev->d_len >> 8);  BUF->len[1]      = (dev->d_len & 0xff);#endif /* CONFIG_NET_IPv6 */  BUF->urgp[0]     = BUF->urgp[1] = 0;  /* Calculate TCP checksum. */  BUF->tcpchksum   = 0;  BUF->tcpchksum   = ~(uip_tcpchksum(dev));#ifdef CONFIG_NET_IPv6  BUF->vtc         = 0x60;  BUF->tcf         = 0x00;  BUF->flow        = 0x00;#else /* CONFIG_NET_IPv6 */  BUF->vhl         = 0x45;  BUF->tos         = 0;  BUF->ipoffset[0] = 0;  BUF->ipoffset[1] = 0;  ++g_ipid;  BUF->ipid[0]     = g_ipid >> 8;  BUF->ipid[1]     = g_ipid & 0xff;  /* Calculate IP checksum. */  BUF->ipchksum    = 0;  BUF->ipchksum    = ~(uip_ipchksum(dev));#endif /* CONFIG_NET_IPv6 */  nvdbg("Outgoing TCP packet length: %d (%d)\n",       dev->d_len, (BUF->len[0] << 8) | BUF->len[1]);#ifdef CONFIG_NET_STATISTICS  uip_stat.tcp.sent++;  uip_stat.ip.sent++;#endif}/**************************************************************************** * Name: uip_tcpsendcommon * * Description: *   We're done with the input processing. We are now ready to send a reply *   Our job is to fill in all the fields of the TCP and IP headers before *   calculating the checksum and finally send the packet. * * Parameters: *   dev    - The device driver structure to use in the send operation *   conn   - The TCP connection structure holding connection information * * Return: *   None * * Assumptions: *   Called from the interrupt level or with interrupts disabled. * ****************************************************************************/static void uip_tcpsendcommon(struct uip_driver_s *dev, struct uip_conn *conn){  memcpy(BUF->ackno, conn->rcv_nxt, 4);  memcpy(BUF->seqno, conn->snd_nxt, 4);  BUF->proto    = UIP_PROTO_TCP;  BUF->srcport  = conn->lport;  BUF->destport = conn->rport;  uiphdr_ipaddr_copy(BUF->srcipaddr, &dev->d_ipaddr);  uiphdr_ipaddr_copy(BUF->destipaddr, &conn->ripaddr);  if (conn->tcpstateflags & UIP_STOPPED)    {      /* If the connection has issued uip_stop(), we advertise a zero       * window so that the remote host will stop sending data.       */      BUF->wnd[0] = 0;      BUF->wnd[1] = 0;    }  else    {      BUF->wnd[0] = ((CONFIG_NET_RECEIVE_WINDOW) >> 8);      BUF->wnd[1] = ((CONFIG_NET_RECEIVE_WINDOW) & 0xff);    }  /* Finish the IP portion of the message, calculate checksums and send   * the message.   */  uip_tcpsendcomplete(dev);}/**************************************************************************** * Public Functions ****************************************************************************//**************************************************************************** * Name: uip_tcpsend * * Description: *   Setup to send a TCP packet * * Parameters: *   dev    - The device driver structure to use in the send operation *   conn   - The TCP connection structure holding connection information *   flags  - flags to apply to the TCP header *   len    - length of the message * * Return: *   None * * Assumptions: *   Called from the interrupt level or with interrupts disabled. * ****************************************************************************/void uip_tcpsend(struct uip_driver_s *dev, struct uip_conn *conn, uint8 flags, uint16 len){  BUF->flags     = flags;  dev->d_len     = len;  BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;  uip_tcpsendcommon(dev, conn);}/**************************************************************************** * Name: uip_tcpreset * * Description: *   Send a TCP reset (no-data) message * * Parameters: *   dev    - The device driver structure to use in the send operation * * Return: *   None * * Assumptions: *   Called from the interrupt level or with interrupts disabled. * ****************************************************************************/void uip_tcpreset(struct uip_driver_s *dev){  uint16 tmp16;  uint8  seqbyte;#ifdef CONFIG_NET_STATISTICS  uip_stat.tcp.rst++;#endif  BUF->flags     = TCP_RST | TCP_ACK;  dev->d_len     = UIP_IPTCPH_LEN;  BUF->tcpoffset = 5 << 4;  /* Flip the seqno and ackno fields in the TCP header. */  seqbyte        = BUF->seqno[3];  BUF->seqno[3]  = BUF->ackno[3];  BUF->ackno[3]  = seqbyte;  seqbyte        = BUF->seqno[2];  BUF->seqno[2]  = BUF->ackno[2];  BUF->ackno[2]  = seqbyte;  seqbyte        = BUF->seqno[1];  BUF->seqno[1]  = BUF->ackno[1];  BUF->ackno[1]  = seqbyte;  seqbyte        = BUF->seqno[0];  BUF->seqno[0]  = BUF->ackno[0];  BUF->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 (++(BUF->ackno[3]) == 0)    {      if (++(BUF->ackno[2]) == 0)        {          if (++(BUF->ackno[1]) == 0)            {              ++(BUF->ackno[0]);            }        }    }  /* Swap port numbers. */  tmp16         = BUF->srcport;  BUF->srcport  = BUF->destport;  BUF->destport = tmp16;  /* Swap IP addresses. */  uiphdr_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);  uiphdr_ipaddr_copy(BUF->srcipaddr, &dev->d_ipaddr);  /* And send out the RST packet */  uip_tcpsendcomplete(dev);}/**************************************************************************** * Name: uip_tcpack * * Description: *   Send the SYN or SYNACK response. * * Parameters: *   dev    - The device driver structure to use in the send operation *   conn   - The TCP connection structure holding connection information *   ack    - The ACK response to send * * Return: *   None * * Assumptions: *   Called from the interrupt level or with interrupts disabled. * ****************************************************************************/void uip_tcpack(struct uip_driver_s *dev, struct uip_conn *conn, uint8 ack){  /* Save the ACK bits */  BUF->flags = ack;  /* We send out the TCP Maximum Segment Size option with our ack. */  BUF->optdata[0] = TCP_OPT_MSS;  BUF->optdata[1] = TCP_OPT_MSS_LEN;  BUF->optdata[2] = (UIP_TCP_MSS) / 256;  BUF->optdata[3] = (UIP_TCP_MSS) & 255;  dev->d_len      = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;  BUF->tcpoffset  = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;  /* Complete the common portions of the TCP message */  uip_tcpsendcommon(dev, conn);}#endif /* CONFIG_NET && CONFIG_NET_TCP */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -