pcaprub : -add several native function to get all the informations about the network intefaces, original code is a python c extension called netifaces

-add also some initial wrappers into capture mixin
-Fixes #4376


git-svn-id: file:///home/svn/framework3/trunk@12799 4d416f70-5f16-0410-b530-b9f4589650da
unstable
amaloteaux 2011-06-01 17:22:48 +00:00
parent 8600bc5bef
commit 40f06cd3e1
7 changed files with 1334 additions and 49 deletions

View File

@ -16,3 +16,28 @@ The latest version can be obtained from Subversion:
The Metasploit Project also provides a Subversion repository:
svn checkout http://metasploit.com/svn/framework3/trunk/external/pcaprub/
The Metasploit Project also added some code from the python netifaces c extension
Original c/python netifaces code is under MIT-style license.
Here goes:
Copyright (c) 2007, 2008 Alastair Houghton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,4 +1,104 @@
require 'mkmf'
puts("platform is #{RUBY_PLATFORM}")
########################
# Netifaces
########################
puts "\n[*] Running checks for netifaces code added by metasploit project"
puts "-----------------------------------------------------------------"
#uncoment to force ioctl on non windows systems
#@force_ioctl = true
@supported_archs = ["i386-mingw32", "i486-linux", "universal-darwin10.0", "i386-openbsd4.8","i386-freebsd8","arm-linux-eabi"]
#arm-linux-eabi tested on maemo5 / N900
puts "[*] Warning : this platform as not been tested" unless @supported_archs.include? RUBY_PLATFORM
if RUBY_PLATFORM =~ /i386-mingw32/
unless have_library("ws2_32" ) and
have_library("iphlpapi") and
have_header("windows.h") and
have_header("winsock2.h") and
have_header("iphlpapi.h")
puts "\nNot all dependencies are satisfied, please check logs"
exit
end
else
headers = ['net/if_dl.h', 'netash/ash.h','netatalk/at.h', 'netax25/ax25.h',
'neteconet/ec.h', 'netipx/ipx.h','netpacket/packet.h', 'netrose/rose.h']
if RUBY_PLATFORM =~ /linux/
headers += [ 'linux/irda.h', 'linux/atm.h',
'linux/llc.h', 'linux/tipc.h',
'linux/dn.h']
end
additionnal_headers = ["sys/types.h","sys/socket.h","sys/un.h","net/if.h","netinet/in.h"]
optional_headers = []
sockaddrs = [ 'at', 'ax25', 'dl', 'eon', 'in', 'in6',
'inarp', 'ipx', 'iso', 'ns', 'un', 'x25',
'rose', 'ash', 'ec', 'll', 'atmpvc', 'atmsvc',
'dn', 'irda', 'llc']
# 1) Check for getifaddrs
unless @force_ioctl
need_ioctl = !(have_func("getifaddrs"))
end
# 2) Check for getnameinfo or redefine it in netifaces.c
have_func("getnameinfo")
# 3) Whitout getifaddrs we'll have to deal with ioctls
if need_ioctl or @force_ioctl
ioctls = [
'SIOCGIFCONF','SIOCGSIZIFCONF','SIOCGIFHWADDR','SIOCGIFADDR','SIOCGIFFLAGS','SIOCGIFDSTADDR',
'SIOCGIFBRDADDR','SIOCGIFNETMASK','SIOCGLIFNUM','SIOCGLIFCONF','SIOCGLIFFLAGS']
ioctls_headers = ['sys/types.h','sys/socket.h','sys/ioctl.h','net/if.h','netinet/in.h','arpa/inet.h']
#TODO Test this on sunos
#if RUBY_PLATFORM =~ /sunos/
# ioctls_headers += ['unistd.h','stropts.h','sys/sockio.h']
#end
$defs.push '-DHAVE_SOCKET_IOCTLS'
ioctls.each do |ioctl|
if have_macro(ioctl, ioctls_headers)
$defs.push "-DHAVE_#{ioctl}"
end
end
end
# 4) Check for optionnal headers
headers.each do |header|
if have_header(header)
optional_headers.push(header)
end
end
# 5) On certain platforms (Linux), there's no sa_len.
# Unfortunately, getifaddrs() doesn't return the
# lengths, because they're in the sa_len field on just about
# everything but Linux.
# In this case we will define a macro that will return the sa_len from
# the sockaddr_xx structure if they are available
if (!have_struct_member("struct sockaddr", "sa_len", ["sys/types.h","sys/socket.h","net/if.h"]))
sockaddrs.each do |sockaddr|
have_type("struct sockaddr_" + sockaddr, additionnal_headers + optional_headers)
end
end
end
#rework the defs to make them compatible with the original netifaces.c code
$defs = $defs.map do |a|
if a =~ /^-DHAVE_TYPE_STRUCT_SOCKADDR_.*$/ then a.gsub("TYPE_STRUCT_","")
elsif a == "-DHAVE_ST_SA_LEN" then a.gsub("HAVE_ST_","HAVE_SOCKADDR_")
else a
end
end
########################
# Pcap
########################
puts "\n[*] Running checks for pcap code..."
puts "-----------------------------------"
if /i386-mingw32/ =~ RUBY_PLATFORM
dir_config("pcap","C:/WpdPack/include","C:/WpdPack/lib")
have_library("wpcap", "pcap_open_live")

688
external/pcaprub/netifaces.c vendored Normal file
View File

@ -0,0 +1,688 @@
#include "ruby.h"
#ifndef RUBY_19
#include "rubysig.h"
#endif
#include "netifaces.h"
#if !defined(WIN32)
#if !HAVE_GETNAMEINFO
#undef getnameinfo
#undef NI_NUMERICHOST
#define getnameinfo our_getnameinfo
#define NI_NUMERICHOST 1
/* A very simple getnameinfo() for platforms without */
static int
getnameinfo (const struct sockaddr *addr, int addr_len,
char *buffer, int buflen,
char *buf2, int buf2len,
int flags)
{
switch (addr->sa_family)
{
case AF_INET:
{
const struct sockaddr_in *sin = (struct sockaddr_in *)addr;
const unsigned char *bytes = (unsigned char *)&sin->sin_addr.s_addr;
char tmpbuf[20];
sprintf (tmpbuf, "%d.%d.%d.%d",
bytes[0], bytes[1], bytes[2], bytes[3]);
strncpy (buffer, tmpbuf, buflen);
}
break;
#ifdef AF_INET6
case AF_INET6:
{
const struct sockaddr_in6 *sin = (const struct sockaddr_in6 *)addr;
const unsigned char *bytes = sin->sin6_addr.s6_addr;
int n;
char tmpbuf[80], *ptr = tmpbuf;
int done_double_colon = FALSE;
int colon_mode = FALSE;
for (n = 0; n < 8; ++n)
{
unsigned char b1 = bytes[2 * n];
unsigned char b2 = bytes[2 * n + 1];
if (b1)
{
if (colon_mode)
{
colon_mode = FALSE;
*ptr++ = ':';
}
sprintf (ptr, "%x%02x", b1, b2);
ptr += strlen (ptr);
*ptr++ = ':';
}
else if (b2)
{
if (colon_mode)
{
colon_mode = FALSE;
*ptr++ = ':';
}
sprintf (ptr, "%x", b2);
ptr += strlen (ptr);
*ptr++ = ':';
}
else {
if (!colon_mode)
{
if (done_double_colon)
{
*ptr++ = '0';
*ptr++ = ':';
}
else
{
if (n == 0)
*ptr++ = ':';
colon_mode = TRUE;
done_double_colon = TRUE;
}
}
}
}
if (colon_mode)
{
colon_mode = FALSE;
*ptr++ = ':';
*ptr++ = '\0';
}
else
{
*--ptr = '\0';
}
strncpy (buffer, tmpbuf, buflen);
}
break;
#endif /* AF_INET6 */
default:
return -1;
}
return 0;
}
#endif
static int
string_from_sockaddr (struct sockaddr *addr,
char *buffer,
int buflen)
{
if (!addr || addr->sa_family == AF_UNSPEC)
return -1;
if (getnameinfo (addr, SA_LEN(addr),
buffer, buflen,
NULL, 0,
NI_NUMERICHOST) != 0)
{
int n, len;
char *ptr;
const char *data;
len = SA_LEN(addr);
#if HAVE_AF_LINK
/* BSD-like systems have AF_LINK */
if (addr->sa_family == AF_LINK)
{
struct sockaddr_dl *dladdr = (struct sockaddr_dl *)addr;
len = dladdr->sdl_alen;
if(len >=0)
data = LLADDR(dladdr);
}
else
{
#endif
#if defined(AF_PACKET)
/* Linux has AF_PACKET instead */
if (addr->sa_family == AF_PACKET)
{
struct sockaddr_ll *lladdr = (struct sockaddr_ll *)addr;
len = lladdr->sll_halen;
//amaloteaux: openbsd and maybe other systems have a len of 0 for enc0,pflog0 .. interfaces
if(len >=0)
data = (const char *)lladdr->sll_addr;
}
else
{
#endif
/* We don't know anything about this sockaddr, so just display
the entire data area in binary. */
len -= (sizeof (struct sockaddr) - sizeof (addr->sa_data));
data = addr->sa_data;
#if defined(AF_PACKET)
}
#endif
#if HAVE_AF_LINK
}
#endif
if ((buflen < 3 * len) || len <= 0)
return -1;
ptr = buffer;
buffer[0] = '\0';
for (n = 0; n < len; ++n)
{
sprintf (ptr, "%02x:", data[n] & 0xff);
ptr += 3;
}
*--ptr = '\0';
}
return 0;
}
#endif /* !defined(WIN32) */
static VALUE add_to_family(VALUE result, VALUE family, VALUE value)
{
Check_Type(result, T_HASH);
Check_Type(family, T_FIXNUM);
Check_Type(value, T_HASH);
VALUE list;
list = rb_hash_aref(result, family);
if (list == Qnil)
list = rb_ary_new();
else
Check_Type(list, T_ARRAY);
rb_ary_push(list, value);
rb_hash_aset(result, family, list);
return result;
}
VALUE
rbnetifaces_s_addresses (VALUE class, VALUE dev)
{
Check_Type(dev, T_STRING);
VALUE result;
int found = FALSE;
result = rb_hash_new();
#if defined(WIN32)
PIP_ADAPTER_INFO pAdapterInfo = NULL;
PIP_ADAPTER_INFO pInfo = NULL;
ULONG ulBufferLength = 0;
DWORD dwRet;
PIP_ADDR_STRING str;
//First, retrieve the adapter information. We do this in a loop, in
//case someone adds or removes adapters in the meantime.
do
{
dwRet = GetAdaptersInfo(pAdapterInfo, &ulBufferLength);
if (dwRet == ERROR_BUFFER_OVERFLOW)
{
if (pAdapterInfo)
free (pAdapterInfo);
pAdapterInfo = (PIP_ADAPTER_INFO)malloc (ulBufferLength);
if (!pAdapterInfo)
{
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
return Qnil;
}
}
} while (dwRet == ERROR_BUFFER_OVERFLOW);
// If we failed, then fail in Ruby too
if (dwRet != ERROR_SUCCESS && dwRet != ERROR_NO_DATA)
{
if (pAdapterInfo)
free (pAdapterInfo);
rb_raise(rb_eRuntimeError, "Unable to obtain adapter information.");
return Qnil;
}
for (pInfo = pAdapterInfo; pInfo; pInfo = pInfo->Next)
{
char buffer[256];
if (strcmp (pInfo->AdapterName, StringValuePtr(dev)) != 0)
continue;
VALUE rbhardw = Qnil;
VALUE rbaddr = Qnil;
VALUE rbnetmask = Qnil;
VALUE rbbraddr = Qnil;
found = TRUE;
// Do the physical address
if (256 >= 3 * pInfo->AddressLength)
{
VALUE hash_hardw;
hash_hardw = rb_hash_new();
char *ptr = buffer;
unsigned n;
*ptr = '\0';
for (n = 0; n < pInfo->AddressLength; ++n)
{
sprintf (ptr, "%02x:", pInfo->Address[n] & 0xff);
ptr += 3;
}
*--ptr = '\0';
rbhardw = rb_str_new2(buffer);
rb_hash_aset(hash_hardw, rb_str_new2("addr"), rbhardw);
result = add_to_family(result, INT2FIX(AF_LINK), hash_hardw);
}
for (str = &pInfo->IpAddressList; str; str = str->Next)
{
VALUE result2;
result2 = rb_hash_new();
if(str->IpAddress.String)
rbaddr = rb_str_new2(str->IpAddress.String);
if(str->IpMask.String)
rbnetmask = rb_str_new2(str->IpMask.String);
//If this isn't the loopback interface, work out the broadcast
//address, for better compatibility with other platforms.
if (pInfo->Type != MIB_IF_TYPE_LOOPBACK)
{
unsigned long inaddr = inet_addr (str->IpAddress.String);
unsigned long inmask = inet_addr (str->IpMask.String);
struct in_addr in;
char *brstr;
in.S_un.S_addr = (inaddr | ~inmask) & 0xfffffffful;
brstr = inet_ntoa (in);
if (brstr)
rbbraddr = rb_str_new2(brstr);
}
if (rbaddr)
rb_hash_aset(result2, rb_str_new2("addr"), rbaddr);
if (rbnetmask)
rb_hash_aset(result2, rb_str_new2("netmask"), rbnetmask);
if (rbbraddr)
rb_hash_aset(result2, rb_str_new2("broadcast"), rbbraddr);
result = add_to_family(result, INT2FIX(AF_INET), result2);
}
} // for
free (pAdapterInfo);
#elif HAVE_GETIFADDRS
struct ifaddrs *addrs = NULL;
struct ifaddrs *addr = NULL;
if (getifaddrs (&addrs) < 0)
{
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
}
for (addr = addrs; addr; addr = addr->ifa_next)
{
char buffer[256];
VALUE rbaddr = Qnil;
VALUE rbnetmask = Qnil;
VALUE rbbraddr = Qnil;
if (strcmp (addr->ifa_name, StringValuePtr(dev)) != 0)
continue;
/* Sometimes there are records without addresses (e.g. in the case of a
dial-up connection via ppp, which on Linux can have a link address
record with no actual address). We skip these as they aren't useful.
Thanks to Christian Kauhaus for reporting this issue. */
if (!addr->ifa_addr)
continue;
found = TRUE;
if (string_from_sockaddr (addr->ifa_addr, buffer, sizeof (buffer)) == 0)
rbaddr = rb_str_new2(buffer);
if (string_from_sockaddr (addr->ifa_netmask, buffer, sizeof (buffer)) == 0)
rbnetmask = rb_str_new2(buffer);
if (string_from_sockaddr (addr->ifa_broadaddr, buffer, sizeof (buffer)) == 0)
rbbraddr = rb_str_new2(buffer);
VALUE result2;
result2 = rb_hash_new();
if (rbaddr)
rb_hash_aset(result2, rb_str_new2("addr"), rbaddr);
if (rbnetmask)
rb_hash_aset(result2, rb_str_new2("netmask"), rbnetmask);
if (rbbraddr)
{
if (addr->ifa_flags & (IFF_POINTOPOINT | IFF_LOOPBACK))
rb_hash_aset(result2, rb_str_new2("peer"), rbbraddr);
else
rb_hash_aset(result2, rb_str_new2("broadcast"), rbbraddr);
}
if (rbaddr || rbnetmask || rbbraddr)
result = add_to_family(result, INT2FIX(addr->ifa_addr->sa_family), result2);
}
freeifaddrs (addrs);
#elif HAVE_SOCKET_IOCTLS
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
{
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
return Qnil;
}
struct CNAME(ifreq) ifr;
char buffer[256];
int is_p2p = FALSE;
VALUE rbaddr = Qnil;
VALUE rbnetmask = Qnil;
VALUE rbbraddr = Qnil;
VALUE rbdstaddr = Qnil;
strncpy (ifr.CNAME(ifr_name), StringValuePtr(dev), IFNAMSIZ);
#if HAVE_SIOCGIFHWADDR
if (ioctl (sock, SIOCGIFHWADDR, &ifr) == 0)
{
if (string_from_sockaddr (&(ifr.CNAME(ifr_addr)), buffer, sizeof (buffer)) == 0)
{
found = TRUE;
VALUE rbhardw = Qnil;
VALUE hash_hardw;
hash_hardw = rb_hash_new();
rbhardw = rb_str_new2(buffer);
rb_hash_aset(hash_hardw, rb_str_new2("addr"), rbhardw);
result = add_to_family(result, INT2FIX(AF_LINK), hash_hardw);
}
}
#endif
#if HAVE_SIOCGIFADDR
#if HAVE_SIOCGLIFNUM
if (ioctl (sock, SIOCGLIFADDR, &ifr) == 0)
{
#else
if (ioctl (sock, SIOCGIFADDR, &ifr) == 0)
{
#endif
if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0)
{
found = TRUE;
rbaddr = rb_str_new2(buffer);
}
}
#endif
#if HAVE_SIOCGIFNETMASK
#if HAVE_SIOCGLIFNUM
if (ioctl (sock, SIOCGLIFNETMASK, &ifr) == 0)
{
#else
if (ioctl (sock, SIOCGIFNETMASK, &ifr) == 0)
{
#endif
if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0)
{
found = TRUE;
rbnetmask = rb_str_new2(buffer);
}
}
#endif
#if HAVE_SIOCGIFFLAGS
#if HAVE_SIOCGLIFNUM
if (ioctl (sock, SIOCGLIFFLAGS, &ifr) == 0)
{
#else
if (ioctl (sock, SIOCGIFFLAGS, &ifr) == 0)
{
#endif
if (ifr.CNAME(ifr_flags) & IFF_POINTOPOINT)
{
is_p2p = TRUE;
}
}
#endif
#if HAVE_SIOCGIFBRDADDR
#if HAVE_SIOCGLIFNUM
if (!is_p2p && ioctl (sock, SIOCGLIFBRDADDR, &ifr) == 0)
{
#else
if (!is_p2p && ioctl (sock, SIOCGIFBRDADDR, &ifr) == 0)
{
#endif
if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0)
{
found = TRUE;
rbbraddr = rb_str_new2(buffer);
}
}
#endif
#if HAVE_SIOCGIFDSTADDR
#if HAVE_SIOCGLIFNUM
if (is_p2p && ioctl (sock, SIOCGLIFBRDADDR, &ifr) == 0)
{
#else
if (is_p2p && ioctl (sock, SIOCGIFBRDADDR, &ifr) == 0)
{
#endif
if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0)
{
found = TRUE;
rbdstaddr = rb_str_new2(buffer);
}
}
#endif
VALUE result2;
result2 = rb_hash_new();
if (rbaddr)
rb_hash_aset(result2, rb_str_new2("addr"), rbaddr);
if (rbnetmask)
rb_hash_aset(result2, rb_str_new2("netmask"), rbnetmask);
if (rbbraddr)
rb_hash_aset(result2, rb_str_new2("broadcast"), rbbraddr);
if (rbdstaddr)
rb_hash_aset(result2, rb_str_new2("peer"), rbbraddr);
if (rbaddr || rbnetmask || rbbraddr || rbdstaddr)
result = add_to_family(result, INT2FIX(AF_INET), result2);
close (sock);
#endif /* HAVE_SOCKET_IOCTLS */
if (found)
return result;
else
return Qnil;
}
VALUE
rbnetifaces_s_interfaces (VALUE self)
{
VALUE result;
result = rb_ary_new();
#if defined(WIN32)
PIP_ADAPTER_INFO pAdapterInfo = NULL;
PIP_ADAPTER_INFO pInfo = NULL;
ULONG ulBufferLength = 0;
DWORD dwRet;
// First, retrieve the adapter information
do {
dwRet = GetAdaptersInfo(pAdapterInfo, &ulBufferLength);
if (dwRet == ERROR_BUFFER_OVERFLOW)
{
if (pAdapterInfo)
free (pAdapterInfo);
pAdapterInfo = (PIP_ADAPTER_INFO)malloc (ulBufferLength);
if (!pAdapterInfo)
{
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
}
}
} while (dwRet == ERROR_BUFFER_OVERFLOW);
// If we failed, then fail in Ruby too
if (dwRet != ERROR_SUCCESS && dwRet != ERROR_NO_DATA)
{
if (pAdapterInfo)
free (pAdapterInfo);
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
return Qnil;
}
if (dwRet == ERROR_NO_DATA)
{
free (pAdapterInfo);
return result;
}
for (pInfo = pAdapterInfo; pInfo; pInfo = pInfo->Next)
{
VALUE ifname = rb_str_new2(pInfo->AdapterName);
//VALUE ifname = rb_str_new2(pInfo->Description);
if(!rb_ary_includes(result, ifname))
rb_ary_push(result, ifname);
}
free (pAdapterInfo);
#elif HAVE_GETIFADDRS
const char *prev_name = NULL;
struct ifaddrs *addrs = NULL;
struct ifaddrs *addr = NULL;
if (getifaddrs (&addrs) < 0)
{
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
}
for (addr = addrs; addr; addr = addr->ifa_next)
{
if (!prev_name || strncmp (addr->ifa_name, prev_name, IFNAMSIZ) != 0)
{
VALUE ifname = rb_str_new2(addr->ifa_name);
if(!rb_ary_includes(result, ifname))
rb_ary_push(result, ifname);
prev_name = addr->ifa_name;
}
}
freeifaddrs (addrs);
#elif HAVE_SIOCGIFCONF
const char *prev_name = NULL;
int fd = socket (AF_INET, SOCK_DGRAM, 0);
struct CNAME(ifconf) ifc;
int len = -1, n;
if (fd < 0) {
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
return Qnil;
}
// Try to find out how much space we need
#if HAVE_SIOCGSIZIFCONF
if (ioctl (fd, SIOCGSIZIFCONF, &len) < 0)
len = -1;
#elif HAVE_SIOCGLIFNUM
#error This code need to be checked first
/*
{ struct lifnum lifn;
lifn.lifn_family = AF_UNSPEC;
lifn.lifn_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
ifc.lifc_family = AF_UNSPEC;
ifc.lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
if (ioctl (fd, SIOCGLIFNUM, (char *)&lifn) < 0)
len = -1;
else
len = lifn.lifn_count;
}
*/
#endif
// As a last resort, guess
if (len < 0)
len = 64;
ifc.CNAME(ifc_len) = len * sizeof (struct CNAME(ifreq));
ifc.CNAME(ifc_buf) = malloc (ifc.CNAME(ifc_len));
if (!ifc.CNAME(ifc_buf)) {
close (fd);
rb_raise(rb_eRuntimeError, "Not enough memory");
return Qnil;
}
#if HAVE_SIOCGLIFNUM
if (ioctl (fd, SIOCGLIFCONF, &ifc) < 0) {
#else
if (ioctl (fd, SIOCGIFCONF, &ifc) < 0) {
#endif
free (ifc.CNAME(ifc_req));
close (fd);
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
return Qnil;
}
struct CNAME(ifreq) *pfreq = ifc.CNAME(ifc_req);
for (n = 0; n < ifc.CNAME(ifc_len)/sizeof(struct CNAME(ifreq));n++,pfreq++)
{
if (!prev_name || strncmp (prev_name, pfreq->CNAME(ifr_name), IFNAMSIZ) != 0)
{
VALUE ifname = rb_str_new2(pfreq->CNAME(ifr_name));
if(!rb_ary_includes(result, ifname))
rb_ary_push(result, ifname);
prev_name = pfreq->CNAME(ifr_name);
}
}
free (ifc.CNAME(ifc_buf));
close (fd);
#endif //
return result;
}

183
external/pcaprub/netifaces.h vendored Normal file
View File

@ -0,0 +1,183 @@
#ifndef WIN32
# include <sys/types.h>
# include <sys/socket.h>
# include <net/if.h>
# include <netdb.h>
# if HAVE_SOCKET_IOCTLS
# include <sys/ioctl.h>
# include <netinet/in.h>
# include <arpa/inet.h>
#if defined(__sun)
#include <unistd.h>
#include <stropts.h>
#include <sys/sockio.h>
#endif
# endif /* HAVE_SOCKET_IOCTLS */
/* For logical interfaces support we convert all names to same name prefixed with l */
#if HAVE_SIOCGLIFNUM
#define CNAME(x) l##x
#else
#define CNAME(x) x
#endif
#if HAVE_NET_IF_DL_H
# include <net/if_dl.h>
#endif
/* For Linux, include all the sockaddr
definitions we can lay our hands on. */
#if !HAVE_SOCKADDR_SA_LEN
# if HAVE_NETASH_ASH_H
# include <netash/ash.h>
# endif
# if HAVE_NETATALK_AT_H
# include <netatalk/at.h>
# endif
# if HAVE_NETAX25_AX25_H
# include <netax25/ax25.h>
# endif
# if HAVE_NETECONET_EC_H
# include <neteconet/ec.h>
# endif
# if HAVE_NETIPX_IPX_H
# include <netipx/ipx.h>
# endif
# if HAVE_NETPACKET_PACKET_H
# include <netpacket/packet.h>
# endif
# if HAVE_NETROSE_ROSE_H
# include <netrose/rose.h>
# endif
# if HAVE_LINUX_IRDA_H
# include <linux/irda.h>
# endif
# if HAVE_LINUX_ATM_H
# include <linux/atm.h>
# endif
# if HAVE_LINUX_LLC_H
# include <linux/llc.h>
# endif
# if HAVE_LINUX_TIPC_H
# include <linux/tipc.h>
# endif
# if HAVE_LINUX_DN_H
# include <linux/dn.h>
# endif
/* Map address families to sizes of sockaddr structs */
static int af_to_len(int af)
{
switch (af)
{
case AF_INET: return sizeof (struct sockaddr_in);
#if defined(AF_INET6) && HAVE_SOCKADDR_IN6
case AF_INET6: return sizeof (struct sockaddr_in6);
#endif
#if defined(AF_AX25) && HAVE_SOCKADDR_AX25
# if defined(AF_NETROM)
case AF_NETROM: /* I'm assuming this is carried over x25 */
# endif
case AF_AX25: return sizeof (struct sockaddr_ax25);
#endif
#if defined(AF_IPX) && HAVE_SOCKADDR_IPX
case AF_IPX: return sizeof (struct sockaddr_ipx);
#endif
#if defined(AF_APPLETALK) && HAVE_SOCKADDR_AT
case AF_APPLETALK: return sizeof (struct sockaddr_at);
#endif
#if defined(AF_ATMPVC) && HAVE_SOCKADDR_ATMPVC
case AF_ATMPVC: return sizeof (struct sockaddr_atmpvc);
#endif
#if defined(AF_ATMSVC) && HAVE_SOCKADDR_ATMSVC
case AF_ATMSVC: return sizeof (struct sockaddr_atmsvc);
#endif
#if defined(AF_X25) && HAVE_SOCKADDR_X25
case AF_X25: return sizeof (struct sockaddr_x25);
#endif
#if defined(AF_ROSE) && HAVE_SOCKADDR_ROSE
case AF_ROSE: return sizeof (struct sockaddr_rose);
#endif
#if defined(AF_DECnet) && HAVE_SOCKADDR_DN
case AF_DECnet: return sizeof (struct sockaddr_dn);
#endif
#if defined(AF_PACKET) && HAVE_SOCKADDR_LL
case AF_PACKET: return sizeof (struct sockaddr_ll);
#endif
#if defined(AF_ASH) && HAVE_SOCKADDR_ASH
case AF_ASH: return sizeof (struct sockaddr_ash);
#endif
#if defined(AF_ECONET) && HAVE_SOCKADDR_EC
case AF_ECONET: return sizeof (struct sockaddr_ec);
#endif
#if defined(AF_IRDA) && HAVE_SOCKADDR_IRDA
case AF_IRDA: return sizeof (struct sockaddr_irda);
#endif
}
return sizeof (struct sockaddr);
}
#define SA_LEN(sa) af_to_len(sa->sa_family)
#if HAVE_SIOCGLIFNUM
#define SS_LEN(sa) af_to_len(sa->ss_family)
#else
#define SS_LEN(sa) SA_LEN(sa)
#endif
#else
//remove a warning on openbsd
#ifndef SA_LEN
#define SA_LEN(sa) sa->sa_len
#endif
#endif /* !HAVE_SOCKADDR_SA_LEN */
# if HAVE_GETIFADDRS
# include <ifaddrs.h>
# endif /* HAVE_GETIFADDRS */
# if !HAVE_GETIFADDRS && (!HAVE_SOCKET_IOCTLS || !HAVE_SIOCGIFCONF)
/* If the platform doesn't define, what we need, barf. If you're seeing this,
it means you need to write suitable code to retrieve interface information
on your system. */
# error You need to add code for your platform.
# endif
#else /* defined(WIN32) */
#include <windows.h>
#include <winsock2.h>
#include <iphlpapi.h>
#endif /* defined(WIN32) */
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/* On systems without AF_LINK (Windows, for instance), define it anyway, but
give it a crazy value. On Linux, which has AF_PACKET but not AF_LINK,
define AF_LINK as the latter instead. */
#ifndef AF_LINK
# ifdef AF_PACKET
# define AF_LINK AF_PACKET
# else
# define AF_LINK -1000
# endif
# define HAVE_AF_LINK 0
#else
# define HAVE_AF_LINK 1
#endif
//Prototypes
//Get a list of the adresses for a network interface
VALUE rbnetifaces_s_addresses (VALUE class, VALUE dev);
//Get a list of the network interfaces
VALUE rbnetifaces_s_interfaces (VALUE self);

View File

@ -4,6 +4,7 @@
#include "rubysig.h"
#endif
#include "netifaces.h"
#include <pcap.h>
@ -524,51 +525,236 @@ rbpcap_stats(VALUE self)
void
Init_pcaprub()
{
// Pcap
rb_cPcap = rb_define_class("Pcap", rb_cObject);
rb_define_module_function(rb_cPcap, "version", rbpcap_s_version, 0);
rb_define_module_function(rb_cPcap, "lookupdev", rbpcap_s_lookupdev, 0);
rb_define_module_function(rb_cPcap, "lookupnet", rbpcap_s_lookupnet, 1);
rb_define_module_function(rb_cPcap, "lookupaddrs", rbpcap_s_lookupaddrs, 1);
// Pcap
rb_cPcap = rb_define_class("Pcap", rb_cObject);
rb_define_module_function(rb_cPcap, "version", rbpcap_s_version, 0);
rb_define_module_function(rb_cPcap, "lookupdev", rbpcap_s_lookupdev, 0);
rb_define_module_function(rb_cPcap, "lookupnet", rbpcap_s_lookupnet, 1);
rb_define_module_function(rb_cPcap, "lookupaddrs", rbpcap_s_lookupaddrs, 1);
rb_define_const(rb_cPcap, "DLT_NULL", INT2NUM(DLT_NULL));
rb_define_const(rb_cPcap, "DLT_EN10MB", INT2NUM(DLT_EN10MB));
rb_define_const(rb_cPcap, "DLT_EN3MB", INT2NUM(DLT_EN3MB));
rb_define_const(rb_cPcap, "DLT_AX25", INT2NUM(DLT_AX25));
rb_define_const(rb_cPcap, "DLT_PRONET", INT2NUM(DLT_PRONET));
rb_define_const(rb_cPcap, "DLT_CHAOS", INT2NUM(DLT_CHAOS));
rb_define_const(rb_cPcap, "DLT_IEEE802", INT2NUM(DLT_IEEE802));
rb_define_const(rb_cPcap, "DLT_ARCNET", INT2NUM(DLT_ARCNET));
rb_define_const(rb_cPcap, "DLT_SLIP", INT2NUM(DLT_SLIP));
rb_define_const(rb_cPcap, "DLT_PPP", INT2NUM(DLT_PPP));
rb_define_const(rb_cPcap, "DLT_FDDI", INT2NUM(DLT_FDDI));
rb_define_const(rb_cPcap, "DLT_ATM_RFC1483", INT2NUM(DLT_ATM_RFC1483));
rb_define_const(rb_cPcap, "DLT_RAW", INT2NUM(DLT_RAW));
rb_define_const(rb_cPcap, "DLT_SLIP_BSDOS", INT2NUM(DLT_SLIP_BSDOS));
rb_define_const(rb_cPcap, "DLT_PPP_BSDOS", INT2NUM(DLT_PPP_BSDOS));
rb_define_const(rb_cPcap, "DLT_IEEE802_11", INT2NUM(DLT_IEEE802_11));
rb_define_const(rb_cPcap, "DLT_IEEE802_11_RADIO", INT2NUM(DLT_IEEE802_11_RADIO));
rb_define_const(rb_cPcap, "DLT_IEEE802_11_RADIO_AVS", INT2NUM(DLT_IEEE802_11_RADIO_AVS));
rb_define_const(rb_cPcap, "DLT_LINUX_SLL", INT2NUM(DLT_LINUX_SLL));
rb_define_const(rb_cPcap, "DLT_PRISM_HEADER", INT2NUM(DLT_PRISM_HEADER));
rb_define_const(rb_cPcap, "DLT_AIRONET_HEADER", INT2NUM(DLT_AIRONET_HEADER));
rb_define_const(rb_cPcap, "DLT_NULL", INT2NUM(DLT_NULL));
rb_define_const(rb_cPcap, "DLT_EN10MB", INT2NUM(DLT_EN10MB));
rb_define_const(rb_cPcap, "DLT_EN3MB", INT2NUM(DLT_EN3MB));
rb_define_const(rb_cPcap, "DLT_AX25", INT2NUM(DLT_AX25));
rb_define_const(rb_cPcap, "DLT_PRONET", INT2NUM(DLT_PRONET));
rb_define_const(rb_cPcap, "DLT_CHAOS", INT2NUM(DLT_CHAOS));
rb_define_const(rb_cPcap, "DLT_IEEE802", INT2NUM(DLT_IEEE802));
rb_define_const(rb_cPcap, "DLT_ARCNET", INT2NUM(DLT_ARCNET));
rb_define_const(rb_cPcap, "DLT_SLIP", INT2NUM(DLT_SLIP));
rb_define_const(rb_cPcap, "DLT_PPP", INT2NUM(DLT_PPP));
rb_define_const(rb_cPcap, "DLT_FDDI", INT2NUM(DLT_FDDI));
rb_define_const(rb_cPcap, "DLT_ATM_RFC1483", INT2NUM(DLT_ATM_RFC1483));
rb_define_const(rb_cPcap, "DLT_RAW", INT2NUM(DLT_RAW));
rb_define_const(rb_cPcap, "DLT_SLIP_BSDOS", INT2NUM(DLT_SLIP_BSDOS));
rb_define_const(rb_cPcap, "DLT_PPP_BSDOS", INT2NUM(DLT_PPP_BSDOS));
rb_define_const(rb_cPcap, "DLT_IEEE802_11", INT2NUM(DLT_IEEE802_11));
rb_define_const(rb_cPcap, "DLT_IEEE802_11_RADIO", INT2NUM(DLT_IEEE802_11_RADIO));
rb_define_const(rb_cPcap, "DLT_IEEE802_11_RADIO_AVS", INT2NUM(DLT_IEEE802_11_RADIO_AVS));
rb_define_const(rb_cPcap, "DLT_LINUX_SLL", INT2NUM(DLT_LINUX_SLL));
rb_define_const(rb_cPcap, "DLT_PRISM_HEADER", INT2NUM(DLT_PRISM_HEADER));
rb_define_const(rb_cPcap, "DLT_AIRONET_HEADER", INT2NUM(DLT_AIRONET_HEADER));
rb_define_singleton_method(rb_cPcap, "new", rbpcap_new_s, 0);
rb_define_singleton_method(rb_cPcap, "new", rbpcap_new_s, 0);
rb_define_singleton_method(rb_cPcap, "open_live", rbpcap_open_live_s, 4);
rb_define_singleton_method(rb_cPcap, "open_offline", rbpcap_open_offline_s, 1);
rb_define_singleton_method(rb_cPcap, "open_dead", rbpcap_open_dead_s, 2);
rb_define_singleton_method(rb_cPcap, "dump_open", rbpcap_dump_open, 1);
rb_define_singleton_method(rb_cPcap, "open_live", rbpcap_open_live_s, 4);
rb_define_singleton_method(rb_cPcap, "open_offline", rbpcap_open_offline_s, 1);
rb_define_singleton_method(rb_cPcap, "open_dead", rbpcap_open_dead_s, 2);
rb_define_singleton_method(rb_cPcap, "dump_open", rbpcap_dump_open, 1);
rb_define_method(rb_cPcap, "dump", rbpcap_dump, 3);
rb_define_method(rb_cPcap, "dump", rbpcap_dump, 3);
rb_define_method(rb_cPcap, "each", rbpcap_capture, 0);
rb_define_method(rb_cPcap, "next", rbpcap_next, 0);
rb_define_method(rb_cPcap, "setfilter", rbpcap_setfilter, 1);
rb_define_method(rb_cPcap, "inject", rbpcap_inject, 1);
rb_define_method(rb_cPcap, "datalink", rbpcap_datalink, 0);
rb_define_method(rb_cPcap, "each", rbpcap_capture, 0);
rb_define_method(rb_cPcap, "next", rbpcap_next, 0);
rb_define_method(rb_cPcap, "setfilter", rbpcap_setfilter, 1);
rb_define_method(rb_cPcap, "inject", rbpcap_inject, 1);
rb_define_method(rb_cPcap, "datalink", rbpcap_datalink, 0);
rb_define_method(rb_cPcap, "snapshot", rbpcap_snapshot, 0);
rb_define_method(rb_cPcap, "snaplen", rbpcap_snapshot, 0);
rb_define_method(rb_cPcap, "stats", rbpcap_stats, 0);
rb_define_method(rb_cPcap, "snapshot", rbpcap_snapshot, 0);
rb_define_method(rb_cPcap, "snaplen", rbpcap_snapshot, 0);
rb_define_method(rb_cPcap, "stats", rbpcap_stats, 0);
//Netifaces
rb_define_module_function(rb_cPcap, "interfaces", rbnetifaces_s_interfaces, 0);
rb_define_module_function(rb_cPcap, "addresses", rbnetifaces_s_addresses, 1);
//constants
// Address families (auto-detect using #ifdef)
#ifdef AF_INET
rb_define_const(rb_cPcap, "AF_INET", INT2NUM(AF_INET));
#endif
#ifdef AF_INET6
rb_define_const(rb_cPcap, "AF_INET6", INT2NUM(AF_INET6));
#endif
#ifdef AF_UNSPEC
rb_define_const(rb_cPcap, "AF_UNSPEC", INT2NUM(AF_UNSPEC));
#endif
#ifdef AF_UNIX
rb_define_const(rb_cPcap, "AF_UNIX", INT2NUM(AF_UNIX));
#endif
#ifdef AF_FILE
rb_define_const(rb_cPcap, "AF_FILE", INT2NUM(AF_FILE));
#endif
#ifdef AF_AX25
rb_define_const(rb_cPcap, "AF_AX25", INT2NUM(AF_AX25));
#endif
#ifdef AF_IMPLINK
rb_define_const(rb_cPcap, "AF_IMPLINK", INT2NUM(AF_IMPLINK));
#endif
#ifdef AF_PUP
rb_define_const(rb_cPcap, "AF_PUP", INT2NUM(AF_PUP));
#endif
#ifdef AF_CHAOS
rb_define_const(rb_cPcap, "AF_CHAOS", INT2NUM(AF_CHAOS));
#endif
#ifdef AF_NS
rb_define_const(rb_cPcap, "AF_NS", INT2NUM(AF_NS));
#endif
#ifdef AF_ISO
rb_define_const(rb_cPcap, "AF_ISO", INT2NUM(AF_ISO));
#endif
#ifdef AF_ECMA
rb_define_const(rb_cPcap, "AF_ECMA", INT2NUM(AF_ECMA));
#endif
#ifdef AF_DATAKIT
rb_define_const(rb_cPcap, "AF_DATAKIT", INT2NUM(AF_DATAKIT));
#endif
#ifdef AF_CCITT
rb_define_const(rb_cPcap, "AF_CCITT", INT2NUM(AF_CCITT));
#endif
#ifdef AF_SNA
rb_define_const(rb_cPcap, "AF_SNA", INT2NUM(AF_SNA));
#endif
#ifdef AF_DECnet
rb_define_const(rb_cPcap, "AF_DECnet", INT2NUM(AF_DECnet));
#endif
#ifdef AF_DLI
rb_define_const(rb_cPcap, "AF_DLI", INT2NUM(AF_DLI));
#endif
#ifdef AF_LAT
rb_define_const(rb_cPcap, "AF_LAT", INT2NUM(AF_LAT));
#endif
#ifdef AF_HYLINK
rb_define_const(rb_cPcap, "AF_HYLINK", INT2NUM(AF_HYLINK));
#endif
#ifdef AF_APPLETALK
rb_define_const(rb_cPcap, "AF_APPLETALK", INT2NUM(AF_APPLETALK));
#endif
#ifdef AF_ROUTE
rb_define_const(rb_cPcap, "AF_ROUTE", INT2NUM(AF_ROUTE));
#endif
#ifdef AF_LINK
rb_define_const(rb_cPcap, "AF_LINK", INT2NUM(AF_LINK));
#endif
#ifdef AF_PACKET
rb_define_const(rb_cPcap, "AF_PACKET", INT2NUM(AF_PACKET));
#endif
#ifdef AF_COIP
rb_define_const(rb_cPcap, "AF_COIP", INT2NUM(AF_COIP));
#endif
#ifdef AF_CNT
rb_define_const(rb_cPcap, "AF_CNT", INT2NUM(AF_CNT));
#endif
#ifdef AF_IPX
rb_define_const(rb_cPcap, "AF_IPX", INT2NUM(AF_IPX));
#endif
#ifdef AF_SIP
rb_define_const(rb_cPcap, "AF_SIP", INT2NUM(AF_SIP));
#endif
#ifdef AF_NDRV
rb_define_const(rb_cPcap, "AF_NDRV", INT2NUM(AF_NDRV));
#endif
#ifdef AF_ISDN
rb_define_const(rb_cPcap, "AF_ISDN", INT2NUM(AF_ISDN));
#endif
#ifdef AF_NATM
rb_define_const(rb_cPcap, "AF_NATM", INT2NUM(AF_NATM));
#endif
#ifdef AF_SYSTEM
rb_define_const(rb_cPcap, "AF_SYSTEM", INT2NUM(AF_SYSTEM));
#endif
#ifdef AF_NETBIOS
rb_define_const(rb_cPcap, "AF_NETBIOS", INT2NUM(AF_NETBIOS));
#endif
#ifdef AF_NETBEUI
rb_define_const(rb_cPcap, "AF_NETBEUI", INT2NUM(AF_NETBEUI));
#endif
#ifdef AF_PPP
rb_define_const(rb_cPcap, "AF_PPP", INT2NUM(AF_PPP));
#endif
#ifdef AF_ATM
rb_define_const(rb_cPcap, "AF_ATM", INT2NUM(AF_ATM));
#endif
#ifdef AF_ATMPVC
rb_define_const(rb_cPcap, "AF_ATMPVC", INT2NUM(AF_ATMPVC));
#endif
#ifdef AF_ATMSVC
rb_define_const(rb_cPcap, "AF_ATMSVC", INT2NUM(AF_ATMSVC));
#endif
#ifdef AF_NETGRAPH
rb_define_const(rb_cPcap, "AF_NETGRAPH", INT2NUM(AF_NETGRAPH));
#endif
#ifdef AF_VOICEVIEW
rb_define_const(rb_cPcap, "AF_VOICEVIEW", INT2NUM(AF_VOICEVIEW));
#endif
#ifdef AF_FIREFOX
rb_define_const(rb_cPcap, "AF_FIREFOX", INT2NUM(AF_FIREFOX));
#endif
#ifdef AF_UNKNOWN1
rb_define_const(rb_cPcap, "AF_UNKNOWN1", INT2NUM(AF_UNKNOWN1));
#endif
#ifdef AF_BAN
rb_define_const(rb_cPcap, "AF_BAN", INT2NUM(AF_BAN));
#endif
#ifdef AF_CLUSTER
rb_define_const(rb_cPcap, "AF_CLUSTER", INT2NUM(AF_CLUSTER));
#endif
#ifdef AF_12844
rb_define_const(rb_cPcap, "AF_12844", INT2NUM(AF_12844));
#endif
#ifdef AF_IRDA
rb_define_const(rb_cPcap, "AF_IRDA", INT2NUM(AF_IRDA));
#endif
#ifdef AF_NETDES
rb_define_const(rb_cPcap, "AF_NETDES", INT2NUM(AF_NETDES));
#endif
#ifdef AF_NETROM
rb_define_const(rb_cPcap, "AF_NETROM", INT2NUM(AF_NETROM));
#endif
#ifdef AF_BRIDGE
rb_define_const(rb_cPcap, "AF_BRIDGE", INT2NUM(AF_BRIDGE));
#endif
#ifdef AF_X25
rb_define_const(rb_cPcap, "AF_X25", INT2NUM(AF_X25));
#endif
#ifdef AF_ROSE
rb_define_const(rb_cPcap, "AF_ROSE", INT2NUM(AF_ROSE));
#endif
#ifdef AF_SECURITY
rb_define_const(rb_cPcap, "AF_SECURITY", INT2NUM(AF_SECURITY));
#endif
#ifdef AF_KEY
rb_define_const(rb_cPcap, "AF_KEY", INT2NUM(AF_KEY));
#endif
#ifdef AF_NETLINK
rb_define_const(rb_cPcap, "AF_NETLINK", INT2NUM(AF_NETLINK));
#endif
#ifdef AF_ASH
rb_define_const(rb_cPcap, "AF_ASH", INT2NUM(AF_ASH));
#endif
#ifdef AF_ECONET
rb_define_const(rb_cPcap, "AF_ECONET", INT2NUM(AF_ECONET));
#endif
#ifdef AF_PPPOX
rb_define_const(rb_cPcap, "AF_PPPOX", INT2NUM(AF_PPPOX));
#endif
#ifdef AF_WANPIPE
rb_define_const(rb_cPcap, "AF_WANPIPE", INT2NUM(AF_WANPIPE));
#endif
#ifdef AF_BLUETOOTH
rb_define_const(rb_cPcap, "AF_BLUETOOTH", INT2NUM(AF_BLUETOOTH));
#endif
}

View File

@ -100,5 +100,26 @@ class Pcap::UnitTest < Test::Unit::TestCase
puts "Background thread ticked #{@c} times while capture was running"
true
end
def test_netifaces_constants
puts "AF_LINK Value is #{Pcap::AF_LINK}"
puts "AF_INET Value is #{Pcap::AF_INET}"
puts "AF_INET6 Value is #{Pcap::AF_INET6}" if Pcap::AF_INET6
end
def test_netifaces_functions
Pcap.interfaces.sort.each do |iface|
puts "#{iface} :"
Pcap.addresses(iface).sort.each do |family,values|
puts "\t#{family} :"
values.each do |val|
puts "\t\taddr : #{val['addr']}" if val.has_key?("addr")
puts "\t\tnetmask : #{val['netmask']}" if val.has_key?("netmask")
puts "\t\tbroadcast : #{val['broadcast']}" if val.has_key?("broadcast")
puts "\n"
end
end
end
end
end

View File

@ -382,14 +382,6 @@ module Exploit::Capture
end
end
# lookupaddr is not available in pcaprub 0.9.2 and prior,
# which is going to be installed in a lot of places. Modules
# which want it should check explicitly for it. TODO: Bug upstream
# to release it for real in 0.9.3
def lookupaddr_implemented?
@pcaprub_loaded and Pcap.respond_to?(:lookupaddrs)
end
def lookupnet
check_pcaprub_loaded
dev = datastore['INTERFACE'] || ::Pcap.lookupdev
@ -413,6 +405,96 @@ module Exploit::Capture
attr_accessor :capture, :arp_cache, :arp_capture, :dst_cache
# lookupaddr is not available in pcaprub 0.9.2 and prior,
# which is going to be installed in a lot of places. Modules
# which want it should check explicitly for it. TODO: Bug upstream
# to release it for real in 0.9.3
def lookupaddr_implemented?
@pcaprub_loaded and Pcap.respond_to?(:lookupaddrs)
end
#Netifaces code
def list_interfaces
check_pcaprub_loaded
Pcap.interfaces
end
def is_interface?(dev)
check_pcaprub_loaded
Pcap.interfaces.include? dev
end
def get_mac(dev)
check_pcaprub_loaded
addrs = Pcap.addresses(dev)
raise RuntimeError, "Interface #{dev} do not exists" if !addrs
raise RuntimeError, "Can not get mac address for interface #{dev}" if !addrs[Pcap::AF_LINK][0]['addr']
addrs[Pcap::AF_LINK][0]['addr']
end
def get_ipv4_addr_count(dev)
check_pcaprub_loaded
addrs = Pcap.addresses(dev)
raise RuntimeError, "Interface #{dev} do not exists" if !addrs
addrs[Pcap::AF_INET].length
end
def get_ipv4_addr(dev, num=0)
check_pcaprub_loaded
addrs = Pcap.addresses(dev)
raise RuntimeError, "Interface #{dev} do not exists" if !addrs
raise RuntimeError, "Interface #{dev} do not have an ipv4 address at position #{num}" if addrs[Pcap::AF_INET].length < num + 1
raise RuntimeError, "Can not get the ipv4 address for interface #{dev}" if !addrs[Pcap::AF_INET][num]['addr']
addrs[Pcap::AF_INET][num]['addr']
end
def get_ipv4_netmask(dev, num=0)
check_pcaprub_loaded
addrs = Pcap.addresses(dev)
raise RuntimeError, "Interface #{dev} do not exists" if !addrs
raise RuntimeError, "Interface #{dev} do not have an ipv4 address at position #{num}" if addrs[Pcap::AF_INET].length < num + 1
raise RuntimeError, "Can not get ipv4 netmask for interface #{dev}" if !addrs[Pcap::AF_INET][num]['netmask']
addrs[Pcap::AF_INET][num]['netmask']
end
def get_ipv4_broadcast(dev, num=0)
check_pcaprub_loaded
addrs = Pcap.addresses(dev)
raise RuntimeError, "Interface #{dev} do not exists" if !addrs
raise RuntimeError, "Interface #{dev} do not have an ipv4 address at position #{num}" if addrs[Pcap::AF_INET].length < num + 1
raise RuntimeError, "Can not get ipv4 broadcast address for interface #{dev}" if !addrs[Pcap::AF_INET][num]['broadcast']
addrs[Pcap::AF_INET][num]['broadcast']
end
def get_ipv6_addr_count(dev)
check_pcaprub_loaded
raise RuntimeError, "Ipv6 informations are not available on this platform" if !Pcap::AF_INET6
addrs = Pcap.addresses(dev)
raise RuntimeError, "Interface #{dev} do not exists" if !addrs
addrs[Pcap::AF_INET6].length
end
def get_ipv6_addr(dev, num=0)
check_pcaprub_loaded
raise RuntimeError, "Ipv6 informations are not available on this platform" if !Pcap::AF_INET6
addrs = Pcap.addresses(dev)
raise RuntimeError, "Interface #{dev} do not exists" if !addrs
raise RuntimeError, "Interface #{dev} do not have an ipv6 address at position #{num}" if addrs[Pcap::AF_INET6].length < num + 1
raise RuntimeError, "Can not get ipv6 address for interface #{dev}" if !addrs[Pcap::AF_INET6][num]['addr']
addrs[Pcap::AF_INET6][num]['addr'].gsub(/%(.)*$/,'')
end
def get_ipv6_netmask(dev, num=0)
check_pcaprub_loaded
raise RuntimeError, "Ipv6 informations are not available on this platform" if !Pcap::AF_INET6
addrs = Pcap.addresses(dev)
raise RuntimeError, "Interface #{dev} do not exists" if !addrs
raise RuntimeError, "Interface #{dev} do not have an ipv6 address at position #{num}" if addrs[Pcap::AF_INET6].length < num + 1
raise RuntimeError, "Can not get ipv6 netmask address for interface #{dev}" if !addrs[Pcap::AF_INET6][num]['netmask']
addrs[Pcap::AF_INET6][num]['netmask']
end
end
end