* Pulled an AutoconfigClient class out of DHCPClient - all clients are supposed
to inherit from that one (there is still just a single client, though, this just simplifies having a generic mechanism to register and use auto-config clients). * AutoconfigLooper now listens to link changes, and will reconfigure the interface if a new link is there - this even seems to work in emulation, will test on real hardware next. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28827 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
bf6bf2e36b
commit
293ed4fe5b
31
src/servers/net/AutoconfigClient.cpp
Normal file
31
src/servers/net/AutoconfigClient.cpp
Normal file
@ -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;
|
||||
}
|
33
src/servers/net/AutoconfigClient.h
Normal file
33
src/servers/net/AutoconfigClient.h
Normal file
@ -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 <Handler.h>
|
||||
#include <Messenger.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
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
|
@ -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 <errno.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#include <net_notifications.h>
|
||||
|
||||
#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;
|
||||
|
@ -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 <Messenger.h>
|
||||
#include <String.h>
|
||||
|
||||
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
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
@ -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;
|
||||
|
@ -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 <Handler.h>
|
||||
#include <Messenger.h>
|
||||
#include <String.h>
|
||||
#include "AutoconfigClient.h"
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
@ -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];
|
||||
|
@ -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
|
||||
|
@ -7,10 +7,22 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "AutoconfigLooper.h"
|
||||
#include "NetServer.h"
|
||||
#include "Services.h"
|
||||
#include "Settings.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <map>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Deskbar.h>
|
||||
@ -22,26 +34,15 @@
|
||||
#include <Server.h>
|
||||
#include <TextView.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#include <map>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "AutoconfigLooper.h"
|
||||
#include "Services.h"
|
||||
#include "Settings.h"
|
||||
|
||||
|
||||
static const char *kSignature = "application/x-vnd.haiku-net_server";
|
||||
|
||||
|
||||
typedef std::map<std::string, BLooper*> LooperMap;
|
||||
typedef std::map<std::string, AutoconfigLooper*> 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);
|
||||
|
Loading…
Reference in New Issue
Block a user