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