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

📄 udp.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
        {          break;        }      }    }    /*-----------------------------------------------------------------*/    /* If no match, accept port number match if address is wildcard.   */    /*-----------------------------------------------------------------*/    if ((sock == NULL) && port_match)    {      if (port_match->local.sin_addr.s_addr == INADDR_ANY)        sock = port_match;    }  }  /*-------------------------------------------------------------------*/  /* If no match, update statistics and send ICMP "port unreachable".  */  /*-------------------------------------------------------------------*/  if (sock == NULL)  {    ++Stats.UdpNoPorts;    IcmpDestUR(ICC_PORTUR, RxBuf, src_addr, dst_addr);  }  /*-------------------------------------------------------------------*/  /* Else, deliver datagram to selected socket.                        */  /*-------------------------------------------------------------------*/  else  {    /*-----------------------------------------------------------------*/    /* Ignore buffer if receive queue is full.                         */    /*-----------------------------------------------------------------*/    if (sock->q_count >= UDP_MAX_QUEUE)      ++Stats.UdpInErrors;    /*-----------------------------------------------------------------*/    /* Else accept if not shutdown for receiving.                      */    /*-----------------------------------------------------------------*/    else if ((sock->flags & SF_RCV_SHUT) == FALSE)    {      /*---------------------------------------------------------------*/      /* Append to socket queue and reserve buffer.                    */      /*---------------------------------------------------------------*/      ++sock->q_count;      RxBuf->next = NULL;      if (sock->rq_head == NULL)        sock->rq_head = RxBuf;      else        sock->rq_tail->next = RxBuf;      sock->rq_tail = RxBuf;      RxBuf = NULL;      /*---------------------------------------------------------------*/      /* Unblock any waiting readers by posting "data received" event. */      /*---------------------------------------------------------------*/      NetPostEvent(sock, SE_DATA_RCVD);      ++Stats.UdpInDatagrams;      /*---------------------------------------------------------------*/      /* If not already there, move socket to head of UDP list.        */      /*---------------------------------------------------------------*/      link = (CircLink *)sock;      if (link != UdpLruList.next_bck)      {        /*-------------------------------------------------------------*/        /* Remove from socket list.                                    */        /*-------------------------------------------------------------*/        link->next_bck->next_fwd = link->next_fwd;        link->next_fwd->next_bck = link->next_bck;        /*-------------------------------------------------------------*/        /* Append to head of socket list.                              */        /*-------------------------------------------------------------*/        link->next_bck = UdpLruList.next_bck;        link->next_fwd = &UdpLruList;        UdpLruList.next_bck->next_fwd = link;        UdpLruList.next_bck = link;      }    }  }}/***********************************************************************//*     UdpSend: Send UDP datagram to specified IP address              *//*                                                                     *//*      Inputs: sock = pointer to SOCKET structure                     *//*              dst = destination SockAddr                             *//*              buf = pointer to NetBuf containing datagram            *//*              len = amount of data to send                           *//*              rt = route to destination or gateway                   *//*                                                                     *//***********************************************************************/void UdpSend(CSOCKET sock, const SockAddr *dst, NetBuf *buf, int len,             Route *rt){  Ip *ip = (Ip *)buf->ip_pkt;  Udp *udp = buf->ip_data;  /*-------------------------------------------------------------------*/  /* Start IP header field initialization.                             */  /*-------------------------------------------------------------------*/  ip->protocol = IPT_UDP;  ip->dst_ip = dst->sin_addr.s_addr;  ip->src_ip = rt->ni->ip_addr;  /*-------------------------------------------------------------------*/  /* Assign buffer length.                                             */  /*-------------------------------------------------------------------*/  buf->length = UDP_HLEN + len;  /*-------------------------------------------------------------------*/  /* Complete UDP header field initialization (in network order).      */  /*-------------------------------------------------------------------*/  udp->src_port = sock->local.sin_port;  udp->dst_port = dst->sin_port;  udp->length = htons((ui16)buf->length);  /*-------------------------------------------------------------------*/  /* Calculate checksum. Use all ones representation for zero.         */  /*-------------------------------------------------------------------*/  udp->checksum = 0;  if ((sock->flags & SF_NOCHECKSUM) == 0)  {    udp->checksum = checksum(buf);    if (udp->checksum == 0)      udp->checksum = ~0;  }  /*-------------------------------------------------------------------*/  /* Pass packet to IP layer for delivery and update statistics.       */  /*-------------------------------------------------------------------*/  IpSend(rt, buf, buf->length, sock->ip_tos);  ++Stats.UdpOutDatagrams;}/***********************************************************************//*  UdpConnect: Ensure local port is assigned and check remote address *//*                                                                     *//*       Input: sock = pointer to socket to add                        *//*                                                                     *//*     Returns: 0 if no errors, else -1 with errno set to error code   *//*                                                                     *//***********************************************************************/int UdpConnect(SOCKET sock){  /*-------------------------------------------------------------------*/  /* If local port is not specified, pick one.                         */  /*-------------------------------------------------------------------*/  if (sock->local.sin_port == 0)  {    sock->local.sin_port = UdpNextPort();    if (sock->local.sin_port == 0)    {      NetError(sock, EMFILE);      return -1;    }  }  /*-------------------------------------------------------------------*/  /* Else, verify that the address is not already used.                */  /*-------------------------------------------------------------------*/  else  {    CircLink *link = UdpLruList.next_bck;    for (; link != &UdpLruList; link = link->next_bck)    {      SOCKET next = (SOCKET)link;      /*---------------------------------------------------------------*/      /* Have match if unconnected socket matches local address or if  */      /* connected socket matches local and remote addresses.          */      /*---------------------------------------------------------------*/      if ((sock->local.sin_port == next->local.sin_port) &&          (sock->local.sin_addr.s_addr == next->local.sin_addr.s_addr))      {        if (!(next->flags & SF_CONNECTED) ||            ((sock->remote.sin_port == next->remote.sin_port) &&         (sock->remote.sin_addr.s_addr == next->remote.sin_addr.s_addr)))        {          if (sock != next)          {            NetError(sock, EADDRINUSE);            return -1;          }        }      }    }  }  /*-------------------------------------------------------------------*/  /* Set "connected" flag and return 0 for no errors.                  */  /*-------------------------------------------------------------------*/  sock->flags |= SF_CONNECTED;  return 0;}/***********************************************************************//* UdpQuerySock: Loop through UDP socket list, reporting status        *//*                                                                     *//***********************************************************************/void UdpQuerySock(void){  CircLink *link = UdpLruList.next_bck;  /*-------------------------------------------------------------------*/  /* Sweep through LRU-sorted UDP socket list.                         */  /*-------------------------------------------------------------------*/  for (; link != &UdpLruList; link = link->next_bck)    printf(" %2u UDP\n", ((SOCKET)link - &Socks[0]) + 1);}

⌨️ 快捷键说明

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