void test_icmp_checksum(void) { struct icmphdr header; CU_ASSERT_EQUAL(icmp_checksum(NULL), -1); CU_ASSERT_EQUAL(icmp_checksum(&header), 0); }
// ------------------------------------------------ // Function: ping_request() // ------------------------------------------------ // Input: IP address // Network interface ID // Output: - // ------------------------------------------------ // Description: Sends a ping request message // ------------------------------------------------ void ping_request(IPV4 ip, BYTE interface) { PPBUF buf; buf = ip_new(ip, 64, interface); if(buf == NULL) return; // --------------------- // assemble ICMP message // --------------------- IPH(buf->start)->prot = IP_PROT_ICMP; ICMP(buf->data)->type = PING_REQUEST; ICMP(buf->data)->code = 0; ICMP(buf->data)->checksum = 0; ICMP(buf->data)->id = random(); ICMP(buf->data)->seq = random(); buf->size = sizeof(ICMP_HDR); // ------------------ // calculate checksum // ------------------ icmp_checksum(buf->data, buf->size); ICMP(buf->data)->checksum = HTONS(~WORDOF(chk_H, chk_L)); // ----------------------------- // sends message to IP interface // ----------------------------- ip_send(buf); release_buffer(buf); }
// ------------------------------------------------ // Function: icmp_parse() // ------------------------------------------------ // Input: Message buffer // Output: - // ------------------------------------------------ // Description: Parse a ICMP message // ------------------------------------------------ void icmp_parse(PPBUF pbuf) { // --------------------- // checksum verification // --------------------- icmp_checksum(pbuf->data, pbuf->size); if(chk_H != 0xff) return; if(chk_L != 0xff) return; // ------------------------------- // checks recognized message types // ------------------------------- switch(ICMP(pbuf->data)->type) { case PING_REQUEST: // --------- // answer it // --------- retain_buffer(pbuf); ip_answer(pbuf); ICMP(pbuf->data)->type = PING_REPLY; // --------------- // update checksum // --------------- ICMP(pbuf->data)->checksum = 0; icmp_checksum(pbuf->data, pbuf->size); ICMP(pbuf->data)->checksum = HTONS(~WORDOF(chk_H, chk_L)); // ---------------------------- // sends answer to IP interface // ---------------------------- ip_send(pbuf); release_buffer(pbuf); break; case PING_REPLY: // -------------------------------------- // answer received, signal waiting thread // -------------------------------------- os_signal(SIG_ICMP); break; } }
static size_t __icmp_gen(icmp_hdr_t *hdr, uint8_t type, uint8_t code, size_t dlen) { size_t len; hdr->type = type; hdr->code = code; len = sizeof(icmp_hdr_t) + dlen; icmp_checksum(hdr, len); debug(ICMP, "snd ICMP %s rest 0x%x\n", __icmp_type_str(type), hdr->rest); return len; }