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