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