/* * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: * Axel Dörfler, axeld@pinc-software.de */ #ifndef INTERFACES_H #define INTERFACES_H #include "routes.h" #include "stack_private.h" #include #include #include #include #include #include struct net_device_interface; struct InterfaceAddress : DoublyLinkedListLinkImpl, net_interface_address, Referenceable { InterfaceAddress(); InterfaceAddress(net_interface* interface, net_domain* domain); virtual ~InterfaceAddress(); status_t SetTo(const ifaliasreq& request); status_t SetLocal(const sockaddr* to); status_t SetDestination(const sockaddr* to); status_t SetMask(const sockaddr* to); sockaddr** AddressFor(int32 option); InterfaceAddress*& HashTableLink() { return fLink; } #if ENABLE_DEBUGGER_COMMANDS void Dump(size_t index = 0, bool hideInterface = false); #endif static status_t Set(sockaddr** _address, const sockaddr* to); static sockaddr* Prepare(sockaddr** _address, size_t length); private: void _Init(net_interface* interface, net_domain* domain); private: InterfaceAddress* fLink; }; typedef DoublyLinkedList AddressList; struct domain_datalink { domain_datalink* hash_link; net_domain* domain; struct net_datalink_protocol* first_protocol; struct net_datalink_protocol_module_info* first_info; // support for binding to an interface net_route_private direct_route; InterfaceAddress direct_address; }; struct DatalinkHashDefinition { typedef const int KeyType; typedef domain_datalink ValueType; DatalinkHashDefinition() { } size_t HashKey(const KeyType& key) const { return (size_t)key; } size_t Hash(domain_datalink* datalink) const { return datalink->domain->family; } bool Compare(const KeyType& key, domain_datalink* datalink) const { return datalink->domain->family == key; } domain_datalink*& GetLink(domain_datalink* datalink) const { return datalink->hash_link; } }; typedef BOpenHashTable DatalinkTable; class Interface : public DoublyLinkedListLinkImpl, public net_interface, public Referenceable { public: Interface(const char* name, net_device_interface* deviceInterface); virtual ~Interface(); InterfaceAddress* FirstForFamily(int family); InterfaceAddress* FirstUnconfiguredForFamily(int family); InterfaceAddress* AddressForDestination(net_domain* domain, const sockaddr* destination); status_t AddAddress(InterfaceAddress* address); void RemoveAddress(InterfaceAddress* address); bool GetNextAddress(InterfaceAddress** _address); InterfaceAddress* AddressAt(size_t index); size_t CountAddresses(); status_t Control(net_domain* domain, int32 option, ifreq& request, ifreq* userRequest, size_t length); recursive_lock& Lock() { return fLock; } net_device_interface* DeviceInterface() { return fDeviceInterface; } status_t CreateDomainDatalinkIfNeeded( net_domain* domain); domain_datalink* DomainDatalink(uint8 family); domain_datalink* DomainDatalink(net_domain* domain) { return DomainDatalink(domain->family); } #if ENABLE_DEBUGGER_COMMANDS void Dump() const; #endif private: status_t _SetUp(); void _SetDown(); InterfaceAddress* _FirstForFamily(int family); status_t _ChangeAddress(RecursiveLocker& locker, InterfaceAddress* address, int32 option, const sockaddr* oldAddress, const sockaddr* newAddress); private: recursive_lock fLock; net_device_interface* fDeviceInterface; AddressList fAddresses; DatalinkTable fDatalinkTable; }; typedef DoublyLinkedList InterfaceList; status_t init_interfaces(); status_t uninit_interfaces(); // interfaces status_t add_interface(const char* name, net_domain_private* domain, const ifaliasreq& request, net_device_interface* deviceInterface); status_t remove_interface(Interface* interface); void interface_went_down(Interface* interface); status_t add_interface_address(Interface* interface, net_domain_private* domain, const ifaliasreq& request); status_t update_interface_address(InterfaceAddress* interfaceAddress, int32 option, const sockaddr* oldAddress, const sockaddr* newAddress); Interface* get_interface(net_domain* domain, uint32 index); Interface* get_interface(net_domain* domain, const char* name); Interface* get_interface_for_device(net_domain* domain, uint32 index); Interface* get_interface_for_link(net_domain* domain, const sockaddr* address); InterfaceAddress* get_interface_address(const struct sockaddr* address); InterfaceAddress* get_interface_address_for_destination(net_domain* domain, const sockaddr* destination); InterfaceAddress* get_interface_address_for_link(net_domain* domain, const sockaddr* linkAddress, bool unconfiguredOnly); uint32 count_interfaces(); status_t list_interfaces(int family, void* buffer, size_t* _bufferSize); #endif // INTERFACES_H