1 /* 2 * Copyright 2006-2007, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 */ 8 9 10 #include "datalink.h" 11 #include "domains.h" 12 #include "interfaces.h" 13 #include "routes.h" 14 #include "stack_private.h" 15 16 #include <net_device.h> 17 #include <KernelExport.h> 18 #include <util/AutoLock.h> 19 20 #include <net/if.h> 21 #include <net/if_media.h> 22 #include <net/route.h> 23 #include <sys/sockio.h> 24 25 #include <new> 26 #include <stdlib.h> 27 #include <stdio.h> 28 #include <string.h> 29 30 31 struct datalink_protocol : net_protocol { 32 struct net_domain_private *domain; 33 }; 34 35 struct interface_protocol : net_datalink_protocol { 36 struct net_device_module_info *device_module; 37 struct net_device *device; 38 }; 39 40 41 static status_t 42 device_reader_thread(void *_interface) 43 { 44 net_device_interface *interface = (net_device_interface *)_interface; 45 net_device *device = interface->device; 46 status_t status = B_OK; 47 48 while ((device->flags & IFF_UP) != 0) { 49 net_buffer *buffer; 50 status = device->module->receive_data(device, &buffer); 51 if (status == B_OK) { 52 //dprintf("received buffer of %ld bytes length\n", buffer->size); 53 54 // feed device monitors 55 // TODO: locking! 56 DeviceMonitorList::Iterator iterator 57 = interface->monitor_funcs.GetIterator(); 58 while (iterator.HasNext()) { 59 net_device_monitor *monitor = iterator.Next(); 60 monitor->func(monitor->cookie, buffer); 61 } 62 63 int32 type = interface->deframe_func(device, buffer); 64 if (type >= 0) { 65 // find handler for this packet 66 // TODO: locking! 67 DeviceHandlerList::Iterator iterator 68 = interface->receive_funcs.GetIterator(); 69 status = B_ERROR; 70 71 while (iterator.HasNext()) { 72 net_device_handler *handler = iterator.Next(); 73 74 if (handler->type == type) { 75 status = handler->func(handler->cookie, buffer); 76 if (status == B_OK) 77 break; 78 } 79 } 80 } else 81 status = type; 82 83 if (status == B_OK) { 84 // the buffer no longer belongs to us 85 continue; 86 } 87 88 gNetBufferModule.free(buffer); 89 } else { 90 // In case of error, give the other threads some 91 // time to run since this is a near real time thread. 92 // 93 // TODO: can this value be lower? 1000 works fine in 94 // my system. 10ms seems a bit too much and adds 95 // as latency. 96 snooze(10000); 97 } 98 99 // if the interface went down IFF_UP was removed 100 // and the receive_data() above should have been 101 // interrupted. One check should be enough, specially 102 // considering the snooze above. 103 // 104 // TODO: make sure that when receive_data() returns 105 // after closing the new device->flags are 106 // already visible in all processors. 107 } 108 109 return status; 110 } 111 112 113 static struct sockaddr ** 114 interface_address(net_interface *interface, int32 option) 115 { 116 switch (option) { 117 case SIOCSIFADDR: 118 case SIOCGIFADDR: 119 return &interface->address; 120 121 case SIOCSIFNETMASK: 122 case SIOCGIFNETMASK: 123 return &interface->mask; 124 125 case SIOCSIFBRDADDR: 126 case SIOCSIFDSTADDR: 127 case SIOCGIFBRDADDR: 128 case SIOCGIFDSTADDR: 129 return &interface->destination; 130 131 default: 132 return NULL; 133 } 134 } 135 136 137 void 138 remove_default_routes(net_interface_private *interface, int32 option) 139 { 140 net_route route; 141 route.destination = interface->address; 142 route.gateway = NULL; 143 route.interface = interface; 144 145 if (interface->mask != NULL 146 && (option == SIOCSIFNETMASK || option == SIOCSIFADDR)) { 147 route.mask = interface->mask; 148 route.flags = 0; 149 remove_route(interface->domain, &route); 150 } 151 152 if (option == SIOCSIFADDR) { 153 route.mask = NULL; 154 route.flags = RTF_LOCAL | RTF_HOST; 155 remove_route(interface->domain, &route); 156 } 157 } 158 159 160 void 161 add_default_routes(net_interface_private *interface, int32 option) 162 { 163 net_route route; 164 route.destination = interface->address; 165 route.gateway = NULL; 166 route.interface = interface; 167 168 if (interface->mask != NULL 169 && (option == SIOCSIFNETMASK || option == SIOCSIFADDR)) { 170 route.mask = interface->mask; 171 route.flags = 0; 172 add_route(interface->domain, &route); 173 } 174 175 if (option == SIOCSIFADDR) { 176 route.mask = NULL; 177 route.flags = RTF_LOCAL | RTF_HOST; 178 add_route(interface->domain, &route); 179 } 180 } 181 182 183 // #pragma mark - datalink module 184 185 186 status_t 187 datalink_control(net_domain *_domain, int32 option, void *value, 188 size_t *_length) 189 { 190 net_domain_private *domain = (net_domain_private *)_domain; 191 if (domain == NULL || domain->family == AF_LINK) { 192 // the AF_LINK family is already handled completely in the link protocol 193 return B_BAD_VALUE; 194 } 195 196 switch (option) { 197 case SIOCGIFINDEX: 198 { 199 // get index of interface 200 struct ifreq request; 201 if (user_memcpy(&request, value, IF_NAMESIZE) < B_OK) 202 return B_BAD_ADDRESS; 203 204 benaphore_lock(&domain->lock); 205 206 net_interface *interface = find_interface(domain, 207 request.ifr_name); 208 if (interface != NULL) 209 request.ifr_index = interface->index; 210 else 211 request.ifr_index = 0; 212 213 benaphore_unlock(&domain->lock); 214 215 if (request.ifr_index == 0) 216 return ENODEV; 217 218 return user_memcpy(value, &request, sizeof(struct ifreq)); 219 } 220 case SIOCGIFNAME: 221 { 222 // get name of interface via index 223 struct ifreq request; 224 if (user_memcpy(&request, value, sizeof(struct ifreq)) < B_OK) 225 return B_BAD_ADDRESS; 226 227 benaphore_lock(&domain->lock); 228 status_t status = B_OK; 229 230 net_interface *interface = find_interface(domain, 231 request.ifr_index); 232 if (interface != NULL) 233 strlcpy(request.ifr_name, interface->name, IF_NAMESIZE); 234 else 235 status = B_BAD_VALUE; 236 237 benaphore_unlock(&domain->lock); 238 239 if (status < B_OK) 240 return status; 241 242 return user_memcpy(value, &request, sizeof(struct ifreq)); 243 } 244 245 case SIOCAIFADDR: 246 { 247 // add new interface address 248 struct ifreq request; 249 if (user_memcpy(&request, value, sizeof(struct ifreq)) < B_OK) 250 return B_BAD_ADDRESS; 251 252 return add_interface_to_domain(domain, request); 253 } 254 case SIOCDIFADDR: 255 { 256 // remove interface address 257 struct ifreq request; 258 if (user_memcpy(&request, value, sizeof(struct ifreq)) < B_OK) 259 return B_BAD_ADDRESS; 260 261 BenaphoreLocker _(domain->lock); 262 263 net_interface *interface = find_interface(domain, 264 request.ifr_name); 265 if (interface == NULL) 266 return ENODEV; 267 return remove_interface_from_domain(interface); 268 } 269 270 case SIOCGIFCOUNT: 271 { 272 // count number of interfaces 273 struct ifconf config; 274 config.ifc_value = count_domain_interfaces(); 275 276 return user_memcpy(value, &config, sizeof(struct ifconf)); 277 } 278 279 case SIOCGIFCONF: 280 { 281 // retrieve ifreqs for all interfaces 282 struct ifconf config; 283 if (user_memcpy(&config, value, sizeof(struct ifconf)) < B_OK) 284 return B_BAD_ADDRESS; 285 286 status_t result = list_domain_interfaces(config.ifc_buf, 287 (size_t *)&config.ifc_len); 288 if (result != B_OK) 289 return result; 290 291 return user_memcpy(value, &config, sizeof(struct ifconf)); 292 } 293 294 case SIOCGRTSIZE: 295 { 296 // determine size of buffer to hold the routing table 297 struct ifconf config; 298 config.ifc_value = route_table_size(domain); 299 300 return user_memcpy(value, &config, sizeof(struct ifconf)); 301 } 302 case SIOCGRTTABLE: 303 { 304 // retrieve all routes for this domain 305 struct ifconf config; 306 if (user_memcpy(&config, value, sizeof(struct ifconf)) < B_OK) 307 return B_BAD_ADDRESS; 308 309 return list_routes(domain, config.ifc_buf, config.ifc_len); 310 } 311 case SIOCGETRT: 312 return get_route_information(domain, value, *_length); 313 314 default: 315 { 316 // try to pass the request to an existing interface 317 318 struct ifreq request; 319 if (user_memcpy(&request, value, sizeof(struct ifreq)) < B_OK) 320 return B_BAD_ADDRESS; 321 322 BenaphoreLocker _(domain->lock); 323 status_t status = B_OK; 324 325 net_interface *interface = find_interface(domain, 326 request.ifr_name); 327 if (interface != NULL) { 328 // filter out bringing the interface up or down 329 if (option == SIOCSIFFLAGS) { 330 if (((uint32)request.ifr_flags & IFF_UP) 331 != (interface->flags & IFF_UP)) { 332 if ((interface->flags & IFF_UP) != 0) { 333 interface_set_down(interface); 334 } else { 335 // bring it up 336 status = interface->first_info->interface_up( 337 interface->first_protocol); 338 if (status == B_OK) { 339 interface->flags |= IFF_UP 340 | (interface->device->media & IFM_ACTIVE 341 ? IFF_LINK : 0); 342 } 343 } 344 } 345 346 if (status == B_OK) 347 interface->flags |= request.ifr_flags & ~(IFF_UP | IFF_LINK); 348 } else { 349 // pass the request into the datalink protocol stack 350 status = interface->first_info->control( 351 interface->first_protocol, option, value, *_length); 352 } 353 } else 354 status = B_BAD_VALUE; 355 356 return status; 357 } 358 } 359 return B_BAD_VALUE; 360 } 361 362 363 status_t 364 datalink_send_data(struct net_route *route, net_buffer *buffer) 365 { 366 net_interface *interface = route->interface; 367 net_domain *domain = interface->domain; 368 369 //dprintf("send buffer (%ld bytes) to interface %s (route flags %lx)\n", 370 // buffer->size, interface->name, route->flags); 371 372 if (route->flags & RTF_REJECT) 373 return ENETUNREACH; 374 375 if (route->flags & RTF_LOCAL) { 376 // this one goes back to the domain directly 377 return domain->module->receive_data(buffer); 378 } 379 380 if (route->flags & RTF_GATEWAY) { 381 // this route involves a gateway, we need to use the gateway address 382 // instead of the destination address: 383 if (route->gateway == NULL) 384 return B_MISMATCHED_VALUES; 385 memcpy(&buffer->destination, route->gateway, sizeof(sockaddr)); 386 } 387 388 // this goes out to the datalink protocols 389 return interface->first_info->send_data(interface->first_protocol, buffer); 390 } 391 392 393 /*! 394 Tests if \a address is a local address in the domain. 395 \param _interface will be set to the interface belonging to that address 396 if non-NULL. 397 \param _matchedType will be set to either zero or MSG_BCAST if non-NULL. 398 */ 399 bool 400 datalink_is_local_address(net_domain *_domain, const struct sockaddr *address, 401 net_interface **_interface, uint32 *_matchedType) 402 { 403 net_domain_private *domain = (net_domain_private *)_domain; 404 if (domain == NULL || address == NULL) 405 return false; 406 407 BenaphoreLocker locker(domain->lock); 408 409 net_interface *interface = NULL; 410 net_interface *fallback = NULL; 411 uint32 matchedType = 0; 412 413 while (true) { 414 interface = (net_interface *)list_get_next_item( 415 &domain->interfaces, interface); 416 if (interface == NULL) 417 break; 418 if (interface->address == NULL) { 419 fallback = interface; 420 continue; 421 } 422 423 // check for matching unicast address first 424 if (domain->address_module->equal_addresses(interface->address, address)) 425 break; 426 427 // check for matching broadcast address if interface support broadcasting 428 if (interface->flags & IFF_BROADCAST 429 && domain->address_module->equal_addresses(interface->destination, 430 address)) { 431 matchedType = MSG_BCAST; 432 break; 433 } 434 } 435 436 if (interface == NULL) { 437 interface = fallback; 438 if (interface == NULL) 439 return false; 440 } 441 442 if (_interface != NULL) 443 *_interface = interface; 444 if (_matchedType != NULL) 445 *_matchedType = matchedType; 446 return true; 447 } 448 449 450 static status_t 451 datalink_std_ops(int32 op, ...) 452 { 453 switch (op) { 454 case B_MODULE_INIT: 455 case B_MODULE_UNINIT: 456 return B_OK; 457 458 default: 459 return B_ERROR; 460 } 461 } 462 463 464 // #pragma mark - net_datalink_protocol 465 466 467 status_t 468 interface_protocol_init(struct net_interface *_interface, net_datalink_protocol **_protocol) 469 { 470 net_interface_private *interface = (net_interface_private *)_interface; 471 472 interface_protocol *protocol = new (std::nothrow) interface_protocol; 473 if (protocol == NULL) 474 return B_NO_MEMORY; 475 476 protocol->device_module = interface->device->module; 477 protocol->device = interface->device; 478 479 *_protocol = protocol; 480 return B_OK; 481 } 482 483 484 status_t 485 interface_protocol_uninit(net_datalink_protocol *protocol) 486 { 487 delete protocol; 488 return B_OK; 489 } 490 491 492 status_t 493 interface_protocol_send_data(net_datalink_protocol *_protocol, 494 net_buffer *buffer) 495 { 496 interface_protocol *protocol = (interface_protocol *)_protocol; 497 net_interface_private *interface = (net_interface_private *)protocol->interface; 498 499 // feed device monitors 500 // TODO: locking! 501 DeviceMonitorList::Iterator iterator = 502 interface->device_interface->monitor_funcs.GetIterator(); 503 while (iterator.HasNext()) { 504 net_device_monitor *monitor = iterator.Next(); 505 monitor->func(monitor->cookie, buffer); 506 } 507 508 return protocol->device_module->send_data(protocol->device, buffer); 509 } 510 511 512 status_t 513 interface_protocol_up(net_datalink_protocol *_protocol) 514 { 515 interface_protocol *protocol = (interface_protocol *)_protocol; 516 net_device_interface *deviceInterface = 517 ((net_interface_private *)protocol->interface)->device_interface; 518 net_device *device = protocol->device; 519 520 // TODO: locking! 521 522 if (deviceInterface->up_count != 0) { 523 deviceInterface->up_count++; 524 return B_OK; 525 } 526 527 status_t status = protocol->device_module->up(device); 528 if (status < B_OK) 529 return status; 530 531 // give the thread a nice name 532 char name[B_OS_NAME_LENGTH]; 533 snprintf(name, sizeof(name), "%s reader", device->name); 534 535 deviceInterface->reader_thread = spawn_kernel_thread(device_reader_thread, name, 536 B_REAL_TIME_DISPLAY_PRIORITY - 10, deviceInterface); 537 if (deviceInterface->reader_thread < B_OK) 538 return deviceInterface->reader_thread; 539 540 device->flags |= IFF_UP; 541 resume_thread(deviceInterface->reader_thread); 542 543 deviceInterface->up_count = 1; 544 return B_OK; 545 } 546 547 548 void 549 interface_protocol_down(net_datalink_protocol *_protocol) 550 { 551 interface_protocol *protocol = (interface_protocol *)_protocol; 552 net_device_interface *deviceInterface = 553 ((net_interface_private *)protocol->interface)->device_interface; 554 555 // TODO: locking! 556 if (deviceInterface->up_count == 0) 557 return; 558 559 deviceInterface->up_count--; 560 561 domain_interface_went_down(protocol->interface); 562 563 if (deviceInterface->up_count > 0) 564 return; 565 566 down_device_interface(deviceInterface); 567 } 568 569 570 status_t 571 interface_protocol_control(net_datalink_protocol *_protocol, 572 int32 option, void *argument, size_t length) 573 { 574 interface_protocol *protocol = (interface_protocol *)_protocol; 575 net_interface_private *interface = (net_interface_private *)protocol->interface; 576 577 switch (option) { 578 case SIOCSIFADDR: 579 case SIOCSIFNETMASK: 580 case SIOCSIFBRDADDR: 581 case SIOCSIFDSTADDR: 582 { 583 // set logical interface address 584 struct ifreq request; 585 if (user_memcpy(&request, argument, sizeof(struct ifreq)) < B_OK) 586 return B_BAD_ADDRESS; 587 588 sockaddr **_address = interface_address(interface, option); 589 if (_address == NULL) 590 return B_BAD_VALUE; 591 592 sockaddr *address = *_address; 593 sockaddr *original = address; 594 595 // allocate new address if needed 596 if (address == NULL 597 || (address->sa_len < request.ifr_addr.sa_len 598 && request.ifr_addr.sa_len > sizeof(struct sockaddr))) { 599 address = (sockaddr *)malloc( 600 max_c(request.ifr_addr.sa_len, sizeof(struct sockaddr))); 601 } 602 603 // copy new address over 604 if (address != NULL) { 605 remove_default_routes(interface, option); 606 607 if (original != address) { 608 free(original); 609 *_address = address; 610 } 611 612 memcpy(address, &request.ifr_addr, request.ifr_addr.sa_len); 613 add_default_routes(interface, option); 614 } 615 616 return address != NULL ? B_OK : B_NO_MEMORY; 617 } 618 619 case SIOCGIFADDR: 620 case SIOCGIFNETMASK: 621 case SIOCGIFBRDADDR: 622 case SIOCGIFDSTADDR: 623 { 624 // get logical interface address 625 sockaddr **_address = interface_address(interface, option); 626 if (_address == NULL) 627 return B_BAD_VALUE; 628 629 struct ifreq request; 630 631 sockaddr *address = *_address; 632 if (address != NULL) 633 memcpy(&request.ifr_addr, address, address->sa_len); 634 else { 635 request.ifr_addr.sa_len = 2; 636 request.ifr_addr.sa_family = AF_UNSPEC; 637 } 638 639 // copy address over 640 return user_memcpy(&((struct ifreq *)argument)->ifr_addr, 641 &request.ifr_addr, request.ifr_addr.sa_len); 642 } 643 644 case SIOCGIFFLAGS: 645 { 646 // get flags 647 struct ifreq request; 648 request.ifr_flags = interface->flags; 649 650 return user_memcpy(&((struct ifreq *)argument)->ifr_flags, 651 &request.ifr_flags, sizeof(request.ifr_flags)); 652 } 653 654 case SIOCGIFPARAM: 655 { 656 // get interface parameter 657 struct ifreq request; 658 strlcpy(request.ifr_parameter.base_name, interface->base_name, IF_NAMESIZE); 659 strlcpy(request.ifr_parameter.device, interface->device_interface->name, 660 IF_NAMESIZE); 661 request.ifr_parameter.sub_type = 0; 662 // TODO: for now, we ignore the sub type... 663 664 return user_memcpy(&((struct ifreq *)argument)->ifr_parameter, 665 &request.ifr_parameter, sizeof(request.ifr_parameter)); 666 } 667 668 case SIOCGIFSTATS: 669 { 670 // get stats 671 return user_memcpy(&((struct ifreq *)argument)->ifr_stats, 672 &interface->device_interface->device->stats, 673 sizeof(struct ifreq_stats)); 674 } 675 676 case SIOCGIFTYPE: 677 { 678 // get type 679 struct ifreq request; 680 request.ifr_type = interface->type; 681 682 return user_memcpy(&((struct ifreq *)argument)->ifr_type, 683 &request.ifr_type, sizeof(request.ifr_type)); 684 } 685 686 case SIOCGIFMTU: 687 { 688 // get MTU 689 struct ifreq request; 690 request.ifr_mtu = interface->mtu; 691 692 return user_memcpy(&((struct ifreq *)argument)->ifr_mtu, 693 &request.ifr_mtu, sizeof(request.ifr_mtu)); 694 } 695 case SIOCSIFMTU: 696 { 697 // set MTU 698 struct ifreq request; 699 if (user_memcpy(&request, argument, sizeof(struct ifreq)) < B_OK) 700 return B_BAD_ADDRESS; 701 702 // check for valid bounds 703 if (request.ifr_mtu < 100 704 || (uint32)request.ifr_mtu > interface->device->mtu) 705 return B_BAD_VALUE; 706 707 interface->mtu = request.ifr_mtu; 708 return B_OK; 709 } 710 711 case SIOCSIFMEDIA: 712 { 713 // set media 714 struct ifreq request; 715 if (user_memcpy(&request, argument, sizeof(struct ifreq)) < B_OK) 716 return B_BAD_ADDRESS; 717 718 return interface->device_interface->module->set_media( 719 interface->device, request.ifr_media); 720 } 721 case SIOCGIFMEDIA: 722 { 723 // get media 724 struct ifreq request; 725 request.ifr_media = interface->device->media; 726 727 return user_memcpy(&((struct ifreq *)argument)->ifr_media, 728 &request.ifr_media, sizeof(request.ifr_media)); 729 } 730 731 case SIOCGIFMETRIC: 732 { 733 // get metric 734 struct ifreq request; 735 request.ifr_metric = interface->metric; 736 737 return user_memcpy(&((struct ifreq *)argument)->ifr_metric, 738 &request.ifr_metric, sizeof(request.ifr_metric)); 739 } 740 case SIOCSIFMETRIC: 741 { 742 // set metric 743 struct ifreq request; 744 if (user_memcpy(&request, argument, sizeof(struct ifreq)) < B_OK) 745 return B_BAD_ADDRESS; 746 747 interface->metric = request.ifr_metric; 748 return B_OK; 749 } 750 751 case SIOCADDRT: 752 case SIOCDELRT: 753 // interface related route options 754 return control_routes(interface, option, argument, length); 755 } 756 757 return protocol->device_module->control(protocol->device, 758 option, argument, length); 759 } 760 761 762 net_datalink_module_info gNetDatalinkModule = { 763 { 764 NET_DATALINK_MODULE_NAME, 765 0, 766 datalink_std_ops 767 }, 768 769 datalink_control, 770 datalink_send_data, 771 datalink_is_local_address, 772 773 add_route, 774 remove_route, 775 get_route, 776 put_route, 777 register_route_info, 778 unregister_route_info, 779 update_route_info 780 }; 781 782 net_datalink_protocol_module_info gDatalinkInterfaceProtocolModule = { 783 { 784 NULL, 785 0, 786 NULL 787 }, 788 interface_protocol_init, 789 interface_protocol_uninit, 790 interface_protocol_send_data, 791 interface_protocol_up, 792 interface_protocol_down, 793 interface_protocol_control, 794 }; 795