mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-10-29 18:07:27 +01:00
Merge branch 'feature/6476-list-all-ifaces'
Conflicts: modules/auxiliary/scanner/afp/afp_server_info.rb
This commit is contained in:
commit
6a6dd06103
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
data/meterpreter/msflinker_linux_x86.bin
Executable file → Normal file
BIN
data/meterpreter/msflinker_linux_x86.bin
Executable file → Normal file
Binary file not shown.
@ -37,16 +37,26 @@ typedef struct ___u128 {
|
||||
__u32 a4;
|
||||
}__u128;
|
||||
|
||||
struct iface_address {
|
||||
int family;
|
||||
union {
|
||||
__u32 addr;
|
||||
__u128 addr6;
|
||||
} ip;
|
||||
union {
|
||||
__u32 netmask;
|
||||
__u128 netmask6;
|
||||
} nm;
|
||||
};
|
||||
|
||||
struct iface_entry {
|
||||
unsigned char name[IFNAMSIZ+1];
|
||||
__u32 addr;
|
||||
__u32 netmask;
|
||||
unsigned char hwaddr[6];
|
||||
__u128 addr6;
|
||||
__u128 netmask6;
|
||||
uint32_t mtu;
|
||||
uint32_t index;
|
||||
unsigned char flags[FLAGS_LEN+1];
|
||||
int addr_count;
|
||||
struct iface_address *addr_list;
|
||||
};
|
||||
|
||||
struct ifaces_list {
|
||||
|
@ -1528,4 +1528,4 @@ DWORD packet_receive_via_http(Remote *remote, Packet **packet)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,15 +1,15 @@
|
||||
#include "precomp.h"
|
||||
|
||||
/*
|
||||
* Returns zero or more local interfaces to the requestor
|
||||
*/
|
||||
DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet)
|
||||
#ifdef _WIN32
|
||||
#include <ws2ipdef.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD get_interfaces_windows_mib(Remote *remote, Packet *response)
|
||||
{
|
||||
Packet *response = packet_create_response(packet);
|
||||
DWORD result = ERROR_SUCCESS;
|
||||
DWORD entryCount;
|
||||
|
||||
#ifdef _WIN32
|
||||
Tlv entries[6];
|
||||
PMIB_IPADDRTABLE table = NULL;
|
||||
DWORD tableSize = sizeof(MIB_IPADDRROW) * 33;
|
||||
@ -35,26 +35,24 @@ DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet)
|
||||
}
|
||||
|
||||
// Enumerate the entries
|
||||
for (index = 0;
|
||||
index < table->dwNumEntries;
|
||||
index++)
|
||||
for (index = 0; index < table->dwNumEntries; index++)
|
||||
{
|
||||
entryCount = 0;
|
||||
|
||||
interface_index_bigendian = htonl(table->table[index].dwIndex);
|
||||
entries[entryCount].header.length = sizeof(DWORD);
|
||||
entries[entryCount].header.type = TLV_TYPE_INTERFACE_INDEX;
|
||||
entries[entryCount].buffer = (PUCHAR)&interface_index_bigendian;
|
||||
entries[entryCount].header.type = TLV_TYPE_INTERFACE_INDEX;
|
||||
entries[entryCount].buffer = (PUCHAR)&interface_index_bigendian;
|
||||
entryCount++;
|
||||
|
||||
entries[entryCount].header.length = sizeof(DWORD);
|
||||
entries[entryCount].header.type = TLV_TYPE_IP;
|
||||
entries[entryCount].buffer = (PUCHAR)&table->table[index].dwAddr;
|
||||
entries[entryCount].header.type = TLV_TYPE_IP;
|
||||
entries[entryCount].buffer = (PUCHAR)&table->table[index].dwAddr;
|
||||
entryCount++;
|
||||
|
||||
entries[entryCount].header.length = sizeof(DWORD);
|
||||
entries[entryCount].header.type = TLV_TYPE_NETMASK;
|
||||
entries[entryCount].buffer = (PUCHAR)&table->table[index].dwMask;
|
||||
entries[entryCount].header.type = TLV_TYPE_NETMASK;
|
||||
entries[entryCount].buffer = (PUCHAR)&table->table[index].dwMask;
|
||||
entryCount++;
|
||||
|
||||
iface.dwIndex = table->table[index].dwIndex;
|
||||
@ -63,28 +61,28 @@ DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet)
|
||||
if (GetIfEntry(&iface) == NO_ERROR)
|
||||
{
|
||||
entries[entryCount].header.length = iface.dwPhysAddrLen;
|
||||
entries[entryCount].header.type = TLV_TYPE_MAC_ADDR;
|
||||
entries[entryCount].buffer = (PUCHAR)iface.bPhysAddr;
|
||||
entries[entryCount].header.type = TLV_TYPE_MAC_ADDR;
|
||||
entries[entryCount].buffer = (PUCHAR)iface.bPhysAddr;
|
||||
entryCount++;
|
||||
|
||||
mtu_bigendian = htonl(iface.dwMtu);
|
||||
entries[entryCount].header.length = sizeof(DWORD);
|
||||
entries[entryCount].header.type = TLV_TYPE_INTERFACE_MTU;
|
||||
entries[entryCount].buffer = (PUCHAR)&mtu_bigendian;
|
||||
entries[entryCount].header.type = TLV_TYPE_INTERFACE_MTU;
|
||||
entries[entryCount].buffer = (PUCHAR)&mtu_bigendian;
|
||||
entryCount++;
|
||||
|
||||
if (iface.bDescr)
|
||||
{
|
||||
entries[entryCount].header.length = iface.dwDescrLen + 1;
|
||||
entries[entryCount].header.type = TLV_TYPE_MAC_NAME;
|
||||
entries[entryCount].buffer = (PUCHAR)iface.bDescr;
|
||||
entries[entryCount].header.type = TLV_TYPE_MAC_NAME;
|
||||
entries[entryCount].buffer = (PUCHAR)iface.bDescr;
|
||||
entryCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the interface group
|
||||
packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE,
|
||||
entries, entryCount);
|
||||
entries, entryCount);
|
||||
}
|
||||
|
||||
} while (0);
|
||||
@ -92,64 +90,249 @@ DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet)
|
||||
if (table)
|
||||
free(table);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
DWORD get_interfaces_windows(Remote *remote, Packet *response) {
|
||||
DWORD result = ERROR_SUCCESS;
|
||||
DWORD entryCount;
|
||||
// Most of the time we'll need:
|
||||
// index, name (description), MAC addr, mtu, flags, IP addr, netmask, maybe scope id
|
||||
// In some cases, the interface will have multiple addresses, so we'll realloc
|
||||
// this when necessary, but this will cover the common case.
|
||||
DWORD allocd_entries = 10;
|
||||
Tlv *entries = (Tlv *)malloc(sizeof(Tlv) * 10);
|
||||
|
||||
DWORD mtu_bigendian;
|
||||
DWORD interface_index_bigendian;
|
||||
|
||||
ULONG flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_DNS_SERVER;
|
||||
|
||||
LPSOCKADDR sockaddr;
|
||||
|
||||
ULONG family = AF_UNSPEC;
|
||||
IP_ADAPTER_ADDRESSES *pAdapters = NULL;
|
||||
IP_ADAPTER_ADDRESSES *pCurr = NULL;
|
||||
ULONG outBufLen = 0;
|
||||
DWORD (WINAPI *gaa)(DWORD, DWORD, void *, void *, void *);
|
||||
|
||||
// Use the larger version so we're guaranteed to have a large enough struct
|
||||
IP_ADAPTER_UNICAST_ADDRESS_LH *pAddr;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
gaa = (DWORD (WINAPI *)(DWORD,DWORD,void*,void*,void*))GetProcAddress(
|
||||
GetModuleHandle("iphlpapi"), "GetAdaptersAddresses"
|
||||
);
|
||||
if (!gaa) {
|
||||
result = get_interfaces_windows_mib(remote, response);
|
||||
|
||||
// --- DEBUG ---
|
||||
packet_add_tlv_uint(response, TLV_TYPE_EXIT_CODE, 666);
|
||||
// --- END DEBUG ---
|
||||
break;
|
||||
}
|
||||
|
||||
gaa(family, flags, NULL, pAdapters, &outBufLen);
|
||||
if (!(pAdapters = (IP_ADAPTER_ADDRESSES *)malloc(outBufLen)))
|
||||
{
|
||||
result = ERROR_NOT_ENOUGH_MEMORY;
|
||||
break;
|
||||
}
|
||||
if (gaa(family, flags, NULL, pAdapters, &outBufLen))
|
||||
{
|
||||
result = GetLastError();
|
||||
break;
|
||||
}
|
||||
|
||||
// Enumerate the entries
|
||||
for (pCurr = pAdapters; pCurr; pCurr = pCurr->Next)
|
||||
{
|
||||
entryCount = 0;
|
||||
|
||||
interface_index_bigendian = htonl(pCurr->IfIndex);
|
||||
entries[entryCount].header.length = sizeof(DWORD);
|
||||
entries[entryCount].header.type = TLV_TYPE_INTERFACE_INDEX;
|
||||
entries[entryCount].buffer = (PUCHAR)&interface_index_bigendian;
|
||||
entryCount++;
|
||||
|
||||
entries[entryCount].header.length = pCurr->PhysicalAddressLength;
|
||||
entries[entryCount].header.type = TLV_TYPE_MAC_ADDR;
|
||||
entries[entryCount].buffer = (PUCHAR)pCurr->PhysicalAddress;
|
||||
entryCount++;
|
||||
|
||||
entries[entryCount].header.length = wcslen(pCurr->Description)*2 + 1;
|
||||
entries[entryCount].header.type = TLV_TYPE_MAC_NAME;
|
||||
entries[entryCount].buffer = (PUCHAR)pCurr->Description;
|
||||
entryCount++;
|
||||
|
||||
mtu_bigendian = htonl(pCurr->Mtu);
|
||||
entries[entryCount].header.length = sizeof(DWORD);
|
||||
entries[entryCount].header.type = TLV_TYPE_INTERFACE_MTU;
|
||||
entries[entryCount].buffer = (PUCHAR)&mtu_bigendian;
|
||||
entryCount++;
|
||||
|
||||
|
||||
for (pAddr = (void*)pCurr->FirstUnicastAddress; pAddr; pAddr = (void*)pAddr->Next)
|
||||
{
|
||||
// This loop can add up to three Tlv's - one for address, one for scope_id, one for netmask.
|
||||
// Go ahead and allocate enough room for all of them.
|
||||
if (allocd_entries < entryCount+3) {
|
||||
entries = realloc(entries, sizeof(Tlv) * (entryCount+3));
|
||||
allocd_entries += 3;
|
||||
}
|
||||
|
||||
sockaddr = pAddr->Address.lpSockaddr;
|
||||
if (sockaddr->sa_family == AF_INET) {
|
||||
entries[entryCount].header.length = 4;
|
||||
entries[entryCount].header.type = TLV_TYPE_IP;
|
||||
entries[entryCount].buffer = (PUCHAR)&(((struct sockaddr_in *)sockaddr)->sin_addr);
|
||||
if (pCurr->Length > 68) {
|
||||
|
||||
// --- DEBUG ---
|
||||
packet_add_tlv_uint(response, TLV_TYPE_EXIT_CODE, 1337);
|
||||
// --- END DEBUG ---
|
||||
|
||||
|
||||
entryCount++;
|
||||
entries[entryCount].header.length = 4;
|
||||
entries[entryCount].header.type = TLV_TYPE_NETMASK;
|
||||
entries[entryCount].buffer = (PUCHAR)&(((struct sockaddr_in *)sockaddr)->sin_addr);
|
||||
}
|
||||
} else {
|
||||
entries[entryCount].header.length = 16;
|
||||
entries[entryCount].header.type = TLV_TYPE_IP;
|
||||
entries[entryCount].buffer = (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_addr);
|
||||
|
||||
entryCount++;
|
||||
entries[entryCount].header.length = sizeof(DWORD);
|
||||
entries[entryCount].header.type = TLV_TYPE_IP6_SCOPE;
|
||||
entries[entryCount].buffer = (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_scope_id);
|
||||
|
||||
if (pCurr->Length > 68) {
|
||||
entryCount++;
|
||||
entries[entryCount].header.length = 16;
|
||||
entries[entryCount].header.type = TLV_TYPE_NETMASK;
|
||||
entries[entryCount].buffer = (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_addr);
|
||||
}
|
||||
|
||||
}
|
||||
entryCount++;
|
||||
}
|
||||
// Add the interface group
|
||||
packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE,
|
||||
entries, entryCount);
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (entries)
|
||||
free(entries);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
int get_interfaces_linux(Remote *remote, Packet *response) {
|
||||
struct ifaces_list *ifaces = NULL;
|
||||
int i;
|
||||
int if_error;
|
||||
int result;
|
||||
uint32_t interface_index_bigendian, mtu_bigendian;
|
||||
Tlv entries[9];
|
||||
// wild guess, should probably malloc
|
||||
Tlv entries[39];
|
||||
|
||||
if_error = netlink_get_interfaces(&ifaces);
|
||||
dprintf("Grabbing interfaces");
|
||||
result = netlink_get_interfaces(&ifaces);
|
||||
dprintf("Got 'em");
|
||||
|
||||
if (if_error) {
|
||||
result = if_error;
|
||||
} else {
|
||||
if (!result) {
|
||||
for (i = 0; i < ifaces->entries; i++) {
|
||||
int tlv_cnt = 0;
|
||||
int j = 0;
|
||||
dprintf("Building TLV for iface %d", i);
|
||||
|
||||
entries[0].header.length = strlen(ifaces->ifaces[i].name)+1;
|
||||
entries[0].header.type = TLV_TYPE_MAC_NAME;
|
||||
entries[0].buffer = (PUCHAR)ifaces->ifaces[i].name;
|
||||
entries[tlv_cnt].header.length = strlen(ifaces->ifaces[i].name)+1;
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_MAC_NAME;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)ifaces->ifaces[i].name;
|
||||
tlv_cnt++;
|
||||
|
||||
entries[1].header.length = 6;
|
||||
entries[1].header.type = TLV_TYPE_MAC_ADDR;
|
||||
entries[1].buffer = (PUCHAR)ifaces->ifaces[i].hwaddr;
|
||||
entries[tlv_cnt].header.length = 6;
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_MAC_ADDR;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)ifaces->ifaces[i].hwaddr;
|
||||
tlv_cnt++;
|
||||
|
||||
entries[2].header.length = sizeof(__u32);
|
||||
entries[2].header.type = TLV_TYPE_IP;
|
||||
entries[2].buffer = (PUCHAR)&ifaces->ifaces[i].addr;
|
||||
for (j = 0; j < ifaces->ifaces[i].addr_count; j++) {
|
||||
if (ifaces->ifaces[i].addr_list[j].family == AF_INET) {
|
||||
dprintf("ip addr for %s", ifaces->ifaces[i].name);
|
||||
entries[tlv_cnt].header.length = sizeof(__u32);
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_IP;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)&ifaces->ifaces[i].addr_list[j].ip.addr;
|
||||
tlv_cnt++;
|
||||
|
||||
entries[3].header.length = sizeof(__u32);
|
||||
entries[3].header.type = TLV_TYPE_NETMASK;
|
||||
entries[3].buffer = (PUCHAR)&ifaces->ifaces[i].netmask;
|
||||
//dprintf("netmask for %s", ifaces->ifaces[i].name);
|
||||
entries[tlv_cnt].header.length = sizeof(__u32);
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_NETMASK;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)&ifaces->ifaces[i].addr_list[j].nm.netmask;
|
||||
tlv_cnt++;
|
||||
} else {
|
||||
dprintf("-- ip six addr for %s", ifaces->ifaces[i].name);
|
||||
entries[tlv_cnt].header.length = sizeof(__u128);
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_IP;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)&ifaces->ifaces[i].addr_list[j].ip.addr6;
|
||||
tlv_cnt++;
|
||||
|
||||
entries[4].header.length = sizeof(__u128);
|
||||
entries[4].header.type = TLV_TYPE_IP6;
|
||||
entries[4].buffer = (PUCHAR)&ifaces->ifaces[i].addr6;
|
||||
|
||||
entries[5].header.length = sizeof(__u128);
|
||||
entries[5].header.type = TLV_TYPE_NETMASK6;
|
||||
entries[5].buffer = (PUCHAR)&ifaces->ifaces[i].netmask6;
|
||||
//dprintf("netmask6 for %s", ifaces->ifaces[i].name);
|
||||
entries[tlv_cnt].header.length = sizeof(__u128);
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_NETMASK;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)&ifaces->ifaces[i].addr_list[j].nm.netmask6;
|
||||
tlv_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
mtu_bigendian = htonl(ifaces->ifaces[i].mtu);
|
||||
entries[6].header.length = sizeof(uint32_t);
|
||||
entries[6].header.type = TLV_TYPE_INTERFACE_MTU;
|
||||
entries[6].buffer = (PUCHAR)&mtu_bigendian;
|
||||
entries[tlv_cnt].header.length = sizeof(uint32_t);
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_MTU;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)&mtu_bigendian;
|
||||
tlv_cnt++;
|
||||
|
||||
entries[7].header.length = strlen(ifaces->ifaces[i].flags)+1;
|
||||
entries[7].header.type = TLV_TYPE_INTERFACE_FLAGS;
|
||||
entries[7].buffer = (PUCHAR)ifaces->ifaces[i].flags;
|
||||
entries[tlv_cnt].header.length = strlen(ifaces->ifaces[i].flags)+1;
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_FLAGS;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)ifaces->ifaces[i].flags;
|
||||
tlv_cnt++;
|
||||
|
||||
interface_index_bigendian = htonl(ifaces->ifaces[i].index);
|
||||
entries[8].header.length = sizeof(uint32_t);
|
||||
entries[8].header.type = TLV_TYPE_INTERFACE_INDEX;
|
||||
entries[8].buffer = (PUCHAR)&interface_index_bigendian;
|
||||
|
||||
packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE, entries, 9);
|
||||
entries[tlv_cnt].header.length = sizeof(uint32_t);
|
||||
entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_INDEX;
|
||||
entries[tlv_cnt].buffer = (PUCHAR)&interface_index_bigendian;
|
||||
tlv_cnt++;
|
||||
|
||||
dprintf("Adding TLV to group");
|
||||
packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE, entries, tlv_cnt);
|
||||
dprintf("done Adding TLV to group");
|
||||
}
|
||||
}
|
||||
|
||||
if (ifaces)
|
||||
free(ifaces);
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Returns zero or more local interfaces to the requestor
|
||||
*/
|
||||
DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet)
|
||||
{
|
||||
Packet *response = packet_create_response(packet);
|
||||
DWORD result = ERROR_SUCCESS;
|
||||
|
||||
#ifdef _WIN32
|
||||
result = get_interfaces_windows(remote, response);
|
||||
#else
|
||||
result = get_interfaces_linux(remote, response);
|
||||
#endif
|
||||
|
||||
// Transmit the response if valid
|
||||
@ -159,5 +342,3 @@ DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -355,26 +355,6 @@
|
||||
TLV_META_TYPE_GROUP, \
|
||||
TLV_TYPE_EXTENSION_STDAPI, \
|
||||
1423)
|
||||
#define TLV_TYPE_SUBNET6 \
|
||||
MAKE_CUSTOM_TLV( \
|
||||
TLV_META_TYPE_RAW, \
|
||||
TLV_TYPE_EXTENSION_STDAPI, \
|
||||
1424)
|
||||
#define TLV_TYPE_NETMASK6 \
|
||||
MAKE_CUSTOM_TLV( \
|
||||
TLV_META_TYPE_RAW, \
|
||||
TLV_TYPE_EXTENSION_STDAPI, \
|
||||
1425)
|
||||
#define TLV_TYPE_GATEWAY6 \
|
||||
MAKE_CUSTOM_TLV( \
|
||||
TLV_META_TYPE_RAW, \
|
||||
TLV_TYPE_EXTENSION_STDAPI, \
|
||||
1426)
|
||||
#define TLV_TYPE_NETWORK_ROUTE6 \
|
||||
MAKE_CUSTOM_TLV( \
|
||||
TLV_META_TYPE_GROUP, \
|
||||
TLV_TYPE_EXTENSION_STDAPI, \
|
||||
1427)
|
||||
#define TLV_TYPE_IP \
|
||||
MAKE_CUSTOM_TLV( \
|
||||
TLV_META_TYPE_RAW, \
|
||||
@ -395,9 +375,9 @@
|
||||
TLV_META_TYPE_GROUP, \
|
||||
TLV_TYPE_EXTENSION_STDAPI, \
|
||||
1433)
|
||||
#define TLV_TYPE_IP6 \
|
||||
#define TLV_TYPE_IP6_SCOPE \
|
||||
MAKE_CUSTOM_TLV( \
|
||||
TLV_META_TYPE_RAW, \
|
||||
TLV_META_TYPE_RAW, \
|
||||
TLV_TYPE_EXTENSION_STDAPI, \
|
||||
1434)
|
||||
|
||||
|
@ -158,8 +158,8 @@ int netlink_parse(int fd, int seq, netlink_cb_t callback, void *data)
|
||||
}
|
||||
|
||||
for(nh = (struct nlmsghdr *)(buf); NLMSG_OK(nh, len); nh = (struct nlmsghdr *) NLMSG_NEXT(nh, len)) {
|
||||
dprintf("buf = %p, nh = %p", buf, nh);
|
||||
dprintf("nh->nlmsg_type = %d", nh->nlmsg_type);
|
||||
//dprintf("buf = %p, nh = %p", buf, nh);
|
||||
//dprintf("nh->nlmsg_type = %d", nh->nlmsg_type);
|
||||
|
||||
if(nh->nlmsg_type == NLMSG_DONE) {
|
||||
end = 1;
|
||||
@ -168,12 +168,12 @@ int netlink_parse(int fd, int seq, netlink_cb_t callback, void *data)
|
||||
|
||||
if(nh->nlmsg_type == NLMSG_ERROR) {
|
||||
struct nlmsgerr *me = (struct nlmsgerr *) NLMSG_DATA (nh);
|
||||
dprintf("in NLMSG_ERROR handling.. me = %p");
|
||||
dprintf("me->error = %d", me->error);
|
||||
//dprintf("in NLMSG_ERROR handling.. me = %p", me);
|
||||
//dprintf("me->error = %d", me->error);
|
||||
if(me->error) {
|
||||
dprintf("so, we have: nlmsg_len: %d, nlmsg_type: %d, nlmsg_flags: %d, nlmsg_seq: %d, nlmsg_pid: %d",
|
||||
me->msg.nlmsg_len, me->msg.nlmsg_type, me->msg.nlmsg_flags,
|
||||
me->msg.nlmsg_seq, me->msg.nlmsg_pid);
|
||||
//dprintf("so, we have: nlmsg_len: %d, nlmsg_type: %d, nlmsg_flags: %d, nlmsg_seq: %d, nlmsg_pid: %d",
|
||||
// me->msg.nlmsg_len, me->msg.nlmsg_type, me->msg.nlmsg_flags,
|
||||
// me->msg.nlmsg_seq, me->msg.nlmsg_pid);
|
||||
|
||||
if(me->msg.nlmsg_seq == seq) {
|
||||
dprintf("Hum. kernel doesn't like our message :~(");
|
||||
@ -188,7 +188,7 @@ int netlink_parse(int fd, int seq, netlink_cb_t callback, void *data)
|
||||
|
||||
//
|
||||
|
||||
dprintf("[%s] dispatching into callback", __FUNCTION__);
|
||||
dprintf("dispatching into callback");
|
||||
|
||||
status = callback(nh, data);
|
||||
|
||||
@ -262,7 +262,7 @@ int netlink_parse_routing_table(struct nlmsghdr *nh, void *data)
|
||||
dprintf("Adjusted rm at +4");
|
||||
}
|
||||
|
||||
dprintf("rtm_family : 0x%x , rtm_dst_len : 0x%x, rtm_src_len : 0x%x",rm->rtm_family, rm->rtm_dst_len, rm->rtm_src_len);
|
||||
//dprintf("rtm_family : 0x%x , rtm_dst_len : 0x%x, rtm_src_len : 0x%x",rm->rtm_family, rm->rtm_dst_len, rm->rtm_src_len);
|
||||
// print directly connected routes
|
||||
if(rm->rtm_type != RTN_UNICAST && rm->rtm_type != RTN_LOCAL) {
|
||||
dprintf("got %d instead of RTN_UNICAST (%d) or RTN_LOCAL (%d)", rm->rtm_type, RTN_UNICAST,RTN_LOCAL);
|
||||
@ -289,7 +289,7 @@ int netlink_parse_routing_table(struct nlmsghdr *nh, void *data)
|
||||
else
|
||||
is_ipv6 = 1;
|
||||
|
||||
dprintf("nh->nlmsg_len: %d, NLMSG_LENGTH(sizeof(..)): %d, is_ipv6 : %d", nh->nlmsg_len, NLMSG_LENGTH(sizeof(struct rtmsg)),is_ipv6);
|
||||
//dprintf("nh->nlmsg_len: %d, NLMSG_LENGTH(sizeof(..)): %d, is_ipv6 : %d", nh->nlmsg_len, NLMSG_LENGTH(sizeof(struct rtmsg)),is_ipv6);
|
||||
|
||||
len = nh->nlmsg_len - NLMSG_LENGTH (sizeof(struct rtmsg));
|
||||
if(len <= 0) {
|
||||
@ -297,12 +297,12 @@ int netlink_parse_routing_table(struct nlmsghdr *nh, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
dprintf("RTA_DST=%d, RTA_SRC=%d, RTA_GATEWAY=%d, RTA_PREFSRC=%d, RTA_OIF=%d, RTA_PRIORITY=%d", RTA_DST, RTA_SRC, RTA_GATEWAY, RTA_PREFSRC,RTA_OIF, RTA_PRIORITY);
|
||||
//dprintf("RTA_DST=%d, RTA_SRC=%d, RTA_GATEWAY=%d, RTA_PREFSRC=%d, RTA_OIF=%d, RTA_PRIORITY=%d", RTA_DST, RTA_SRC, RTA_GATEWAY, RTA_PREFSRC,RTA_OIF, RTA_PRIORITY);
|
||||
|
||||
|
||||
dprintf("rtm_table : %d, RT_TABLE_UNSPEC=%d, RT_TABLE_DEFAULT =%d, RT_TABLE_MAIN=%d,RT_TABLE_LOCAL=%d", rm->rtm_table,RT_TABLE_UNSPEC, RT_TABLE_DEFAULT , RT_TABLE_MAIN, RT_TABLE_LOCAL);
|
||||
//dprintf("rtm_table : %d, RT_TABLE_UNSPEC=%d, RT_TABLE_DEFAULT =%d, RT_TABLE_MAIN=%d,RT_TABLE_LOCAL=%d", rm->rtm_table,RT_TABLE_UNSPEC, RT_TABLE_DEFAULT , RT_TABLE_MAIN, RT_TABLE_LOCAL);
|
||||
|
||||
dprintf("rtm_type : %d, RTN_UNICAST=%d, RTN_LOCAL=%d", rm->rtm_type,RTN_UNICAST, RTN_LOCAL);
|
||||
//dprintf("rtm_type : %d, RTN_UNICAST=%d, RTN_LOCAL=%d", rm->rtm_type,RTN_UNICAST, RTN_LOCAL);
|
||||
// okay, so.
|
||||
//
|
||||
|
||||
@ -310,11 +310,11 @@ int netlink_parse_routing_table(struct nlmsghdr *nh, void *data)
|
||||
{
|
||||
if (is_ipv6) {
|
||||
what6 = (unsigned char *) RTA_DATA(ra);
|
||||
dprintf("ra @ %p, type = %d, length = %d, payload = %d, payload data = %08x %08x %08x %08x", ra, ra->rta_type, ra->rta_len, RTA_PAYLOAD(ra), *(__u32 *)what6, *(__u32 *)(what6+4), *(__u32 *)(what6+8), *(__u32 *)(what6+12));
|
||||
//dprintf("ra @ %p, type = %d, length = %d, payload = %d, payload data = %08x %08x %08x %08x", ra, ra->rta_type, ra->rta_len, RTA_PAYLOAD(ra), *(__u32 *)what6, *(__u32 *)(what6+4), *(__u32 *)(what6+8), *(__u32 *)(what6+12));
|
||||
}
|
||||
else {
|
||||
what = (__u32 *) RTA_DATA(ra);
|
||||
dprintf("ra @ %p, type = %d, length = %d, payload = %d, payload data = %08x", ra, ra->rta_type, ra->rta_len, RTA_PAYLOAD(ra), *what);
|
||||
//dprintf("ra @ %p, type = %d, length = %d, payload = %d, payload data = %08x", ra, ra->rta_type, ra->rta_len, RTA_PAYLOAD(ra), *what);
|
||||
}
|
||||
|
||||
switch(ra->rta_type) {
|
||||
@ -341,7 +341,7 @@ int netlink_parse_routing_table(struct nlmsghdr *nh, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
dprintf("and while you're here, rtm_dst_len = %d", rm->rtm_dst_len);
|
||||
//dprintf("and while you're here, rtm_dst_len = %d", rm->rtm_dst_len);
|
||||
|
||||
if (is_ipv6) {
|
||||
// if netmask is FFFFFFFF FFFFFFFF 00000000 00000000 (/64), netmask6.a1 and netmask6.a2 == 0xffffffff, and nestmask6.a3 and .a4 == 0
|
||||
@ -387,11 +387,11 @@ int netlink_parse_routing_table(struct nlmsghdr *nh, void *data)
|
||||
|
||||
strncpy(re6->interface, int_name, IFNAMSIZ);
|
||||
re6->metric = metric;
|
||||
dprintf("re6->dest6 = %08x %08x %08x %08x, re6->netmask6 = %08x %08x %08x %08x, re6->nexthop6 = %08x %08x %08x %08x, interface = %s, metric = %d",
|
||||
re6->dest6.a1,re6->dest6.a2,re6->dest6.a3,re6->dest6.a4,
|
||||
re6->netmask6.a1,re6->netmask6.a2,re6->netmask6.a3,re6->netmask6.a4,
|
||||
re6->nexthop6.a1,re6->nexthop6.a2,re6->nexthop6.a3,re6->nexthop6.a4,
|
||||
re6->interface,re6->metric);
|
||||
//dprintf("re6->dest6 = %08x %08x %08x %08x, re6->netmask6 = %08x %08x %08x %08x, re6->nexthop6 = %08x %08x %08x %08x, interface = %s, metric = %d",
|
||||
// re6->dest6.a1,re6->dest6.a2,re6->dest6.a3,re6->dest6.a4,
|
||||
// re6->netmask6.a1,re6->netmask6.a2,re6->netmask6.a3,re6->netmask6.a4,
|
||||
// re6->nexthop6.a1,re6->nexthop6.a2,re6->nexthop6.a3,re6->nexthop6.a4,
|
||||
// re6->interface,re6->metric);
|
||||
tmp6->entries++;
|
||||
|
||||
*table_v6 = tmp6;
|
||||
@ -414,7 +414,7 @@ int netlink_parse_routing_table(struct nlmsghdr *nh, void *data)
|
||||
strncpy(re->interface, int_name, IFNAMSIZ);
|
||||
re->metric = metric;
|
||||
|
||||
dprintf("re->dest = %08x, re->netmask = %08x, re->nexthop = %08x, interface = %s, metric = %d", re->dest, re->netmask, re->nexthop,re->interface,re->metric);
|
||||
//dprintf("re->dest = %08x, re->netmask = %08x, re->nexthop = %08x, interface = %s, metric = %d", re->dest, re->netmask, re->nexthop,re->interface,re->metric);
|
||||
tmp->entries++;
|
||||
|
||||
*table_v4 = tmp;
|
||||
@ -531,7 +531,7 @@ int netlink_parse_interface_link(struct nlmsghdr *nh, void *data)
|
||||
iface = (unsigned char *)iface + 4;
|
||||
dprintf("Adjusted iface at +4");
|
||||
}
|
||||
dprintf("ifi_family : 0x%x , ifi_type : 0x%x, ifi_index : 0x%x",iface->ifi_family, iface->ifi_type, iface->ifi_index);
|
||||
//dprintf("ifi_family : 0x%x , ifi_type : 0x%x, ifi_index : 0x%x",iface->ifi_family, iface->ifi_type, iface->ifi_index);
|
||||
len = nh->nlmsg_len - NLMSG_LENGTH(sizeof(*iface));
|
||||
memset(&iface_tmp, 0, sizeof(iface_tmp));
|
||||
|
||||
@ -642,8 +642,7 @@ int netlink_parse_interface_address(struct nlmsghdr *nh, void *data)
|
||||
{
|
||||
struct ifaces_list ** iface_list = ( struct ifaces_list **) data;
|
||||
struct iface_entry * iff;
|
||||
struct iface_entry * iff_tmp;
|
||||
struct ifaces_list *tmp;
|
||||
struct ifaces_list * iface_list_tmp;
|
||||
struct iface_entry iface_tmp;
|
||||
|
||||
struct ifaddrmsg *iaddr;
|
||||
@ -652,6 +651,11 @@ int netlink_parse_interface_address(struct nlmsghdr *nh, void *data)
|
||||
uint32_t newsize;
|
||||
unsigned char is_ipv6;
|
||||
|
||||
struct iface_address *addr_tmp;
|
||||
|
||||
// strictly for debugging
|
||||
char addr_str[64];
|
||||
|
||||
iaddr = NLMSG_DATA(nh);
|
||||
// stumbled upon an old system with 4 bytes padding between nlmsghdr and ifaddrmsg, try to detect it
|
||||
if (!likely_ifaddrmsg(iaddr)) {
|
||||
@ -659,7 +663,6 @@ int netlink_parse_interface_address(struct nlmsghdr *nh, void *data)
|
||||
dprintf("Adjusted iaddr at +4");
|
||||
}
|
||||
|
||||
dprintf("ifa_family : 0x%x , ifa_prefixlen : 0x%x, ifa_flags : 0x%x, ifa_scope : 0x%x",iaddr->ifa_family, iaddr->ifa_prefixlen, iaddr->ifa_flags, iaddr->ifa_scope);
|
||||
len = nh->nlmsg_len - NLMSG_LENGTH(sizeof(*iaddr));
|
||||
|
||||
if (iaddr->ifa_family == AF_INET6)
|
||||
@ -667,127 +670,111 @@ int netlink_parse_interface_address(struct nlmsghdr *nh, void *data)
|
||||
else if (iaddr->ifa_family == AF_INET)
|
||||
is_ipv6 = 0;
|
||||
else {
|
||||
dprintf("Got iaddr->ifa_family : %d which is unknown (iaddr->ifa_index : %d)", iaddr->ifa_family, iaddr->ifa_index);
|
||||
//dprintf("Got iaddr->ifa_family : %d which is unknown (iaddr->ifa_index : %d)", iaddr->ifa_family, iaddr->ifa_index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&iface_tmp, 0, sizeof(iface_tmp));
|
||||
iface_tmp.index = iaddr->ifa_index;
|
||||
|
||||
dprintf("-------------------------------------");
|
||||
for (attribute = IFA_RTA(iaddr); RTA_OK(attribute, len); attribute = RTA_NEXT(attribute, len))
|
||||
{
|
||||
dprintf("Start of loop, attribute->rta_type = %d", attribute->rta_type);
|
||||
switch(attribute->rta_type)
|
||||
{
|
||||
case IFA_ADDRESS:
|
||||
// Make room for a new address
|
||||
iface_tmp.addr_count++;
|
||||
iface_tmp.addr_list = realloc(iface_tmp.addr_list, sizeof(struct iface_address) * iface_tmp.addr_count);
|
||||
addr_tmp = &iface_tmp.addr_list[iface_tmp.addr_count-1];
|
||||
if (is_ipv6)
|
||||
memcpy(&iface_tmp.addr6, (unsigned char *) RTA_DATA(attribute), sizeof(__u128));
|
||||
else
|
||||
iface_tmp.addr = *(__u32 *) RTA_DATA(attribute);
|
||||
{
|
||||
addr_tmp->family = AF_INET6;
|
||||
memcpy(&addr_tmp->ip.addr6, (unsigned char *) RTA_DATA(attribute), sizeof(__u128));
|
||||
} else {
|
||||
addr_tmp->family = AF_INET;
|
||||
addr_tmp->ip.addr = *(__u32 *) RTA_DATA(attribute);
|
||||
}
|
||||
address_calculate_netmask(addr_tmp, iaddr->ifa_prefixlen);
|
||||
|
||||
inet_ntop(addr_tmp->family, &addr_tmp->ip, addr_str, sizeof(addr_str));
|
||||
dprintf("Interface: %s", addr_str);
|
||||
inet_ntop(addr_tmp->family, &addr_tmp->nm, addr_str, sizeof(addr_str));
|
||||
dprintf("Netmask: %s", addr_str);
|
||||
break;
|
||||
|
||||
case IFA_LABEL:
|
||||
strncpy(iface_tmp.name, (unsigned char *) RTA_DATA(attribute), IFNAMSIZ);
|
||||
dprintf("Copied name %s", iface_tmp.name);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
dprintf("-------------------------------------");
|
||||
}
|
||||
|
||||
dprintf("and while you're here, iaddr->ifa_prefixlen = %d", iaddr->ifa_prefixlen);
|
||||
|
||||
if (is_ipv6) {
|
||||
// if netmask is FFFFFFFF FFFFFFFF 00000000 00000000 (/64), netmask6.a1 and netmask6.a2 == 0xffffffff, and nestmask6.a3 and .a4 == 0
|
||||
// netmask6 is set to 0 at the beginning of the function, no need to reset the values to 0 if it is needed
|
||||
// XXX really ugly, but works
|
||||
if (iaddr->ifa_prefixlen >= 96) {
|
||||
iface_tmp.netmask6.a4 = (1 << (iaddr->ifa_prefixlen-96))-1;
|
||||
iface_tmp.netmask6.a1 = iface_tmp.netmask6.a2 = iface_tmp.netmask6.a3 = 0xffffffff;
|
||||
}
|
||||
else if (iaddr->ifa_prefixlen >= 64) {
|
||||
iface_tmp.netmask6.a3 = (1 << (iaddr->ifa_prefixlen-64))-1;
|
||||
iface_tmp.netmask6.a1 = iface_tmp.netmask6.a2 = 0xffffffff;
|
||||
}
|
||||
else if (iaddr->ifa_prefixlen >= 32) {
|
||||
iface_tmp.netmask6.a2 = (1 << (iaddr->ifa_prefixlen-32))-1;
|
||||
iface_tmp.netmask6.a1 = 0xffffffff;
|
||||
}
|
||||
else
|
||||
iface_tmp.netmask6.a1 = (1 << iaddr->ifa_prefixlen)-1;
|
||||
}
|
||||
else {
|
||||
if (iaddr->ifa_prefixlen == 32)
|
||||
iface_tmp.netmask = 0xffffffff;
|
||||
else
|
||||
iface_tmp.netmask = ((1 << iaddr->ifa_prefixlen) - 1);
|
||||
|
||||
}
|
||||
dprintf("Exited loop");
|
||||
|
||||
/*
|
||||
* try to find the iface by index and name
|
||||
* an IP alias (eth0:0 for instance) will have the same index but not the same name/label
|
||||
* no alias when getting IPv6 address, so just search using the index
|
||||
* An IP alias (eth0:0 for instance) will have the same index but not the
|
||||
* same name/label. There are no aliases when getting IPv6 address, so
|
||||
* just search using the index.
|
||||
*/
|
||||
if (is_ipv6) {
|
||||
iff = find_iface_by_index(*iface_list, iaddr->ifa_index);
|
||||
iff = find_iface_by_index(*iface_list, iface_tmp.index);
|
||||
if (iff == NULL) {
|
||||
dprintf("Cannot find iface with index %d", iaddr->ifa_index);
|
||||
dprintf("Cannot find iface with index %d", iface_tmp.index);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
iff = find_iface_by_index_and_name(*iface_list, iaddr->ifa_index, iface_tmp.name);
|
||||
iff = find_iface_by_index_and_name(*iface_list, iface_tmp.index, iface_tmp.name);
|
||||
|
||||
if (iff == NULL) {
|
||||
dprintf("[%s] %s an alias?", __FUNCTION__, iface_tmp.name);
|
||||
// didn't find this name, probably an alias such as eth0:0
|
||||
iff = find_iface_by_index(*iface_list, iaddr->ifa_index);
|
||||
/* Now we're dealing with an IPv4 alias such as eth0:0. With a regular
|
||||
* interface, the mac address, mtu, flags, etc. would already have been
|
||||
* initialized when we did the RTM_GETLINK request. Since an alias
|
||||
* doesn't count as a physical interface, that didn't happen, so copy
|
||||
* all of the parent interface's info to this one.
|
||||
*/
|
||||
dprintf("%s an alias?", iface_tmp.name);
|
||||
iff = find_iface_by_index(*iface_list, iface_tmp.index);
|
||||
if (iff == NULL) {
|
||||
dprintf("Cannot find iface with index %d", iaddr->ifa_index);
|
||||
dprintf("Cannot find iface with index %d", iface_tmp.index);
|
||||
return 0;
|
||||
}
|
||||
// found it, copy the data to save it
|
||||
// old MAC addr and MTU
|
||||
memcpy(iface_tmp.hwaddr, iff->hwaddr, 6);
|
||||
iface_tmp.mtu = iff->mtu;
|
||||
iface_tmp.index = iff->index;
|
||||
memcpy(&iface_tmp.addr6, &iff->addr6, sizeof(__u128));
|
||||
memcpy(&iface_tmp.netmask6, &iff->netmask6, sizeof(__u128));
|
||||
strncpy(iface_tmp.flags, iff->flags, FLAGS_LEN);
|
||||
// allocate new one
|
||||
|
||||
// expand the list to accomodate the new one
|
||||
newsize = sizeof(struct ifaces_list);
|
||||
newsize += ((*iface_list)->entries + 1) * sizeof(struct iface_entry);
|
||||
iface_list_tmp = realloc(*iface_list, newsize);
|
||||
|
||||
tmp = realloc(*iface_list, newsize);
|
||||
|
||||
if(tmp == NULL) {
|
||||
if(iface_list_tmp == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
iff = &(tmp->ifaces[tmp->entries]);
|
||||
iff = &(iface_list_tmp->ifaces[iface_list_tmp->entries]);
|
||||
memset(iff, 0, sizeof(struct iface_entry));
|
||||
// copy back saved data in new iface_entry
|
||||
memcpy(iff->hwaddr, iface_tmp.hwaddr, 6);
|
||||
iff->mtu = iface_tmp.mtu;
|
||||
iff->index = iface_tmp.index;
|
||||
memcpy(&iff->addr6, &iface_tmp.addr6, sizeof(__u128));
|
||||
memcpy(&iff->netmask6, &iface_tmp.netmask6, sizeof(__u128));
|
||||
|
||||
strncpy(iff->flags, iface_tmp.flags, FLAGS_LEN);
|
||||
// copy new name
|
||||
strncpy(iff->name, iface_tmp.name, IFNAMSIZ);
|
||||
|
||||
tmp->entries++;
|
||||
*iface_list = tmp;
|
||||
}
|
||||
//now, iff points to a iface_entry, just copy add/addr6 and netmask/netmask6
|
||||
if (is_ipv6) {
|
||||
memcpy(&iff->addr6, &iface_tmp.addr6, sizeof(__u128));
|
||||
memcpy(&iff->netmask6, &iface_tmp.netmask6, sizeof(__u128));
|
||||
}
|
||||
else {
|
||||
iff->addr = iface_tmp.addr;
|
||||
iff->netmask = iface_tmp.netmask;
|
||||
iface_list_tmp->entries++;
|
||||
*iface_list = iface_list_tmp;
|
||||
}
|
||||
|
||||
dprintf("iff->index = %d, iff->name = %s, iff->addr = %08x, iff->netmask = %08x, iff->addr6 = %08x %08x %08x %08x, iff->netmask6 = %08x %08x %08x %08x",
|
||||
iff->index, iff->name, iff->addr, iff->netmask,
|
||||
iff->addr6.a1,iff->addr6.a2,iff->addr6.a3,iff->addr6.a4, iff->netmask6.a1,iff->netmask6.a2,iff->netmask6.a3,iff->netmask6.a4);
|
||||
inet_ntop(addr_tmp->family, &addr_tmp->ip, addr_str, sizeof(addr_str));
|
||||
dprintf("Appending: %s", addr_str);
|
||||
iface_entry_append_address(iff, &iface_tmp.addr_list[0]);
|
||||
dprintf("iff->addr_count = %d; iface_tmp.addr_count = %d", iff->addr_count, iface_tmp.addr_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -836,7 +823,7 @@ int netlink_get_interfaces(struct ifaces_list **iface_list)
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
// for each interface created before, will get the IPv4 / IPv6 addr
|
||||
status = netlink_parse(fd, seq, netlink_parse_interface_address, iface_list);
|
||||
status = netlink_parse(fd, seq, netlink_parse_interface_address, iface_list);
|
||||
close(fd);
|
||||
if(status != 0) {
|
||||
if (*iface_list)
|
||||
@ -848,3 +835,42 @@ int netlink_get_interfaces(struct ifaces_list **iface_list)
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
void address_calculate_netmask(struct iface_address *address, int ifa_prefixlen) {
|
||||
|
||||
if (address->family == AF_INET6) {
|
||||
// if netmask is FFFFFFFF FFFFFFFF 00000000 00000000 (/64), netmask6.a1 and netmask6.a2 == 0xffffffff, and nestmask6.a3 and .a4 == 0
|
||||
// netmask6 is set to 0 at the beginning of the function, no need to reset the values to 0 if it is needed
|
||||
// XXX really ugly, but works
|
||||
if (ifa_prefixlen >= 96) {
|
||||
address->nm.netmask6.a4 = (1 << (ifa_prefixlen-96))-1;
|
||||
address->nm.netmask6.a1 = address->nm.netmask6.a2 = address->nm.netmask6.a3 = 0xffffffff;
|
||||
}
|
||||
else if (ifa_prefixlen >= 64) {
|
||||
address->nm.netmask6.a3 = (1 << (ifa_prefixlen-64))-1;
|
||||
address->nm.netmask6.a1 = address->nm.netmask6.a2 = 0xffffffff;
|
||||
}
|
||||
else if (ifa_prefixlen >= 32) {
|
||||
address->nm.netmask6.a2 = (1 << (ifa_prefixlen-32))-1;
|
||||
address->nm.netmask6.a1 = 0xffffffff;
|
||||
}
|
||||
else
|
||||
address->nm.netmask6.a1 = (1 << ifa_prefixlen)-1;
|
||||
}
|
||||
else {
|
||||
if (ifa_prefixlen == 32)
|
||||
address->nm.netmask = 0xffffffff;
|
||||
else
|
||||
address->nm.netmask = ((1 << ifa_prefixlen) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void iface_entry_append_address(struct iface_entry *iface, struct iface_address *address) {
|
||||
iface->addr_count++;
|
||||
iface->addr_list = realloc(iface->addr_list, sizeof(struct iface_address) * iface->addr_count);
|
||||
dprintf("Realloc'd %p", iface->addr_list);
|
||||
|
||||
memcpy(&iface->addr_list[iface->addr_count-1], address, sizeof(struct iface_address));
|
||||
}
|
||||
|
||||
|
@ -312,18 +312,18 @@ class Meterpreter < Rex::Post::Meterpreter::Client
|
||||
|
||||
# Try to match our visible IP to a real interface
|
||||
# TODO: Deal with IPv6 addresses
|
||||
found = ifaces.find {|i| i.ip == shost }
|
||||
found = !!(ifaces.find {|i| i.addrs.find {|a| p a; a == shost } })
|
||||
nhost = nil
|
||||
hobj = nil
|
||||
|
||||
if Rex::Socket.is_ipv4?(shost) and not found
|
||||
|
||||
# Try to find an interface with a default route
|
||||
default_routes = routes.select{ |r| r.subnet == "0.0.0.0" }
|
||||
default_routes = routes.select{ |r| r.subnet == "0.0.0.0" || r.subnet == "::" }
|
||||
default_routes.each do |r|
|
||||
ifaces.each do |i|
|
||||
cidr = Rex::Socket.net2bitmask( i.netmask ) rescue "/32"
|
||||
rang = Rex::Socket::RangeWalker.new( "#{i.ip}/#{cidr}" ) rescue nil
|
||||
bits = Rex::Socket.net2bitmask( i.netmask ) rescue 32
|
||||
rang = Rex::Socket::RangeWalker.new( "#{i.ip}/#{bits}" ) rescue nil
|
||||
if rang and rang.include?( r.gateway )
|
||||
nhost = i.ip
|
||||
break
|
||||
|
@ -58,16 +58,27 @@ class Config
|
||||
response = client.send_request(request)
|
||||
|
||||
response.each(TLV_TYPE_NETWORK_INTERFACE) { |iface|
|
||||
addrs = []
|
||||
netmasks = []
|
||||
while (a = iface.get_tlv_value(TLV_TYPE_IP, addrs.length))
|
||||
# Netmasks aren't tightly associated with addresses, they're
|
||||
# just thrown all together in the interface TLV ordered to
|
||||
# match up. This could be done better by creating another
|
||||
# GroupTlv type for addresses containing an address, a netmask,
|
||||
# and possibly a scope.
|
||||
n = iface.get_tlv_value(TLV_TYPE_NETMASK, addrs.length)
|
||||
addrs << Rex::Socket.addr_ntoa(a)
|
||||
netmasks << Rex::Socket.addr_ntoa(n) if n
|
||||
end
|
||||
ifaces << Interface.new(
|
||||
iface.get_tlv_value(TLV_TYPE_INTERFACE_INDEX),
|
||||
iface.get_tlv_value(TLV_TYPE_IP),
|
||||
iface.get_tlv_value(TLV_TYPE_NETMASK),
|
||||
iface.get_tlv_value(TLV_TYPE_MAC_ADDRESS),
|
||||
iface.get_tlv_value(TLV_TYPE_MAC_NAME),
|
||||
iface.get_tlv_value(TLV_TYPE_IP6),
|
||||
iface.get_tlv_value(TLV_TYPE_NETMASK6),
|
||||
iface.get_tlv_value(TLV_TYPE_INTERFACE_MTU),
|
||||
iface.get_tlv_value(TLV_TYPE_INTERFACE_FLAGS))
|
||||
:index => iface.get_tlv_value(TLV_TYPE_INTERFACE_INDEX),
|
||||
:mac_addr => iface.get_tlv_value(TLV_TYPE_MAC_ADDRESS),
|
||||
:mac_name => iface.get_tlv_value(TLV_TYPE_MAC_NAME),
|
||||
:mtu => iface.get_tlv_value(TLV_TYPE_INTERFACE_MTU),
|
||||
:flags => iface.get_tlv_value(TLV_TYPE_INTERFACE_FLAGS),
|
||||
:addrs => addrs,
|
||||
:netmasks => netmasks
|
||||
)
|
||||
}
|
||||
|
||||
return ifaces
|
||||
|
@ -27,16 +27,14 @@ class Interface
|
||||
# Returns a logical interface and initializes it to the supplied
|
||||
# parameters.
|
||||
#
|
||||
def initialize(index, ip, netmask, mac_addr, mac_name, ip6=nil, netmask6=nil, mtu=nil, flags=nil)
|
||||
self.index = index || -1
|
||||
self.ip = (ip ? IPAddr.ntop(ip) : nil)
|
||||
self.netmask = (netmask ? IPAddr.ntop(netmask) : nil)
|
||||
self.mac_addr = mac_addr
|
||||
self.mac_name = mac_name
|
||||
self.ip6 = (ip6 ? IPAddr.new_ntoh(ip6).to_s : nil)
|
||||
self.netmask6 = (netmask6 ? IPAddr.new_ntoh(netmask6).to_s : nil)
|
||||
self.mtu = mtu
|
||||
self.flags = flags
|
||||
def initialize(opts={})
|
||||
self.index = opts[:index] || -1
|
||||
self.mac_addr = opts[:mac_addr]
|
||||
self.mac_name = opts[:mac_name]
|
||||
self.mtu = opts[:mtu]
|
||||
self.flags = opts[:flags]
|
||||
self.addrs = opts[:addrs]
|
||||
self.netmasks = opts[:netmasks]
|
||||
end
|
||||
|
||||
#
|
||||
@ -54,11 +52,22 @@ class Interface
|
||||
macocts[3], macocts[4], macocts[5])],
|
||||
["MTU" , mtu ],
|
||||
["Flags" , flags ],
|
||||
["IPv4 Address" , ((ip and ip != "0.0.0.0") ? ip : nil) ],
|
||||
["IPv4 Netmask" , netmask ],
|
||||
["IPv6 Address" , ((ip6 and ip6 != "::") ? ip6 : nil) ],
|
||||
["IPv6 Netmask" , ((netmask6 and netmask6 != "::") ? netmask6 : nil) ],
|
||||
]
|
||||
|
||||
# If all went as planned, addrs and netmasks will have the same number
|
||||
# of elements and be properly ordered such that they match up
|
||||
# correctly.
|
||||
addr_masks = addrs.zip(netmasks)
|
||||
|
||||
addr_masks.select { |a| Rex::Socket.is_ipv4?(a[0]) }.each { |a|
|
||||
info << [ "IPv4 Address", a[0] ]
|
||||
info << [ "IPv4 Netmask", a[1] ]
|
||||
}
|
||||
addr_masks.select { |a| Rex::Socket.is_ipv6?(a[0]) }.each { |a|
|
||||
info << [ "IPv6 Address", a[0] ]
|
||||
info << [ "IPv6 Netmask", a[1] ]
|
||||
}
|
||||
|
||||
pad = info.map{|i| i[0] }.max_by{|k|k.length}.length
|
||||
|
||||
ret = sprintf(
|
||||
@ -76,17 +85,20 @@ class Interface
|
||||
end
|
||||
|
||||
#
|
||||
# The indedx of the interface.
|
||||
# The first address associated with this Interface
|
||||
#
|
||||
def ip
|
||||
addrs.first
|
||||
end
|
||||
|
||||
#
|
||||
# The index of the interface.
|
||||
#
|
||||
attr_accessor :index
|
||||
#
|
||||
# The IP address bound to the interface.
|
||||
# An Array of IP addresses bound to the Interface.
|
||||
#
|
||||
attr_accessor :ip
|
||||
#
|
||||
# The subnet mask associated with the interface.
|
||||
#
|
||||
attr_accessor :netmask
|
||||
attr_accessor :addrs
|
||||
#
|
||||
# The physical (MAC) address of the NIC.
|
||||
#
|
||||
@ -96,10 +108,6 @@ class Interface
|
||||
#
|
||||
attr_accessor :mac_name
|
||||
#
|
||||
# The IPv6 address bound to the interface.
|
||||
#
|
||||
attr_accessor :ip6
|
||||
#
|
||||
# The subnet mask associated with the IPv6 interface.
|
||||
#
|
||||
attr_accessor :netmask6
|
||||
@ -111,6 +119,7 @@ class Interface
|
||||
# The flags associated with the interface.
|
||||
#
|
||||
attr_accessor :flags
|
||||
attr_accessor :netmasks
|
||||
end
|
||||
|
||||
end; end; end; end; end; end
|
||||
|
@ -51,17 +51,12 @@ TLV_TYPE_SUBNET = TLV_META_TYPE_RAW | 1420
|
||||
TLV_TYPE_NETMASK = TLV_META_TYPE_RAW | 1421
|
||||
TLV_TYPE_GATEWAY = TLV_META_TYPE_RAW | 1422
|
||||
TLV_TYPE_NETWORK_ROUTE = TLV_META_TYPE_GROUP | 1423
|
||||
TLV_TYPE_SUBNET6 = TLV_META_TYPE_RAW | 1424
|
||||
TLV_TYPE_NETMASK6 = TLV_META_TYPE_RAW | 1425
|
||||
TLV_TYPE_GATEWAY6 = TLV_META_TYPE_RAW | 1426
|
||||
TLV_TYPE_NETWORK_ROUTE6 = TLV_META_TYPE_GROUP | 1427
|
||||
|
||||
|
||||
TLV_TYPE_IP = TLV_META_TYPE_RAW | 1430
|
||||
TLV_TYPE_MAC_ADDRESS = TLV_META_TYPE_RAW | 1431
|
||||
TLV_TYPE_MAC_NAME = TLV_META_TYPE_STRING | 1432
|
||||
TLV_TYPE_NETWORK_INTERFACE = TLV_META_TYPE_GROUP | 1433
|
||||
TLV_TYPE_IP6 = TLV_META_TYPE_RAW | 1434
|
||||
TLV_TYPE_IP6_SCOPE = TLV_META_TYPE_RAW | 1434
|
||||
|
||||
TLV_TYPE_SUBNET_STRING = TLV_META_TYPE_STRING | 1440
|
||||
TLV_TYPE_NETMASK_STRING = TLV_META_TYPE_STRING | 1441
|
||||
|
@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'rex/post/meterpreter/extensions/stdapi/tlv'
|
||||
|
||||
module Rex
|
||||
module Post
|
||||
module Meterpreter
|
||||
@ -129,13 +131,14 @@ class Tlv
|
||||
|
||||
def inspect
|
||||
utype = type ^ TLV_META_TYPE_COMPRESSED
|
||||
group = false
|
||||
meta = case (utype & TLV_META_MASK)
|
||||
when TLV_META_TYPE_STRING; "STRING"
|
||||
when TLV_META_TYPE_UINT; "INT"
|
||||
when TLV_META_TYPE_RAW; "RAW"
|
||||
when TLV_META_TYPE_BOOL; "BOOL"
|
||||
when TLV_META_TYPE_QWORD; "QWORD"
|
||||
when TLV_META_TYPE_GROUP; "GROUP"
|
||||
when TLV_META_TYPE_GROUP; group=true; "GROUP"
|
||||
when TLV_META_TYPE_COMPLEX; "COMPLEX"
|
||||
else; 'unknown-meta-type'
|
||||
end
|
||||
@ -175,16 +178,33 @@ class Tlv
|
||||
when TLV_TYPE_MIGRATE_PAYLOAD; "MIGRATE-PAYLOAD"
|
||||
when TLV_TYPE_MIGRATE_ARCH; "MIGRATE-ARCH"
|
||||
|
||||
# Extension classes don't exist yet, so can't use their constants
|
||||
# here.
|
||||
#when Extensions::Stdapi::TLV_TYPE_IP; 'ip-address'
|
||||
when Extensions::Stdapi::TLV_TYPE_NETWORK_INTERFACE; 'network-interface'
|
||||
when Extensions::Stdapi::TLV_TYPE_IP; 'ip-address'
|
||||
when Extensions::Stdapi::TLV_TYPE_NETMASK; 'netmask'
|
||||
when Extensions::Stdapi::TLV_TYPE_MAC_ADDRESS; 'mac-address'
|
||||
when Extensions::Stdapi::TLV_TYPE_MAC_NAME; 'interface-name'
|
||||
when Extensions::Stdapi::TLV_TYPE_IP6_SCOPE; 'address-scope'
|
||||
when Extensions::Stdapi::TLV_TYPE_INTERFACE_MTU; 'interface-mtu'
|
||||
when Extensions::Stdapi::TLV_TYPE_INTERFACE_FLAGS; 'interface-flags'
|
||||
when Extensions::Stdapi::TLV_TYPE_INTERFACE_INDEX; 'interface-index'
|
||||
|
||||
else; "unknown-#{type}"
|
||||
end
|
||||
val = value.inspect
|
||||
if val.length > 50
|
||||
val = val[0,50] + ' ..."'
|
||||
end
|
||||
"#<#{self.class} type=#{stype} #{self.class.to_s =~ /Packet/ ? "tlvs=#{@tlvs.inspect}" : "meta=#{meta} value=#{val}"} >"
|
||||
group ||= (self.class.to_s =~ /Packet/)
|
||||
if group
|
||||
tlvs_inspect = "tlvs=[\n"
|
||||
@tlvs.each { |t|
|
||||
tlvs_inspect << " #{t.inspect}\n"
|
||||
}
|
||||
tlvs_inspect << "]"
|
||||
else
|
||||
tlvs_inspect = "meta=#{meta} value=#{val}"
|
||||
end
|
||||
"#<#{self.class} type=#{stype} #{tlvs_inspect}>"
|
||||
end
|
||||
|
||||
##
|
||||
|
Loading…
Reference in New Issue
Block a user