diff --git a/src/servers/net/DHCPClient.cpp b/src/servers/net/DHCPClient.cpp index 19363b854f..b8f89695b8 100644 --- a/src/servers/net/DHCPClient.cpp +++ b/src/servers/net/DHCPClient.cpp @@ -11,10 +11,8 @@ #include "DHCPClient.h" #include "NetServer.h" -#include #include #include -#include #include #include @@ -336,6 +334,7 @@ dhcp_message::FinishOptions(uint8* options) DHCPClient::DHCPClient(BMessenger target, const char* device) : AutoconfigClient("dhcp", target, device), fConfiguration(kMsgConfigureInterface), + fResolverConfiguration(kMsgConfigureResolver), fRunner(NULL), fLeaseTime(0) { @@ -519,7 +518,8 @@ DHCPClient::_Negotiate(dhcp_state state) BMessage address; address.AddString("family", "inet"); address.AddString("address", _ToString(fAssignedAddress)); - _ParseOptions(*message, address); + fResolverConfiguration.MakeEmpty(); + _ParseOptions(*message, address, fResolverConfiguration); fConfiguration.AddMessage("address", &address); @@ -543,7 +543,8 @@ DHCPClient::_Negotiate(dhcp_state state) // TODO: we might want to configure the stuff, don't we? BMessage address; - _ParseOptions(*message, address); + fResolverConfiguration.MakeEmpty(); + _ParseOptions(*message, address, fResolverConfiguration); // TODO: currently, only lease time and DNS is updated this way // our address request has been acknowledged @@ -552,6 +553,12 @@ DHCPClient::_Negotiate(dhcp_state state) // configure interface BMessage reply; status = Target().SendMessage(&fConfiguration, &reply); + if (status == B_OK) + status = reply.FindInt32("status", &fStatus); + + // configure resolver + reply.MakeEmpty(); + status = Target().SendMessage(&fResolverConfiguration, &reply); if (status == B_OK) status = reply.FindInt32("status", &fStatus); break; @@ -609,20 +616,13 @@ DHCPClient::_RestartLease(bigtime_t leaseTime) void -DHCPClient::_ParseOptions(dhcp_message& message, BMessage& address) +DHCPClient::_ParseOptions(dhcp_message& message, BMessage& address, + BMessage& resolverConfiguration) { dhcp_option_cookie cookie; message_option option; const uint8* data; size_t size; - // TODO: resolv.conf should be parsed, all information should be - // maintained and it should be distinguished between user entered - // and auto-generated parts of the file, with this method only re-writing - // the auto-generated parts of course. - // TODO: We write resolv.conf once per _ParseOptions invokation, there - // is the first DHCP_OFFER message and the final DHCP_ACK message - // from the same server, which should contain all the final data. - bool resolvConfCreated = false; while (message.NextOption(cookie, option, data, size)) { // iterate through all options switch (option) { @@ -637,24 +637,14 @@ DHCPClient::_ParseOptions(dhcp_message& message, BMessage& address) break; case OPTION_DOMAIN_NAME_SERVER: { - BPath path; - if (find_directory(B_COMMON_SETTINGS_DIRECTORY, &path) != B_OK - || path.Append("network/resolv.conf") != B_OK) { - break; - } - - const char* openMode = resolvConfCreated ? "a" : "w"; - FILE* file = fopen(path.Path(), openMode); for (uint32 i = 0; i < size / 4; i++) { syslog(LOG_INFO, "DNS: %s\n", _ToString(&data[i * 4]).String()); - if (file != NULL) { - resolvConfCreated = true; - fprintf(file, "nameserver %s\n", - _ToString(&data[i * 4]).String()); - } + resolverConfiguration.AddString("nameserver", + _ToString(&data[i * 4]).String()); } - fclose(file); + resolverConfiguration.AddInt32("nameserver_count", + size / 4); break; } case OPTION_SERVER_ADDRESS: @@ -678,29 +668,19 @@ DHCPClient::_ParseOptions(dhcp_message& message, BMessage& address) break; case OPTION_HOST_NAME: - syslog(LOG_INFO, "DHCP host name: \"%.*s\"\n", - (int)size, (const char*)data); + syslog(LOG_INFO, "DHCP host name: \"%.*s\"\n", (int)size, + (const char*)data); break; case OPTION_DOMAIN_NAME: { - syslog(LOG_INFO, "DHCP domain name: \"%.*s\"\n", - (int)size, (const char*)data); + char domain[256]; + strlcpy(domain, (const char*)data, + min_c(size + 1, sizeof(domain))); - BPath path; - if (find_directory(B_COMMON_SETTINGS_DIRECTORY, &path) != B_OK - || path.Append("network/resolv.conf") != B_OK) { - break; - } - - const char* openMode = resolvConfCreated ? "a" : "w"; - FILE* file = fopen(path.Path(), openMode); - if (file != NULL) { - resolvConfCreated = true; - fprintf(file, "domain %.*s\n", (int)size, - (const char*)data); - fclose(file); - } + syslog(LOG_INFO, "DHCP domain name: \"%s\"\n", domain); + + resolverConfiguration.AddString("domain", domain); break; } diff --git a/src/servers/net/DHCPClient.h b/src/servers/net/DHCPClient.h index a26cdd3b68..04afc2845b 100644 --- a/src/servers/net/DHCPClient.h +++ b/src/servers/net/DHCPClient.h @@ -39,7 +39,8 @@ public: private: status_t _Negotiate(dhcp_state state); void _ParseOptions(dhcp_message& message, - BMessage& address); + BMessage& address, + BMessage& resolverConfiguration); void _PrepareMessage(dhcp_message& message, dhcp_state state); status_t _SendMessage(int socket, dhcp_message& message, @@ -55,6 +56,7 @@ private: private: BMessage fConfiguration; + BMessage fResolverConfiguration; BMessageRunner* fRunner; uint8 fMAC[6]; uint32 fTransactionID; diff --git a/src/servers/net/NetServer.cpp b/src/servers/net/NetServer.cpp index 6d3d10e75e..58c38edc01 100644 --- a/src/servers/net/NetServer.cpp +++ b/src/servers/net/NetServer.cpp @@ -1,9 +1,10 @@ /* - * Copyright 2006-2009, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: * Axel Dörfler, axeld@pinc-software.de + * Vegard Wærp, vegarwa@online.no */ @@ -33,6 +34,7 @@ #include #include #include +#include #include "AutoconfigLooper.h" #include "Services.h" @@ -57,6 +59,7 @@ class NetServer : public BServer { bool _TestForInterface(int socket, const char* name); status_t _ConfigureInterface(int socket, BMessage& interface, bool fromMessage = false); + status_t _ConfigureResolver(BMessage& resolverConfiguration); bool _QuitLooperForDevice(const char* device); AutoconfigLooper* _LooperForDevice(const char* device); status_t _ConfigureDevice(int socket, const char* path); @@ -300,6 +303,7 @@ NetServer::MessageReceived(BMessage* message) close(socket); break; } + case kMsgInterfaceSettingsUpdated: { // we need a socket to talk to the networking stack @@ -345,6 +349,16 @@ NetServer::MessageReceived(BMessage* message) break; } + case kMsgConfigureResolver: + { + status_t status = _ConfigureResolver(*message); + + BMessage reply(B_REPLY); + reply.AddInt32("status", status); + message->SendReply(&reply); + break; + } + default: BApplication::MessageReceived(message); return; @@ -720,6 +734,37 @@ NetServer::_ConfigureInterface(int socket, BMessage& interface, } +status_t +NetServer::_ConfigureResolver(BMessage& resolverConfiguration) +{ + // TODO: resolv.conf should be parsed, all information should be + // maintained and it should be distinguished between user entered + // and auto-generated parts of the file, with this method only re-writing + // the auto-generated parts of course. + + BPath path; + if (find_directory(B_COMMON_SETTINGS_DIRECTORY, &path) != B_OK + || path.Append("network/resolv.conf") != B_OK) + return B_ERROR; + + FILE* file = fopen(path.Path(), "w"); + if (file != NULL) { + const char* nameserver; + for (int32 i = 0; resolverConfiguration.FindString("nameserver", i, + &nameserver) == B_OK; i++) { + fprintf(file, "nameserver %s\n", nameserver); + } + + const char* domain; + if (resolverConfiguration.FindString("domain", &domain) == B_OK) + fprintf(file, "domain %s\n", domain); + + fclose(file); + } + return B_OK; +} + + bool NetServer::_QuitLooperForDevice(const char* device) { diff --git a/src/servers/net/NetServer.h b/src/servers/net/NetServer.h index 13526ff041..975e2f15a2 100644 --- a/src/servers/net/NetServer.h +++ b/src/servers/net/NetServer.h @@ -1,5 +1,5 @@ /* - * Copyright 2006-2009, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -15,9 +15,10 @@ // NOTE: this header is used by other applications (such as ifconfig, -// and Network) because of these two defines +// and Network) because of these three defines #define kNetServerSignature "application/x-vnd.haiku-net_server" #define kMsgConfigureInterface 'COif' +#define kMsgConfigureResolver 'COrs' extern bool get_family_index(const char* name, int32& familyIndex);