diff --git a/src/servers/net/AutoconfigClient.cpp b/src/servers/net/AutoconfigClient.cpp new file mode 100644 index 0000000000..b7e424f2af --- /dev/null +++ b/src/servers/net/AutoconfigClient.cpp @@ -0,0 +1,31 @@ +/* + * Copyright 2008, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler, axeld@pinc-software.de + */ + + +#include "AutoconfigClient.h" + + +AutoconfigClient::AutoconfigClient(const char* name, BMessenger target, + const char* device) + : BHandler(name), + fTarget(target), + fDevice(device) +{ +} + + +AutoconfigClient::~AutoconfigClient() +{ +} + + +status_t +AutoconfigClient::Initialize() +{ + return B_NOT_SUPPORTED; +} diff --git a/src/servers/net/AutoconfigClient.h b/src/servers/net/AutoconfigClient.h new file mode 100644 index 0000000000..724bc0a1aa --- /dev/null +++ b/src/servers/net/AutoconfigClient.h @@ -0,0 +1,33 @@ +/* + * Copyright 2008, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler, axeld@pinc-software.de + */ +#ifndef AUTOCONFIG_CLIENT_H +#define AUTOCONFIG_CLIENT_H + + +#include +#include +#include + + +class AutoconfigClient : public BHandler { +public: + AutoconfigClient(const char* name, + BMessenger target, const char* device); + virtual ~AutoconfigClient(); + + virtual status_t Initialize(); + + const BMessenger& Target() const { return fTarget; } + const char* Device() const { return fDevice.String(); } + +private: + BMessenger fTarget; + BString fDevice; +}; + +#endif // AUTOCONFIG_CLIENT_H diff --git a/src/servers/net/AutoconfigLooper.cpp b/src/servers/net/AutoconfigLooper.cpp index c8bcf73ff1..6b55f928a9 100644 --- a/src/servers/net/AutoconfigLooper.cpp +++ b/src/servers/net/AutoconfigLooper.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006-2007, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2008, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -8,16 +8,20 @@ #include "AutoconfigLooper.h" -#include "DHCPClient.h" -#include "NetServer.h" #include #include +#include #include #include #include #include +#include + +#include "DHCPClient.h" +#include "NetServer.h" + static const uint32 kMsgReadyToRun = 'rdyr'; @@ -25,7 +29,8 @@ static const uint32 kMsgReadyToRun = 'rdyr'; AutoconfigLooper::AutoconfigLooper(BMessenger target, const char* device) : BLooper(device), fTarget(target), - fDevice(device) + fDevice(device), + fCurrentClient(NULL) { BMessage ready(kMsgReadyToRun); PostMessage(&ready); @@ -38,7 +43,19 @@ AutoconfigLooper::~AutoconfigLooper() void -AutoconfigLooper::_ReadyToRun() +AutoconfigLooper::_RemoveClient() +{ + if (fCurrentClient == NULL) + return; + + RemoveHandler(fCurrentClient); + delete fCurrentClient; + fCurrentClient = NULL; +} + + +void +AutoconfigLooper::_Configure() { ifreq request; if (!prepare_request(request, fDevice.String())) @@ -57,16 +74,19 @@ AutoconfigLooper::_ReadyToRun() close(socket); + // remove current handler + + _RemoveClient(); + // start with DHCP - DHCPClient* client = new DHCPClient(fTarget, fDevice.String()); - AddHandler(client); + fCurrentClient = new DHCPClient(fTarget, fDevice.String()); + AddHandler(fCurrentClient); - if (client->Initialize() == B_OK) + if (fCurrentClient->Initialize() == B_OK) return; - RemoveHandler(client); - delete client; + _RemoveClient(); puts("DHCP failed miserably!"); @@ -89,11 +109,11 @@ AutoconfigLooper::_ReadyToRun() last = 1; } - char string[64]; // IANA defined the default autoconfig network (for when a DHCP request // fails for some reason) as being 169.254.0.0/255.255.0.0. We are only // generating the last octet but we could also use the 2 last octets if // wanted. + char string[64]; snprintf(string, sizeof(string), "169.254.0.%u", last); BMessage address; @@ -105,6 +125,14 @@ AutoconfigLooper::_ReadyToRun() } +void +AutoconfigLooper::_ReadyToRun() +{ + start_watching_network(B_WATCH_NETWORK_LINK_CHANGES, this); + _Configure(); +} + + void AutoconfigLooper::MessageReceived(BMessage* message) { @@ -113,6 +141,23 @@ AutoconfigLooper::MessageReceived(BMessage* message) _ReadyToRun(); break; + case B_NETWORK_MONITOR: + const char* device; + int32 opcode; + int32 media; + if (message->FindInt32("opcode", &opcode) != B_OK + || opcode != B_NETWORK_DEVICE_LINK_CHANGED + || message->FindString("device", &device) != B_OK + || fDevice != device + || message->FindInt32("media", &media) != B_OK) + break; + + if ((media & IFM_ACTIVE) != 0) { + // Reconfigure the interface when we have a link again + _Configure(); + } + break; + default: BLooper::MessageReceived(message); break; diff --git a/src/servers/net/AutoconfigLooper.h b/src/servers/net/AutoconfigLooper.h index b4a322d998..a70e17a955 100644 --- a/src/servers/net/AutoconfigLooper.h +++ b/src/servers/net/AutoconfigLooper.h @@ -1,5 +1,5 @@ /* - * Copyright 2006, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2008, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -13,21 +13,26 @@ #include #include +class AutoconfigClient; class AutoconfigLooper : public BLooper { - public: - AutoconfigLooper(BMessenger target, const char* device); - virtual ~AutoconfigLooper(); +public: + AutoconfigLooper(BMessenger target, + const char* device); + virtual ~AutoconfigLooper(); - virtual void MessageReceived(BMessage* message); + virtual void MessageReceived(BMessage* message); - BMessenger Target() const { return fTarget; } + BMessenger Target() const { return fTarget; } - private: - void _ReadyToRun(); +private: + void _RemoveClient(); + void _Configure(); + void _ReadyToRun(); - BMessenger fTarget; - BString fDevice; + BMessenger fTarget; + BString fDevice; + AutoconfigClient* fCurrentClient; }; #endif // AUTOCONFIG_LOOPER_H diff --git a/src/servers/net/DHCPClient.cpp b/src/servers/net/DHCPClient.cpp index 78a5beb789..05843db481 100644 --- a/src/servers/net/DHCPClient.cpp +++ b/src/servers/net/DHCPClient.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -329,9 +330,7 @@ dhcp_message::FinishOptions(uint8 *next) DHCPClient::DHCPClient(BMessenger target, const char* device) - : BHandler("dhcp"), - fTarget(target), - fDevice(device), + : AutoconfigClient("dhcp", target, device), fConfiguration(kMsgConfigureInterface), fRunner(NULL), fLeaseTime(0) @@ -347,6 +346,8 @@ DHCPClient::DHCPClient(BMessenger target, const char* device) fServer.sin_family = AF_INET; fServer.sin_len = sizeof(struct sockaddr_in); fServer.sin_port = htons(DHCP_SERVER_PORT); + + openlog_thread("DHCP", 0, LOG_DAEMON); } @@ -368,6 +369,8 @@ DHCPClient::~DHCPClient() _SendMessage(socket, release, fServer); close(socket); + + closelog_thread(); } @@ -375,7 +378,7 @@ status_t DHCPClient::Initialize() { fStatus = _Negotiate(INIT); - printf("DHCP for %s, status: %s\n", fDevice.String(), strerror(fStatus)); + syslog(LOG_DEBUG, "DHCP for %s, status: %s\n", Device(), strerror(fStatus)); return fStatus; } @@ -416,7 +419,7 @@ DHCPClient::_Negotiate(dhcp_state state) if (linkSocket >= 0) { // we need to know the index of the device to be able to bind to it ifreq request; - prepare_request(request, fDevice.String()); + prepare_request(request, Device()); if (ioctl(linkSocket, SIOCGIFINDEX, &request, sizeof(struct ifreq)) == 0) { setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, @@ -502,7 +505,7 @@ DHCPClient::_Negotiate(dhcp_state state) fAssignedAddress = message->your_address; fConfiguration.MakeEmpty(); - fConfiguration.AddString("device", fDevice.String()); + fConfiguration.AddString("device", Device()); fConfiguration.AddBool("auto", true); BMessage address; @@ -540,7 +543,7 @@ DHCPClient::_Negotiate(dhcp_state state) // configure interface BMessage reply; - fTarget.SendMessage(&fConfiguration, &reply); + Target().SendMessage(&fConfiguration, &reply); if (reply.FindInt32("status", &fStatus) != B_OK) status = B_OK; @@ -622,10 +625,11 @@ DHCPClient::_ParseOptions(dhcp_message& message, BMessage& address) // TODO: for now, we write it just out to /etc/resolv.conf FILE* file = fopen("/etc/resolv.conf", "w"); for (uint32 i = 0; i < size / 4; i++) { - printf("DNS: %s\n", _ToString(&data[i*4]).String()); + syslog(LOG_INFO, "DNS: %s\n", + _ToString(&data[i * 4]).String()); if (file != NULL) { fprintf(file, "nameserver %s\n", - _ToString(&data[i*4]).String()); + _ToString(&data[i * 4]).String()); } } fclose(file); @@ -636,16 +640,17 @@ DHCPClient::_ParseOptions(dhcp_message& message, BMessage& address) break; case OPTION_ADDRESS_LEASE_TIME: - printf("lease time of %lu seconds\n", htonl(*(uint32*)data)); + syslog(LOG_INFO, "lease time of %lu seconds\n", + htonl(*(uint32*)data)); fLeaseTime = htonl(*(uint32*)data) * 1000000LL; break; case OPTION_RENEWAL_TIME: - printf("renewal time of %lu seconds\n", + syslog(LOG_INFO, "renewal time of %lu seconds\n", htonl(*(uint32*)data)); fRenewalTime = htonl(*(uint32*)data) * 1000000LL; break; case OPTION_REBINDING_TIME: - printf("rebinding time of %lu seconds\n", + syslog(LOG_INFO, "rebinding time of %lu seconds\n", htonl(*(uint32*)data)); fRebindingTime = htonl(*(uint32*)data) * 1000000LL; break; @@ -655,7 +660,7 @@ DHCPClient::_ParseOptions(dhcp_message& message, BMessage& address) char name[256]; memcpy(name, data, size); name[size] = '\0'; - printf("DHCP host name: \"%s\"\n", name); + syslog(LOG_INFO, "DHCP host name: \"%s\"\n", name); break; } @@ -664,7 +669,7 @@ DHCPClient::_ParseOptions(dhcp_message& message, BMessage& address) char name[256]; memcpy(name, data, size); name[size] = '\0'; - printf("DHCP domain name: \"%s\"\n", name); + syslog(LOG_INFO, "DHCP domain name: \"%s\"\n", name); break; } @@ -672,7 +677,7 @@ DHCPClient::_ParseOptions(dhcp_message& message, BMessage& address) break; default: - printf("unknown option %lu\n", (uint32)option); + syslog(LOG_INFO, "unknown option %lu\n", (uint32)option); break; } } @@ -754,7 +759,8 @@ DHCPClient::_TimeoutShift(int socket, time_t& timeout, uint32& tries) if (++tries > 2) return false; } - printf("DHCP timeout shift: %lu secs (try %lu)\n", timeout, tries); + syslog(LOG_DEBUG, "DHCP timeout shift: %lu secs (try %lu)\n", timeout, + tries); struct timeval value; value.tv_sec = timeout; diff --git a/src/servers/net/DHCPClient.h b/src/servers/net/DHCPClient.h index 188f8c4d19..8f6706ac94 100644 --- a/src/servers/net/DHCPClient.h +++ b/src/servers/net/DHCPClient.h @@ -1,5 +1,5 @@ /* - * Copyright 2006, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2008, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -9,9 +9,7 @@ #define DHCP_CLIENT_H -#include -#include -#include +#include "AutoconfigClient.h" #include @@ -28,12 +26,12 @@ enum dhcp_state { }; -class DHCPClient : public BHandler { +class DHCPClient : public AutoconfigClient { public: DHCPClient(BMessenger target, const char* device); virtual ~DHCPClient(); - status_t Initialize(); + virtual status_t Initialize(); virtual void MessageReceived(BMessage* message); @@ -49,8 +47,6 @@ class DHCPClient : public BHandler { BString _ToString(const uint8* data) const; BString _ToString(in_addr_t address) const; - BMessenger fTarget; - BString fDevice; BMessage fConfiguration; BMessageRunner* fRunner; uint8 fMAC[6]; diff --git a/src/servers/net/Jamfile b/src/servers/net/Jamfile index e6a1bd9466..9ddac3679d 100644 --- a/src/servers/net/Jamfile +++ b/src/servers/net/Jamfile @@ -11,6 +11,7 @@ AddResources net_server : net_server.rdef ; Server net_server : NetServer.cpp Settings.cpp + AutoconfigClient.cpp AutoconfigLooper.cpp DHCPClient.cpp Services.cpp diff --git a/src/servers/net/NetServer.cpp b/src/servers/net/NetServer.cpp index 888a44f838..258ef76bec 100644 --- a/src/servers/net/NetServer.cpp +++ b/src/servers/net/NetServer.cpp @@ -7,10 +7,22 @@ */ -#include "AutoconfigLooper.h" #include "NetServer.h" -#include "Services.h" -#include "Settings.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include #include #include @@ -22,26 +34,15 @@ #include #include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include +#include "AutoconfigLooper.h" +#include "Services.h" +#include "Settings.h" static const char *kSignature = "application/x-vnd.haiku-net_server"; -typedef std::map LooperMap; +typedef std::map LooperMap; class NetServer : public BServer { @@ -59,7 +60,7 @@ class NetServer : public BServer { status_t _ConfigureInterface(int socket, BMessage& interface, bool fromMessage = false); bool _QuitLooperForDevice(const char* device); - BLooper* _LooperForDevice(const char* device); + AutoconfigLooper* _LooperForDevice(const char* device); status_t _ConfigureDevice(int socket, const char* path); void _ConfigureDevices(int socket, const char* path, BMessage* suggestedInterface = NULL); @@ -258,7 +259,7 @@ NetServer::AboutRequested() view->GetFont(&font); font.SetSize(18); - font.SetFace(B_BOLD_FACE); + font.SetFace(B_BOLD_FACE); view->SetFontAndColor(0, 17, &font); alert->Go(NULL); @@ -363,7 +364,7 @@ NetServer::_IsValidInterface(int socket, const char* name) if (addresses == 0) return false; - // check if it has a hardware address, too, in case of ethernet + // check if it has a hardware address, too, in case of ethernet if (ioctl(socket, SIOCGIFPARAM, &request, sizeof(struct ifreq)) < 0) return false; @@ -568,7 +569,7 @@ NetServer::_ConfigureInterface(int socket, BMessage& interface, bool fromMessage if (addressMessage.FindString("address", &string) == B_OK && parse_address(familyIndex, string, address)) { hasAddress = true; - + if (addressMessage.FindString("mask", &string) == B_OK && parse_address(familyIndex, string, mask)) hasMask = true; @@ -612,13 +613,13 @@ NetServer::_ConfigureInterface(int socket, BMessage& interface, bool fromMessage if (hasAddress) { memcpy(&request.ifr_addr, &address, address.sa_len); - + if (ioctl(familySocket, SIOCSIFADDR, &request, sizeof(struct ifreq)) < 0) { fprintf(stderr, "%s: Setting address failed: %s\n", Name(), strerror(errno)); continue; } } - + if (ioctl(familySocket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) < 0) { fprintf(stderr, "%s: Getting flags failed: %s\n", Name(), strerror(errno)); continue; @@ -695,15 +696,15 @@ NetServer::_QuitLooperForDevice(const char* device) return false; // there is a looper for this device - quit it - iterator->second->Lock(); - iterator->second->Quit(); + if (iterator->second->Lock()) + iterator->second->Quit(); fDeviceMap.erase(iterator); return true; } -BLooper* +AutoconfigLooper* NetServer::_LooperForDevice(const char* device) { LooperMap::const_iterator iterator = fDeviceMap.find(device);