国产精品免费嫩草研究院|无遮羞动漫在线观看AV|国产麻豆精品传媒AV国产在线|村在线观看|寂寞情人1正版|韩国床震韩国床震古|精品系列专区久久

【lwip】10-ICMP協(xié)議&源碼分析( 四 )

10.5.4 超時代碼字段/** ICMP超時代碼字段 */enum icmp_te_type {/** 生存時間超時值TTL為0 */ICMP_TE_TTL= 0,/** 分片數(shù)據(jù)報重裝超時 */ICMP_TE_FRAG = 1};10.6 發(fā)送ICMP差錯報告10.6.1 發(fā)送ICMP差錯報文基函數(shù)icmp_send_response()函數(shù)就是發(fā)送ICMP差錯報文的基函數(shù),可以封裝這個函數(shù)實現(xiàn)各種ICMP差錯報文 。
該函數(shù)主要邏輯:

  • 檢查觸發(fā)ICMP差錯報告的IP報文pbuf中的數(shù)據(jù)size是否符合要求 。
    • 目的不可達的ICMP差錯報文一般需要IP首部+8字節(jié)數(shù)據(jù) 。
  • 申請ICMP差錯報文pbuf資源 。
  • 組裝ICMP數(shù)據(jù)報 。
  • 路由匹配網(wǎng)卡 。
  • 通過IP層輸出函數(shù)發(fā)送ICMP報文 。
/** * Send an icmp packet in response to an incoming packet. * * @param p the input packet for which the 'unreachable' should be sent, *p->payload pointing to the IP header * @param type Type of the ICMP header * @param code Code of the ICMP header */static voidicmp_send_response(struct pbuf *p, u8_t type, u8_t code){struct pbuf *q; /* ICMP差錯報文pbuf指針 */struct ip_hdr *iphdr; /* 觸發(fā)ICMP差錯報告的IP頭指針 */struct icmp_echo_hdr *icmphdr; /* ICMP報文首部指針 */ip4_addr_t iphdr_src; /* 觸發(fā)ICMP差錯報告的IP源地址 */struct netif *netif; /* 發(fā)送ICMP差錯報告的網(wǎng)卡 */u16_t response_pkt_len; /* ICMP數(shù)據(jù)區(qū)長度 *//* 增加試圖發(fā)送的消息數(shù) */MIB2_STATS_INC(mib2.icmpoutmsgs);/* IP頭+8 */response_pkt_len = IP_HLEN + ICMP_DEST_UNREACH_DATASIZE;if (p->tot_len < response_pkt_len) { /* 如果觸發(fā)ICMP差錯報告的IP報文pbuf數(shù)據(jù)區(qū)不夠8,就全部上傳即可 。*/response_pkt_len = p->tot_len;}/* 申請ICMP差錯報告的pbuf資源,長度為ICMP差錯報告首部+數(shù)據(jù)區(qū)*/q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + response_pkt_len, PBUF_RAM);if (q == NULL) {LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n"));MIB2_STATS_INC(mib2.icmpouterrors);return;}LWIP_ASSERT("check that first pbuf can hold icmp message",(q->len >= (sizeof(struct icmp_echo_hdr) + response_pkt_len)));iphdr = (struct ip_hdr *)p->payload; /* 提取IP報文首部 */LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from "));ip4_addr_debug_print_val(ICMP_DEBUG, iphdr->src);LWIP_DEBUGF(ICMP_DEBUG, (" to "));ip4_addr_debug_print_val(ICMP_DEBUG, iphdr->dest);LWIP_DEBUGF(ICMP_DEBUG, ("\n"));icmphdr = (struct icmp_echo_hdr *)q->payload;icmphdr->type = type; /* 設(shè)置ICMP類型字段 */icmphdr->code = code; /* 設(shè)置ICMP代碼字段 */icmphdr->id = 0; /* 設(shè)置ICMP標識字段 */icmphdr->seqno = 0; /* 設(shè)置ICMP序號字段 *//* 拷貝觸發(fā)ICMP差錯的IP報文首部+(<=8)字節(jié)的原數(shù)據(jù)到ICMP差錯報告數(shù)據(jù)區(qū) */SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload,response_pkt_len);ip4_addr_copy(iphdr_src, iphdr->src); /* 提取IP源地址 */#ifdef LWIP_HOOK_IP4_ROUTE_SRC{ip4_addr_t iphdr_dst;ip4_addr_copy(iphdr_dst, iphdr->dest); /* 提取IP目的地址 */netif = ip4_route_src(&iphdr_dst, &iphdr_src); /* 路由匹配網(wǎng)卡 */}#elsenetif = ip4_route(&iphdr_src); /* 路由匹配網(wǎng)卡 */#endifif (netif != NULL) { /* 匹配網(wǎng)卡成功 */icmphdr->chksum = 0; /* ICMP校驗和字段 */#if CHECKSUM_GEN_ICMPIF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP) {icmphdr->chksum = inet_chksum(icmphdr, q->len); /* 計算ICMP校驗和 */}#endifICMP_STATS_INC(icmp.xmit);/* 通過指定網(wǎng)卡把ICMP報文轉(zhuǎn)交到IP層發(fā)送出去 */ip4_output_if(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP, netif);}/* 釋放ICMP報文資源 */pbuf_free(q);}10.6.2 icmp_dest_unreach()目的不可達差錯報告icmp_dest_unreach()
  • struct pbuf *p:目的不可達的pbuf包 。
  • enum icmp_dur_type t:目的不可達的原因 。
/** * Send an icmp 'destination unreachable' packet, called from ip_input() if * the transport layer protocol is unknown and from udp_input() if the local * port is not bound. * * @param p the input packet for which the 'unreachable' should be sent, *p->payload pointing to the IP header * @param t type of the 'unreachable' packet */voidicmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t){MIB2_STATS_INC(mib2.icmpoutdestunreachs);icmp_send_response(p, ICMP_DUR, t);}

經(jīng)驗總結(jié)擴展閱讀