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

📄 ip.c

📁 lwip-1.4.0
💻 C
📖 第 1 页 / 共 3 页
字号:
             u8_t ttl, u8_t tos,             u8_t proto, struct netif *netif){#if IP_OPTIONS_SEND  return ip_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0);}/** * Same as ip_output_if() but with the possibility to include IP options: * * @ param ip_options pointer to the IP options, copied into the IP header * @ param optlen length of ip_options */err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,       u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,       u16_t optlen){#endif /* IP_OPTIONS_SEND */  struct ip_hdr *iphdr;  ip_addr_t dest_addr;#if CHECKSUM_GEN_IP_INLINE  u32_t chk_sum = 0;#endif /* CHECKSUM_GEN_IP_INLINE */  /* pbufs passed to IP must have a ref-count of 1 as their payload pointer     gets altered as the packet is passed down the stack */  LWIP_ASSERT("p->ref == 1", p->ref == 1);  snmp_inc_ipoutrequests();  /* Should the IP header be generated or is it already included in p? */  if (dest != IP_HDRINCL) {    u16_t ip_hlen = IP_HLEN;#if IP_OPTIONS_SEND    u16_t optlen_aligned = 0;    if (optlen != 0) {#if CHECKSUM_GEN_IP_INLINE      int i;#endif /* CHECKSUM_GEN_IP_INLINE */      /* round up to a multiple of 4 */      optlen_aligned = ((optlen + 3) & ~3);      ip_hlen += optlen_aligned;      /* First write in the IP options */      if (pbuf_header(p, optlen_aligned)) {        LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output_if_opt: not enough room for IP options in pbuf\n"));        IP_STATS_INC(ip.err);        snmp_inc_ipoutdiscards();        return ERR_BUF;      }      MEMCPY(p->payload, ip_options, optlen);      if (optlen < optlen_aligned) {        /* zero the remaining bytes */        memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen);      }#if CHECKSUM_GEN_IP_INLINE      for (i = 0; i < optlen_aligned/2; i++) {        chk_sum += ((u16_t*)p->payload)[i];      }#endif /* CHECKSUM_GEN_IP_INLINE */    }#endif /* IP_OPTIONS_SEND */    /* generate IP header */    if (pbuf_header(p, IP_HLEN)) {      LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output: not enough room for IP header in pbuf\n"));      IP_STATS_INC(ip.err);      snmp_inc_ipoutdiscards();      return ERR_BUF;    }    iphdr = (struct ip_hdr *)p->payload;    LWIP_ASSERT("check that first pbuf can hold struct ip_hdr",               (p->len >= sizeof(struct ip_hdr)));    IPH_TTL_SET(iphdr, ttl);    IPH_PROTO_SET(iphdr, proto);#if CHECKSUM_GEN_IP_INLINE    chk_sum += LWIP_MAKE_U16(proto, ttl);#endif /* CHECKSUM_GEN_IP_INLINE */    /* dest cannot be NULL here */    ip_addr_copy(iphdr->dest, *dest);#if CHECKSUM_GEN_IP_INLINE    chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF;    chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16;#endif /* CHECKSUM_GEN_IP_INLINE */    IPH_VHLTOS_SET(iphdr, 4, ip_hlen / 4, tos);#if CHECKSUM_GEN_IP_INLINE    chk_sum += iphdr->_v_hl_tos;#endif /* CHECKSUM_GEN_IP_INLINE */    IPH_LEN_SET(iphdr, htons(p->tot_len));#if CHECKSUM_GEN_IP_INLINE    chk_sum += iphdr->_len;#endif /* CHECKSUM_GEN_IP_INLINE */    IPH_OFFSET_SET(iphdr, 0);    IPH_ID_SET(iphdr, htons(ip_id));#if CHECKSUM_GEN_IP_INLINE    chk_sum += iphdr->_id;#endif /* CHECKSUM_GEN_IP_INLINE */    ++ip_id;    if (ip_addr_isany(src)) {      ip_addr_copy(iphdr->src, netif->ip_addr);    } else {      /* src cannot be NULL here */      ip_addr_copy(iphdr->src, *src);    }#if CHECKSUM_GEN_IP_INLINE    chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF;    chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16;    chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);    chk_sum = (chk_sum >> 16) + chk_sum;    chk_sum = ~chk_sum;    iphdr->_chksum = chk_sum; /* network order */#else /* CHECKSUM_GEN_IP_INLINE */    IPH_CHKSUM_SET(iphdr, 0);#if CHECKSUM_GEN_IP    IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen));#endif#endif /* CHECKSUM_GEN_IP_INLINE */  } else {    /* IP header already included in p */    iphdr = (struct ip_hdr *)p->payload;    ip_addr_copy(dest_addr, iphdr->dest);    dest = &dest_addr;  }  IP_STATS_INC(ip.xmit);  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num));  ip_debug_print(p);#if ENABLE_LOOPBACK  if (ip_addr_cmp(dest, &netif->ip_addr)) {    /* Packet to self, enqueue it for loopback */    LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));    return netif_loop_output(netif, p, dest);  }#if LWIP_IGMP  if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) {    netif_loop_output(netif, p, dest);  }#endif /* LWIP_IGMP */#endif /* ENABLE_LOOPBACK */#if IP_FRAG  /* don't fragment if interface has mtu set to 0 [loopif] */  if (netif->mtu && (p->tot_len > netif->mtu)) {    return ip_frag(p, netif, dest);  }#endif /* IP_FRAG */  LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));  return netif->output(netif, p, dest);}/** * Simple interface to ip_output_if. It finds the outgoing network * interface and calls upon ip_output_if to do the actual work. * * @param p the packet to send (p->payload points to the data, e.g. next            protocol header; if dest == IP_HDRINCL, p already includes an IP            header and p->payload points to that IP header) * @param src the source IP address to send from (if src == IP_ADDR_ANY, the *         IP  address of the netif used to send is used as source address) * @param dest the destination IP address to send the packet to * @param ttl the TTL value to be set in the IP header * @param tos the TOS value to be set in the IP header * @param proto the PROTOCOL to be set in the IP header * * @return ERR_RTE if no route is found *         see ip_output_if() for more return values */err_tip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,          u8_t ttl, u8_t tos, u8_t proto){  struct netif *netif;  /* pbufs passed to IP must have a ref-count of 1 as their payload pointer     gets altered as the packet is passed down the stack */  LWIP_ASSERT("p->ref == 1", p->ref == 1);  if ((netif = ip_route(dest)) == NULL) {    LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",      ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));    IP_STATS_INC(ip.rterr);    return ERR_RTE;  }  return ip_output_if(p, src, dest, ttl, tos, proto, netif);}#if LWIP_NETIF_HWADDRHINT/** Like ip_output, but takes and addr_hint pointer that is passed on to netif->addr_hint *  before calling ip_output_if. * * @param p the packet to send (p->payload points to the data, e.g. next            protocol header; if dest == IP_HDRINCL, p already includes an IP            header and p->payload points to that IP header) * @param src the source IP address to send from (if src == IP_ADDR_ANY, the *         IP  address of the netif used to send is used as source address) * @param dest the destination IP address to send the packet to * @param ttl the TTL value to be set in the IP header * @param tos the TOS value to be set in the IP header * @param proto the PROTOCOL to be set in the IP header * @param addr_hint address hint pointer set to netif->addr_hint before *        calling ip_output_if() * * @return ERR_RTE if no route is found *         see ip_output_if() for more return values */err_tip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,          u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint){  struct netif *netif;  err_t err;  /* pbufs passed to IP must have a ref-count of 1 as their payload pointer     gets altered as the packet is passed down the stack */  LWIP_ASSERT("p->ref == 1", p->ref == 1);  if ((netif = ip_route(dest)) == NULL) {    LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",      ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));    IP_STATS_INC(ip.rterr);    return ERR_RTE;  }  netif->addr_hint = addr_hint;  err = ip_output_if(p, src, dest, ttl, tos, proto, netif);  netif->addr_hint = NULL;  return err;}#endif /* LWIP_NETIF_HWADDRHINT*/#if IP_DEBUG/* Print an IP header by using LWIP_DEBUGF * @param p an IP packet, p->payload pointing to the IP header */voidip_debug_print(struct pbuf *p){  struct ip_hdr *iphdr = (struct ip_hdr *)p->payload;  u8_t *payload;  payload = (u8_t *)iphdr + IP_HLEN;  LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));  LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" |  0x%02"X16_F" |     %5"U16_F"     | (v, hl, tos, len)\n",                    IPH_V(iphdr),                    IPH_HL(iphdr),                    IPH_TOS(iphdr),                    ntohs(IPH_LEN(iphdr))));  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));  LWIP_DEBUGF(IP_DEBUG, ("|    %5"U16_F"      |%"U16_F"%"U16_F"%"U16_F"|    %4"U16_F"   | (id, flags, offset)\n",                    ntohs(IPH_ID(iphdr)),                    ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,                    ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,                    ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,                    ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |    0x%04"X16_F"     | (ttl, proto, chksum)\n",                    IPH_TTL(iphdr),                    IPH_PROTO(iphdr),                    ntohs(IPH_CHKSUM(iphdr))));  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (src)\n",                    ip4_addr1_16(&iphdr->src),                    ip4_addr2_16(&iphdr->src),                    ip4_addr3_16(&iphdr->src),                    ip4_addr4_16(&iphdr->src)));  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));  LWIP_DEBUGF(IP_DEBUG, ("|  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  |  %3"U16_F"  | (dest)\n",                    ip4_addr1_16(&iphdr->dest),                    ip4_addr2_16(&iphdr->dest),                    ip4_addr3_16(&iphdr->dest),                    ip4_addr4_16(&iphdr->dest)));  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));}#endif /* IP_DEBUG */

⌨️ 快捷键说明

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