From 12a752750c3d21c30cb16062aa8e51b3e96e2e9e Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 3 Aug 2015 14:16:35 +0200 Subject: [PATCH] try sending ipv6 llmnr request --- test/pts/bnep_test.c | 176 ++++++++++++++++++++++++++++++------------- 1 file changed, 124 insertions(+), 52 deletions(-) diff --git a/test/pts/bnep_test.c b/test/pts/bnep_test.c index 43f844225..17cc0c88e 100644 --- a/test/pts/bnep_test.c +++ b/test/pts/bnep_test.c @@ -73,8 +73,10 @@ #define NETWORK_TYPE_ARP 0x0806 #define NETWORK_TYPE_IPv6 0x86DD -#define IPv4_PROTOCOL_ICMP 0x0001 -#define IPv4_PROTOCOL_UDP 0x0011 +#define IP_PROTOCOL_ICMP_IPv4 0x0001 +#define IP_PROTOCOL_ICMP_IPv6 0x003a +#define IP_PROTOCOL_UDP 0x0011 +#define IPv4_ #define ICMP_V4_TYPE_PING_REQUEST 0x08 #define ICMP_V4_TYPE_PING_RESPONSE 0x00 @@ -96,8 +98,10 @@ static bd_addr_t pts_addr = {0x00,0x1b,0xDC,0x07,0x32,0xEF}; //static bd_addr_t pts_addr = {0xE0,0x06,0xE6,0xBB,0x95,0x79}; // Ole Thinkpad // static bd_addr_t other_addr = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x16}; static bd_addr_t other_addr = { 0,0,0,0,0,0}; + // broadcast static bd_addr_t broadcast_addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +// static bd_addr_t broadcast_addr = { 0x33, 0x33, 0x00, 0x01, 0x00, 0x03 }; // Outgoing: Must match PTS TSPX_UUID_src_addresss static uint16_t bnep_src_uuid = 0x1115; @@ -242,7 +246,7 @@ static uint16_t calc_internet_checksum(uint8_t * data, int size){ static void send_ping_request_ipv4(void){ - uint8_t ipv4_packet[] = { + uint8_t ipv4_header[] = { // ip 0x45, 0x00, 0x00, 0x00, // version + ihl, dscp } ecn, total len 0x00, 0x00, 0x00, 0x00, // identification (16), flags + fragment offset @@ -261,13 +265,13 @@ static void send_ping_request_ipv4(void){ int pos = setup_ethernet_header(1, 0, 0, NETWORK_TYPE_IPv4); // IPv4 // ipv4 - int total_length = sizeof(ipv4_packet) + sizeof(icmp_packet); - net_store_16(ipv4_packet, 2, total_length); - uint16_t ipv4_checksum = calc_internet_checksum(ipv4_packet, sizeof(ipv4_packet)); - net_store_16(ipv4_packet, 10, ipv4_checksum); + int total_length = sizeof(ipv4_header) + sizeof(icmp_packet); + net_store_16(ipv4_header, 2, total_length); + uint16_t ipv4_checksum = calc_internet_checksum(ipv4_header, sizeof(ipv4_header)); + net_store_16(ipv4_header, 10, ipv4_checksum); // TODO: also set src/dest ip address - memcpy(&network_buffer[pos], ipv4_packet, sizeof(ipv4_packet)); - pos += sizeof(ipv4_packet); + memcpy(&network_buffer[pos], ipv4_header, sizeof(ipv4_header)); + pos += sizeof(ipv4_header); // icmp uint16_t icmp_checksum = calc_internet_checksum(icmp_packet, sizeof(icmp_packet)); @@ -281,7 +285,7 @@ static void send_ping_request_ipv4(void){ static void send_ping_response_ipv4(void){ - uint8_t ipv4_packet[] = { + uint8_t ipv4_header[] = { // ip 0x45, 0x00, 0x00, 0x00, // version + ihl, dscp } ecn, total len 0x00, 0x00, 0x00, 0x00, // identification (16), flags + fragment offset @@ -300,13 +304,13 @@ static void send_ping_response_ipv4(void){ int pos = setup_ethernet_header(1, 0, 0, NETWORK_TYPE_IPv4); // IPv4 // ipv4 - int total_length = sizeof(ipv4_packet) + sizeof(icmp_packet); - net_store_16(ipv4_packet, 2, total_length); - uint16_t ipv4_checksum = calc_internet_checksum(ipv4_packet, sizeof(ipv4_packet)); - net_store_16(ipv4_packet, 10, ipv4_checksum); + int total_length = sizeof(ipv4_header) + sizeof(icmp_packet); + net_store_16(ipv4_header, 2, total_length); + uint16_t ipv4_checksum = calc_internet_checksum(ipv4_header, sizeof(ipv4_header)); + net_store_16(ipv4_header, 10, ipv4_checksum); // TODO: also set src/dest ip address - memcpy(&network_buffer[pos], ipv4_packet, sizeof(ipv4_packet)); - pos += sizeof(ipv4_packet); + memcpy(&network_buffer[pos], ipv4_header, sizeof(ipv4_header)); + pos += sizeof(ipv4_header); // icmp uint16_t icmp_checksum = calc_internet_checksum(icmp_packet, sizeof(icmp_packet)); @@ -320,7 +324,7 @@ static void send_ping_response_ipv4(void){ static void send_ping_request_ipv6(void){ - uint8_t ipv6_packet[] = { + uint8_t ipv6_header[] = { // ip 0x60, 0x00, 0x00, 0x00, // version (4) + traffic class (8) + flow label (24) 0x00, 0x00, 58, 0x01, // payload length(16), next header = IPv6-ICMP, hop limit @@ -345,14 +349,14 @@ static void send_ping_request_ipv6(void){ // ipv6 int payload_length = sizeof(icmp_packet); - net_store_16(ipv6_packet, 4, payload_length); + net_store_16(ipv6_header, 4, payload_length); // TODO: also set src/dest ip address - int checksum = calc_internet_checksum(&ipv6_packet[8], 32); - checksum = sum_ones_complement(checksum, sizeof(ipv6_packet) + sizeof(icmp_packet)); + int checksum = calc_internet_checksum(&ipv6_header[8], 32); + checksum = sum_ones_complement(checksum, sizeof(ipv6_header) + sizeof(icmp_packet)); checksum = sum_ones_complement(checksum, 58 << 8); net_store_16(icmp_packet, 2, checksum); - memcpy(&network_buffer[pos], ipv6_packet, sizeof(ipv6_packet)); - pos += sizeof(ipv6_packet); + memcpy(&network_buffer[pos], ipv6_header, sizeof(ipv6_header)); + pos += sizeof(ipv6_header); // icmp uint16_t icmp_checksum = calc_internet_checksum(icmp_packet, sizeof(icmp_packet)); @@ -366,7 +370,7 @@ static void send_ping_request_ipv6(void){ static void send_ndp_probe_ipv6(void){ - uint8_t ipv6_packet[] = { + uint8_t ipv6_header[] = { // ip 0x60, 0x00, 0x00, 0x00, // version (4) + traffic class (8) + flow label (24) 0x00, 0x00, 58, 0x01, // payload length(16), next header = IPv6-ICMP, hop limit @@ -391,24 +395,23 @@ static void send_ndp_probe_ipv6(void){ // ipv6 int payload_length = sizeof(icmp_packet); - net_store_16(ipv6_packet, 4, payload_length); + net_store_16(ipv6_header, 4, payload_length); // source address :: // dest addresss - Modified EUI-64 - // ipv6_packet[24..31] = FE80:: - ipv6_packet[32] = local_addr[0] ^ 0x2; - ipv6_packet[33] = local_addr[1]; - ipv6_packet[34] = local_addr[2]; - ipv6_packet[35] = 0xff; - ipv6_packet[36] = 0xfe; - ipv6_packet[37] = local_addr[3]; - ipv6_packet[38] = local_addr[4]; - ipv6_packet[39] = local_addr[5]; - int checksum = calc_internet_checksum(&ipv6_packet[8], 32); - checksum = sum_ones_complement(checksum, sizeof(ipv6_packet) + sizeof(icmp_packet)); + // ipv6_header[24..31] = FE80:: + ipv6_header[32] = local_addr[0] ^ 0x2; + ipv6_header[33] = local_addr[1]; + ipv6_header[34] = local_addr[2]; + ipv6_header[35] = 0xff; + ipv6_header[36] = 0xfe; + ipv6_header[37] = local_addr[3]; + ipv6_header[38] = local_addr[4]; + ipv6_header[39] = local_addr[5]; + int checksum = calc_internet_checksum(&ipv6_header[8], 32); + checksum = sum_ones_complement(checksum, sizeof(ipv6_header) + sizeof(icmp_packet)); checksum = sum_ones_complement(checksum, 58 << 8); - net_store_16(icmp_packet, 2, checksum); - memcpy(&network_buffer[pos], ipv6_packet, sizeof(ipv6_packet)); - pos += sizeof(ipv6_packet); + memcpy(&network_buffer[pos], ipv6_header, sizeof(ipv6_header)); + pos += sizeof(ipv6_header); // icmp uint16_t icmp_checksum = calc_internet_checksum(icmp_packet, sizeof(icmp_packet)); @@ -423,11 +426,11 @@ static void send_ndp_probe_ipv6(void){ static void send_llmnr_request_ipv4(void){ uint8_t ipv4_header[] = { - 0x45, 0x00, 0x00, 0x00, // version + ihl, dscp } ecn, total len + 0x45, 0x00, 0x00, 0x00, // version + ihl, dscp } ecn, total len 0x00, 0x00, 0x00, 0x00, // identification (16), flags + fragment offset 0x01, 0x11, 0x00, 0x00, // time to live, procotol: UDP, checksum (16), 192, 168, 167, 152, // source IP address - 224, 0, 0, 252, // destination IP address + 224, 0, 0, 252, // destination IP address }; uint8_t udp_header[8]; @@ -440,7 +443,7 @@ static void send_llmnr_request_ipv4(void){ int total_length = sizeof(ipv4_header) + sizeof(udp_header) + sizeof (llmnr_packet); net_store_16(ipv4_header, 2, total_length); uint16_t ipv4_checksum = calc_internet_checksum(ipv4_header, sizeof(ipv4_header)); - net_store_16(ipv4_header, 10, ipv4_checksum); + net_store_16(ipv4_header, 10, ~ipv4_checksum); // TODO: also set src/dest ip address memcpy(&network_buffer[pos], ipv4_header, sizeof(ipv4_header)); pos += sizeof(ipv4_header); @@ -465,6 +468,69 @@ static void send_llmnr_request_ipv4(void){ send_buffer(pos); } +static void send_llmnr_request_ipv6(void){ + // https://msdn.microsoft.com/en-us/library/dd240361.aspx + uint8_t ipv6_header[] = { + 0x60, 0x00, 0x00, 0x00, // version (6) + traffic class (8) + flow label (24) + 0x00, 0x00, 17, 0x01, // payload length(16), next header = UDP, hop limit + 0xfe, 0x80, 0x00, 0x00, // source IP address + 0x00, 0x00, 0x00, 0x00, // source IP address + 0xd9, 0xf6, 0xce, 0x2e, // source IP address + 0x48, 0x75, 0xab, 0x03, // source IP address + 0xff, 0x02, 0x00, 0x00, // destination IP address + 0x00, 0x00, 0x00, 0x00, // destination IP address + 0x00, 0x00, 0x00, 0x00, // destination IP address + 0x00, 0x01, 0x00, 0x03, // destination IP address + }; + + uint8_t udp_header[8]; + uint8_t llmnr_packet[12]; + + uint8_t dns_data[] = { 0x08, 0x61, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x74, 0x76, + 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, + 0x01, 0x00, 0x01 }; + + int payload_length = sizeof(udp_header) + sizeof(llmnr_packet) + sizeof(dns_data); + + // llmnr header + bzero(llmnr_packet, sizeof(llmnr_packet)); + net_store_16(llmnr_packet, 0, 0x1235); + net_store_16(llmnr_packet, 4, 1); // one query + + // ipv6 header + net_store_16(ipv6_header, 4, payload_length); + + // udp header + bzero(udp_header, sizeof(udp_header)); + net_store_16(udp_header, 0, 5355); // source port + net_store_16(udp_header, 2, 5355); // destination port + net_store_16(udp_header, 4, payload_length); + int checksum = calc_internet_checksum(&ipv6_header[8], 32); + checksum = sum_ones_complement(checksum, ipv6_header[4]); // payload len + checksum = sum_ones_complement(checksum, ipv6_header[6] << 8); // next header + checksum = sum_ones_complement(checksum, calc_internet_checksum(udp_header, sizeof(udp_header))); + checksum = sum_ones_complement(checksum, calc_internet_checksum(llmnr_packet, sizeof(llmnr_packet))); + checksum = sum_ones_complement(checksum, calc_internet_checksum(dns_data, sizeof(dns_data))); + net_store_16(udp_header, 6, ~checksum); + + // ethernet header + int pos = setup_ethernet_header(1, 0, 1, NETWORK_TYPE_IPv6); // IPv6 + + memcpy(&network_buffer[pos], ipv6_header, sizeof(ipv6_header)); + pos += sizeof(ipv6_header); + + memcpy(&network_buffer[pos], udp_header, sizeof(udp_header)); + pos += sizeof(udp_header); + + memcpy(&network_buffer[pos], llmnr_packet, sizeof(llmnr_packet)); + pos += sizeof(llmnr_packet); + + memcpy(&network_buffer[pos], dns_data, sizeof(dns_data)); + pos += sizeof(dns_data); + + // send + send_buffer(pos); +} static void show_usage(void){ @@ -487,12 +553,6 @@ static void show_usage(void){ printf("6 - send IPv6 NDP request\n"); printf("7 - send IPv4 LLMNR request\n"); printf("8 - send IPv6 LLMNR request\n"); -#if 0 - printf("1 - get IP address via DHCP\n"); - printf("2 - send DNS request\n"); - printf("9 - send some IPv6 packet\n"); - printf("0 - send some IPv6 packet 2\n"); -#endif printf("---\n"); printf("Ctrl-c - exit\n"); printf("---\n"); @@ -553,8 +613,7 @@ static int stdin_process(struct data_source *ds){ break; case '8': printf("Sending IPv6 LLMNR Request\n"); - printf("(Not implemented yet)\n"); - // send_llmnr_request_ipv6(); + send_llmnr_request_ipv6(); break; default: show_usage(); @@ -678,7 +737,7 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha break; } case 0x11: // UDP - printf("UDP packet\n"); + printf("UDP IPv4 packet\n"); hexdumpf(&packet[payload_offset], size - payload_offset); break; default: @@ -687,8 +746,21 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha } break; case NETWORK_TYPE_IPv6: - printf("IPV6 packet"); - hexdumpf(&packet[14], size - 14); + protocol_type = packet[6]; + switch(protocol_type){ + case 0x11: // UDP + printf("UDP IPv6 packet\n"); + payload_offset = 40; // fixed + hexdumpf(&packet[payload_offset], size - payload_offset); + + // send response + + break; + default: + printf("IPv6 packet of protocol 0x%02x\n", protocol_type); + hexdumpf(&packet[14], size - 14); + break; + } break; default: printf("Unknown network type %x", network_type);