* 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:
Axel Dörfler
2008-12-27 22:15:17 +00:00
parent bf6bf2e36b
commit 293ed4fe5b
8 changed files with 190 additions and 72 deletions
+56 -11
View File
@@ -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;