mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
work in progress: get_interfaces()
This commit is contained in:
parent
b7be283ce9
commit
d51a48acca
@ -23,6 +23,9 @@
|
||||
|
||||
#if defined(WIN32_VC) || defined(WIN64_VC)
|
||||
#include <winsock2.h> // For gethostname()
|
||||
#else
|
||||
#include <net/if.h>
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -33,6 +36,7 @@
|
||||
ConnectionManager::
|
||||
ConnectionManager() : _set_mutex("ConnectionManager::_set_mutex")
|
||||
{
|
||||
_interfaces_scanned = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -504,6 +508,95 @@ get_host_name() {
|
||||
return string();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ConnectionManager::scan_interfaces
|
||||
// Access: Published
|
||||
// Description: Repopulates the list reported by
|
||||
// get_num_interface()/get_interface(). It is not
|
||||
// necessary to call this explicitly, unless you want to
|
||||
// re-determine the connected interfaces (for instance,
|
||||
// if you suspect the hardware has recently changed).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ConnectionManager::
|
||||
scan_interfaces() {
|
||||
LightMutexHolder holder(_set_mutex);
|
||||
_interfaces.clear();
|
||||
_interfaces_scanned = true;
|
||||
|
||||
#ifdef WIN32_VC
|
||||
// TODO.
|
||||
|
||||
#else // WIN32_VC
|
||||
struct ifaddrs *ifa;
|
||||
if (getifaddrs(&ifa) != 0) {
|
||||
// Failure.
|
||||
net_cat.error()
|
||||
<< "Failed to call getifaddrs\n";
|
||||
return;
|
||||
}
|
||||
|
||||
struct ifaddrs *p = ifa;
|
||||
while (p != NULL) {
|
||||
if (p->ifa_addr->sa_family == AF_INET) {
|
||||
Interface interface;
|
||||
interface.set_name(p->ifa_name);
|
||||
if (p->ifa_addr != NULL) {
|
||||
interface.set_ip(NetAddress(Socket_Address(*(sockaddr_in *)p->ifa_addr)));
|
||||
}
|
||||
if (p->ifa_netmask != NULL) {
|
||||
interface.set_netmask(NetAddress(Socket_Address(*(sockaddr_in *)p->ifa_netmask)));
|
||||
}
|
||||
if ((p->ifa_flags & IFF_BROADCAST) && p->ifa_broadaddr != NULL) {
|
||||
interface.set_broadcast(NetAddress(Socket_Address(*(sockaddr_in *)p->ifa_broadaddr)));
|
||||
} else if ((p->ifa_flags & IFF_POINTOPOINT) && p->ifa_dstaddr != NULL) {
|
||||
interface.set_p2p(NetAddress(Socket_Address(*(sockaddr_in *)p->ifa_dstaddr)));
|
||||
}
|
||||
_interfaces.push_back(interface);
|
||||
}
|
||||
|
||||
p = p->ifa_next;
|
||||
}
|
||||
|
||||
freeifaddrs(ifa);
|
||||
|
||||
#endif // WIN32_VC
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ConnectionManager::get_num_interfaces
|
||||
// Access: Published
|
||||
// Description: This returns the number of usable network interfaces
|
||||
// detected on this machine. (Currently, only IPv4
|
||||
// interfaces are reported.) See scan_interfaces() to
|
||||
// repopulate this list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int ConnectionManager::
|
||||
get_num_interfaces() {
|
||||
if (!_interfaces_scanned) {
|
||||
scan_interfaces();
|
||||
}
|
||||
LightMutexHolder holder(_set_mutex);
|
||||
return _interfaces.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ConnectionManager::get_interface
|
||||
// Access: Published
|
||||
// Description: Returns the nth usable network interface detected on
|
||||
// this machine. (Currently, only IPv4 interfaces are
|
||||
// reported.) See scan_interfaces() to repopulate this
|
||||
// list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const ConnectionManager::Interface &ConnectionManager::
|
||||
get_interface(int n) {
|
||||
if (!_interfaces_scanned) {
|
||||
scan_interfaces();
|
||||
}
|
||||
LightMutexHolder holder(_set_mutex);
|
||||
nassertr(n >= 0 && n < (int)_interfaces.size(), _interfaces[0]);
|
||||
return _interfaces[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ConnectionManager::new_connection
|
||||
// Access: Protected
|
||||
@ -629,3 +722,26 @@ remove_writer(ConnectionWriter *writer) {
|
||||
LightMutexHolder holder(_set_mutex);
|
||||
_writers.erase(writer);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ConnectionManager::Interface::Output
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ConnectionManager::Interface::
|
||||
output(ostream &out) const {
|
||||
out << get_name() << " [";
|
||||
if (has_ip()) {
|
||||
out << " " << get_ip();
|
||||
}
|
||||
if (has_netmask()) {
|
||||
out << " netmask " << get_netmask();
|
||||
}
|
||||
if (has_broadcast()) {
|
||||
out << " broadcast " << get_broadcast();
|
||||
}
|
||||
if (has_p2p()) {
|
||||
out << " p2p " << get_p2p();
|
||||
}
|
||||
out << " ]";
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "connection.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pset.h"
|
||||
#include "pvector.h"
|
||||
#include "lightMutex.h"
|
||||
|
||||
class NetAddress;
|
||||
@ -66,6 +67,50 @@ PUBLISHED:
|
||||
|
||||
static string get_host_name();
|
||||
|
||||
class Interface {
|
||||
PUBLISHED:
|
||||
const string &get_name() const { return _name; }
|
||||
bool has_ip() const { return (_flags & F_has_ip) != 0; }
|
||||
const NetAddress &get_ip() const { return _ip; }
|
||||
bool has_netmask() const { return (_flags & F_has_netmask) != 0; }
|
||||
const NetAddress &get_netmask() const { return _netmask; }
|
||||
bool has_broadcast() const { return (_flags & F_has_broadcast) != 0; }
|
||||
const NetAddress &get_broadcast() const { return _broadcast; }
|
||||
bool has_p2p() const { return (_flags & F_has_p2p) != 0; }
|
||||
const NetAddress &get_p2p() const { return _p2p; }
|
||||
|
||||
void output(ostream &out) const;
|
||||
|
||||
public:
|
||||
Interface() { _flags = 0; }
|
||||
void set_name(const string &name) { _name = name; }
|
||||
void set_ip(const NetAddress &ip) { _ip = ip; _flags |= F_has_ip; }
|
||||
void set_netmask(const NetAddress &ip) { _netmask = ip; _flags |= F_has_netmask; }
|
||||
void set_broadcast(const NetAddress &ip) { _broadcast = ip; _flags |= F_has_broadcast; }
|
||||
void set_p2p(const NetAddress &ip) { _p2p = ip; _flags |= F_has_p2p; }
|
||||
|
||||
private:
|
||||
string _name;
|
||||
|
||||
NetAddress _ip;
|
||||
NetAddress _netmask;
|
||||
NetAddress _broadcast;
|
||||
NetAddress _p2p;
|
||||
int _flags;
|
||||
|
||||
enum Flags {
|
||||
F_has_ip = 0x001,
|
||||
F_has_netmask = 0x002,
|
||||
F_has_broadcast = 0x004,
|
||||
F_has_p2p = 0x008,
|
||||
};
|
||||
};
|
||||
|
||||
void scan_interfaces();
|
||||
int get_num_interfaces();
|
||||
const Interface &get_interface(int n);
|
||||
MAKE_SEQ(get_interfaces, get_num_interfaces, get_interface);
|
||||
|
||||
protected:
|
||||
void new_connection(const PT(Connection) &connection);
|
||||
virtual void flush_read_connection(Connection *connection);
|
||||
@ -85,6 +130,10 @@ protected:
|
||||
Writers _writers;
|
||||
LightMutex _set_mutex;
|
||||
|
||||
typedef pvector<Interface> Interfaces;
|
||||
Interfaces _interfaces;
|
||||
bool _interfaces_scanned;
|
||||
|
||||
private:
|
||||
friend class ConnectionReader;
|
||||
friend class ConnectionWriter;
|
||||
@ -92,4 +141,9 @@ private:
|
||||
friend class Connection;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const ConnectionManager::Interface &interface) {
|
||||
interface.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user