1 /* 2 * Copyright 2006-2010, 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 * Vegard Wærp, vegarwa@online.no 8 */ 9 10 11 #include "NetServer.h" 12 13 #include <errno.h> 14 #include <map> 15 #include <stdio.h> 16 #include <stdlib.h> 17 #include <string> 18 #include <string.h> 19 #include <unistd.h> 20 21 #include <arpa/inet.h> 22 #include <net/if_dl.h> 23 #include <net/if_types.h> 24 #include <netinet/in.h> 25 #include <sys/socket.h> 26 #include <sys/sockio.h> 27 28 #include <Alert.h> 29 #include <Deskbar.h> 30 #include <Directory.h> 31 #include <Entry.h> 32 #include <Path.h> 33 #include <PathMonitor.h> 34 #include <Roster.h> 35 #include <Server.h> 36 #include <TextView.h> 37 #include <FindDirectory.h> 38 39 #include "AutoconfigLooper.h" 40 #include "Services.h" 41 #include "Settings.h" 42 43 44 typedef std::map<std::string, AutoconfigLooper*> LooperMap; 45 46 47 class NetServer : public BServer { 48 public: 49 NetServer(status_t& status); 50 virtual ~NetServer(); 51 52 virtual void AboutRequested(); 53 virtual void ReadyToRun(); 54 virtual void MessageReceived(BMessage* message); 55 56 private: 57 bool _IsValidInterface(int socket, const char* name); 58 void _RemoveInvalidInterfaces(int socket); 59 status_t _RemoveInterface(int socket, const char* name); 60 status_t _DisableInterface(int socket, const char* name); 61 bool _TestForInterface(int socket, const char* name); 62 status_t _ConfigureInterface(int socket, 63 BMessage& interface, 64 bool fromMessage = false); 65 status_t _ConfigureResolver( 66 BMessage& resolverConfiguration); 67 bool _QuitLooperForDevice(const char* device); 68 AutoconfigLooper* _LooperForDevice(const char* device); 69 status_t _ConfigureDevice(int socket, const char* path); 70 void _ConfigureDevices(int socket, const char* path, 71 BMessage* suggestedInterface = NULL); 72 void _ConfigureInterfaces(int socket, 73 BMessage* _missingDevice = NULL); 74 void _BringUpInterfaces(); 75 void _StartServices(); 76 void _HandleDeviceMonitor(int socket, 77 BMessage* message); 78 79 private: 80 Settings fSettings; 81 LooperMap fDeviceMap; 82 BMessenger fServices; 83 }; 84 85 86 struct address_family { 87 int family; 88 const char* name; 89 const char* identifiers[4]; 90 bool (*parse_address)(const char* string, sockaddr* _address); 91 void (*set_any_address)(sockaddr* address); 92 void (*set_port)(sockaddr* address, int32 port); 93 }; 94 95 96 // AF_INET family 97 static bool inet_parse_address(const char* string, sockaddr* address); 98 static void inet_set_any_address(sockaddr* address); 99 static void inet_set_port(sockaddr* address, int32 port); 100 101 static const address_family kFamilies[] = { 102 { 103 AF_INET, 104 "inet", 105 {"AF_INET", "inet", "ipv4", NULL}, 106 inet_parse_address, 107 inet_set_any_address, 108 inet_set_port 109 }, 110 { -1, NULL, {NULL}, NULL } 111 }; 112 113 114 static bool 115 inet_parse_address(const char* string, sockaddr* _address) 116 { 117 in_addr inetAddress; 118 119 if (inet_aton(string, &inetAddress) != 1) 120 return false; 121 122 sockaddr_in& address = *(sockaddr_in *)_address; 123 address.sin_family = AF_INET; 124 address.sin_len = sizeof(struct sockaddr_in); 125 address.sin_port = 0; 126 address.sin_addr = inetAddress; 127 memset(&address.sin_zero[0], 0, sizeof(address.sin_zero)); 128 129 return true; 130 } 131 132 133 void 134 inet_set_any_address(sockaddr* _address) 135 { 136 sockaddr_in& address = *(sockaddr_in*)_address; 137 address.sin_family = AF_INET; 138 address.sin_len = sizeof(struct sockaddr_in); 139 address.sin_port = 0; 140 address.sin_addr.s_addr = INADDR_ANY; 141 memset(&address.sin_zero[0], 0, sizeof(address.sin_zero)); 142 } 143 144 145 void 146 inet_set_port(sockaddr* _address, int32 port) 147 { 148 sockaddr_in& address = *(sockaddr_in*)_address; 149 address.sin_port = port; 150 } 151 152 153 // #pragma mark - 154 155 156 bool 157 get_family_index(const char* name, int32& familyIndex) 158 { 159 for (int32 i = 0; kFamilies[i].family >= 0; i++) { 160 for (int32 j = 0; kFamilies[i].identifiers[j]; j++) { 161 if (!strcmp(name, kFamilies[i].identifiers[j])) { 162 // found a match 163 familyIndex = i; 164 return true; 165 } 166 } 167 } 168 169 // defaults to AF_INET 170 familyIndex = 0; 171 return false; 172 } 173 174 175 int 176 family_at_index(int32 index) 177 { 178 return kFamilies[index].family; 179 } 180 181 182 bool 183 parse_address(int32 familyIndex, const char* argument, struct sockaddr& address) 184 { 185 if (argument == NULL) 186 return false; 187 188 return kFamilies[familyIndex].parse_address(argument, &address); 189 } 190 191 192 void 193 set_any_address(int32 familyIndex, struct sockaddr& address) 194 { 195 kFamilies[familyIndex].set_any_address(&address); 196 } 197 198 199 void 200 set_port(int32 familyIndex, struct sockaddr& address, int32 port) 201 { 202 kFamilies[familyIndex].set_port(&address, port); 203 } 204 205 206 bool 207 prepare_request(ifreq& request, const char* name) 208 { 209 if (strlen(name) > IF_NAMESIZE) 210 return false; 211 212 strcpy(request.ifr_name, name); 213 return true; 214 } 215 216 217 status_t 218 get_mac_address(const char* device, uint8* address) 219 { 220 int socket = ::socket(AF_LINK, SOCK_DGRAM, 0); 221 if (socket < 0) 222 return errno; 223 224 ifreq request; 225 if (!prepare_request(request, device)) { 226 close(socket); 227 return B_ERROR; 228 } 229 230 if (ioctl(socket, SIOCGIFADDR, &request, sizeof(struct ifreq)) < 0) { 231 close(socket); 232 return errno; 233 } 234 235 close(socket); 236 237 sockaddr_dl &link = *(sockaddr_dl *)&request.ifr_addr; 238 if (link.sdl_type != IFT_ETHER) 239 return B_BAD_TYPE; 240 241 if (link.sdl_alen == 0) 242 return B_ENTRY_NOT_FOUND; 243 244 uint8 *mac = (uint8 *)LLADDR(&link); 245 memcpy(address, mac, 6); 246 247 return B_OK; 248 } 249 250 251 // #pragma mark - 252 253 254 NetServer::NetServer(status_t& error) 255 : BServer(kNetServerSignature, false, &error) 256 { 257 } 258 259 260 NetServer::~NetServer() 261 { 262 BPrivate::BPathMonitor::StopWatching("/dev/net", this); 263 } 264 265 266 void 267 NetServer::AboutRequested() 268 { 269 BAlert *alert = new BAlert("about", "Networking Server\n" 270 "\tCopyright " B_UTF8_COPYRIGHT "2006, Haiku.\n", "OK"); 271 BTextView *view = alert->TextView(); 272 BFont font; 273 274 view->SetStylable(true); 275 276 view->GetFont(&font); 277 font.SetSize(18); 278 font.SetFace(B_BOLD_FACE); 279 view->SetFontAndColor(0, 17, &font); 280 281 alert->Go(NULL); 282 } 283 284 285 void 286 NetServer::ReadyToRun() 287 { 288 fSettings.StartMonitoring(this); 289 _BringUpInterfaces(); 290 _StartServices(); 291 292 BPrivate::BPathMonitor::StartWatching("/dev/net", B_ENTRY_CREATED 293 | B_ENTRY_REMOVED | B_WATCH_FILES_ONLY | B_WATCH_RECURSIVELY, this); 294 } 295 296 297 void 298 NetServer::MessageReceived(BMessage* message) 299 { 300 switch (message->what) { 301 case B_PATH_MONITOR: 302 { 303 fSettings.Update(message); 304 305 // we need a socket to talk to the networking stack 306 int socket = ::socket(AF_INET, SOCK_DGRAM, 0); 307 if (socket < 0) 308 break; 309 _HandleDeviceMonitor(socket, message); 310 close(socket); 311 break; 312 } 313 314 case kMsgInterfaceSettingsUpdated: 315 { 316 // we need a socket to talk to the networking stack 317 int socket = ::socket(AF_INET, SOCK_DGRAM, 0); 318 if (socket < 0) 319 break; 320 321 _ConfigureInterfaces(socket); 322 close(socket); 323 break; 324 } 325 326 case kMsgServiceSettingsUpdated: 327 { 328 BMessage update = fSettings.Services(); 329 update.what = kMsgUpdateServices; 330 331 fServices.SendMessage(&update); 332 break; 333 } 334 335 case kMsgConfigureInterface: 336 { 337 #if 0 338 if (!message->ReturnAddress().IsTargetLocal()) { 339 // for now, we only accept this message from add-ons 340 break; 341 } 342 #endif 343 344 // we need a socket to talk to the networking stack 345 int socket = ::socket(AF_INET, SOCK_DGRAM, 0); 346 if (socket < 0) 347 break; 348 349 status_t status = _ConfigureInterface(socket, *message, true); 350 351 BMessage reply(B_REPLY); 352 reply.AddInt32("status", status); 353 message->SendReply(&reply); 354 355 close(socket); 356 break; 357 } 358 359 case kMsgConfigureResolver: 360 { 361 status_t status = _ConfigureResolver(*message); 362 363 BMessage reply(B_REPLY); 364 reply.AddInt32("status", status); 365 message->SendReply(&reply); 366 break; 367 } 368 369 default: 370 BApplication::MessageReceived(message); 371 return; 372 } 373 } 374 375 376 /*! 377 Checks if an interface is valid, that is, if it has an address in any 378 family, and, in case of ethernet, a hardware MAC address. 379 */ 380 bool 381 NetServer::_IsValidInterface(int socket, const char* name) 382 { 383 ifreq request; 384 if (!prepare_request(request, name)) 385 return B_ERROR; 386 387 // check if it has an address 388 389 int32 addresses = 0; 390 391 for (int32 i = 0; kFamilies[i].family >= 0; i++) { 392 int familySocket = ::socket(kFamilies[i].family, SOCK_DGRAM, 0); 393 if (familySocket < 0) 394 continue; 395 396 if (ioctl(familySocket, SIOCGIFADDR, &request, sizeof(struct ifreq)) == 0) { 397 if (request.ifr_addr.sa_family == kFamilies[i].family) 398 addresses++; 399 } 400 401 close(familySocket); 402 } 403 404 if (addresses == 0) 405 return false; 406 407 // check if it has a hardware address, too, in case of ethernet 408 409 if (ioctl(socket, SIOCGIFPARAM, &request, sizeof(struct ifreq)) < 0) 410 return false; 411 412 int linkSocket = ::socket(AF_LINK, SOCK_DGRAM, 0); 413 if (linkSocket < 0) 414 return false; 415 416 prepare_request(request, request.ifr_parameter.device); 417 if (ioctl(linkSocket, SIOCGIFADDR, &request, sizeof(struct ifreq)) < 0) { 418 close(linkSocket); 419 return false; 420 } 421 422 close(linkSocket); 423 424 sockaddr_dl &link = *(sockaddr_dl *)&request.ifr_addr; 425 if (link.sdl_type == IFT_ETHER && link.sdl_alen < 6) 426 return false; 427 428 return true; 429 } 430 431 432 void 433 NetServer::_RemoveInvalidInterfaces(int socket) 434 { 435 // get a list of all interfaces 436 437 ifconf config; 438 config.ifc_len = sizeof(config.ifc_value); 439 if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0) 440 return; 441 442 uint32 count = (uint32)config.ifc_value; 443 if (count == 0) { 444 // there are no interfaces yet 445 return; 446 } 447 448 void *buffer = malloc(count * sizeof(struct ifreq)); 449 if (buffer == NULL) { 450 fprintf(stderr, "%s: Out of memory.\n", Name()); 451 return; 452 } 453 454 config.ifc_len = count * sizeof(struct ifreq); 455 config.ifc_buf = buffer; 456 if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0) { 457 free(buffer); 458 return; 459 } 460 461 ifreq *interface = (ifreq *)buffer; 462 463 for (uint32 i = 0; i < count; i++) { 464 if (!_IsValidInterface(socket, interface->ifr_name)) { 465 // remove invalid interface 466 _RemoveInterface(socket, interface->ifr_name); 467 } 468 469 interface = (ifreq *)((addr_t)interface + IF_NAMESIZE 470 + interface->ifr_addr.sa_len); 471 } 472 473 free(buffer); 474 } 475 476 477 bool 478 NetServer::_TestForInterface(int socket, const char* name) 479 { 480 // get a list of all interfaces 481 482 ifconf config; 483 config.ifc_len = sizeof(config.ifc_value); 484 if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0) 485 return false; 486 487 uint32 count = (uint32)config.ifc_value; 488 if (count == 0) { 489 // there are no interfaces yet 490 return false; 491 } 492 493 void *buffer = malloc(count * sizeof(struct ifreq)); 494 if (buffer == NULL) { 495 fprintf(stderr, "%s: Out of memory.\n", Name()); 496 return false; 497 } 498 499 config.ifc_len = count * sizeof(struct ifreq); 500 config.ifc_buf = buffer; 501 if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0) { 502 free(buffer); 503 return false; 504 } 505 506 ifreq *interface = (ifreq *)buffer; 507 int32 nameLength = strlen(name); 508 bool success = false; 509 510 for (uint32 i = 0; i < count; i++) { 511 if (!strncmp(interface->ifr_name, name, nameLength)) { 512 success = true; 513 break; 514 } 515 516 interface = (ifreq *)((addr_t)interface + IF_NAMESIZE 517 + interface->ifr_addr.sa_len); 518 } 519 520 free(buffer); 521 return success; 522 } 523 524 525 status_t 526 NetServer::_RemoveInterface(int socket, const char* name) 527 { 528 ifreq request; 529 if (!prepare_request(request, name)) 530 return B_ERROR; 531 532 if (ioctl(socket, SIOCDIFADDR, &request, sizeof(request)) < 0) { 533 fprintf(stderr, "%s: Could not delete interface %s: %s\n", 534 Name(), name, strerror(errno)); 535 return B_ERROR; 536 } 537 538 return B_OK; 539 } 540 541 542 status_t 543 NetServer::_DisableInterface(int socket, const char* name) 544 { 545 ifreq request; 546 if (!prepare_request(request, name)) 547 return B_ERROR; 548 549 if (ioctl(socket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) < 0) { 550 fprintf(stderr, "%s: Getting flags failed: %s\n", Name(), 551 strerror(errno)); 552 return B_ERROR; 553 } 554 // Set interface down 555 request.ifr_flags &= ~(IFF_UP | IFF_AUTO_CONFIGURED | IFF_CONFIGURING); 556 557 if (ioctl(socket, SIOCSIFFLAGS, &request, sizeof(struct ifreq)) < 0) { 558 fprintf(stderr, "%s: Setting flags failed: %s\n", Name(), 559 strerror(errno)); 560 return B_ERROR; 561 } 562 563 fprintf(stderr, "%s: set %s interface down...\n", Name(), name); 564 565 return B_OK; 566 } 567 568 569 status_t 570 NetServer::_ConfigureInterface(int socket, BMessage& interface, 571 bool fromMessage) 572 { 573 const char *device; 574 if (interface.FindString("device", &device) != B_OK) 575 return B_BAD_VALUE; 576 577 ifreq request; 578 if (!prepare_request(request, device)) 579 return B_ERROR; 580 581 bool startAutoConfig = false; 582 583 int32 flags; 584 if (interface.FindInt32("flags", &flags) < B_OK) 585 flags = IFF_UP; 586 587 bool autoConfigured; 588 if (interface.FindBool("auto", &autoConfigured) == B_OK && autoConfigured) 589 flags |= IFF_AUTO_CONFIGURED; 590 591 int32 mtu; 592 if (interface.FindInt32("mtu", &mtu) < B_OK) 593 mtu = -1; 594 595 int32 metric; 596 if (interface.FindInt32("metric", &metric) < B_OK) 597 metric = -1; 598 599 BMessage addressMessage; 600 for (int32 index = 0; interface.FindMessage("address", index, 601 &addressMessage) == B_OK; index++) { 602 const char* family; 603 if (addressMessage.FindString("family", &family) < B_OK) 604 continue; 605 606 int32 familyIndex; 607 if (!get_family_index(family, familyIndex)) { 608 // we don't support this family 609 continue; 610 } 611 612 int familySocket = socket; 613 if (family_at_index(familyIndex) != AF_INET) 614 socket = ::socket(family_at_index(familyIndex), SOCK_DGRAM, 0); 615 if (socket < 0) { 616 // the family is not available in this environment 617 continue; 618 } 619 620 uint32 interfaceIndex = 0; 621 if (ioctl(socket, SIOCGIFINDEX, &request, sizeof(request)) >= 0) 622 interfaceIndex = request.ifr_index; 623 624 if (interfaceIndex == 0) { 625 // we need to create the interface first 626 request.ifr_parameter.base_name[0] = '\0'; 627 request.ifr_parameter.device[0] = '\0'; 628 request.ifr_parameter.sub_type = 0; 629 // the default device is okay for us 630 631 if (ioctl(socket, SIOCAIFADDR, &request, sizeof(request)) < 0) { 632 fprintf(stderr, "%s: Could not add interface: %s\n", Name(), 633 strerror(errno)); 634 return errno; 635 } 636 } 637 638 // retrieve addresses 639 640 bool autoConfig; 641 if (addressMessage.FindBool("auto_config", &autoConfig) != B_OK) 642 autoConfig = false; 643 #if 0 644 if (autoConfig && fromMessage) { 645 // we don't accept auto-config messages this way 646 continue; 647 } 648 #endif 649 650 bool hasAddress = false, hasMask = false, hasPeer = false; 651 bool hasBroadcast = false; 652 struct sockaddr address, mask, peer, broadcast, gateway; 653 const char* string; 654 655 if (!autoConfig) { 656 if (addressMessage.FindString("address", &string) == B_OK 657 && parse_address(familyIndex, string, address)) { 658 hasAddress = true; 659 660 if (addressMessage.FindString("mask", &string) == B_OK 661 && parse_address(familyIndex, string, mask)) 662 hasMask = true; 663 } 664 if (addressMessage.FindString("peer", &string) == B_OK 665 && parse_address(familyIndex, string, peer)) 666 hasPeer = true; 667 if (addressMessage.FindString("broadcast", &string) == B_OK 668 && parse_address(familyIndex, string, broadcast)) 669 hasBroadcast = true; 670 } 671 672 route_entry route; 673 memset(&route, 0, sizeof(route_entry)); 674 route.flags = RTF_STATIC | RTF_DEFAULT; 675 676 request.ifr_route = route; 677 678 if (autoConfig) { 679 _QuitLooperForDevice(device); 680 startAutoConfig = true; 681 } else if (addressMessage.FindString("gateway", &string) == B_OK 682 && parse_address(familyIndex, string, gateway)) { 683 // add gateway route, if we're asked for it 684 685 ioctl(socket, SIOCDELRT, &request, sizeof(request)); 686 // Try to remove a previous default route, doesn't matter 687 // if it fails. 688 689 route.flags = RTF_STATIC | RTF_DEFAULT | RTF_GATEWAY; 690 route.gateway = &gateway; 691 692 request.ifr_route = route; 693 if (ioctl(socket, SIOCADDRT, &request, sizeof(request)) < 0) { 694 fprintf(stderr, "%s: Could not add route for %s: %s\n", 695 Name(), device, strerror(errno)); 696 } 697 } 698 699 // set addresses 700 701 if (hasAddress) { 702 memcpy(&request.ifr_addr, &address, address.sa_len); 703 704 if (ioctl(familySocket, SIOCSIFADDR, &request, sizeof(struct ifreq)) < 0) { 705 fprintf(stderr, "%s: Setting address failed: %s\n", Name(), strerror(errno)); 706 continue; 707 } 708 } 709 710 if (ioctl(familySocket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) < 0) { 711 fprintf(stderr, "%s: Getting flags failed: %s\n", Name(), strerror(errno)); 712 continue; 713 } 714 int32 currentFlags = request.ifr_flags; 715 716 if (hasMask) { 717 memcpy(&request.ifr_mask, &mask, mask.sa_len); 718 719 if (ioctl(familySocket, SIOCSIFNETMASK, &request, sizeof(struct ifreq)) < 0) { 720 fprintf(stderr, "%s: Setting subnet mask failed: %s\n", Name(), strerror(errno)); 721 continue; 722 } 723 } 724 725 if (hasBroadcast) { 726 memcpy(&request.ifr_broadaddr, &broadcast, broadcast.sa_len); 727 728 if (ioctl(familySocket, SIOCSIFBRDADDR, &request, sizeof(struct ifreq)) < 0) { 729 fprintf(stderr, "%s: Setting broadcast address failed: %s\n", Name(), strerror(errno)); 730 continue; 731 } 732 } 733 734 if (hasPeer) { 735 memcpy(&request.ifr_dstaddr, &peer, peer.sa_len); 736 737 if (ioctl(familySocket, SIOCSIFDSTADDR, &request, sizeof(struct ifreq)) < 0) { 738 fprintf(stderr, "%s: Setting peer address failed: %s\n", Name(), strerror(errno)); 739 continue; 740 } 741 } 742 743 // set flags 744 745 if (flags != 0) { 746 request.ifr_flags = (currentFlags & ~IFF_CONFIGURING) | flags; 747 if (!autoConfigured) 748 request.ifr_flags = request.ifr_flags & ~IFF_AUTO_CONFIGURED; 749 750 if (ioctl(familySocket, SIOCSIFFLAGS, &request, sizeof(struct ifreq)) < 0) 751 fprintf(stderr, "%s: Setting flags failed: %s\n", Name(), strerror(errno)); 752 } 753 754 // set options 755 756 if (mtu != -1) { 757 request.ifr_mtu = mtu; 758 if (ioctl(familySocket, SIOCSIFMTU, &request, sizeof(struct ifreq)) < 0) 759 fprintf(stderr, "%s: Setting MTU failed: %s\n", Name(), strerror(errno)); 760 } 761 762 if (metric != -1) { 763 request.ifr_metric = metric; 764 if (ioctl(familySocket, SIOCSIFMETRIC, &request, sizeof(struct ifreq)) < 0) 765 fprintf(stderr, "%s: Setting metric failed: %s\n", Name(), strerror(errno)); 766 } 767 } 768 769 if (startAutoConfig) { 770 // start auto configuration 771 AutoconfigLooper* looper = new AutoconfigLooper(this, device); 772 looper->Run(); 773 774 fDeviceMap[device] = looper; 775 } 776 777 return B_OK; 778 } 779 780 781 status_t 782 NetServer::_ConfigureResolver(BMessage& resolverConfiguration) 783 { 784 // TODO: resolv.conf should be parsed, all information should be 785 // maintained and it should be distinguished between user entered 786 // and auto-generated parts of the file, with this method only re-writing 787 // the auto-generated parts of course. 788 789 BPath path; 790 if (find_directory(B_COMMON_SETTINGS_DIRECTORY, &path) != B_OK 791 || path.Append("network/resolv.conf") != B_OK) 792 return B_ERROR; 793 794 FILE* file = fopen(path.Path(), "w"); 795 if (file != NULL) { 796 const char* nameserver; 797 for (int32 i = 0; resolverConfiguration.FindString("nameserver", i, 798 &nameserver) == B_OK; i++) { 799 fprintf(file, "nameserver %s\n", nameserver); 800 } 801 802 const char* domain; 803 if (resolverConfiguration.FindString("domain", &domain) == B_OK) 804 fprintf(file, "domain %s\n", domain); 805 806 fclose(file); 807 } 808 return B_OK; 809 } 810 811 812 bool 813 NetServer::_QuitLooperForDevice(const char* device) 814 { 815 LooperMap::iterator iterator = fDeviceMap.find(device); 816 if (iterator == fDeviceMap.end()) 817 return false; 818 819 // there is a looper for this device - quit it 820 if (iterator->second->Lock()) 821 iterator->second->Quit(); 822 823 fDeviceMap.erase(iterator); 824 return true; 825 } 826 827 828 AutoconfigLooper* 829 NetServer::_LooperForDevice(const char* device) 830 { 831 LooperMap::const_iterator iterator = fDeviceMap.find(device); 832 if (iterator == fDeviceMap.end()) 833 return NULL; 834 835 return iterator->second; 836 } 837 838 839 status_t 840 NetServer::_ConfigureDevice(int socket, const char* path) 841 { 842 // bring interface up, but don't configure it just yet 843 BMessage interface; 844 interface.AddString("device", path); 845 BMessage address; 846 address.AddString("family", "inet"); 847 address.AddBool("auto_config", true); 848 interface.AddMessage("address", &address); 849 850 return _ConfigureInterface(socket, interface); 851 } 852 853 854 void 855 NetServer::_ConfigureDevices(int socket, const char* startPath, 856 BMessage* suggestedInterface) 857 { 858 BDirectory directory(startPath); 859 BEntry entry; 860 while (directory.GetNextEntry(&entry) == B_OK) { 861 char name[B_FILE_NAME_LENGTH]; 862 struct stat stat; 863 BPath path; 864 if (entry.GetName(name) != B_OK 865 || entry.GetPath(&path) != B_OK 866 || entry.GetStat(&stat) != B_OK) 867 continue; 868 869 if (S_ISBLK(stat.st_mode) || S_ISCHR(stat.st_mode)) { 870 if (suggestedInterface != NULL 871 && suggestedInterface->RemoveName("device") == B_OK 872 && suggestedInterface->AddString("device", path.Path()) == B_OK 873 && _ConfigureInterface(socket, *suggestedInterface) == B_OK) 874 suggestedInterface = NULL; 875 else 876 _ConfigureDevice(socket, path.Path()); 877 } else if (entry.IsDirectory()) 878 _ConfigureDevices(socket, path.Path(), suggestedInterface); 879 } 880 } 881 882 883 void 884 NetServer::_ConfigureInterfaces(int socket, BMessage* _missingDevice) 885 { 886 BMessage interface; 887 uint32 cookie = 0; 888 bool missing = false; 889 while (fSettings.GetNextInterface(cookie, interface) == B_OK) { 890 const char *device; 891 if (interface.FindString("device", &device) != B_OK) 892 continue; 893 894 bool disabled = false; 895 if (interface.FindBool("disabled", &disabled) == B_OK && disabled) { 896 // disabled by user request 897 _DisableInterface(socket, device); 898 continue; 899 } 900 901 if (!strncmp(device, "/dev/net/", 9)) { 902 // it's a kernel device, check if it's present 903 BEntry entry(device); 904 if (!entry.Exists()) { 905 if (!missing && _missingDevice != NULL) { 906 *_missingDevice = interface; 907 missing = true; 908 } 909 continue; 910 } 911 } 912 913 _ConfigureInterface(socket, interface); 914 } 915 } 916 917 918 void 919 NetServer::_BringUpInterfaces() 920 { 921 // we need a socket to talk to the networking stack 922 int socket = ::socket(AF_INET, SOCK_DGRAM, 0); 923 if (socket < 0) { 924 fprintf(stderr, "%s: The networking stack doesn't seem to be " 925 "available.\n", Name()); 926 Quit(); 927 return; 928 } 929 930 _RemoveInvalidInterfaces(socket); 931 932 // First, we look into the settings, and try to bring everything up from there 933 934 BMessage missingDevice; 935 _ConfigureInterfaces(socket, &missingDevice); 936 937 // check configuration 938 939 if (!_TestForInterface(socket, "loop")) { 940 // there is no loopback interface, create one 941 BMessage interface; 942 interface.AddString("device", "loop"); 943 BMessage address; 944 address.AddString("family", "inet"); 945 address.AddString("address", "127.0.0.1"); 946 interface.AddMessage("address", &address); 947 948 _ConfigureInterface(socket, interface); 949 } 950 951 // TODO: also check if the networking driver is correctly initialized! 952 // (and check for other devices to take over its configuration) 953 954 if (!_TestForInterface(socket, "/dev/net/")) { 955 // there is no driver configured - see if there is one and try to use it 956 _ConfigureDevices(socket, "/dev/net", 957 missingDevice.HasString("device") ? &missingDevice : NULL); 958 } 959 960 close(socket); 961 } 962 963 964 void 965 NetServer::_StartServices() 966 { 967 BHandler* services = new (std::nothrow) Services(fSettings.Services()); 968 if (services != NULL) { 969 AddHandler(services); 970 fServices = BMessenger(services); 971 } 972 } 973 974 975 void 976 NetServer::_HandleDeviceMonitor(int socket, BMessage* message) 977 { 978 int32 opcode; 979 if (message->FindInt32("opcode", &opcode) != B_OK 980 || (opcode != B_ENTRY_CREATED && opcode != B_ENTRY_REMOVED)) 981 return; 982 983 const char* path; 984 const char* watchedPath; 985 if (message->FindString("watched_path", &watchedPath) != B_OK 986 || message->FindString("path", &path) != B_OK) 987 return; 988 989 if (opcode == B_ENTRY_CREATED) 990 _ConfigureDevice(socket, path); 991 else 992 _RemoveInterface(socket, path); 993 } 994 995 996 // #pragma mark - 997 998 999 int 1000 main(int argc, char** argv) 1001 { 1002 status_t status; 1003 NetServer server(status); 1004 if (status != B_OK) { 1005 fprintf(stderr, "net_server: Failed to create application: %s\n", 1006 strerror(status)); 1007 return 1; 1008 } 1009 1010 server.Run(); 1011 return 0; 1012 } 1013 1014