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