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

📄 udp.c

📁 lwip-1.4.0
💻 C
📖 第 1 页 / 共 3 页
字号:
        }      }#endif /* SO_REUSE && SO_REUSE_RXTOALL */      /* callback */      if (pcb->recv != NULL) {        /* now the recv function is responsible for freeing p */        pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr(), src);      } else {        /* no recv function registered? then we have to free the pbuf! */        pbuf_free(p);        goto end;      }    } else {      LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: not for us.\n"));#if LWIP_ICMP      /* No match was found, send ICMP destination port unreachable unless         destination address was broadcast/multicast. */      if (!broadcast &&          !ip_addr_ismulticast(&current_iphdr_dest)) {        /* move payload pointer back to ip header */        pbuf_header(p, (IPH_HL(iphdr) * 4) + UDP_HLEN);        LWIP_ASSERT("p->payload == iphdr", (p->payload == iphdr));        icmp_dest_unreach(p, ICMP_DUR_PORT);      }#endif /* LWIP_ICMP */      UDP_STATS_INC(udp.proterr);      UDP_STATS_INC(udp.drop);      snmp_inc_udpnoports();      pbuf_free(p);    }  } else {    pbuf_free(p);  }end:  PERF_STOP("udp_input");}/** * Send data using UDP. * * @param pcb UDP PCB used to send the data. * @param p chain of pbuf's to be sent. * * The datagram will be sent to the current remote_ip & remote_port * stored in pcb. If the pcb is not bound to a port, it will * automatically be bound to a random port. * * @return lwIP error code. * - ERR_OK. Successful. No error occured. * - ERR_MEM. Out of memory. * - ERR_RTE. Could not find route to destination address. * - More errors could be returned by lower protocol layers. * * @see udp_disconnect() udp_sendto() */err_tudp_send(struct udp_pcb *pcb, struct pbuf *p){  /* send to the packet using remote ip and port stored in the pcb */  return udp_sendto(pcb, p, &pcb->remote_ip, pcb->remote_port);}#if LWIP_CHECKSUM_ON_COPY/** Same as udp_send() but with checksum */err_tudp_send_chksum(struct udp_pcb *pcb, struct pbuf *p,                u8_t have_chksum, u16_t chksum){  /* send to the packet using remote ip and port stored in the pcb */  return udp_sendto_chksum(pcb, p, &pcb->remote_ip, pcb->remote_port,    have_chksum, chksum);}#endif /* LWIP_CHECKSUM_ON_COPY *//** * Send data to a specified address using UDP. * * @param pcb UDP PCB used to send the data. * @param p chain of pbuf's to be sent. * @param dst_ip Destination IP address. * @param dst_port Destination UDP port. * * dst_ip & dst_port are expected to be in the same byte order as in the pcb. * * If the PCB already has a remote address association, it will * be restored after the data is sent. *  * @return lwIP error code (@see udp_send for possible error codes) * * @see udp_disconnect() udp_send() */err_tudp_sendto(struct udp_pcb *pcb, struct pbuf *p,  ip_addr_t *dst_ip, u16_t dst_port){#if LWIP_CHECKSUM_ON_COPY  return udp_sendto_chksum(pcb, p, dst_ip, dst_port, 0, 0);}/** Same as udp_sendto(), but with checksum */err_tudp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,                  u16_t dst_port, u8_t have_chksum, u16_t chksum){#endif /* LWIP_CHECKSUM_ON_COPY */  struct netif *netif;  LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n"));  /* find the outgoing network interface for this packet */#if LWIP_IGMP  netif = ip_route((ip_addr_ismulticast(dst_ip))?(&(pcb->multicast_ip)):(dst_ip));#else  netif = ip_route(dst_ip);#endif /* LWIP_IGMP */  /* no outgoing network interface could be found? */  if (netif == NULL) {    LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",      ip4_addr1_16(dst_ip), ip4_addr2_16(dst_ip), ip4_addr3_16(dst_ip), ip4_addr4_16(dst_ip)));    UDP_STATS_INC(udp.rterr);    return ERR_RTE;  }#if LWIP_CHECKSUM_ON_COPY  return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum);#else /* LWIP_CHECKSUM_ON_COPY */  return udp_sendto_if(pcb, p, dst_ip, dst_port, netif);#endif /* LWIP_CHECKSUM_ON_COPY */}/** * Send data to a specified address using UDP. * The netif used for sending can be specified. * * This function exists mainly for DHCP, to be able to send UDP packets * on a netif that is still down. * * @param pcb UDP PCB used to send the data. * @param p chain of pbuf's to be sent. * @param dst_ip Destination IP address. * @param dst_port Destination UDP port. * @param netif the netif used for sending. * * dst_ip & dst_port are expected to be in the same byte order as in the pcb. * * @return lwIP error code (@see udp_send for possible error codes) * * @see udp_disconnect() udp_send() */err_tudp_sendto_if(struct udp_pcb *pcb, struct pbuf *p,  ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif){#if LWIP_CHECKSUM_ON_COPY  return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, 0, 0);}/** Same as udp_sendto_if(), but with checksum */err_tudp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,                     u16_t dst_port, struct netif *netif, u8_t have_chksum,                     u16_t chksum){#endif /* LWIP_CHECKSUM_ON_COPY */  struct udp_hdr *udphdr;  ip_addr_t *src_ip;  err_t err;  struct pbuf *q; /* q will be sent down the stack */#if IP_SOF_BROADCAST  /* broadcast filter? */  if ( ((pcb->so_options & SOF_BROADCAST) == 0) && ip_addr_isbroadcast(dst_ip, netif) ) {    LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,      ("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));    return ERR_VAL;  }#endif /* IP_SOF_BROADCAST */  /* if the PCB is not yet bound to a port, bind it here */  if (pcb->local_port == 0) {    LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n"));    err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);    if (err != ERR_OK) {      LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n"));      return err;    }  }  /* not enough space to add an UDP header to first pbuf in given p chain? */  if (pbuf_header(p, UDP_HLEN)) {    /* allocate header in a separate new pbuf */    q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);    /* new header pbuf could not be allocated? */    if (q == NULL) {      LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n"));      return ERR_MEM;    }    if (p->tot_len != 0) {      /* chain header q in front of given pbuf p (only if p contains data) */      pbuf_chain(q, p);    }    /* first pbuf q points to header pbuf */    LWIP_DEBUGF(UDP_DEBUG,                ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));  } else {    /* adding space for header within p succeeded */    /* first pbuf q equals given pbuf */    q = p;    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));  }  LWIP_ASSERT("check that first pbuf can hold struct udp_hdr",              (q->len >= sizeof(struct udp_hdr)));  /* q now represents the packet to be sent */  udphdr = (struct udp_hdr *)q->payload;  udphdr->src = htons(pcb->local_port);  udphdr->dest = htons(dst_port);  /* in UDP, 0 checksum means 'no checksum' */  udphdr->chksum = 0x0000;   /* Multicast Loop? */#if LWIP_IGMP  if (ip_addr_ismulticast(dst_ip) && ((pcb->flags & UDP_FLAGS_MULTICAST_LOOP) != 0)) {    q->flags |= PBUF_FLAG_MCASTLOOP;  }#endif /* LWIP_IGMP */  /* PCB local address is IP_ANY_ADDR? */  if (ip_addr_isany(&pcb->local_ip)) {    /* use outgoing network interface IP address as source address */    src_ip = &(netif->ip_addr);  } else {    /* check if UDP PCB local IP address is correct     * this could be an old address if netif->ip_addr has changed */    if (!ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {      /* local_ip doesn't match, drop the packet */      if (q != p) {        /* free the header pbuf */        pbuf_free(q);        q = NULL;        /* p is still referenced by the caller, and will live on */      }      return ERR_VAL;    }    /* use UDP PCB local IP address as source address */    src_ip = &(pcb->local_ip);  }  LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len));#if LWIP_UDPLITE  /* UDP Lite protocol? */  if (pcb->flags & UDP_FLAGS_UDPLITE) {    u16_t chklen, chklen_hdr;    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len));    /* set UDP message length in UDP header */    chklen_hdr = chklen = pcb->chksum_len_tx;    if ((chklen < sizeof(struct udp_hdr)) || (chklen > q->tot_len)) {      if (chklen != 0) {        LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE pcb->chksum_len is illegal: %"U16_F"\n", chklen));      }      /* For UDP-Lite, checksum length of 0 means checksum         over the complete packet. (See RFC 3828 chap. 3.1)         At least the UDP-Lite header must be covered by the         checksum, therefore, if chksum_len has an illegal         value, we generate the checksum over the complete         packet to be safe. */      chklen_hdr = 0;      chklen = q->tot_len;    }    udphdr->len = htons(chklen_hdr);    /* calculate checksum */#if CHECKSUM_GEN_UDP    udphdr->chksum = inet_chksum_pseudo_partial(q, src_ip, dst_ip,      IP_PROTO_UDPLITE, q->tot_len,#if !LWIP_CHECKSUM_ON_COPY      chklen);#else /* !LWIP_CHECKSUM_ON_COPY */      (have_chksum ? UDP_HLEN : chklen));    if (have_chksum) {      u32_t acc;      acc = udphdr->chksum + (u16_t)~(chksum);      udphdr->chksum = FOLD_U32T(acc);    }#endif /* !LWIP_CHECKSUM_ON_COPY */    /* chksum zero must become 0xffff, as zero means 'no checksum' */    if (udphdr->chksum == 0x0000) {      udphdr->chksum = 0xffff;    }#endif /* CHECKSUM_GEN_UDP */    /* output to IP */    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n"));#if LWIP_NETIF_HWADDRHINT    netif->addr_hint = &(pcb->addr_hint);#endif /* LWIP_NETIF_HWADDRHINT*/    err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);#if LWIP_NETIF_HWADDRHINT    netif->addr_hint = NULL;#endif /* LWIP_NETIF_HWADDRHINT*/  } else#endif /* LWIP_UDPLITE */  {      /* UDP */    LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len));    udphdr->len = htons(q->tot_len);    /* calculate checksum */#if CHECKSUM_GEN_UDP    if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {      u16_t udpchksum;#if LWIP_CHECKSUM_ON_COPY      if (have_chksum) {        u32_t acc;        udpchksum = inet_chksum_pseudo_partial(q, src_ip, dst_ip, IP_PROTO_UDP,          q->tot_len, UDP_HLEN);        acc = udpchksum + (u16_t)~(chksum);        udpchksum = FOLD_U32T(acc);      } else#endif /* LWIP_CHECKSUM_ON_COPY */      {        udpchksum = inet_chksum_pseudo(q, src_ip, dst_ip, IP_PROTO_UDP, q->tot_len);      }

⌨️ 快捷键说明

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