xref: /haiku/src/servers/net/AutoconfigLooper.cpp (revision 1acbe440b8dd798953bec31d18ee589aa3f71b73)
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 "DHCPClient.h"
12 #include "NetServer.h"
13 
14 #include <errno.h>
15 #include <net/if_dl.h>
16 #include <net/if_types.h>
17 #include <stdio.h>
18 #include <sys/socket.h>
19 #include <sys/sockio.h>
20 
21 
22 static const uint32 kMsgReadyToRun = 'rdyr';
23 
24 
25 AutoconfigLooper::AutoconfigLooper(BMessenger target, const char* device)
26 	: BLooper(device),
27 	fTarget(target),
28 	fDevice(device)
29 {
30 	BMessage ready(kMsgReadyToRun);
31 	PostMessage(&ready);
32 }
33 
34 
35 AutoconfigLooper::~AutoconfigLooper()
36 {
37 }
38 
39 
40 void
41 AutoconfigLooper::_ReadyToRun()
42 {
43 	BMessage interface(kMsgConfigureInterface);
44 	interface.AddString("device", fDevice.String());
45 	interface.AddInt32("net:status", kStatusPreparing);
46 	fTarget.SendMessage(&interface);
47 
48 	// start with DHCP
49 
50 	DHCPClient* client = new DHCPClient(fTarget, fDevice.String());
51 	AddHandler(client);
52 
53 	if (client->Initialize() == B_OK)
54 		return;
55 
56 	RemoveHandler(client);
57 	delete client;
58 
59 	puts("DHCP failed miserably!");
60 
61 	// DHCP obviously didn't work out, take some default values for now
62 	// TODO: have a look at zeroconf
63 	// TODO: this could also be done add-on based
64 
65 	interface.ReplaceInt32("net:status", kStatusLinkNoConfig);
66 
67 	uint8 mac[6];
68 	uint8 last = 56;
69 	if (get_mac_address(fDevice.String(), mac) == B_OK) {
70 		// choose IP address depending on the MAC address, if available
71 		last = mac[0] ^ mac[1] ^ mac[2] ^ mac[3] ^ mac[4] ^ mac[5];
72 		if (last > 253)
73 			last = 253;
74 		else if (last == 0)
75 			last = 1;
76 	}
77 
78 	char string[64];
79 	snprintf(string, sizeof(string), "192.168.0.%u", last);
80 
81 	BMessage address;
82 	address.AddString("family", "inet");
83 	address.AddString("address", string);
84 	address.AddString("gateway", "192.168.0.254");
85 	interface.AddMessage("address", &address);
86 
87 	fTarget.SendMessage(&interface);
88 }
89 
90 
91 void
92 AutoconfigLooper::MessageReceived(BMessage* message)
93 {
94 	switch (message->what) {
95 		case kMsgReadyToRun:
96 			_ReadyToRun();
97 			break;
98 
99 		default:
100 			BLooper::MessageReceived(message);
101 			break;
102 	}
103 }
104 
105