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