int icmp_generic_decode (unsigned char * buffer, size_t bufsize, struct ip **ipp, icmphdr_t ** icmpp) { size_t hlen; unsigned short cksum; struct ip *ip; icmphdr_t *icmp; /* IP header */ ip = (struct ip *) buffer; hlen = ip->ip_hl << 2; if (bufsize < hlen + ICMP_MINLEN) return -1; /* ICMP header */ icmp = (icmphdr_t *) (buffer + hlen); /* Prepare return values */ *ipp = ip; *icmpp = icmp; /* Recompute checksum */ cksum = icmp->icmp_cksum; icmp->icmp_cksum = 0; icmp->icmp_cksum = icmp_cksum ((unsigned char *) icmp, bufsize - hlen); if (icmp->icmp_cksum != cksum) return 1; return 0; }
/******************************************************************************* 函数名称 : healthy_check_set_ping_data 功能描述 : ping 报数据组装函数 输入参数 : hc_ping_s *ping_cfg: 当前检测ip 配置 u32 seqno : ping 报序号 输出参数 : 无 返回值 : 无 -------------------------------------------------------------------------------- 最近一次修改记录 : 修改作者 : 王宗发 修改目的 : 新增函数 修改日期 : 20101020 ********************************************************************************/ void healthy_check_set_ping_data(hc_ping_s *ping_cfg, u32 seqno) { struct timeval tv; struct icmp6_hdr *icmp6 = NULL; gettimeofday (&tv, NULL); ping_cfg->start_time = tv; icmp6 = (struct icmp6_hdr *) ping_cfg->ping_buf; icmp6->icmp6_cksum = 0; icmp6->icmp6_seq = seqno + 1; /*在icmp报中记录发送时间*/ memcpy((u8 *)icmp6 + sizeof(struct icmp6_hdr), &tv, sizeof(struct timeval)); icmp6->icmp6_cksum = icmp_cksum ((u8 *)(ping_cfg->ping_buf), (s32)(ping_cfg->buf_len)); return; }
int icmp_generic_encode (unsigned char * buffer, size_t bufsize, int type, int ident, int seqno) { icmphdr_t *icmp; if (bufsize < ICMP_MINLEN) return -1; icmp = (icmphdr_t *) buffer; icmp->icmp_type = type; icmp->icmp_code = 0; icmp->icmp_cksum = 0; icmp->icmp_seq = htons (seqno); icmp->icmp_id = htons (ident); icmp->icmp_cksum = icmp_cksum (buffer, bufsize); return 0; }
static void icmp_unexpect_ttl(uint8_t *icmp_packet, struct ofputil_packet_in *pi, uint8_t header_len, uint8_t type, uint8_t code, uint32_t info) { uint16_t total_len = sizeof(struct iphdr) + sizeof(struct icmphdr) + header_len + 8; uint8_t *old_payload = pi->packet; struct ethhdr * old_eth = (struct ethhdr *)old_payload; struct ethhdr * new_eth = (struct ethhdr *)icmp_packet; memcpy(new_eth->h_source, old_eth->h_dest, sizeof(struct eth_addr)); memcpy(new_eth->h_dest, old_eth->h_source, sizeof(struct eth_addr)); new_eth->h_proto = htons(ETH_P_IP); struct iphdr * old_ipv4 = (struct iphdr *) (old_eth + 1); struct iphdr * new_ipv4 = (struct iphdr *) (new_eth + 1); new_ipv4->ihl = 0x5; new_ipv4->version = 0x4; new_ipv4->tos = old_ipv4->tos; new_ipv4->tot_len = htons(total_len); ip_ident_seed += 27; new_ipv4->id = htons(ip_ident_seed); new_ipv4->frag_off = 0; new_ipv4->ttl = 64; new_ipv4->protocol = IPPROTO_ICMP; new_ipv4->check = 0; new_ipv4->saddr = saddr.s_addr; new_ipv4->daddr = old_ipv4->saddr; new_ipv4->check = ipv4_cksum(new_ipv4); struct icmphdr * icmp = (struct icmphdr *) (new_ipv4 + 1); icmp->type = type; icmp->code = code; icmp->un.gateway = info; icmp->checksum = 0; uint8_t *payload = (uint8_t *)(icmp + 1); old_payload += sizeof(struct ethhdr); memcpy(payload, old_payload, 8 + header_len); icmp->checksum = icmp_cksum(total_len - sizeof(struct iphdr), (struct icmphdr const*) icmp); return; }