1 /* icmp.c 2 * 3 * Copyright (c) 2019-2023 Apple Inc. All rights reserved. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * https://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 * This code implements ICMP I/O functions for the Thread border router. 18 */ 19 20 #ifndef LINUX 21 #include <netinet/in.h> 22 #include <net/if.h> 23 #include <netinet6/in6_var.h> 24 #include <netinet6/nd6.h> 25 #include <net/if_media.h> 26 #include <sys/stat.h> 27 #else 28 #define _GNU_SOURCE 29 #include <netinet/in.h> 30 #include <fcntl.h> 31 #include <bsd/stdlib.h> 32 #include <net/if.h> 33 #endif 34 #include <sys/socket.h> 35 #include <sys/ioctl.h> 36 #include <net/route.h> 37 #include <netinet/icmp6.h> 38 #include <stdio.h> 39 #include <unistd.h> 40 #include <errno.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <ctype.h> 44 #include <arpa/inet.h> 45 #if !USE_SYSCTL_COMMAND_TO_ENABLE_FORWARDING 46 #ifndef LINUX 47 #include <sys/sysctl.h> 48 #endif // LINUX 49 #endif // !USE_SYSCTL_COMMAND_TO_ENABLE_FORWARDING 50 #include <stdlib.h> 51 #include <stddef.h> 52 #include <dns_sd.h> 53 #include <inttypes.h> 54 #include <signal.h> 55 56 #ifdef IOLOOP_MACOS 57 #include <xpc/xpc.h> 58 59 #include <TargetConditionals.h> 60 #include <SystemConfiguration/SystemConfiguration.h> 61 #include <SystemConfiguration/SCPrivate.h> 62 #include <SystemConfiguration/SCNetworkConfigurationPrivate.h> 63 #include <SystemConfiguration/SCNetworkSignature.h> 64 #include <network_information.h> 65 66 #include <CoreUtils/CoreUtils.h> 67 #endif // IOLOOP_MACOS 68 69 #include "srp.h" 70 #include "dns-msg.h" 71 #include "ioloop.h" 72 #include "cti-services.h" 73 #include "srp-mdns-proxy.h" 74 #include "route.h" 75 #include "icmp.h" 76 #include "state-machine.h" 77 #include "thread-service.h" 78 #include "omr-watcher.h" 79 80 81 icmp_listener_t icmp_listener; 82 83 void 84 icmp_message_free(icmp_message_t *message) 85 { 86 if (message->options != NULL) { 87 free(message->options); 88 } 89 if (message->wakeup != NULL) { 90 ioloop_cancel_wake_event(message->wakeup); 91 ioloop_wakeup_release(message->wakeup); 92 } 93 free(message); 94 } 95 96 void 97 icmp_message_dump(icmp_message_t *message, 98 struct in6_addr *source_address, struct in6_addr *destination_address) 99 { 100 link_layer_address_t *lladdr; 101 prefix_information_t *prefix_info; 102 route_information_t *route_info; 103 uint8_t *flags; 104 int i; 105 char retransmission_timer_buf[11]; // Maximum size of a uint32_t printed as decimal. 106 char *retransmission_timer = "infinite"; 107 108 if (message->retransmission_timer != ND6_INFINITE_LIFETIME) { 109 snprintf(retransmission_timer_buf, sizeof(retransmission_timer_buf), "%" PRIu32, message->retransmission_timer); 110 retransmission_timer = retransmission_timer_buf; 111 } 112 113 SEGMENTED_IPv6_ADDR_GEN_SRP(source_address->s6_addr, src_addr_buf); 114 SEGMENTED_IPv6_ADDR_GEN_SRP(destination_address->s6_addr, dst_addr_buf); 115 if (message->type == icmp_type_router_advertisement) { 116 INFO("router advertisement from " PRI_SEGMENTED_IPv6_ADDR_SRP " to " PRI_SEGMENTED_IPv6_ADDR_SRP 117 " hop_limit %d on " PUB_S_SRP ": checksum = %x " 118 "cur_hop_limit = %d flags = %x router_lifetime = %d reachable_time = %" PRIu32 119 " retransmission_timer = " PUB_S_SRP, 120 SEGMENTED_IPv6_ADDR_PARAM_SRP(source_address->s6_addr, src_addr_buf), 121 SEGMENTED_IPv6_ADDR_PARAM_SRP(destination_address->s6_addr, dst_addr_buf), 122 message->hop_limit, message->interface->name, message->checksum, message->cur_hop_limit, message->flags, 123 message->router_lifetime, message->reachable_time, retransmission_timer); 124 } else if (message->type == icmp_type_router_solicitation) { 125 INFO("router solicitation from " PRI_SEGMENTED_IPv6_ADDR_SRP " to " PRI_SEGMENTED_IPv6_ADDR_SRP 126 " hop_limit %d on " PUB_S_SRP ": code = %d checksum = %x", 127 SEGMENTED_IPv6_ADDR_PARAM_SRP(source_address->s6_addr, src_addr_buf), 128 SEGMENTED_IPv6_ADDR_PARAM_SRP(destination_address->s6_addr, dst_addr_buf), 129 message->hop_limit, message->interface->name, 130 message->code, message->checksum); 131 } else { 132 INFO("icmp message from " PRI_SEGMENTED_IPv6_ADDR_SRP " to " PRI_SEGMENTED_IPv6_ADDR_SRP " hop_limit %d on " 133 PUB_S_SRP ": type = %d code = %d checksum = %x", 134 SEGMENTED_IPv6_ADDR_PARAM_SRP(source_address->s6_addr, src_addr_buf), 135 SEGMENTED_IPv6_ADDR_PARAM_SRP(destination_address->s6_addr, dst_addr_buf), 136 message->hop_limit, message->interface->name, message->type, 137 message->code, message->checksum); 138 } 139 140 for (i = 0; i < message->num_options; i++) { 141 icmp_option_t *option = &message->options[i]; 142 switch(option->type) { 143 case icmp_option_source_link_layer_address: 144 lladdr = &option->option.link_layer_address; 145 INFO(" source link layer address " PRI_MAC_ADDR_SRP, MAC_ADDR_PARAM_SRP(lladdr->address)); 146 break; 147 case icmp_option_target_link_layer_address: 148 lladdr = &option->option.link_layer_address; 149 INFO(" destination link layer address " PRI_MAC_ADDR_SRP, MAC_ADDR_PARAM_SRP(lladdr->address)); 150 break; 151 case icmp_option_prefix_information: 152 prefix_info = &option->option.prefix_information; 153 SEGMENTED_IPv6_ADDR_GEN_SRP(prefix_info->prefix.s6_addr, prefix_buf); 154 INFO(" prefix info: " PRI_SEGMENTED_IPv6_ADDR_SRP "/%d %x %" PRIu32 " %" PRIu32, 155 SEGMENTED_IPv6_ADDR_PARAM_SRP(prefix_info->prefix.s6_addr, prefix_buf), prefix_info->length, 156 prefix_info->flags, prefix_info->valid_lifetime, prefix_info->preferred_lifetime); 157 break; 158 case icmp_option_route_information: 159 route_info = &option->option.route_information; 160 SEGMENTED_IPv6_ADDR_GEN_SRP(route_info->prefix.s6_addr, router_prefix_buf); 161 INFO(" route info: " PRI_SEGMENTED_IPv6_ADDR_SRP "/%d %x %d", 162 SEGMENTED_IPv6_ADDR_PARAM_SRP(route_info->prefix.s6_addr, router_prefix_buf), route_info->length, 163 route_info->flags, route_info->route_lifetime); 164 break; 165 case icmp_option_ra_flags_extension: 166 flags = option->option.ra_flags_extension; 167 INFO(" ra flags extension: %x %x %x %x %x %x", flags[0], flags[1], flags[2], flags[3], flags[4], flags[5]); 168 break; 169 default: 170 INFO(" option type %d", option->type); 171 break; 172 } 173 } 174 } 175 176 static bool 177 icmp_message_parse_options(icmp_message_t *message, uint8_t *icmp_buf, unsigned length, unsigned *offset) 178 { 179 uint8_t option_type, option_length_8; 180 unsigned option_length; 181 unsigned scan_offset = *offset; 182 icmp_option_t *option; 183 uint32_t reserved32; 184 prefix_information_t *prefix_information; 185 route_information_t *route_information; 186 187 int prefix_bytes; 188 189 // Count the options and validate the lengths 190 message->num_options = 0; 191 while (scan_offset < length) { 192 if (!dns_u8_parse(icmp_buf, length, &scan_offset, &option_type)) { 193 return false; 194 } 195 if (!dns_u8_parse(icmp_buf, length, &scan_offset, &option_length_8)) { 196 return false; 197 } 198 if (option_length_8 == 0) { // RFC4191 section 4.6: The value 0 is invalid. 199 ERROR("icmp_option_parse: option type %d length 0 is invalid.", option_type); 200 return false; 201 } 202 if (scan_offset + option_length_8 * 8 - 2 > length) { 203 ERROR("icmp_option_parse: option type %d length %d is longer than remaining available space %u", 204 option_type, option_length_8 * 8, length - scan_offset + 2); 205 return false; 206 } 207 scan_offset += option_length_8 * 8 - 2; 208 message->num_options++; 209 } 210 // If there are no options, we're done. No options is valid, so return true. 211 if (message->num_options == 0) { 212 return true; 213 } 214 message->options = calloc(message->num_options, sizeof(*message->options)); 215 if (message->options == NULL) { 216 ERROR("No memory for icmp options."); 217 return false; 218 } 219 option = message->options; 220 while (*offset < length) { 221 scan_offset = *offset; 222 if (!dns_u8_parse(icmp_buf, length, &scan_offset, &option_type)) { 223 return false; 224 } 225 if (!dns_u8_parse(icmp_buf, length, &scan_offset, &option_length_8)) { 226 return false; 227 } 228 // We already validated the length in the previous pass. 229 option->type = option_type; 230 option_length = option_length_8 * 8; 231 232 switch(option_type) { 233 case icmp_option_source_link_layer_address: 234 case icmp_option_target_link_layer_address: 235 // At this juncture we are assuming that everything we care about looks like an 236 // ethernet interface. So for this case, length should be 8. 237 if (option_length != 8) { 238 INFO("Ignoring unexpectedly long link layer address: %d", option_length); 239 // Don't store the option. 240 message->num_options--; 241 *offset += option_length; 242 continue; 243 } 244 option->option.link_layer_address.length = 6; 245 memcpy(option->option.link_layer_address.address, &icmp_buf[scan_offset], 6); 246 break; 247 case icmp_option_prefix_information: 248 prefix_information = &option->option.prefix_information; 249 // Only a length of 32 is valid. This is an invalid ICMP packet, not just misunderunderstood 250 if (option_length != 32) { 251 return false; 252 } 253 // prefix length 8 254 if (!dns_u8_parse(icmp_buf, length, &scan_offset, &prefix_information->length)) { 255 return false; 256 } 257 // flags 8a 258 if (!dns_u8_parse(icmp_buf, length, &scan_offset, &prefix_information->flags)) { 259 return false; 260 } 261 // valid lifetime 32 262 if (!dns_u32_parse(icmp_buf, length, &scan_offset, 263 &prefix_information->valid_lifetime)) { 264 return false; 265 } 266 // preferred lifetime 32 267 if (!dns_u32_parse(icmp_buf, length, &scan_offset, 268 &prefix_information->preferred_lifetime)) { 269 return false; 270 } 271 // reserved2 32 272 if (!dns_u32_parse(icmp_buf, length, &scan_offset, &reserved32)) { 273 return false; 274 } 275 // prefix 128 276 in6prefix_copy_from_data(&prefix_information->prefix, &icmp_buf[scan_offset], 16); 277 break; 278 case icmp_option_route_information: 279 route_information = &option->option.route_information; 280 281 // route length 8 282 if (!dns_u8_parse(icmp_buf, length, &scan_offset, &route_information->length)) { 283 return false; 284 } 285 switch(option_length) { 286 case 8: 287 prefix_bytes = 0; 288 break; 289 case 16: 290 prefix_bytes = 8; 291 break; 292 case 24: 293 prefix_bytes = 16; 294 break; 295 default: 296 ERROR("invalid route information option length %d for route length %d", 297 option_length, route_information->length); 298 return false; 299 } 300 // flags 8 301 if (!dns_u8_parse(icmp_buf, length, &scan_offset, &route_information->flags)) { 302 return false; 303 } 304 // route lifetime 32 305 if (!dns_u32_parse(icmp_buf, length, &scan_offset, &route_information->route_lifetime)) { 306 return false; 307 } 308 // route (64, 96 or 128) 309 in6prefix_copy_from_data(&route_information->prefix, &icmp_buf[scan_offset], prefix_bytes); 310 break; 311 case icmp_option_ra_flags_extension: 312 // The RA Flags extension as defined in RFC 5175 must have a length of 1 (meaning 8 bytes). 313 // It's possible that a later spec will define a length > 1, but since we are implementing 314 // RFC5175, we are required to silently ignore anything after the first 8 bytes. Since 315 // we've already checked for length=0 (invalid), we can just take our six bytes of flags 316 // and not bounds-check further. 317 memcpy(option->option.ra_flags_extension, &icmp_buf[scan_offset], sizeof(option->option.ra_flags_extension)); 318 break; 319 default: 320 case icmp_option_mtu: 321 case icmp_option_redirected_header: 322 // don't care 323 break; 324 } 325 *offset += option_length; 326 option++; 327 } 328 return true; 329 } 330 331 332 static void 333 icmp_message(route_state_t *route_state, uint8_t *icmp_buf, unsigned length, int ifindex, int hop_limit, addr_t *src, addr_t *dest) 334 { 335 unsigned offset = 0; 336 uint32_t reserved32; 337 interface_t *interface; 338 icmp_message_t *message = calloc(1, sizeof(*message)); 339 if (message == NULL) { 340 ERROR("Unable to allocate icmp_message_t for parsing"); 341 return; 342 } 343 344 message->source = src->sin6.sin6_addr; 345 message->destination = dest->sin6.sin6_addr; 346 message->hop_limit = hop_limit; 347 for (interface = route_state->interfaces; interface; interface = interface->next) { 348 if (interface->index == ifindex) { 349 message->interface = interface; 350 break; 351 } 352 } 353 message->received_time = ioloop_timenow(); 354 message->received_time_already_adjusted = false; 355 message->new_router = true; 356 message->route_state = route_state; 357 358 if (message->interface == NULL) { 359 SEGMENTED_IPv6_ADDR_GEN_SRP(message->source.s6_addr, src_buf); 360 SEGMENTED_IPv6_ADDR_GEN_SRP(message->destination.s6_addr, dst_buf); 361 INFO("ICMP message type %d from " PRI_SEGMENTED_IPv6_ADDR_SRP " to " PRI_SEGMENTED_IPv6_ADDR_SRP 362 " on interface index %d, which isn't listed.", 363 icmp_buf[0], SEGMENTED_IPv6_ADDR_PARAM_SRP(message->source.s6_addr, src_buf), 364 SEGMENTED_IPv6_ADDR_PARAM_SRP(message->destination.s6_addr, dst_buf), ifindex); 365 icmp_message_free(message); 366 return; 367 } 368 369 if (length < sizeof (struct icmp6_hdr)) { 370 ERROR("Short ICMP message: length %d is shorter than ICMP header length %zd", length, sizeof(struct icmp6_hdr)); 371 icmp_message_free(message); 372 return; 373 } 374 INFO("length %d", length); 375 376 // The increasingly innaccurately named dns parse functions will work fine for this. 377 if (!dns_u8_parse(icmp_buf, length, &offset, &message->type)) { 378 goto out; 379 } 380 if (!dns_u8_parse(icmp_buf, length, &offset, &message->code)) { 381 goto out; 382 } 383 // XXX check the checksum 384 if (!dns_u16_parse(icmp_buf, length, &offset, &message->checksum)) { 385 goto out; 386 } 387 switch(message->type) { 388 case icmp_type_router_advertisement: 389 if (!dns_u8_parse(icmp_buf, length, &offset, &message->cur_hop_limit)) { 390 goto out; 391 } 392 if (!dns_u8_parse(icmp_buf, length, &offset, &message->flags)) { 393 goto out; 394 } 395 if (!dns_u16_parse(icmp_buf, length, &offset, &message->router_lifetime)) { 396 goto out; 397 } 398 if (!dns_u32_parse(icmp_buf, length, &offset, &message->reachable_time)) { 399 goto out; 400 } 401 if (!dns_u32_parse(icmp_buf, length, &offset, &message->retransmission_timer)) { 402 goto out; 403 } 404 405 if (!icmp_message_parse_options(message, icmp_buf, length, &offset)) { 406 goto out; 407 } 408 icmp_message_dump(message, &message->source, &message->destination); 409 router_advertisement(message); 410 // router_advertisement() is given ownership of the message 411 return; 412 413 case icmp_type_router_solicitation: 414 if (!dns_u32_parse(icmp_buf, length, &offset, &reserved32)) { 415 goto out; 416 } 417 if (!icmp_message_parse_options(message, icmp_buf, length, &offset)) { 418 goto out; 419 } 420 icmp_message_dump(message, &message->source, &message->destination); 421 router_solicit(message); 422 // router_solicit() is given ownership of the message. 423 return; 424 425 case icmp_type_neighbor_advertisement: 426 icmp_message_dump(message, &message->source, &message->destination); 427 neighbor_advertisement(message); 428 break; 429 430 case icmp_type_neighbor_solicitation: 431 case icmp_type_echo_request: 432 case icmp_type_echo_reply: 433 case icmp_type_redirect: 434 break; 435 } 436 437 out: 438 icmp_message_free(message); 439 return; 440 } 441 442 #ifndef FUZZING 443 static 444 #endif 445 void 446 icmp_callback(io_t *NONNULL io, void *UNUSED context) 447 { 448 ssize_t rv; 449 uint8_t icmp_buf[1500]; 450 int ifindex = 0; 451 addr_t src, dest; 452 int hop_limit = 0; 453 454 #ifndef FUZZING 455 rv = ioloop_recvmsg(io->fd, &icmp_buf[0], sizeof(icmp_buf), &ifindex, &hop_limit, &src, &dest); 456 #else 457 rv = read(io->fd, &icmp_buf, sizeof(icmp_buf)); 458 #endif 459 if (rv < 0) { 460 ERROR("icmp_callback: can't read ICMP message: " PUB_S_SRP, strerror(errno)); 461 return; 462 } 463 for (route_state_t *route_state = route_states; route_state != NULL; route_state = route_state->next) { 464 icmp_message(route_state, icmp_buf, (unsigned)rv, ifindex, hop_limit, &src, &dest); // rv will never be > sizeof(icmp_buf) 465 } 466 } 467 468 static void 469 route_information_to_wire(dns_towire_state_t *towire, void *prefix_data, 470 const char *source_interface, const char *dest_interface) 471 { 472 uint8_t *prefix = prefix_data; 473 474 #ifndef ND_OPT_ROUTE_INFORMATION 475 #define ND_OPT_ROUTE_INFORMATION 24 476 #endif 477 dns_u8_to_wire(towire, ND_OPT_ROUTE_INFORMATION); 478 dns_u8_to_wire(towire, 2); // length / 8 479 dns_u8_to_wire(towire, 64); // Interface prefixes are always 64 bits 480 dns_u8_to_wire(towire, 0); // There's no reason at present to prefer one Thread BR over another 481 dns_u32_to_wire(towire, BR_PREFIX_LIFETIME); // Route lifetime 1800 seconds (30 minutes) 482 dns_rdata_raw_data_to_wire(towire, prefix, 8); // /64 requires 8 bytes. 483 SEGMENTED_IPv6_ADDR_GEN_SRP(prefix, thread_prefix_buf); 484 INFO("Sending route to " PRI_SEGMENTED_IPv6_ADDR_SRP "%%" PUB_S_SRP " on " PUB_S_SRP, 485 SEGMENTED_IPv6_ADDR_PARAM_SRP(prefix, thread_prefix_buf), source_interface, dest_interface); 486 } 487 488 static void 489 icmp_send(uint8_t *message, size_t length, interface_t *interface, const struct in6_addr *destination) 490 { 491 #ifdef FUZZING 492 char buffer[length]; 493 memcpy(buffer, message, length); 494 return; 495 #endif 496 struct iovec iov; 497 struct in6_pktinfo *packet_info; 498 socklen_t cmsg_length = CMSG_SPACE(sizeof(*packet_info)) + CMSG_SPACE(sizeof (int)); 499 uint8_t *cmsg_buffer; 500 struct msghdr msg_header; 501 struct cmsghdr *cmsg_pointer; 502 int hop_limit = 255; 503 ssize_t rv; 504 struct sockaddr_in6 dest; 505 506 // Make space for the control message buffer. 507 cmsg_buffer = calloc(1, cmsg_length); 508 if (cmsg_buffer == NULL) { 509 ERROR("Unable to construct ICMP Router Advertisement: no memory"); 510 return; 511 } 512 513 // Send the message 514 memset(&dest, 0, sizeof(dest)); 515 dest.sin6_family = AF_INET6; 516 dest.sin6_scope_id = interface->index; 517 #ifndef NOT_HAVE_SA_LEN 518 dest.sin6_len = sizeof(dest); 519 #endif 520 msg_header.msg_namelen = sizeof(dest); 521 dest.sin6_addr = *destination; 522 523 msg_header.msg_name = &dest; 524 iov.iov_base = message; 525 iov.iov_len = length; 526 msg_header.msg_iov = &iov; 527 msg_header.msg_iovlen = 1; 528 msg_header.msg_control = cmsg_buffer; 529 msg_header.msg_controllen = cmsg_length; 530 531 // Specify the interface 532 cmsg_pointer = CMSG_FIRSTHDR(&msg_header); 533 cmsg_pointer->cmsg_level = IPPROTO_IPV6; 534 cmsg_pointer->cmsg_type = IPV6_PKTINFO; 535 cmsg_pointer->cmsg_len = CMSG_LEN(sizeof(*packet_info)); 536 packet_info = (struct in6_pktinfo *)CMSG_DATA(cmsg_pointer); 537 memset(packet_info, 0, sizeof(*packet_info)); 538 packet_info->ipi6_ifindex = interface->index; 539 540 // Router advertisements and solicitations have a hop limit of 255 541 cmsg_pointer = CMSG_NXTHDR(&msg_header, cmsg_pointer); 542 cmsg_pointer->cmsg_level = IPPROTO_IPV6; 543 cmsg_pointer->cmsg_type = IPV6_HOPLIMIT; 544 cmsg_pointer->cmsg_len = CMSG_LEN(sizeof(int)); 545 memcpy(CMSG_DATA(cmsg_pointer), &hop_limit, sizeof(hop_limit)); 546 547 548 // Send it 549 rv = sendmsg(icmp_listener.io_state->fd, &msg_header, 0); 550 if (rv < 0) { 551 uint8_t *in6_addr_bytes = ((struct sockaddr_in6 *)(msg_header.msg_name))->sin6_addr.s6_addr; 552 SEGMENTED_IPv6_ADDR_GEN_SRP(in6_addr_bytes, in6_addr_buf); 553 ERROR("icmp_send: sending " PUB_S_SRP " to " PRI_SEGMENTED_IPv6_ADDR_SRP " on interface " PUB_S_SRP 554 " index %d: " PUB_S_SRP, message[0] == ND_ROUTER_SOLICIT ? "solicit" : "advertise", 555 SEGMENTED_IPv6_ADDR_PARAM_SRP(in6_addr_bytes, in6_addr_buf), 556 interface->name, interface->index, strerror(errno)); 557 } else if ((size_t)rv != iov.iov_len) { 558 ERROR("icmp_send: short send to interface " PUB_S_SRP ": %zd < %zd", interface->name, rv, iov.iov_len); 559 } 560 free(cmsg_buffer); 561 } 562 563 void 564 router_advertisement_send(interface_t *interface, const struct in6_addr *destination) 565 { 566 uint8_t *message; 567 dns_towire_state_t towire; 568 route_state_t *route_state = interface->route_state; 569 570 // Thread blocks RAs so no point sending them. 571 if (interface->inactive 572 #ifndef RA_TESTER 573 || interface->is_thread 574 #endif 575 ) { 576 return; 577 } 578 579 #define MAX_ICMP_MESSAGE 1280 580 message = malloc(MAX_ICMP_MESSAGE); 581 if (message == NULL) { 582 ERROR("router_advertisement_send: unable to construct ICMP Router Advertisement: no memory"); 583 return; 584 } 585 586 // Construct the ICMP header and options for each interface. 587 memset(&towire, 0, sizeof towire); 588 towire.p = message; 589 towire.lim = message + MAX_ICMP_MESSAGE; 590 591 // Construct the ICMP header. 592 // We use the DNS message construction functions because it's easy; probably should just make 593 // the towire functions more generic. 594 dns_u8_to_wire(&towire, ND_ROUTER_ADVERT); // icmp6_type 595 dns_u8_to_wire(&towire, 0); // icmp6_code 596 dns_u16_to_wire(&towire, 0); // The kernel computes the checksum (we don't technically have it). 597 dns_u8_to_wire(&towire, 0); // Hop limit, we don't set. 598 dns_u8_to_wire(&towire, 0); // Flags. We don't offer DHCP, so We set neither the M nor the O bit. 599 // We are not a home agent, so no H bit. Lifetime is 0, so Prf is 0. 600 #ifdef ROUTER_LIFETIME_HACK 601 dns_u16_to_wire(&towire, BR_PREFIX_LIFETIME); // Router lifetime, hacked. This shouldn't ever be enabled. 602 #else 603 #ifdef RA_TESTER 604 // Advertise a default route on the simulated thread network 605 if (!strcmp(interface->name, route_state->thread_interface_name)) { 606 dns_u16_to_wire(&towire, BR_PREFIX_LIFETIME); // Router lifetime for default route 607 } else { 608 #endif 609 dns_u16_to_wire(&towire, 0); // Router lifetime for non-default default route(s). 610 #ifdef RA_TESTER 611 } 612 #endif // RA_TESTER 613 #endif // ROUTER_LIFETIME_HACK 614 dns_u32_to_wire(&towire, 0); // Reachable time for NUD, we have no opinion on this. 615 dns_u32_to_wire(&towire, 0); // Retransmission timer, again we have no opinion. 616 617 #ifndef RA_TESTER 618 // Send MTU of 1280 for Thread? 619 if (interface->is_thread) { 620 dns_u8_to_wire(&towire, ND_OPT_MTU); 621 dns_u8_to_wire(&towire, 1); // length / 8 622 dns_u32_to_wire(&towire, 1280); 623 INFO("advertising MTU of 1280 on " PUB_S_SRP, interface->name); 624 } 625 #endif 626 627 // Send Prefix Information option if there's no IPv6 on the link. 628 if (interface->our_prefix_advertised && !interface->suppress_ipv6_prefix && route_state->have_xpanid_prefix) { 629 dns_u8_to_wire(&towire, ND_OPT_PREFIX_INFORMATION); 630 dns_u8_to_wire(&towire, 4); // length / 8 631 dns_u8_to_wire(&towire, 64); // On-link prefix is always 64 bits 632 dns_u8_to_wire(&towire, ND_OPT_PI_FLAG_ONLINK | ND_OPT_PI_FLAG_AUTO); // On link, autoconfig 633 dns_u32_to_wire(&towire, interface->valid_lifetime); 634 dns_u32_to_wire(&towire, interface->preferred_lifetime); 635 dns_u32_to_wire(&towire, 0); // Reserved 636 dns_rdata_raw_data_to_wire(&towire, &interface->ipv6_prefix, sizeof interface->ipv6_prefix); 637 SEGMENTED_IPv6_ADDR_GEN_SRP(interface->ipv6_prefix.s6_addr, ipv6_prefix_buf); 638 INFO("advertising on-link prefix " PRI_SEGMENTED_IPv6_ADDR_SRP " on " PUB_S_SRP, 639 SEGMENTED_IPv6_ADDR_PARAM_SRP(interface->ipv6_prefix.s6_addr, ipv6_prefix_buf), interface->name); 640 641 } 642 643 // In principle we can either send routes to links that are reachable by this router, 644 // or just advertise a router to the entire ULA /48. In theory it doesn't matter 645 // which we do; if we support HNCP at some point we probably need to be specific, but 646 // for now being general is fine because we have no way to share a ULA. 647 // Unfortunately, some RIO implementations do not work with specific routes, so for now 648 // We are doing it the easy way and just advertising the /48. 649 #define SEND_INTERFACE_SPECIFIC_RIOS 1 650 #ifdef SEND_INTERFACE_SPECIFIC_RIOS 651 652 // If neither ROUTE_BETWEEN_NON_THREAD_LINKS nor RA_TESTER are defined, then we never want to 653 // send an RIO other than for the thread network prefix. 654 #if defined (ROUTE_BETWEEN_NON_THREAD_LINKS) || defined(RA_TESTER) 655 interface_t *ifroute; 656 // Send Route Information option for other interfaces. 657 for (ifroute = route_state->interfaces; ifroute; ifroute = ifroute->next) { 658 if (ifroute->inactive) { 659 continue; 660 } 661 if (want_routing(route_state) && 662 ifroute->our_prefix_advertised && 663 #ifdef SEND_ON_LINK_ROUTE 664 // In theory we don't want to send RIO for the on-link prefix, but there's this bug, see. 665 true && 666 #else 667 ifroute != interface && 668 #endif 669 #ifdef RA_TESTER 670 // For the RA tester, we don't need to send an RIO to the thread network because we're the 671 // default router for that network. 672 strcmp(interface->name, route_state->thread_interface_name) 673 #else 674 true 675 #endif 676 ) 677 { 678 route_information_to_wire(&towire, &ifroute->ipv6_prefix, ifroute->name, interface->name); 679 } 680 } 681 #endif // ROUTE_BETWEEN_NON_THREAD_LINKS || RA_TESTER 682 683 #ifndef RA_TESTER 684 // Send route information option for thread prefix 685 if (route_state->omr_watcher != NULL) { 686 omr_prefix_t *thread_prefixes = omr_watcher_prefixes_get(route_state->omr_watcher); 687 688 // Send RIOs for any other prefixes that appear on the Thread network 689 for (struct omr_prefix *prefix = thread_prefixes; prefix != NULL; prefix = prefix->next) { 690 route_information_to_wire(&towire, &prefix->prefix, route_state->thread_interface_name, interface->name); 691 } 692 } 693 #endif 694 #else 695 #ifndef SKIP_SLASH_48 696 dns_u8_to_wire(&towire, ND_OPT_ROUTE_INFORMATION); 697 dns_u8_to_wire(&towire, 3); // length / 8 698 dns_u8_to_wire(&towire, 48); // ULA prefixes are always 48 bits 699 dns_u8_to_wire(&towire, 0); // There's no reason at present to prefer one Thread BR over another 700 dns_u32_to_wire(&towire, BR_PREFIX_LIFETIME); // Route lifetime 1800 seconds (30 minutes) 701 dns_rdata_raw_data_to_wire(&towire, &route_state->srp_server->ula_prefix, 16); // /48 requires 16 bytes 702 #endif // SKIP_SLASH_48 703 #endif // SEND_INTERFACE_SPECIFIC_RIOS 704 705 // Send the stub router flag 706 dns_u8_to_wire(&towire, ND_OPT_RA_FLAGS_EXTENSION); 707 dns_u8_to_wire(&towire, 1); // length / 8 708 dns_u8_to_wire(&towire, RA_FLAGS1_STUB_ROUTER); 709 dns_u8_to_wire(&towire, 0); // Five bytes of zero flag bits 710 dns_u32_to_wire(&towire, 0); 711 712 // Send Source link-layer address option 713 if (interface->have_link_layer_address) { 714 dns_u8_to_wire(&towire, ND_OPT_SOURCE_LINKADDR); 715 dns_u8_to_wire(&towire, 1); // length / 8 716 dns_rdata_raw_data_to_wire(&towire, &interface->link_layer, sizeof(interface->link_layer)); 717 } 718 719 if (towire.error) { 720 ERROR("No space in ICMP output buffer for " PUB_S_SRP " at route.c:%d", interface->name, towire.line); 721 towire.error = 0; 722 } else { 723 SEGMENTED_IPv6_ADDR_GEN_SRP(destination->s6_addr, destination_buf); 724 INFO("sending advertisement to " PRI_SEGMENTED_IPv6_ADDR_SRP " on " PUB_S_SRP, 725 SEGMENTED_IPv6_ADDR_PARAM_SRP(destination->s6_addr, destination_buf), 726 interface->name); 727 icmp_send(message, towire.p - message, interface, destination); 728 } 729 free(message); 730 } 731 732 void 733 router_solicit_send(interface_t *interface) 734 { 735 uint8_t *message; 736 dns_towire_state_t towire; 737 738 // Thread blocks RSs so no point sending them. 739 if (interface->inactive 740 #ifndef RA_TESTER 741 || interface->is_thread 742 #endif 743 ) { 744 return; 745 } 746 #define MAX_ICMP_MESSAGE 1280 747 message = malloc(MAX_ICMP_MESSAGE); 748 if (message == NULL) { 749 ERROR("Unable to construct ICMP Router Advertisement: no memory"); 750 return; 751 } 752 753 // Construct the ICMP header and options for each interface. 754 memset(&towire, 0, sizeof towire); 755 towire.p = message; 756 towire.lim = message + MAX_ICMP_MESSAGE; 757 758 // Construct the ICMP header. 759 // We use the DNS message construction functions because it's easy; probably should just make 760 // the towire functions more generic. 761 dns_u8_to_wire(&towire, ND_ROUTER_SOLICIT); // icmp6_type 762 dns_u8_to_wire(&towire, 0); // icmp6_code 763 dns_u16_to_wire(&towire, 0); // The kernel computes the checksum (we don't technically have it). 764 dns_u32_to_wire(&towire, 0); // Reserved32 765 766 // Send Source link-layer address option 767 if (interface->have_link_layer_address) { 768 dns_u8_to_wire(&towire, ND_OPT_SOURCE_LINKADDR); 769 dns_u8_to_wire(&towire, 1); // length / 8 770 dns_rdata_raw_data_to_wire(&towire, &interface->link_layer, sizeof(interface->link_layer)); 771 } 772 773 if (towire.error) { 774 ERROR("No space in ICMP output buffer for " PUB_S_SRP " at route.c:%d", interface->name, towire.line); 775 } else { 776 if (interface->have_link_layer_address) { 777 INFO("sending router solicit on " PUB_S_SRP " to all routers with source " PRI_MAC_ADDR_SRP, 778 interface->name, MAC_ADDR_PARAM_SRP(interface->link_layer)); 779 } else { 780 INFO("sending router solicit on " PUB_S_SRP " to all routers", interface->name); 781 } 782 icmp_send(message, towire.p - message, interface, &in6addr_linklocal_allrouters); 783 } 784 free(message); 785 } 786 787 void 788 neighbor_solicit_send(interface_t *interface, struct in6_addr *destination) 789 { 790 uint8_t *message; 791 dns_towire_state_t towire; 792 793 #define MAX_ICMP_MESSAGE 1280 794 message = malloc(MAX_ICMP_MESSAGE); 795 if (message == NULL) { 796 ERROR("Unable to construct ICMP Router Advertisement: no memory"); 797 return; 798 } 799 800 // Construct the ICMP header and options for each interface. 801 memset(&towire, 0, sizeof towire); 802 towire.p = message; 803 towire.lim = message + MAX_ICMP_MESSAGE; 804 805 // Construct the ICMP header. 806 // We use the DNS message construction functions because it's easy; probably should just make 807 // the towire functions more generic. 808 dns_u8_to_wire(&towire, ND_NEIGHBOR_SOLICIT); // icmp6_type 809 dns_u8_to_wire(&towire, 0); // icmp6_code 810 dns_u16_to_wire(&towire, 0); // The kernel computes the checksum (we don't technically have it). 811 dns_u32_to_wire(&towire, 0); // Reserved32 812 dns_rdata_raw_data_to_wire(&towire, destination, sizeof(*destination)); // Target address of solicit 813 814 // Send Source link-layer address option 815 if (interface->have_link_layer_address) { 816 dns_u8_to_wire(&towire, ND_OPT_SOURCE_LINKADDR); 817 dns_u8_to_wire(&towire, 1); // length / 8 818 dns_rdata_raw_data_to_wire(&towire, &interface->link_layer, sizeof(interface->link_layer)); 819 } 820 821 if (towire.error) { 822 ERROR("No space in ICMP output buffer for " PUB_S_SRP " at route.c:%d", interface->name, towire.line); 823 } else { 824 SEGMENTED_IPv6_ADDR_GEN_SRP(destination, dest_buf); 825 if (interface->have_link_layer_address) { 826 INFO("sending neighbor solicit on " PUB_S_SRP " to " PRI_SEGMENTED_IPv6_ADDR_SRP " with source " PRI_MAC_ADDR_SRP, 827 interface->name, SEGMENTED_IPv6_ADDR_PARAM_SRP(destination, dest_buf), MAC_ADDR_PARAM_SRP(interface->link_layer)); 828 } else { 829 INFO("sending neighbor solicit on " PUB_S_SRP " to " PRI_SEGMENTED_IPv6_ADDR_SRP, 830 interface->name, SEGMENTED_IPv6_ADDR_PARAM_SRP(destination, dest_buf)); 831 } 832 icmp_send(message, towire.p - message, interface, destination); 833 } 834 free(message); 835 } 836 837 bool 838 start_icmp_listener(void) 839 { 840 #ifndef SRP_TEST_SERVER 841 int sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); 842 int true_flag = 1; 843 #ifdef CONFIGURE_STATIC_INTERFACE_ADDRESSES 844 int false_flag = 0; 845 #endif 846 struct icmp6_filter filter; 847 ssize_t rv; 848 849 if (sock < 0) { 850 ERROR("Unable to listen for icmp messages: " PUB_S_SRP, strerror(errno)); 851 close(sock); 852 return false; 853 } 854 855 // Only accept router advertisements and router solicits. 856 ICMP6_FILTER_SETBLOCKALL(&filter); 857 ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter); 858 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter); 859 ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter); 860 rv = setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof(filter)); 861 if (rv < 0) { 862 ERROR("Can't set IPV6_RECVHOPLIMIT: " PUB_S_SRP ".", strerror(errno)); 863 close(sock); 864 return false; 865 } 866 867 // We want a source address and interface index 868 rv = setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &true_flag, sizeof(true_flag)); 869 if (rv < 0) { 870 ERROR("Can't set IPV6_RECVPKTINFO: " PUB_S_SRP ".", strerror(errno)); 871 close(sock); 872 return false; 873 } 874 875 // We need to be able to reject RAs arriving from off-link. 876 rv = setsockopt(sock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &true_flag, sizeof(true_flag)); 877 if (rv < 0) { 878 ERROR("Can't set IPV6_RECVHOPLIMIT: " PUB_S_SRP ".", strerror(errno)); 879 close(sock); 880 return false; 881 } 882 883 #ifdef CONFIGURE_STATIC_INTERFACE_ADDRESSES 884 // Prevent our router advertisements from updating our routing table. 885 rv = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &false_flag, sizeof(false_flag)); 886 if (rv < 0) { 887 ERROR("Can't set IPV6_RECVHOPLIMIT: " PUB_S_SRP ".", strerror(errno)); 888 close(sock); 889 return false; 890 } 891 #endif 892 893 icmp_listener.io_state = ioloop_file_descriptor_create(sock, NULL, NULL); 894 if (icmp_listener.io_state == NULL) { 895 ERROR("No memory for ICMP I/O structure."); 896 close(sock); 897 return false; 898 } 899 900 // Beacon out a router advertisement every three minutes. 901 icmp_listener.unsolicited_interval = 3 * 60 * 1000; 902 ioloop_add_reader(icmp_listener.io_state, icmp_callback); 903 #else 904 (void)icmp_callback; 905 #endif // !SRP_TEST_SERVER 906 907 return true; 908 } 909 910 void 911 icmp_interface_subscribe(interface_t *interface, bool added) 912 { 913 struct ipv6_mreq req; 914 int rv; 915 916 if (icmp_listener.io_state == NULL) { 917 ERROR("Interface subscribe without ICMP listener."); 918 return; 919 } 920 921 memset(&req, 0, sizeof req); 922 if (interface->index == -1) { 923 ERROR("icmp_interface_subscribe called before interface index fetch for " PUB_S_SRP, interface->name); 924 return; 925 } 926 927 req.ipv6mr_multiaddr = in6addr_linklocal_allrouters; 928 req.ipv6mr_interface = interface->index; 929 rv = setsockopt(icmp_listener.io_state->fd, IPPROTO_IPV6, added ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP, &req, 930 sizeof req); 931 if (rv < 0) { 932 ERROR("Unable to " PUB_S_SRP " all-routers multicast group on " PUB_S_SRP ": " PUB_S_SRP, 933 added ? "join" : "leave", interface->name, strerror(errno)); 934 return; 935 } else { 936 INFO(PUB_S_SRP "subscribed on interface " PUB_S_SRP, added ? "" : "un", 937 interface->name); 938 } 939 940 req.ipv6mr_multiaddr = in6addr_linklocal_allnodes; 941 req.ipv6mr_interface = interface->index; 942 rv = setsockopt(icmp_listener.io_state->fd, IPPROTO_IPV6, added ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP, &req, 943 sizeof req); 944 if (rv < 0) { 945 ERROR("Unable to " PUB_S_SRP " all-nodes multicast group on " PUB_S_SRP ": " PUB_S_SRP, 946 added ? "join" : "leave", interface->name, strerror(errno)); 947 return; 948 } else { 949 INFO(PUB_S_SRP "subscribed on interface " PUB_S_SRP, added ? "" : "un", 950 interface->name); 951 } 952 953 } 954 955 956 // Local Variables: 957 // mode: C 958 // tab-width: 4 959 // c-file-style: "bsd" 960 // c-basic-offset: 4 961 // fill-column: 120 962 // indent-tabs-mode: nil 963 // End: 964