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 inline void SetBusy(bool busy) { atomic_set(&fBusy, busy ? 1 : 0); } 156 inline bool IsBusy() const { return atomic_get((int32*)&fBusy) == 1 ; } 157 158 #if ENABLE_DEBUGGER_COMMANDS 159 void Dump() const; 160 #endif 161 162 private: 163 status_t _SetUp(); 164 InterfaceAddress* _FirstForFamily(int family); 165 status_t _ChangeAddress(RecursiveLocker& locker, 166 InterfaceAddress* address, int32 option, 167 const sockaddr* oldAddress, 168 const sockaddr* newAddress); 169 170 private: 171 recursive_lock fLock; 172 int32 fBusy; 173 net_device_interface* fDeviceInterface; 174 AddressList fAddresses; 175 DatalinkTable fDatalinkTable; 176 }; 177 178 typedef DoublyLinkedList<Interface> InterfaceList; 179 180 181 status_t init_interfaces(); 182 status_t uninit_interfaces(); 183 184 // interfaces 185 status_t add_interface(const char* name, net_domain_private* domain, 186 const ifaliasreq& request, net_device_interface* deviceInterface); 187 void remove_interface(Interface* interface); 188 void interface_removed_device_interface(net_device_interface* deviceInterface); 189 190 status_t add_interface_address(Interface* interface, net_domain_private* domain, 191 const ifaliasreq& request); 192 status_t update_interface_address(InterfaceAddress* interfaceAddress, 193 int32 option, const sockaddr* oldAddress, const sockaddr* newAddress); 194 195 Interface* get_interface(net_domain* domain, uint32 index); 196 Interface* get_interface(net_domain* domain, const char* name); 197 Interface* get_interface_for_device(net_domain* domain, uint32 index); 198 Interface* get_interface_for_link(net_domain* domain, const sockaddr* address); 199 InterfaceAddress* get_interface_address(const struct sockaddr* address); 200 InterfaceAddress* get_interface_address_for_destination(net_domain* domain, 201 const sockaddr* destination); 202 InterfaceAddress* get_interface_address_for_link(net_domain* domain, 203 const sockaddr* linkAddress, bool unconfiguredOnly); 204 205 uint32 count_interfaces(); 206 status_t list_interfaces(int family, void* buffer, size_t* _bufferSize); 207 208 209 #endif // INTERFACES_H 210