1 /* 2 * Copyright 2006-2011, 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 #ifndef INTERFACES_H 9 #define INTERFACES_H 10 11 12 #include "routes.h" 13 #include "stack_private.h" 14 15 #include <net_datalink.h> 16 #include <net_stack.h> 17 18 #include <Referenceable.h> 19 20 #include <util/AutoLock.h> 21 #include <util/DoublyLinkedList.h> 22 #include <util/OpenHashTable.h> 23 24 25 struct net_device_interface; 26 27 28 // Additional address flags 29 #define IFAF_DIRECT_ADDRESS 0x1000 30 31 32 struct InterfaceAddress : DoublyLinkedListLinkImpl<InterfaceAddress>, 33 net_interface_address, BReferenceable { 34 InterfaceAddress(); 35 InterfaceAddress(net_interface* interface, 36 net_domain* domain); 37 virtual ~InterfaceAddress(); 38 39 status_t SetTo(const ifaliasreq& request); 40 41 status_t SetLocal(const sockaddr* to); 42 status_t SetDestination(const sockaddr* to); 43 status_t SetMask(const sockaddr* to); 44 45 sockaddr** AddressFor(int32 option); 46 47 void AddDefaultRoutes(int32 option); 48 void RemoveDefaultRoutes(int32 option); 49 50 bool LocalIsDefined() const; 51 52 InterfaceAddress*& HashTableLink() { return fLink; } 53 54 #if ENABLE_DEBUGGER_COMMANDS 55 void Dump(size_t index = 0, 56 bool hideInterface = false); 57 #endif 58 59 static status_t Set(sockaddr** _address, const sockaddr* to); 60 static sockaddr* Prepare(sockaddr** _address, size_t length); 61 62 private: 63 void _Init(net_interface* interface, 64 net_domain* domain); 65 66 private: 67 InterfaceAddress* fLink; 68 }; 69 70 typedef DoublyLinkedList<InterfaceAddress> AddressList; 71 72 struct domain_datalink { 73 domain_datalink* hash_link; 74 net_domain* domain; 75 76 struct net_datalink_protocol* first_protocol; 77 struct net_datalink_protocol_module_info* first_info; 78 79 // support for binding to an interface 80 net_route_private direct_route; 81 InterfaceAddress direct_address; 82 }; 83 84 struct DatalinkHashDefinition { 85 typedef const int KeyType; 86 typedef domain_datalink ValueType; 87 88 DatalinkHashDefinition() 89 { 90 } 91 92 size_t HashKey(const KeyType& key) const 93 { 94 return (size_t)key; 95 } 96 97 size_t Hash(domain_datalink* datalink) const 98 { 99 return datalink->domain->family; 100 } 101 102 bool Compare(const KeyType& key, domain_datalink* datalink) const 103 { 104 return datalink->domain->family == key; 105 } 106 107 domain_datalink*& GetLink(domain_datalink* datalink) const 108 { 109 return datalink->hash_link; 110 } 111 }; 112 113 typedef BOpenHashTable<DatalinkHashDefinition, true, true> DatalinkTable; 114 115 116 class Interface : public DoublyLinkedListLinkImpl<Interface>, 117 public net_interface, public BReferenceable { 118 public: 119 Interface(const char* name, 120 net_device_interface* deviceInterface); 121 virtual ~Interface(); 122 123 InterfaceAddress* FirstForFamily(int family); 124 InterfaceAddress* FirstUnconfiguredForFamily(int family); 125 InterfaceAddress* AddressForDestination(net_domain* domain, 126 const sockaddr* destination); 127 InterfaceAddress* AddressForLocal(net_domain* domain, 128 const sockaddr* local); 129 130 status_t AddAddress(InterfaceAddress* address); 131 void RemoveAddress(InterfaceAddress* address); 132 bool GetNextAddress(InterfaceAddress** _address); 133 InterfaceAddress* AddressAt(size_t index); 134 int32 IndexOfAddress(InterfaceAddress* address); 135 size_t CountAddresses(); 136 void RemoveAddresses(); 137 138 status_t Control(net_domain* domain, int32 option, 139 ifreq& request, ifreq* userRequest, 140 size_t length); 141 142 void SetDown(); 143 void WentDown(); 144 145 recursive_lock& Lock() { return fLock; } 146 147 net_device_interface* DeviceInterface() { return fDeviceInterface; } 148 149 status_t CreateDomainDatalinkIfNeeded( 150 net_domain* domain); 151 domain_datalink* DomainDatalink(uint8 family); 152 domain_datalink* DomainDatalink(net_domain* domain) 153 { return DomainDatalink(domain->family); } 154 155 #if ENABLE_DEBUGGER_COMMANDS 156 void Dump() const; 157 #endif 158 159 private: 160 status_t _SetUp(); 161 InterfaceAddress* _FirstForFamily(int family); 162 status_t _ChangeAddress(RecursiveLocker& locker, 163 InterfaceAddress* address, int32 option, 164 const sockaddr* oldAddress, 165 const sockaddr* newAddress); 166 167 private: 168 recursive_lock fLock; 169 net_device_interface* fDeviceInterface; 170 AddressList fAddresses; 171 DatalinkTable fDatalinkTable; 172 }; 173 174 typedef DoublyLinkedList<Interface> InterfaceList; 175 176 177 status_t init_interfaces(); 178 status_t uninit_interfaces(); 179 180 // interfaces 181 status_t add_interface(const char* name, net_domain_private* domain, 182 const ifaliasreq& request, net_device_interface* deviceInterface); 183 void remove_interface(Interface* interface); 184 void interface_removed_device_interface(net_device_interface* deviceInterface); 185 186 status_t add_interface_address(Interface* interface, net_domain_private* domain, 187 const ifaliasreq& request); 188 status_t update_interface_address(InterfaceAddress* interfaceAddress, 189 int32 option, const sockaddr* oldAddress, const sockaddr* newAddress); 190 191 Interface* get_interface(net_domain* domain, uint32 index); 192 Interface* get_interface(net_domain* domain, const char* name); 193 Interface* get_interface_for_device(net_domain* domain, uint32 index); 194 Interface* get_interface_for_link(net_domain* domain, const sockaddr* address); 195 InterfaceAddress* get_interface_address(const struct sockaddr* address); 196 InterfaceAddress* get_interface_address_for_destination(net_domain* domain, 197 const sockaddr* destination); 198 InterfaceAddress* get_interface_address_for_link(net_domain* domain, 199 const sockaddr* linkAddress, bool unconfiguredOnly); 200 201 uint32 count_interfaces(); 202 status_t list_interfaces(int family, void* buffer, size_t* _bufferSize); 203 204 205 #endif // INTERFACES_H 206