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 main (int argc, char **argv) { fct_init(); /* A captured sFlow datagram (#14) */ u_int32_t packet[] = { htonl(0x00000005), htonl(0x00000001), htonl(0xb2116ff2), htonl(0x00000010), htonl(0x00002eb2), htonl(0x55f10676), htonl(0x00000006), htonl(0x00000001), htonl(0x000000d0), htonl(0x00003bc4), htonl(0x000001fd), htonl(0x000003e8), htonl(0x00e971b8), htonl(0x00000000), htonl(0x000001fd), htonl(0x00000000), htonl(0x00000002), htonl(0x00000001), htonl(0x00000090), htonl(0x00000001), htonl(0x00000552), htonl(0x00000004), htonl(0x00000080), htonl(0x01005e31), htonl(0x1af56c9c), htonl(0xed6213d6), htonl(0x08004500), htonl(0x054034d9), htonl(0x40003a11), htonl(0x7b3ad460), htonl(0xb312e931), htonl(0x1af5090a), htonl(0x090a052c), htonl(0x00004700), htonl(0x651ee36d), htonl(0x579e13dc), htonl(0x65de7811), htonl(0x377a5cf7), htonl(0x9e21eba7), htonl(0x0f8ebcf1), htonl(0x0ecfa7d7), htonl(0xef1810a4), htonl(0x4da7bcf3), htonl(0x3b8dbae7), htonl(0x8a9ef3c1), htonl(0x3bb875e7), htonl(0x9ab9ef3c), htonl(0x17d73cf7), htonl(0x9e06eee7), htonl(0x9ef3c73a), htonl(0xd194e203), htonl(0x01dea7f6), htonl(0xa8da1200), htonl(0x00000108), htonl(0x33cfb36f), htonl(0x000003e9), htonl(0x00000010), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000001), htonl(0x000000d0), htonl(0x00003bc5), htonl(0x000001fd), htonl(0x000003e8), htonl(0x00e975a0), htonl(0x00000000), htonl(0x000001fd), htonl(0x00000000), htonl(0x00000002), htonl(0x00000001), htonl(0x00000090), htonl(0x00000001), htonl(0x00000552), htonl(0x00000004), htonl(0x00000080), htonl(0x01005e31), htonl(0x1a8f6c9c), htonl(0xed6213d6), htonl(0x08004500), htonl(0x0540394a), htonl(0x40003a11), htonl(0x772fd460), htonl(0xb312e931), htonl(0x1a8f090a), htonl(0x090a052c), htonl(0x00004700), htonl(0x65125e8a), htonl(0x2878413c), htonl(0xa8569182), htonl(0x2f223570), htonl(0x558b4499), htonl(0x27625ad6), htonl(0xbabafb77), htonl(0x8d556e64), htonl(0xf68b6690), htonl(0x85d0d9ac), htonl(0x491de099), htonl(0x2159c756), htonl(0xeb74a2a5), htonl(0x7e019e40), htonl(0xc90f57bc), htonl(0x1e66e5b4), htonl(0x9522a3dc), htonl(0x301446f8), htonl(0x31f31f3f), htonl(0xdbf78329), htonl(0x9baf89b3), htonl(0x000003e9), htonl(0x00000010), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000001), htonl(0x000000d0), htonl(0x00003bc6), htonl(0x000001fd), htonl(0x000003e8), htonl(0x00e97988), htonl(0x00000000), htonl(0x000001fd), htonl(0x00000000), htonl(0x00000002), htonl(0x00000001), htonl(0x00000090), htonl(0x00000001), htonl(0x00000552), htonl(0x00000004), htonl(0x00000080), htonl(0x01005e31), htonl(0x1a686c9c), htonl(0xed6213d6), htonl(0x08004500), htonl(0x05403d93), htonl(0x40003a11), htonl(0x730dd460), htonl(0xb312e931), htonl(0x1a68090a), htonl(0x090a052c), htonl(0x00004700), htonl(0x651a8c9a), htonl(0xc8698831), htonl(0x20740075), htonl(0x1608600a), htonl(0x0640060e), htonl(0x40788603), htonl(0x003203a0), htonl(0x13815260), htonl(0x0d9060d2), htonl(0xf93129c1), htonl(0x078b801a), htonl(0x803a02a0), htonl(0x06600d80), htonl(0x3302843f), htonl(0x80789fb7), htonl(0x0941c6a3), htonl(0xde806e8e), htonl(0x02941392), htonl(0x19c82dc8), htonl(0x14383213), htonl(0x01007408), htonl(0x000003e9), htonl(0x00000010), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000001), htonl(0x000000d0), htonl(0x00003bc7), htonl(0x000001fd), htonl(0x000003e8), htonl(0x00e97d70), htonl(0x00000000), htonl(0x000001fd), htonl(0x00000000), htonl(0x00000002), htonl(0x00000001), htonl(0x00000090), htonl(0x00000001), htonl(0x00000552), htonl(0x00000004), htonl(0x00000080), htonl(0x01005e31), htonl(0x1a486c9c), htonl(0xed6213d6), htonl(0x08004500), htonl(0x05409771), htonl(0x40003a11), htonl(0x194ed460), htonl(0xb313e931), htonl(0x1a48090a), htonl(0x090a052c), htonl(0x00004700), htonl(0x65120000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x000003e9), htonl(0x00000010), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000001), htonl(0x000000d0), htonl(0x00003bc8), htonl(0x000001fd), htonl(0x000003e8), htonl(0x00e98158), htonl(0x00000000), htonl(0x000001fd), htonl(0x00000000), htonl(0x00000002), htonl(0x00000001), htonl(0x00000090), htonl(0x00000001), htonl(0x00000552), htonl(0x00000004), htonl(0x00000080), htonl(0x01005e31), htonl(0x1aa16c9c), htonl(0xed6213d6), htonl(0x08004500), htonl(0x05404682), htonl(0x40003a11), htonl(0x69e5d460), htonl(0xb312e931), htonl(0x1aa1090a), htonl(0x090a052c), htonl(0x00004700), htonl(0x6519ccaf), htonl(0x5e165667), htonl(0x3a001dc5), htonl(0x5faf0000), htonl(0x01081b5e), htonl(0x6563af95), htonl(0xebd15aaf), htonl(0x95baf95b), htonl(0xaf656ebc), htonl(0xcac3d7a2), htonl(0xb0000001), htonl(0x091b5f2b), htonl(0x0d5e8af5), htonl(0xecadd7ca), htonl(0xdd7cac75), htonl(0xe656339d), htonl(0x807d6bcc), htonl(0xac000001), htonl(0x0a1b5e8a), htonl(0xc55e32b2), htonl(0xaf95baf6), htonl(0x000003e9), htonl(0x00000010), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000001), htonl(0x000000d0), htonl(0x00003bc9), htonl(0x000001fd), htonl(0x000003e8), htonl(0x00e98540), htonl(0x00000000), htonl(0x000001fd), htonl(0x00000000), htonl(0x00000002), htonl(0x00000001), htonl(0x00000090), htonl(0x00000001), htonl(0x00000552), htonl(0x00000004), htonl(0x00000080), htonl(0x01005e31), htonl(0x1a906c9c), htonl(0xed6213d6), htonl(0x08004500), htonl(0x05404acb), htonl(0x40003a11), htonl(0x65add460), htonl(0xb312e931), htonl(0x1a90090a), htonl(0x090a052c), htonl(0x00004700), htonl(0x651baafe), htonl(0x0bdedfbc), htonl(0xbd602300), htonl(0x2174c3ce), htonl(0x4b2371b8), htonl(0xe6ffdcf5), htonl(0x786be4e8), htonl(0xc0fd26c2), htonl(0xeed3a46f), htonl(0x4c46f9a6), htonl(0x5db1ca70), htonl(0x79466014), htonl(0xad3298d5), htonl(0x0bb5be20), htonl(0x069402c7), htonl(0xf3a2f740), htonl(0x8b297b99), htonl(0x605378ac), htonl(0xccd10ea4), htonl(0x352cb6f5), htonl(0xc00eb400), htonl(0x000003e9), htonl(0x00000010), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000), htonl(0x00000000) }; sflow_sample_data_t *sample = NULL; sflow_flow_record_t *record = NULL; sflow_raw_header_t *header = NULL; struct sockaddr_storage ss; assert_int(1, next_sample(&packet, sizeof (packet), &sample), "Load sample #1"); assert_int(1, is_sample_format(sample, FLOW_SAMPLE), "Sample #1: format"); assert_int(15300, ntohl(((sflow_flow_sample_t *) (sample + 1))->sequence_number), "Sample #1: seq_number"); assert_int(1, next_record(sample, &record), "Load record #1:1"); assert_int(1, is_record_format(record, RAW_HEADER), "Record #1:1: format"); header = (sflow_raw_header_t *) (record + 1); assert_int(1, get_source(header, &ss), "Record #1:1: Loading source address"); assert_ip("212.96.179.18", &ss, "Record #1:1: Source address"); assert_int(1, get_destination(header, &ss), "Record #1:1: Loading destination address"); assert_ip("233.49.26.245", &ss, "Record #1:1: Destination address"); assert_int(1, next_record(sample, &record), "Load record #1:2"); assert_int(0, is_record_format(record, RAW_HEADER), "Record #1:2: format"); assert_int(0, next_record(sample, &record), "Record #1:3 should fail"); assert_int(1, next_sample(&packet, sizeof (packet), &sample), "Load sample #2"); assert_int(1, is_sample_format(sample, FLOW_SAMPLE), "Sample #2: format"); assert_int(15301, ntohl(((sflow_flow_sample_t *) (sample + 1))->sequence_number), "Sample #2: seq_number"); assert_int(1, next_sample(&packet, sizeof (packet), &sample), "Load sample #3"); assert_int(1, is_sample_format(sample, FLOW_SAMPLE), "Sample #3: format"); assert_int(15302, ntohl(((sflow_flow_sample_t *) (sample + 1))->sequence_number), "Sample #3: seq_number"); assert_int(1, next_sample(&packet, sizeof (packet), &sample), "Load sample #4"); assert_int(1, is_sample_format(sample, FLOW_SAMPLE), "Sample #4: format"); assert_int(15303, ntohl(((sflow_flow_sample_t *) (sample + 1))->sequence_number), "Sample #4: seq_number"); assert_int(1, next_sample(&packet, sizeof (packet), &sample), "Load sample #5"); assert_int(1, is_sample_format(sample, FLOW_SAMPLE), "Sample #5: format"); assert_int(15304, ntohl(((sflow_flow_sample_t *) (sample + 1))->sequence_number), "Sample #5: seq_number"); assert_int(1, next_sample(&packet, sizeof (packet), &sample), "Load sample #6"); assert_int(1, is_sample_format(sample, FLOW_SAMPLE), "Sample #6: format"); assert_int(15305, ntohl(((sflow_flow_sample_t *) (sample + 1))->sequence_number), "Sample #6: seq_number"); assert_int(0, next_sample(&packet, sizeof (packet), &sample), "Sample #7 should fail"); fct_send(); return 0; }
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; }