int test_mf(void) { u_char bytes[ETH_FRAME_LEN]; struct icmphdr ih; build_eth_header(DEFAULT_DST_MAC, DEFAULT_SRC_MAC, 42, ETH_P_IP, bytes); // add IP header. build_ip_header(*DEFAULT_SRC_IP, *DEFAULT_DST_IP, 64, 1, bytes); *(uint16_t*)(bytes + IP_O_FRAG_OFF) = 0x20; // MF ih.type = 8; ih.code = 0; ih.checksum = 0; ih.un.echo.id = 0x4343; ih.un.echo.sequence = 0x4242; // copy into place memcpy(bytes + ICMP_START, &ih, sizeof(ih)); // add some payload memcpy(bytes + ICMP_DATA, "\xbd\x3b\x78\xf8\xbc\x28\x41\x0f\xf7\xcd\x55\x91\xce\xa8\xe7\xac\xb3\xfe\x56\xd0\x6c\xa2\x1d\x41\xc9\x15\x8e\x74\xa0\x09\x4d\x2a\xe8\xd9\x76\xd9\x0c\x10\xb9\x65\x42\x11\xc9\x58\xbe\xce\x90\x89\x67\xaa\x56\xfa\xb7\x5e\xc0\xd0", 56); // checksum ip_checksum(bytes + ICMP_START, sizeof(ih) + 56, (uint16_t*)(bytes + ICMP_START + 2)); // let's see what we get do_pak_handler(bytes, 100 + 2*config.vlan); if (test_result_len) { test_log("did not expect reply"); return 1; } return 0; }
void ping_send(t_env *env) { t_packet packet; struct timeval tv; ssize_t sended; env->count++; if (env->v && !env->has_received && env->count != 1) { printf("%lu bytes from %s: type=%d code=%d\n", sizeof(t_packet) - sizeof(struct iphdr), env->ip, 11, 0); } env->has_received = 0; if (gettimeofday(&tv, NULL)) { ft_putendl_fd("Can't gettimeofday", 2); exit(EXIT_FAILURE); } ft_memcpy(packet.data, &tv, sizeof(tv)); build_ip_header(env, &packet.ip_header); build_icmp_header(env, &packet.icmp_header); if ((sended = sendto(env->socket, &packet, sizeof(packet), MSG_CONFIRM, env->addr, env->addrlen)) == -1) { ft_putnbr(errno); ft_putendl_fd("ft_ping: can't send packet", 2); exit(EXIT_FAILURE); } env->last_send = epoch_micro(); }
int test_udp_cisco_init(void) { u_char bytes[ETH_FRAME_LEN],*ptr; struct udphdr uh; struct timespec ts; memset(bytes, 0, ETH_FRAME_LEN); build_eth_header(DEFAULT_DST_MAC, DEFAULT_SRC_MAC, 42, ETH_P_IP, bytes); build_ip_header(*DEFAULT_SRC_IP, *DEFAULT_DST_IP, 32, 17, bytes); ptr = bytes + ip_start + sizeof(struct ip); uh.source = htons(4242); uh.dest = htons(1967); // packet has 8 bytes of data and 24 bytes of payload uh.len = htons(32); uh.check = 0; // put it in place memcpy(ptr, &uh, sizeof(uh)); ptr += sizeof(uh); // put in the actual data *(ptr) = 0x01; memcpy(ptr+0x10, DEFAULT_DST_IP, 4); *((unsigned short*)(ptr+0x14)) = htons(50505); // actual testing port // then calculate checksum tcp4_checksum((u_char*)DEFAULT_SRC_IP, (u_char*)DEFAULT_DST_IP, 0x11, bytes+UDP_START, 32, (unsigned short*)(bytes+UDP_START+0x06)); // and that's it. do_pak_handler(bytes, 66 + eth_o_vlan); // did we get anything? if (test_result_len != 66 + eth_o_vlan) { test_log("result is not %u bytes long as expected, was %lu", 70, test_result_len); return 1; } if (assert_ip(test_result_buffer, *DEFAULT_DST_IP, *DEFAULT_SRC_IP, 32, 17)) return 1; // checksum check tcp4_checksum((u_char*)DEFAULT_SRC_IP, (u_char*)DEFAULT_DST_IP, 0x11, test_result_buffer+UDP_START, 32, (unsigned short*)(test_result_buffer+UDP_START+0x06)); if (*((unsigned short*)(test_result_buffer+UDP_START+0x06)) != 0x0) { test_log("invalid TCP checksum, ended up with %02x", (unsigned short*)(test_result_buffer+UDP_START+0x06)); return 1; } // check that something nice was sent. if (*(test_result_buffer + UDP_DATA + 0x03) != 0x08 || memcmp(test_result_buffer + UDP_DATA + 0x04, "\0\0\0\0\0\0\0\0", 8)) { test_log("invalid response - check your code"); return 1; } return 0; }
int test_df(void) { u_char bytes[ETH_FRAME_LEN]; struct icmphdr ih; build_eth_header(DEFAULT_DST_MAC, DEFAULT_SRC_MAC, 42, ETH_P_IP, bytes); // add IP header. build_ip_header(*DEFAULT_SRC_IP, *DEFAULT_DST_IP, 64, 1, bytes); *(uint16_t*)(bytes + IP_O_FRAG_OFF) = 0x40; // DF ih.type = 8; ih.code = 0; ih.checksum = 0; ih.un.echo.id = 0x4343; ih.un.echo.sequence = 0x4242; // copy into place memcpy(bytes + ICMP_START, &ih, sizeof(ih)); // add some payload memcpy(bytes + ICMP_DATA, "\xbd\x3b\x78\xf8\xbc\x28\x41\x0f\xf7\xcd\x55\x91\xce\xa8\xe7\xac\xb3\xfe\x56\xd0\x6c\xa2\x1d\x41\xc9\x15\x8e\x74\xa0\x09\x4d\x2a\xe8\xd9\x76\xd9\x0c\x10\xb9\x65\x42\x11\xc9\x58\xbe\xce\x90\x89\x67\xaa\x56\xfa\xb7\x5e\xc0\xd0", 56); // checksum ip_checksum(bytes + ICMP_START, sizeof(ih) + 56, (uint16_t*)(bytes + ICMP_START + 2)); // let's see what we get do_pak_handler(bytes, 100 + 2*config.vlan); if (test_result_len != 100 + 2*config.vlan) { test_log("result is not 102 bytes long as expected, was %lu", test_result_len); return 1; } if (assert_ip(test_result_buffer, *DEFAULT_DST_IP, *DEFAULT_SRC_IP, 64, 1)) return 1; // check that all is good. ip_checksum(test_result_buffer + ICMP_START, sizeof(ih) + 56, (uint16_t*)(test_result_buffer + ICMP_START + 2)); memcpy(&ih, test_result_buffer + ICMP_START, sizeof ih); if (ih.checksum != 0) { test_log("ICMP packet checksum wrong"); return 1; } if (ih.type != 0) { test_log("unexpected ICMP type in response"); return 1; } if (ih.code != 0) { test_log("unexpected ICMP code in response"); return 1; } if (ih.un.echo.id != 0x4343) { test_log("wrong ICMP echo id"); return 1; } if (ih.un.echo.sequence != 0x4242) { test_log("wrong ICMP echo sequence"); return 1; } // check payload return memcmp(test_result_buffer + ICMP_DATA, "\xbd\x3b\x78\xf8\xbc\x28\x41\x0f\xf7\xcd\x55\x91\xce\xa8\xe7\xac\xb3\xfe\x56\xd0\x6c\xa2\x1d\x41\xc9\x15\x8e\x74\xa0\x09\x4d\x2a\xe8\xd9\x76\xd9\x0c\x10\xb9\x65\x42\x11\xc9\x58\xbe\xce\x90\x89\x67\xaa\x56\xfa\xb7\x5e\xc0\xd0", 56); }
int test_udp_cisco_jitter_type_3(void) { u_char bytes[ETH_FRAME_LEN],*ptr; struct udphdr uh; struct timespec ts; uint32_t t2, t3; memset(bytes, 0, ETH_FRAME_LEN); build_eth_header(DEFAULT_DST_MAC, DEFAULT_SRC_MAC, 42, ETH_P_IP, bytes); build_ip_header(*DEFAULT_SRC_IP, *DEFAULT_DST_IP, 40, 17, bytes); ptr = bytes + ip_start + sizeof(struct ip); uh.source = htons(4242); uh.dest = htons(50505); // packet has 8 bytes of data and 32 bytes of payload uh.len = htons(40); uh.check = 0; // put it in place memcpy(ptr, &uh, sizeof(uh)); ptr += sizeof(uh); clock_gettime(CLOCK_REALTIME, &ts); // put in the actual data, microseconds *(uint16_t*)(ptr) = htons(3); ts_to_ntp(&ts, &t2, &t3); *(uint32_t*)(ptr+0x4) = t2; *(uint32_t*)(ptr+0x8) = t3; *(uint16_t*)(ptr+0x34) = 0x123; // then calculate checksum tcp4_checksum((u_char*)DEFAULT_SRC_IP, (u_char*)DEFAULT_DST_IP, 0x11, bytes+UDP_START, 40, (unsigned short*)(bytes+UDP_START+0x06)); // and that's it. // emulate 0.1s delay usleep(10000); do_pak_handler(bytes, 74 + eth_o_vlan); // did we get anything? if (test_result_len != 74 + eth_o_vlan) { test_log("result is not %u bytes long as expected, was %lu", 74 + eth_o_vlan, test_result_len); return 1; } if (assert_ip(test_result_buffer, *DEFAULT_DST_IP, *DEFAULT_SRC_IP, 40, 17)) return 1; // checksum check tcp4_checksum((u_char*)DEFAULT_SRC_IP, (u_char*)DEFAULT_DST_IP, 0x11, test_result_buffer+UDP_START, 40, (unsigned short*)(test_result_buffer+UDP_START+0x06)); if (*((unsigned short*)(test_result_buffer+UDP_START+0x06)) != 0x0) { test_log("invalid TCP checksum, ended up with %02x", (unsigned short*)(test_result_buffer+UDP_START+0x06)); return 1; } // check that sequence number is correct if (*(uint16_t*)(test_result_buffer + UDP_DATA + 0x34) != *(uint16_t*)(test_result_buffer + UDP_DATA + 0x36)) { test_log("got invalid sequence number, expected %02x, got %02x", *(uint16_t*)(test_result_buffer + UDP_DATA + 0x34), *(uint16_t*)(test_result_buffer + UDP_DATA + 0x36)); return 1; } // check that timestamp is bigger if (ntohl(*(uint32_t*)(test_result_buffer + UDP_DATA + 0x4)) >= ntohl(*(uint32_t*)(test_result_buffer + UDP_DATA + 0xC)) && ntohl(*(uint32_t*)(test_result_buffer + UDP_DATA + 0x8)) >= ntohl(*(uint32_t*)(test_result_buffer + UDP_DATA + 0x10))) { test_log("t1 timestamp was larger than t2 timestamp"); return 1; } return 0; }
int test_udp_cisco_echo(void) { u_char bytes[ETH_FRAME_LEN],*ptr; struct udphdr uh; struct timespec ts; memset(bytes, 0, ETH_FRAME_LEN); build_eth_header(DEFAULT_DST_MAC, DEFAULT_SRC_MAC, 42, ETH_P_IP, bytes); build_ip_header(*DEFAULT_SRC_IP, *DEFAULT_DST_IP, 40, 17, bytes); ptr = bytes + ip_start + sizeof(struct ip); uh.source = htons(4242); uh.dest = htons(50505); // packet has 8 bytes of data and 24 bytes of payload uh.len = htons(24); uh.check = 0; // put it in place memcpy(ptr, &uh, sizeof(uh)); ptr += sizeof(uh); // fill with UDP echo specific data *(uint16_t*)(ptr) = htons(1); *(uint16_t*)(ptr + 0x2) = 0; *(uint16_t*)(ptr + 0x4) = htons(24); memcpy(ptr + 0x6, "ABABABABAB", 10); // then calculate checksum tcp4_checksum((u_char*)DEFAULT_SRC_IP, (u_char*)DEFAULT_DST_IP, 0x11, bytes+UDP_START, 40, (unsigned short*)(bytes+UDP_START+0x06)); // and that's it. // emulate 0.1s delay usleep(10000); do_pak_handler(bytes, 58 + eth_o_vlan); // did we get anything? if (test_result_len != 58 + eth_o_vlan) { test_log("result is not %u bytes long as expected, was %lu", 58+eth_o_vlan, test_result_len); return 1; } if (assert_ip(test_result_buffer, *DEFAULT_DST_IP, *DEFAULT_SRC_IP, 40, 17)) return 1; // checksum check tcp4_checksum((u_char*)DEFAULT_SRC_IP, (u_char*)DEFAULT_DST_IP, 0x11, test_result_buffer+UDP_START, 16 + (UDP_DATA - UDP_START), (unsigned short*)(test_result_buffer+UDP_START+0x06)); if (*((unsigned short*)(test_result_buffer+UDP_START+0x06)) != 0x0) { test_log("invalid TCP checksum, ended up with %02x", (unsigned short*)(test_result_buffer+UDP_START+0x06)); return 1; } // make sure it matches ptr = test_result_buffer + UDP_DATA; if (*(uint16_t*)(ptr) != htons(1)) { test_log("invalid version number, expected 1, got %u", ntohs(*(uint16_t*)(ptr))); return 1; } if (memcmp(ptr + 0x6, "ABABABABAB", 10)) { test_log("invalid test pattern received"); return 1; } return 0; }
int test_icmp_timestamp(void) { u_char bytes[ETH_FRAME_LEN],*ptr; u_char fillval[] = "0123456789abcdef"; struct icmphdr ih; struct timespec ts; uint32_t tval; build_eth_header(DEFAULT_DST_MAC, DEFAULT_SRC_MAC, 42, ETH_P_IP, bytes); build_ip_header(*DEFAULT_SRC_IP, *DEFAULT_DST_IP, 64, 1, bytes); ptr = bytes + ip_start + sizeof(struct ip); // fill in the entire ICMP with 0123456789abcdef, then put in some stuff for(tval=0;tval<4;tval++) memcpy(ptr + tval*16, fillval, 16); ih.type = ICMP_TIMESTAMP; ih.code = 0; ih.checksum = 0; ih.un.echo.id = 0x4343; ih.un.echo.sequence = 0x4242; memcpy(ptr, &ih, sizeof(ih)); ptr += sizeof(ih); // toss in some stamps clock_gettime(CLOCK_REALTIME, &ts); tval = get_ts_utc(&ts); memcpy(ptr, &tval, 4); ptr += 4; tval = 0; memcpy(ptr, &tval, 4); ptr += 4; memcpy(ptr, &tval, 4); // checksum ip_checksum(bytes + ICMP_START, 64, (uint16_t*)(bytes + ICMP_START + 2)); // transmit // emulate 0.1s delay usleep(10000); do_pak_handler(bytes, 102); // did we get anything? if (test_result_len != 102) { test_log("result is not 102 bytes long as expected, was %lu", test_result_len); return 1; } if (assert_ip(test_result_buffer, *DEFAULT_DST_IP, *DEFAULT_SRC_IP, 64, 1)) return 1; ip_checksum(test_result_buffer + ip_start + sizeof(struct ip), sizeof(ih)+56, (uint16_t*)(test_result_buffer + ip_start + sizeof(struct ip) + 2)); memcpy(&ih, test_result_buffer + ip_start + sizeof(struct ip), sizeof ih); if (ih.checksum != 0) { test_log("ICMP packet checksum wrong"); return 1; } if (ih.type != ICMP_TIMESTAMPREPLY) { test_log("unexpected ICMP type in response"); return 1; } if (ih.code != 0) { test_log("unexpected ICMP code in response"); return 1; } if (ih.un.echo.id != 0x4343) { test_log("wrong ICMP echo id"); return 1; } if (ih.un.echo.sequence != 0x4242) { test_log("wrong ICMP echo sequence"); return 1; } // ensure that the originate timestamp <= recv timestamp <= transmit timestamp if (*(uint32_t*)(test_result_buffer + ICMP_DATA) > *(uint32_t*)(test_result_buffer + ICMP_DATA + 0x4) || *(uint32_t*)(test_result_buffer + ICMP_DATA) > *(uint32_t*)(test_result_buffer + ICMP_DATA + 0x8) || *(uint32_t*)(test_result_buffer + ICMP_DATA + 0x4) > *(uint32_t*)(test_result_buffer + ICMP_DATA + 0x8)) { test_log("originate <= receive <= transmit did not match: got %08x <= %08x <= %08x", *(uint32_t*)(test_result_buffer + ICMP_DATA), *(uint32_t*)(test_result_buffer + ICMP_DATA + 0x4), *(uint32_t*)(test_result_buffer + ICMP_DATA + 0x8)); return 1; } return 0; }
int test_junos_icmp_rpm(void) { u_char bytes[ETH_FRAME_LEN],*ptr; struct icmphdr ih; struct timespec ts; uint32_t tval; build_eth_header(DEFAULT_DST_MAC, DEFAULT_SRC_MAC, 42, ETH_P_IP, bytes); build_ip_header(*DEFAULT_SRC_IP, *DEFAULT_DST_IP, 64, 1, bytes); ptr = bytes + ip_start + sizeof(struct ip); ih.type = ICMP_TIMESTAMP; ih.code = 0; ih.checksum = 0; ih.un.echo.id = 0x4343; ih.un.echo.sequence = 0x4242; memcpy(ptr, &ih, sizeof(ih)); ptr += sizeof(ih); // toss in some stamps clock_gettime(CLOCK_REALTIME, &ts); tval = get_ts_utc(&ts); memcpy(ptr, &tval, 4); ptr += 4; tval = 0; memcpy(ptr, &tval, 4); ptr += 4; memcpy(ptr, &tval, 4); // then we add some junos specific stuff ptr += 20; memcpy(ptr, "\x00\x01\x96\x10", 4); ptr += 8; // put a stamp here... memcpy(ptr, "\x01\x02\x03\x04\x05\x06\x07\x08", 8); // checksum ip_checksum(bytes + ICMP_START, 64, (uint16_t*)(bytes + ICMP_START + 2)); // transmit // emulate 0.1s delay usleep(10000); do_pak_handler(bytes, 102); // did we get anything? if (test_result_len != 102) { test_log("result is not 102 bytes long as expected, was %lu", test_result_len); return 1; } if (assert_ip(test_result_buffer, *DEFAULT_DST_IP, *DEFAULT_SRC_IP, 64, 1)) return 1; ip_checksum(test_result_buffer + ip_start + sizeof(struct ip), sizeof(ih)+56, (uint16_t*)(test_result_buffer + ip_start + sizeof(struct ip) + 2)); memcpy(&ih, test_result_buffer + ip_start + sizeof(struct ip), sizeof ih); if (ih.checksum != 0) { test_log("ICMP packet checksum wrong"); return 1; } if (ih.type != ICMP_TIMESTAMPREPLY) { test_log("unexpected ICMP type in response"); return 1; } if (ih.code != 0) { test_log("unexpected ICMP code in response"); return 1; } if (ih.un.echo.id != 0x4343) { test_log("wrong ICMP echo id"); return 1; } if (ih.un.echo.sequence != 0x4242) { test_log("wrong ICMP echo sequence"); return 1; } // ensure that the originate timestamp <= recv timestamp <= transmit timestamp if (*(uint32_t*)(test_result_buffer + ICMP_DATA) > *(uint32_t*)(test_result_buffer + ICMP_DATA + 0x4) || *(uint32_t*)(test_result_buffer + ICMP_DATA) > *(uint32_t*)(test_result_buffer + ICMP_DATA + 0x8) || *(uint32_t*)(test_result_buffer + ICMP_DATA + 0x4) > *(uint32_t*)(test_result_buffer + ICMP_DATA + 0x8)) { test_log("originate <= receive <= transmit did not match: got %08x <= %08x <= %08x", *(uint32_t*)(test_result_buffer + ICMP_DATA), *(uint32_t*)(test_result_buffer + ICMP_DATA + 0x4), *(uint32_t*)(test_result_buffer + ICMP_DATA + 0x8)); return 1; } // ensure that we have some stamp in junos reply if (*(uint64_t*)(test_result_buffer + ICMP_DATA + 0x24) == 0) { test_log("missing hardware timestamp in reply"); return 1; } return 0; }
uint8_t * build_ip_udp_pcket(uint8_t *orig_pkt, int orig_pkt_len,lisp_addr_t *addr_from, lisp_addr_t *addr_dest, int port_from,int port_dest, int *encap_pkt_len) { uint8_t *encap_pkt; void *iph_ptr; struct udphdr *udph_ptr; int ip_hdr_len; int udp_hdr_len; int udp_hdr_and_payload_len; uint16_t udpsum; if (lisp_addr_ip_afi(addr_from) != lisp_addr_ip_afi(addr_dest)) { OOR_LOG(LDBG_2, "add_ip_udp_header: Different AFI addresses %d (%s) and %d (%s)", lisp_addr_ip_afi(addr_from), lisp_addr_to_char(addr_from), lisp_addr_ip_afi(addr_dest), lisp_addr_to_char(addr_dest)); return (NULL); } if ((lisp_addr_ip_afi(addr_from) != AF_INET) && (lisp_addr_ip_afi(addr_from) != AF_INET6)) { OOR_LOG(LDBG_2, "add_ip_udp_header: Unknown AFI %d", lisp_addr_ip_afi(addr_from)); return (NULL); } /* Headers lengths */ ip_hdr_len = ip_sock_afi_to_hdr_len(lisp_addr_ip_afi(addr_from)); udp_hdr_len = sizeof(struct udphdr); udp_hdr_and_payload_len = udp_hdr_len + orig_pkt_len; /* Assign memory for the original packet plus the new headers */ *encap_pkt_len = ip_hdr_len + udp_hdr_len + orig_pkt_len; if ((encap_pkt = (uint8_t *) malloc(*encap_pkt_len)) == NULL) { OOR_LOG(LDBG_2, "add_ip_udp_header: Couldn't allocate memory for the packet to be generated %s", strerror(errno)); return (NULL); } /* Make sure it's clean */ memset(encap_pkt, 0, *encap_pkt_len); /* IP header */ iph_ptr = encap_pkt; if ((udph_ptr = build_ip_header(iph_ptr, addr_from, addr_dest, udp_hdr_and_payload_len)) == NULL) { OOR_LOG(LDBG_2, "add_ip_udp_header: Couldn't build the inner ip header"); free(encap_pkt); return (NULL); } /* UDP header */ #ifdef BSD udph_ptr->uh_sport = htons(port_from); udph_ptr->uh_dport = htons(port_dest); udph_ptr->uh_ulen = htons(udp_payload_len); udph_ptr->uh_sum = 0; #else udph_ptr->source = htons(port_from); udph_ptr->dest = htons(port_dest); udph_ptr->len = htons(udp_hdr_and_payload_len); udph_ptr->check = 0; #endif /* Copy original packet after the headers */ memcpy(CO(udph_ptr, udp_hdr_len), orig_pkt, orig_pkt_len); /* * Now compute the headers checksums */ if ((udpsum = udp_checksum(udph_ptr, udp_hdr_and_payload_len, iph_ptr, lisp_addr_ip_afi(addr_from))) == -1) { free(encap_pkt); return (NULL); } udpsum(udph_ptr) = udpsum; return (encap_pkt); }