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