├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── Rakefile ├── ext └── network_interface_ext │ ├── extconf.rb │ ├── netifaces.c │ └── netifaces.h ├── lib ├── network_interface.rb └── network_interface │ └── version.rb ├── network_interface.gemspec ├── setup.sh └── spec ├── netiface_spec.rb └── spec_helper.rb /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in network_interface.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | network_interface (0.0.1) 5 | 6 | GEM 7 | remote: https://rubygems.org/ 8 | specs: 9 | diff-lcs (1.2.4) 10 | rake (10.0.3) 11 | rake-compiler (0.8.3) 12 | rake 13 | rspec (2.13.0) 14 | rspec-core (~> 2.13.0) 15 | rspec-expectations (~> 2.13.0) 16 | rspec-mocks (~> 2.13.0) 17 | rspec-core (2.13.1) 18 | rspec-expectations (2.13.0) 19 | diff-lcs (>= 1.1.3, < 2.0) 20 | rspec-mocks (2.13.1) 21 | 22 | PLATFORMS 23 | ruby 24 | 25 | DEPENDENCIES 26 | bundler (~> 1.3) 27 | network_interface! 28 | rake 29 | rake-compiler 30 | rspec 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2012, Rapid7, Inc. 2 | All rights reserved. 3 | 4 | MIT License 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | "Software"), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | Original c/python netifaces code is under MIT-style license. 26 | 27 | Copyright (c) 2007, 2008 Alastair Houghton 28 | 29 | Permission is hereby granted, free of charge, to any person obtaining a copy 30 | of this software and associated documentation files (the "Software"), to deal 31 | in the Software without restriction, including without limitation the rights 32 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 33 | copies of the Software, and to permit persons to whom the Software is 34 | furnished to do so, subject to the following conditions: 35 | 36 | The above copyright notice and this permission notice shall be included in all 37 | copies or substantial portions of the Software. 38 | 39 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 40 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 41 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 42 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 43 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 44 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 45 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # network_interface 2 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # require "bundler/gem_tasks" 2 | require 'bundler' 3 | Bundler::GemHelper.install_tasks 4 | 5 | require 'rspec/core/rake_task' 6 | RSpec::Core::RakeTask.new 7 | 8 | require 'rake/extensiontask' 9 | Rake::ExtensionTask.new('network_interface_ext') 10 | 11 | task :default => [:clean, :compile, :spec] -------------------------------------------------------------------------------- /ext/network_interface_ext/extconf.rb: -------------------------------------------------------------------------------- 1 | require 'mkmf' 2 | extension_name = 'network_interface_ext' 3 | 4 | ######################## 5 | # Netifaces 6 | ######################## 7 | puts "\n[*] Running checks for netifaces code..." 8 | #uncoment to force ioctl on non windows systems 9 | #@force_ioctl = true 10 | @supported_archs = [ "i386-mingw32", "i486-linux", "x86_64-linux", 11 | "universal-darwin10.0", "i386-openbsd4.8", "i386-freebsd8", 12 | "arm-linux-eabi", "x86_64-darwin12.3.0" ] 13 | #arm-linux-eabi tested on maemo5 / N900 14 | puts "[*] Warning : this platform as not been tested" unless @supported_archs.include? RUBY_PLATFORM 15 | 16 | if RUBY_PLATFORM =~ /i386-mingw32/ 17 | unless have_library("ws2_32" ) and 18 | have_library("iphlpapi") and 19 | have_header("windows.h") and 20 | have_header("winsock2.h") and 21 | have_header("iphlpapi.h") 22 | puts "\nNot all dependencies are satisfied, please check logs" 23 | exit 24 | end 25 | 26 | else 27 | headers = ['net/if_dl.h', 'netash/ash.h','netatalk/at.h', 'netax25/ax25.h', 28 | 'neteconet/ec.h', 'netipx/ipx.h','netpacket/packet.h', 'netrose/rose.h'] 29 | if RUBY_PLATFORM =~ /linux/ 30 | headers += [ 'linux/irda.h', 'linux/atm.h', 31 | 'linux/llc.h', 'linux/tipc.h', 32 | 'linux/dn.h'] 33 | end 34 | additionnal_headers = ["sys/types.h","sys/socket.h","sys/un.h","net/if.h","netinet/in.h"] 35 | optional_headers = [] 36 | sockaddrs = [ 'at', 'ax25', 'dl', 'eon', 'in', 'in6', 37 | 'inarp', 'ipx', 'iso', 'ns', 'un', 'x25', 38 | 'rose', 'ash', 'ec', 'll', 'atmpvc', 'atmsvc', 39 | 'dn', 'irda', 'llc'] 40 | 41 | # 1) Check for getifaddrs 42 | unless @force_ioctl 43 | need_ioctl = !(have_func("getifaddrs")) 44 | end 45 | 46 | # 2) Check for getnameinfo or redefine it in netifaces.c 47 | have_func("getnameinfo") 48 | 49 | # 3) Whitout getifaddrs we'll have to deal with ioctls 50 | if need_ioctl or @force_ioctl 51 | ioctls = [ 52 | 'SIOCGIFCONF','SIOCGSIZIFCONF','SIOCGIFHWADDR','SIOCGIFADDR','SIOCGIFFLAGS','SIOCGIFDSTADDR', 53 | 'SIOCGIFBRDADDR','SIOCGIFNETMASK','SIOCGLIFNUM','SIOCGLIFCONF','SIOCGLIFFLAGS'] 54 | ioctls_headers = ['sys/types.h','sys/socket.h','sys/ioctl.h','net/if.h','netinet/in.h','arpa/inet.h'] 55 | #TODO Test this on sunos 56 | #if RUBY_PLATFORM =~ /sunos/ 57 | # ioctls_headers += ['unistd.h','stropts.h','sys/sockio.h'] 58 | #end 59 | $defs.push '-DHAVE_SOCKET_IOCTLS' 60 | ioctls.each do |ioctl| 61 | if have_macro(ioctl, ioctls_headers) 62 | $defs.push "-DHAVE_#{ioctl}" 63 | end 64 | end 65 | end 66 | 67 | # 4) Check for optional headers 68 | headers.each do |header| 69 | if have_header(header) 70 | optional_headers.push(header) 71 | end 72 | end 73 | 74 | # 5) On certain platforms (Linux), there's no sa_len. 75 | # Unfortunately, getifaddrs() doesn't return the 76 | # lengths, because they're in the sa_len field on just about 77 | # everything but Linux. 78 | # In this case we will define a macro that will return the sa_len from 79 | # the sockaddr_xx structure if they are available 80 | if (!have_struct_member("struct sockaddr", "sa_len", ["sys/types.h","sys/socket.h","net/if.h"])) 81 | sockaddrs.each do |sockaddr| 82 | have_type("struct sockaddr_" + sockaddr, additionnal_headers + optional_headers) 83 | end 84 | end 85 | end 86 | 87 | #rework the defs to make them compatible with the original netifaces.c code 88 | $defs = $defs.map do |a| 89 | if a =~ /^-DHAVE_TYPE_STRUCT_SOCKADDR_.*$/ then a.gsub("TYPE_STRUCT_","") 90 | elsif a == "-DHAVE_ST_SA_LEN" then a.gsub("HAVE_ST_","HAVE_SOCKADDR_") 91 | else a 92 | end 93 | end 94 | 95 | create_makefile(extension_name) -------------------------------------------------------------------------------- /ext/network_interface_ext/netifaces.c: -------------------------------------------------------------------------------- 1 | #include "ruby.h" 2 | #include "netifaces.h" 3 | 4 | #if !defined(WIN32) 5 | #if !HAVE_GETNAMEINFO 6 | #undef getnameinfo 7 | #undef NI_NUMERICHOST 8 | 9 | #define getnameinfo our_getnameinfo 10 | #define NI_NUMERICHOST 1 11 | 12 | /* A very simple getnameinfo() for platforms without */ 13 | static int 14 | getnameinfo (const struct sockaddr *addr, int addr_len, 15 | char *buffer, int buflen, 16 | char *buf2, int buf2len, 17 | int flags) 18 | { 19 | switch (addr->sa_family) 20 | { 21 | case AF_INET: 22 | { 23 | const struct sockaddr_in *sin = (struct sockaddr_in *)addr; 24 | const unsigned char *bytes = (unsigned char *)&sin->sin_addr.s_addr; 25 | char tmpbuf[20]; 26 | 27 | sprintf (tmpbuf, "%d.%d.%d.%d", 28 | bytes[0], bytes[1], bytes[2], bytes[3]); 29 | 30 | strncpy (buffer, tmpbuf, buflen); 31 | } 32 | break; 33 | #ifdef AF_INET6 34 | case AF_INET6: 35 | { 36 | const struct sockaddr_in6 *sin = (const struct sockaddr_in6 *)addr; 37 | const unsigned char *bytes = sin->sin6_addr.s6_addr; 38 | int n; 39 | char tmpbuf[80], *ptr = tmpbuf; 40 | int done_double_colon = FALSE; 41 | int colon_mode = FALSE; 42 | 43 | for (n = 0; n < 8; ++n) 44 | { 45 | unsigned char b1 = bytes[2 * n]; 46 | unsigned char b2 = bytes[2 * n + 1]; 47 | 48 | if (b1) 49 | { 50 | if (colon_mode) 51 | { 52 | colon_mode = FALSE; 53 | *ptr++ = ':'; 54 | } 55 | sprintf (ptr, "%x%02x", b1, b2); 56 | ptr += strlen (ptr); 57 | *ptr++ = ':'; 58 | } 59 | else if (b2) 60 | { 61 | if (colon_mode) 62 | { 63 | colon_mode = FALSE; 64 | *ptr++ = ':'; 65 | } 66 | sprintf (ptr, "%x", b2); 67 | ptr += strlen (ptr); 68 | *ptr++ = ':'; 69 | } 70 | else { 71 | if (!colon_mode) 72 | { 73 | if (done_double_colon) 74 | { 75 | *ptr++ = '0'; 76 | *ptr++ = ':'; 77 | } 78 | else 79 | { 80 | if (n == 0) 81 | *ptr++ = ':'; 82 | colon_mode = TRUE; 83 | done_double_colon = TRUE; 84 | } 85 | } 86 | } 87 | } 88 | if (colon_mode) 89 | { 90 | colon_mode = FALSE; 91 | *ptr++ = ':'; 92 | *ptr++ = '\0'; 93 | } 94 | else 95 | { 96 | *--ptr = '\0'; 97 | } 98 | 99 | strncpy (buffer, tmpbuf, buflen); 100 | } 101 | break; 102 | #endif /* AF_INET6 */ 103 | default: 104 | return -1; 105 | } 106 | 107 | return 0; 108 | } 109 | #endif 110 | 111 | static int 112 | string_from_sockaddr (struct sockaddr *addr, 113 | char *buffer, 114 | int buflen) 115 | { 116 | if (!addr || addr->sa_family == AF_UNSPEC) 117 | return -1; 118 | 119 | if (getnameinfo (addr, SA_LEN(addr), 120 | buffer, buflen, 121 | NULL, 0, 122 | NI_NUMERICHOST) != 0) 123 | { 124 | int n, len; 125 | char *ptr; 126 | const char *data; 127 | 128 | len = SA_LEN(addr); 129 | 130 | #if HAVE_AF_LINK 131 | /* BSD-like systems have AF_LINK */ 132 | if (addr->sa_family == AF_LINK) 133 | { 134 | struct sockaddr_dl *dladdr = (struct sockaddr_dl *)addr; 135 | len = dladdr->sdl_alen; 136 | if(len >=0) 137 | data = LLADDR(dladdr); 138 | } 139 | else 140 | { 141 | #endif 142 | #if defined(AF_PACKET) 143 | /* Linux has AF_PACKET instead */ 144 | if (addr->sa_family == AF_PACKET) 145 | { 146 | struct sockaddr_ll *lladdr = (struct sockaddr_ll *)addr; 147 | len = lladdr->sll_halen; 148 | //amaloteaux: openbsd and maybe other systems have a len of 0 for enc0,pflog0 .. interfaces 149 | if(len >=0) 150 | data = (const char *)lladdr->sll_addr; 151 | } 152 | else 153 | { 154 | #endif 155 | /* We don't know anything about this sockaddr, so just display 156 | the entire data area in binary. */ 157 | len -= (int)(sizeof (struct sockaddr) - sizeof (addr->sa_data)); 158 | data = addr->sa_data; 159 | #if defined(AF_PACKET) 160 | } 161 | #endif 162 | #if HAVE_AF_LINK 163 | } 164 | #endif 165 | 166 | if ((buflen < 3 * len) || len <= 0) 167 | return -1; 168 | 169 | ptr = buffer; 170 | buffer[0] = '\0'; 171 | 172 | for (n = 0; n < len; ++n) 173 | { 174 | sprintf (ptr, "%02x:", data[n] & 0xff); 175 | ptr += 3; 176 | } 177 | *--ptr = '\0'; 178 | } 179 | 180 | return 0; 181 | } 182 | #endif /* !defined(WIN32) */ 183 | 184 | static VALUE add_to_family(VALUE result, VALUE family, VALUE value) 185 | { 186 | VALUE list; 187 | Check_Type(result, T_HASH); 188 | Check_Type(family, T_FIXNUM); 189 | Check_Type(value, T_HASH); 190 | 191 | list = rb_hash_aref(result, family); 192 | 193 | if (list == Qnil) 194 | list = rb_ary_new(); 195 | else 196 | Check_Type(list, T_ARRAY); 197 | 198 | rb_ary_push(list, value); 199 | rb_hash_aset(result, family, list); 200 | return result; 201 | } 202 | 203 | VALUE 204 | rbnetifaces_s_addresses (VALUE class, VALUE dev) 205 | { 206 | VALUE result; 207 | int found = FALSE; 208 | #if defined(WIN32) 209 | PIP_ADAPTER_INFO pAdapterInfo = NULL; 210 | PIP_ADAPTER_INFO pInfo = NULL; 211 | ULONG ulBufferLength = 0; 212 | DWORD dwRet; 213 | PIP_ADDR_STRING str; 214 | #elif HAVE_GETIFADDRS 215 | struct ifaddrs *addrs = NULL; 216 | struct ifaddrs *addr = NULL; 217 | VALUE result2; 218 | #elif HAVE_SOCKET_IOCTLS 219 | int sock; 220 | struct CNAME(ifreq) ifr; 221 | char buffer[256]; 222 | int is_p2p = FALSE; 223 | VALUE rbaddr = Qnil; 224 | VALUE rbnetmask = Qnil; 225 | VALUE rbbraddr = Qnil; 226 | VALUE rbdstaddr = Qnil; 227 | VALUE result2; 228 | #endif 229 | 230 | Check_Type(dev, T_STRING); 231 | result = rb_hash_new(); 232 | 233 | #if defined(WIN32) 234 | //First, retrieve the adapter information. We do this in a loop, in 235 | //case someone adds or removes adapters in the meantime. 236 | do 237 | { 238 | dwRet = GetAdaptersInfo(pAdapterInfo, &ulBufferLength); 239 | 240 | if (dwRet == ERROR_BUFFER_OVERFLOW) 241 | { 242 | if (pAdapterInfo) 243 | free (pAdapterInfo); 244 | pAdapterInfo = (PIP_ADAPTER_INFO)malloc (ulBufferLength); 245 | 246 | if (!pAdapterInfo) 247 | { 248 | rb_raise(rb_eRuntimeError, "Unknow error at OS level"); 249 | return Qnil; 250 | } 251 | } 252 | } while (dwRet == ERROR_BUFFER_OVERFLOW); 253 | 254 | // If we failed, then fail in Ruby too 255 | if (dwRet != ERROR_SUCCESS && dwRet != ERROR_NO_DATA) 256 | { 257 | if (pAdapterInfo) 258 | free (pAdapterInfo); 259 | rb_raise(rb_eRuntimeError, "Unable to obtain adapter information."); 260 | return Qnil; 261 | } 262 | 263 | for (pInfo = pAdapterInfo; pInfo; pInfo = pInfo->Next) 264 | { 265 | char buffer[256]; 266 | //dev is the iface GUID on windows with "\\Device\\NPF_" prefix 267 | int cmpAdapterNamelen = (MAX_ADAPTER_NAME_LENGTH + 4) + 12; 268 | char cmpAdapterName[cmpAdapterNamelen]; 269 | int AdapterName_len = strlen(pInfo->AdapterName); 270 | 271 | VALUE rbhardw = Qnil; 272 | VALUE rbaddr = Qnil; 273 | VALUE rbnetmask = Qnil; 274 | VALUE rbbraddr = Qnil; 275 | 276 | memset(cmpAdapterName, 0x00, cmpAdapterNamelen); 277 | strncpy(cmpAdapterName, "\\Device\\NPF_", 12); 278 | strncpy(cmpAdapterName + 12, pInfo->AdapterName, AdapterName_len); 279 | if (strcmp (cmpAdapterName, StringValuePtr(dev)) != 0) 280 | continue; 281 | 282 | found = TRUE; 283 | 284 | // Do the physical address 285 | if (256 >= 3 * pInfo->AddressLength) 286 | { 287 | char *ptr = buffer; 288 | unsigned n; 289 | VALUE hash_hardw; 290 | hash_hardw = rb_hash_new(); 291 | 292 | *ptr = '\0'; 293 | for (n = 0; n < pInfo->AddressLength; ++n) 294 | { 295 | sprintf (ptr, "%02x:", pInfo->Address[n] & 0xff); 296 | ptr += 3; 297 | } 298 | *--ptr = '\0'; 299 | 300 | rbhardw = rb_str_new2(buffer); 301 | rb_hash_aset(hash_hardw, rb_str_new2("addr"), rbhardw); 302 | result = add_to_family(result, INT2FIX(AF_LINK), hash_hardw); 303 | } 304 | 305 | for (str = &pInfo->IpAddressList; str; str = str->Next) 306 | { 307 | 308 | VALUE result2; 309 | result2 = rb_hash_new(); 310 | 311 | if(str->IpAddress.String) 312 | rbaddr = rb_str_new2(str->IpAddress.String); 313 | if(str->IpMask.String) 314 | rbnetmask = rb_str_new2(str->IpMask.String); 315 | 316 | //If this isn't the loopback interface, work out the broadcast 317 | //address, for better compatibility with other platforms. 318 | if (pInfo->Type != MIB_IF_TYPE_LOOPBACK) 319 | { 320 | unsigned long inaddr = inet_addr (str->IpAddress.String); 321 | unsigned long inmask = inet_addr (str->IpMask.String); 322 | struct in_addr in; 323 | char *brstr; 324 | 325 | in.S_un.S_addr = (inaddr | ~inmask) & 0xfffffffful; 326 | 327 | brstr = inet_ntoa (in); 328 | 329 | if (brstr) 330 | rbbraddr = rb_str_new2(brstr); 331 | } 332 | 333 | if (rbaddr) 334 | rb_hash_aset(result2, rb_str_new2("addr"), rbaddr); 335 | if (rbnetmask) 336 | rb_hash_aset(result2, rb_str_new2("netmask"), rbnetmask); 337 | if (rbbraddr) 338 | rb_hash_aset(result2, rb_str_new2("broadcast"), rbbraddr); 339 | 340 | result = add_to_family(result, INT2FIX(AF_INET), result2); 341 | 342 | } 343 | } // for 344 | 345 | free (pAdapterInfo); 346 | 347 | #elif HAVE_GETIFADDRS 348 | if (getifaddrs (&addrs) < 0) 349 | { 350 | rb_raise(rb_eRuntimeError, "Unknow error at OS level"); 351 | } 352 | 353 | for (addr = addrs; addr; addr = addr->ifa_next) 354 | { 355 | char buffer[256]; 356 | VALUE rbaddr = Qnil; 357 | VALUE rbnetmask = Qnil; 358 | VALUE rbbraddr = Qnil; 359 | 360 | if (strcmp (addr->ifa_name, StringValuePtr(dev)) != 0) 361 | continue; 362 | 363 | /* Sometimes there are records without addresses (e.g. in the case of a 364 | dial-up connection via ppp, which on Linux can have a link address 365 | record with no actual address). We skip these as they aren't useful. 366 | Thanks to Christian Kauhaus for reporting this issue. */ 367 | if (!addr->ifa_addr) 368 | continue; 369 | 370 | found = TRUE; 371 | 372 | if (string_from_sockaddr (addr->ifa_addr, buffer, sizeof (buffer)) == 0) 373 | rbaddr = rb_str_new2(buffer); 374 | 375 | if (string_from_sockaddr (addr->ifa_netmask, buffer, sizeof (buffer)) == 0) 376 | rbnetmask = rb_str_new2(buffer); 377 | 378 | if (string_from_sockaddr (addr->ifa_broadaddr, buffer, sizeof (buffer)) == 0) 379 | rbbraddr = rb_str_new2(buffer); 380 | 381 | result2 = rb_hash_new(); 382 | 383 | if (rbaddr) 384 | rb_hash_aset(result2, rb_str_new2("addr"), rbaddr); 385 | if (rbnetmask) 386 | rb_hash_aset(result2, rb_str_new2("netmask"), rbnetmask); 387 | if (rbbraddr) 388 | { 389 | if (addr->ifa_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) 390 | rb_hash_aset(result2, rb_str_new2("peer"), rbbraddr); 391 | else 392 | rb_hash_aset(result2, rb_str_new2("broadcast"), rbbraddr); 393 | } 394 | if (rbaddr || rbnetmask || rbbraddr) 395 | result = add_to_family(result, INT2FIX(addr->ifa_addr->sa_family), result2); 396 | } 397 | freeifaddrs (addrs); 398 | #elif HAVE_SOCKET_IOCTLS 399 | 400 | sock = socket(AF_INET, SOCK_DGRAM, 0); 401 | 402 | if (sock < 0) 403 | { 404 | rb_raise(rb_eRuntimeError, "Unknow error at OS level"); 405 | return Qnil; 406 | } 407 | 408 | strncpy (ifr.CNAME(ifr_name), StringValuePtr(dev), IFNAMSIZ); 409 | 410 | #if HAVE_SIOCGIFHWADDR 411 | if (ioctl (sock, SIOCGIFHWADDR, &ifr) == 0) 412 | { 413 | if (string_from_sockaddr (&(ifr.CNAME(ifr_addr)), buffer, sizeof (buffer)) == 0) 414 | { 415 | found = TRUE; 416 | 417 | VALUE rbhardw = Qnil; 418 | VALUE hash_hardw; 419 | hash_hardw = rb_hash_new(); 420 | rbhardw = rb_str_new2(buffer); 421 | rb_hash_aset(hash_hardw, rb_str_new2("addr"), rbhardw); 422 | result = add_to_family(result, INT2FIX(AF_LINK), hash_hardw); 423 | } 424 | } 425 | #endif 426 | 427 | 428 | #if HAVE_SIOCGIFADDR 429 | #if HAVE_SIOCGLIFNUM 430 | if (ioctl (sock, SIOCGLIFADDR, &ifr) == 0) 431 | { 432 | #else 433 | if (ioctl (sock, SIOCGIFADDR, &ifr) == 0) 434 | { 435 | #endif 436 | if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0) 437 | { 438 | found = TRUE; 439 | rbaddr = rb_str_new2(buffer); 440 | } 441 | } 442 | #endif 443 | 444 | #if HAVE_SIOCGIFNETMASK 445 | #if HAVE_SIOCGLIFNUM 446 | if (ioctl (sock, SIOCGLIFNETMASK, &ifr) == 0) 447 | { 448 | #else 449 | if (ioctl (sock, SIOCGIFNETMASK, &ifr) == 0) 450 | { 451 | #endif 452 | if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0) 453 | { 454 | found = TRUE; 455 | rbnetmask = rb_str_new2(buffer); 456 | } 457 | } 458 | #endif 459 | 460 | #if HAVE_SIOCGIFFLAGS 461 | #if HAVE_SIOCGLIFNUM 462 | if (ioctl (sock, SIOCGLIFFLAGS, &ifr) == 0) 463 | { 464 | #else 465 | if (ioctl (sock, SIOCGIFFLAGS, &ifr) == 0) 466 | { 467 | #endif 468 | 469 | if (ifr.CNAME(ifr_flags) & IFF_POINTOPOINT) 470 | { 471 | is_p2p = TRUE; 472 | } 473 | } 474 | #endif 475 | 476 | #if HAVE_SIOCGIFBRDADDR 477 | #if HAVE_SIOCGLIFNUM 478 | if (!is_p2p && ioctl (sock, SIOCGLIFBRDADDR, &ifr) == 0) 479 | { 480 | #else 481 | if (!is_p2p && ioctl (sock, SIOCGIFBRDADDR, &ifr) == 0) 482 | { 483 | #endif 484 | 485 | 486 | if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0) 487 | { 488 | found = TRUE; 489 | rbbraddr = rb_str_new2(buffer); 490 | } 491 | } 492 | #endif 493 | 494 | #if HAVE_SIOCGIFDSTADDR 495 | #if HAVE_SIOCGLIFNUM 496 | if (is_p2p && ioctl (sock, SIOCGLIFBRDADDR, &ifr) == 0) 497 | { 498 | #else 499 | if (is_p2p && ioctl (sock, SIOCGIFBRDADDR, &ifr) == 0) 500 | { 501 | #endif 502 | if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0) 503 | { 504 | found = TRUE; 505 | rbdstaddr = rb_str_new2(buffer); 506 | } 507 | } 508 | 509 | #endif 510 | result2 = rb_hash_new(); 511 | 512 | if (rbaddr) 513 | rb_hash_aset(result2, rb_str_new2("addr"), rbaddr); 514 | if (rbnetmask) 515 | rb_hash_aset(result2, rb_str_new2("netmask"), rbnetmask); 516 | if (rbbraddr) 517 | rb_hash_aset(result2, rb_str_new2("broadcast"), rbbraddr); 518 | if (rbdstaddr) 519 | rb_hash_aset(result2, rb_str_new2("peer"), rbbraddr); 520 | 521 | if (rbaddr || rbnetmask || rbbraddr || rbdstaddr) 522 | result = add_to_family(result, INT2FIX(AF_INET), result2); 523 | 524 | close (sock); 525 | #endif /* HAVE_SOCKET_IOCTLS */ 526 | 527 | if (found) 528 | return result; 529 | else 530 | return Qnil; 531 | 532 | } 533 | 534 | VALUE 535 | rbnetifaces_s_interfaces (VALUE self) 536 | { 537 | VALUE result; 538 | #if defined(WIN32) 539 | PIP_ADAPTER_INFO pAdapterInfo = NULL; 540 | PIP_ADAPTER_INFO pInfo = NULL; 541 | ULONG ulBufferLength = 0; 542 | DWORD dwRet; 543 | #elif HAVE_GETIFADDRS 544 | const char *prev_name = NULL; 545 | struct ifaddrs *addrs = NULL; 546 | struct ifaddrs *addr = NULL; 547 | #elif HAVE_SIOCGIFCONF 548 | const char *prev_name = NULL; 549 | int fd, len, n; 550 | struct CNAME(ifconf) ifc; 551 | struct CNAME(ifreq) *pfreq; 552 | #endif 553 | 554 | result = rb_ary_new(); 555 | 556 | #if defined(WIN32) 557 | // First, retrieve the adapter information 558 | do { 559 | dwRet = GetAdaptersInfo(pAdapterInfo, &ulBufferLength); 560 | 561 | if (dwRet == ERROR_BUFFER_OVERFLOW) 562 | { 563 | if (pAdapterInfo) 564 | free (pAdapterInfo); 565 | pAdapterInfo = (PIP_ADAPTER_INFO)malloc (ulBufferLength); 566 | 567 | if (!pAdapterInfo) 568 | { 569 | rb_raise(rb_eRuntimeError, "Unknow error at OS level"); 570 | } 571 | } 572 | } while (dwRet == ERROR_BUFFER_OVERFLOW); 573 | 574 | // If we failed, then fail in Ruby too 575 | if (dwRet != ERROR_SUCCESS && dwRet != ERROR_NO_DATA) 576 | { 577 | if (pAdapterInfo) 578 | free (pAdapterInfo); 579 | 580 | rb_raise(rb_eRuntimeError, "Unknow error at OS level"); 581 | return Qnil; 582 | } 583 | if (dwRet == ERROR_NO_DATA) 584 | { 585 | free (pAdapterInfo); 586 | return result; 587 | } 588 | 589 | for (pInfo = pAdapterInfo; pInfo; pInfo = pInfo->Next) 590 | { 591 | int outputnamelen = (MAX_ADAPTER_NAME_LENGTH + 4) + 12; 592 | char outputname[outputnamelen]; 593 | int AdapterName_len = strlen(pInfo->AdapterName); 594 | VALUE ifname; 595 | memset(outputname, 0x00, outputnamelen); 596 | strncpy(outputname, "\\Device\\NPF_", 12); 597 | strncpy(outputname + 12, pInfo->AdapterName, AdapterName_len); 598 | ifname = rb_str_new2(outputname) ; 599 | 600 | if(!rb_ary_includes(result, ifname)) 601 | rb_ary_push(result, ifname); 602 | } 603 | 604 | free (pAdapterInfo); 605 | 606 | #elif HAVE_GETIFADDRS 607 | if (getifaddrs (&addrs) < 0) 608 | { 609 | rb_raise(rb_eRuntimeError, "Unknow error at OS level"); 610 | } 611 | 612 | for (addr = addrs; addr; addr = addr->ifa_next) 613 | { 614 | if (!prev_name || strncmp (addr->ifa_name, prev_name, IFNAMSIZ) != 0) 615 | { 616 | VALUE ifname = rb_str_new2(addr->ifa_name); 617 | 618 | if(!rb_ary_includes(result, ifname)) 619 | rb_ary_push(result, ifname); 620 | 621 | prev_name = addr->ifa_name; 622 | } 623 | } 624 | 625 | freeifaddrs (addrs); 626 | #elif HAVE_SIOCGIFCONF 627 | 628 | fd = socket (AF_INET, SOCK_DGRAM, 0); 629 | len = -1; 630 | if (fd < 0) { 631 | rb_raise(rb_eRuntimeError, "Unknow error at OS level"); 632 | return Qnil; 633 | } 634 | 635 | // Try to find out how much space we need 636 | #if HAVE_SIOCGSIZIFCONF 637 | if (ioctl (fd, SIOCGSIZIFCONF, &len) < 0) 638 | len = -1; 639 | #elif HAVE_SIOCGLIFNUM 640 | #error This code need to be checked first 641 | /* 642 | { struct lifnum lifn; 643 | lifn.lifn_family = AF_UNSPEC; 644 | lifn.lifn_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES; 645 | ifc.lifc_family = AF_UNSPEC; 646 | ifc.lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES; 647 | if (ioctl (fd, SIOCGLIFNUM, (char *)&lifn) < 0) 648 | len = -1; 649 | else 650 | len = lifn.lifn_count; 651 | } 652 | */ 653 | #endif 654 | 655 | // As a last resort, guess 656 | if (len < 0) 657 | len = 64; 658 | 659 | ifc.CNAME(ifc_len) = len * sizeof (struct CNAME(ifreq)); 660 | ifc.CNAME(ifc_buf) = malloc (ifc.CNAME(ifc_len)); 661 | 662 | if (!ifc.CNAME(ifc_buf)) { 663 | close (fd); 664 | rb_raise(rb_eRuntimeError, "Not enough memory"); 665 | return Qnil; 666 | } 667 | 668 | #if HAVE_SIOCGLIFNUM 669 | if (ioctl (fd, SIOCGLIFCONF, &ifc) < 0) { 670 | #else 671 | if (ioctl (fd, SIOCGIFCONF, &ifc) < 0) { 672 | 673 | #endif 674 | free (ifc.CNAME(ifc_req)); 675 | close (fd); 676 | rb_raise(rb_eRuntimeError, "Unknow error at OS level"); 677 | return Qnil; 678 | } 679 | 680 | *pfreq = ifc.CNAME(ifc_req); 681 | 682 | for (n = 0; n < ifc.CNAME(ifc_len)/sizeof(struct CNAME(ifreq));n++,pfreq++) 683 | { 684 | if (!prev_name || strncmp (prev_name, pfreq->CNAME(ifr_name), IFNAMSIZ) != 0) 685 | { 686 | VALUE ifname = rb_str_new2(pfreq->CNAME(ifr_name)); 687 | if(!rb_ary_includes(result, ifname)) 688 | rb_ary_push(result, ifname); 689 | 690 | prev_name = pfreq->CNAME(ifr_name); 691 | } 692 | } 693 | 694 | free (ifc.CNAME(ifc_buf)); 695 | close (fd); 696 | 697 | #endif // 698 | 699 | return result; 700 | } 701 | 702 | //This function is usefull only under windows to retrieve some additionnal interfaces informations 703 | VALUE 704 | rbnetifaces_s_interface_info (VALUE self, VALUE dev) 705 | { 706 | VALUE result = Qnil; 707 | 708 | #if defined(WIN32) 709 | 710 | PIP_ADAPTER_INFO pAdapterInfo = NULL; 711 | PIP_ADAPTER_INFO pInfo = NULL; 712 | ULONG ulBufferLength = 0; 713 | DWORD dwRet; 714 | 715 | // First, retrieve the adapter information 716 | do { 717 | dwRet = GetAdaptersInfo(pAdapterInfo, &ulBufferLength); 718 | 719 | if (dwRet == ERROR_BUFFER_OVERFLOW) 720 | { 721 | if (pAdapterInfo) 722 | free (pAdapterInfo); 723 | pAdapterInfo = (PIP_ADAPTER_INFO)malloc (ulBufferLength); 724 | 725 | if (!pAdapterInfo) 726 | { 727 | rb_raise(rb_eRuntimeError, "Unknow error at OS level"); 728 | } 729 | } 730 | } while (dwRet == ERROR_BUFFER_OVERFLOW); 731 | 732 | // If we failed, then fail in Ruby too 733 | if (dwRet != ERROR_SUCCESS && dwRet != ERROR_NO_DATA) 734 | { 735 | if (pAdapterInfo) 736 | free (pAdapterInfo); 737 | 738 | rb_raise(rb_eRuntimeError, "Unknow error at OS level"); 739 | return Qnil; 740 | } 741 | if (dwRet == ERROR_NO_DATA) 742 | { 743 | free (pAdapterInfo); 744 | return result; 745 | } 746 | 747 | for (pInfo = pAdapterInfo; pInfo; pInfo = pInfo->Next) 748 | { 749 | // registry name location 750 | const char* prefix = "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\"; 751 | const char* sufix = "\\Connection"; 752 | int prefix_len, sufix_len, adaptername_len; 753 | char* keypath = NULL; 754 | HKEY hKey; 755 | LONG lRet = 0; 756 | LPBYTE buffer = NULL; 757 | DWORD dwSize = 0; 758 | 759 | //dev is the iface GUID on windows with "\\Device\\NPF_" prefix 760 | int cmpAdapterNamelen = (MAX_ADAPTER_NAME_LENGTH + 4) + 12; 761 | char cmpAdapterName[cmpAdapterNamelen]; 762 | int AdapterName_len = strlen(pInfo->AdapterName); 763 | memset(cmpAdapterName, 0x00, cmpAdapterNamelen); 764 | strncpy(cmpAdapterName, "\\Device\\NPF_", 12); 765 | strncpy(cmpAdapterName + 12, pInfo->AdapterName, AdapterName_len); 766 | if (strcmp (cmpAdapterName, StringValuePtr(dev)) != 0) 767 | continue; 768 | 769 | result = rb_hash_new(); 770 | rb_hash_aset(result, rb_str_new2("description"), rb_str_new2(pInfo->Description)); 771 | rb_hash_aset(result, rb_str_new2("guid"), rb_str_new2(pInfo->AdapterName)); 772 | 773 | // Get the name from the registry 774 | prefix_len = strlen(prefix); 775 | sufix_len = strlen(sufix); 776 | adaptername_len = strlen(pInfo->AdapterName); 777 | keypath = malloc(prefix_len + sufix_len + adaptername_len + 1); 778 | memset(keypath, 0x00, prefix_len + sufix_len + adaptername_len + 1); 779 | strncpy(keypath, prefix, prefix_len); 780 | strncpy(keypath + prefix_len, pInfo->AdapterName, adaptername_len); 781 | strncpy(keypath + prefix_len + adaptername_len, sufix, sufix_len); 782 | 783 | if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keypath, 0, KEY_READ, &hKey) == ERROR_SUCCESS) 784 | { 785 | // obtain current value size 786 | lRet = RegQueryValueEx(hKey, "Name", NULL, NULL, NULL, &dwSize); 787 | if (dwSize > 0 && ERROR_SUCCESS == lRet) 788 | { 789 | buffer = malloc((dwSize * sizeof(BYTE)) + 4); 790 | memset(buffer, 0x00, (dwSize * sizeof(BYTE)) + 4); 791 | lRet = RegQueryValueEx(hKey, "Name", NULL, NULL, buffer, &dwSize); 792 | if (ERROR_SUCCESS == lRet) 793 | { 794 | rb_hash_aset(result, rb_str_new2("name"), rb_str_new2(buffer)); 795 | } 796 | else 797 | { 798 | rb_hash_aset(result, rb_str_new2("name"), rb_str_new2("")); 799 | } 800 | free(buffer); 801 | } 802 | else 803 | { 804 | rb_hash_aset(result, rb_str_new2("name"), rb_str_new2("")); 805 | } 806 | RegCloseKey(hKey); 807 | } 808 | else 809 | { 810 | rb_hash_aset(result, rb_str_new2("name"), rb_str_new2("")); 811 | } 812 | free(keypath); 813 | } 814 | free (pAdapterInfo); 815 | #endif 816 | 817 | return result; 818 | } 819 | 820 | VALUE rb_cNetworkInterface; 821 | void 822 | Init_network_interface_ext() 823 | { 824 | rb_cNetworkInterface = rb_define_module("NetworkInterface"); 825 | rb_define_module_function(rb_cNetworkInterface, "interfaces", rbnetifaces_s_interfaces, 0); 826 | rb_define_module_function(rb_cNetworkInterface, "addresses", rbnetifaces_s_addresses, 1); 827 | rb_define_module_function(rb_cNetworkInterface, "interface_info", rbnetifaces_s_interface_info, 1); 828 | 829 | //constants 830 | // Address families (auto-detect using #ifdef) 831 | 832 | #ifdef AF_INET 833 | rb_define_const(rb_cNetworkInterface, "AF_INET", INT2NUM(AF_INET)); 834 | #endif 835 | #ifdef AF_INET6 836 | rb_define_const(rb_cNetworkInterface, "AF_INET6", INT2NUM(AF_INET6)); 837 | #endif 838 | #ifdef AF_UNSPEC 839 | rb_define_const(rb_cNetworkInterface, "AF_UNSPEC", INT2NUM(AF_UNSPEC)); 840 | #endif 841 | #ifdef AF_UNIX 842 | rb_define_const(rb_cNetworkInterface, "AF_UNIX", INT2NUM(AF_UNIX)); 843 | #endif 844 | #ifdef AF_FILE 845 | rb_define_const(rb_cNetworkInterface, "AF_FILE", INT2NUM(AF_FILE)); 846 | #endif 847 | #ifdef AF_AX25 848 | rb_define_const(rb_cNetworkInterface, "AF_AX25", INT2NUM(AF_AX25)); 849 | #endif 850 | #ifdef AF_IMPLINK 851 | rb_define_const(rb_cNetworkInterface, "AF_IMPLINK", INT2NUM(AF_IMPLINK)); 852 | #endif 853 | #ifdef AF_PUP 854 | rb_define_const(rb_cNetworkInterface, "AF_PUP", INT2NUM(AF_PUP)); 855 | #endif 856 | #ifdef AF_CHAOS 857 | rb_define_const(rb_cNetworkInterface, "AF_CHAOS", INT2NUM(AF_CHAOS)); 858 | #endif 859 | #ifdef AF_NS 860 | rb_define_const(rb_cNetworkInterface, "AF_NS", INT2NUM(AF_NS)); 861 | #endif 862 | #ifdef AF_ISO 863 | rb_define_const(rb_cNetworkInterface, "AF_ISO", INT2NUM(AF_ISO)); 864 | #endif 865 | #ifdef AF_ECMA 866 | rb_define_const(rb_cNetworkInterface, "AF_ECMA", INT2NUM(AF_ECMA)); 867 | #endif 868 | #ifdef AF_DATAKIT 869 | rb_define_const(rb_cNetworkInterface, "AF_DATAKIT", INT2NUM(AF_DATAKIT)); 870 | #endif 871 | #ifdef AF_CCITT 872 | rb_define_const(rb_cNetworkInterface, "AF_CCITT", INT2NUM(AF_CCITT)); 873 | #endif 874 | #ifdef AF_SNA 875 | rb_define_const(rb_cNetworkInterface, "AF_SNA", INT2NUM(AF_SNA)); 876 | #endif 877 | #ifdef AF_DECnet 878 | rb_define_const(rb_cNetworkInterface, "AF_DECnet", INT2NUM(AF_DECnet)); 879 | #endif 880 | #ifdef AF_DLI 881 | rb_define_const(rb_cNetworkInterface, "AF_DLI", INT2NUM(AF_DLI)); 882 | #endif 883 | #ifdef AF_LAT 884 | rb_define_const(rb_cNetworkInterface, "AF_LAT", INT2NUM(AF_LAT)); 885 | #endif 886 | #ifdef AF_HYLINK 887 | rb_define_const(rb_cNetworkInterface, "AF_HYLINK", INT2NUM(AF_HYLINK)); 888 | #endif 889 | #ifdef AF_APPLETALK 890 | rb_define_const(rb_cNetworkInterface, "AF_APPLETALK", INT2NUM(AF_APPLETALK)); 891 | #endif 892 | #ifdef AF_ROUTE 893 | rb_define_const(rb_cNetworkInterface, "AF_ROUTE", INT2NUM(AF_ROUTE)); 894 | #endif 895 | #ifdef AF_LINK 896 | rb_define_const(rb_cNetworkInterface, "AF_LINK", INT2NUM(AF_LINK)); 897 | #endif 898 | #ifdef AF_PACKET 899 | rb_define_const(rb_cNetworkInterface, "AF_PACKET", INT2NUM(AF_PACKET)); 900 | #endif 901 | #ifdef AF_COIP 902 | rb_define_const(rb_cNetworkInterface, "AF_COIP", INT2NUM(AF_COIP)); 903 | #endif 904 | #ifdef AF_CNT 905 | rb_define_const(rb_cNetworkInterface, "AF_CNT", INT2NUM(AF_CNT)); 906 | #endif 907 | #ifdef AF_IPX 908 | rb_define_const(rb_cNetworkInterface, "AF_IPX", INT2NUM(AF_IPX)); 909 | #endif 910 | #ifdef AF_SIP 911 | rb_define_const(rb_cNetworkInterface, "AF_SIP", INT2NUM(AF_SIP)); 912 | #endif 913 | #ifdef AF_NDRV 914 | rb_define_const(rb_cNetworkInterface, "AF_NDRV", INT2NUM(AF_NDRV)); 915 | #endif 916 | #ifdef AF_ISDN 917 | rb_define_const(rb_cNetworkInterface, "AF_ISDN", INT2NUM(AF_ISDN)); 918 | #endif 919 | #ifdef AF_NATM 920 | rb_define_const(rb_cNetworkInterface, "AF_NATM", INT2NUM(AF_NATM)); 921 | #endif 922 | #ifdef AF_SYSTEM 923 | rb_define_const(rb_cNetworkInterface, "AF_SYSTEM", INT2NUM(AF_SYSTEM)); 924 | #endif 925 | #ifdef AF_NETBIOS 926 | rb_define_const(rb_cNetworkInterface, "AF_NETBIOS", INT2NUM(AF_NETBIOS)); 927 | #endif 928 | #ifdef AF_NETBEUI 929 | rb_define_const(rb_cNetworkInterface, "AF_NETBEUI", INT2NUM(AF_NETBEUI)); 930 | #endif 931 | #ifdef AF_PPP 932 | rb_define_const(rb_cNetworkInterface, "AF_PPP", INT2NUM(AF_PPP)); 933 | #endif 934 | #ifdef AF_ATM 935 | rb_define_const(rb_cNetworkInterface, "AF_ATM", INT2NUM(AF_ATM)); 936 | #endif 937 | #ifdef AF_ATMPVC 938 | rb_define_const(rb_cNetworkInterface, "AF_ATMPVC", INT2NUM(AF_ATMPVC)); 939 | #endif 940 | #ifdef AF_ATMSVC 941 | rb_define_const(rb_cNetworkInterface, "AF_ATMSVC", INT2NUM(AF_ATMSVC)); 942 | #endif 943 | #ifdef AF_NETGRAPH 944 | rb_define_const(rb_cNetworkInterface, "AF_NETGRAPH", INT2NUM(AF_NETGRAPH)); 945 | #endif 946 | #ifdef AF_VOICEVIEW 947 | rb_define_const(rb_cNetworkInterface, "AF_VOICEVIEW", INT2NUM(AF_VOICEVIEW)); 948 | #endif 949 | #ifdef AF_FIREFOX 950 | rb_define_const(rb_cNetworkInterface, "AF_FIREFOX", INT2NUM(AF_FIREFOX)); 951 | #endif 952 | #ifdef AF_UNKNOWN1 953 | rb_define_const(rb_cNetworkInterface, "AF_UNKNOWN1", INT2NUM(AF_UNKNOWN1)); 954 | #endif 955 | #ifdef AF_BAN 956 | rb_define_const(rb_cNetworkInterface, "AF_BAN", INT2NUM(AF_BAN)); 957 | #endif 958 | #ifdef AF_CLUSTER 959 | rb_define_const(rb_cNetworkInterface, "AF_CLUSTER", INT2NUM(AF_CLUSTER)); 960 | #endif 961 | #ifdef AF_12844 962 | rb_define_const(rb_cNetworkInterface, "AF_12844", INT2NUM(AF_12844)); 963 | #endif 964 | #ifdef AF_IRDA 965 | rb_define_const(rb_cNetworkInterface, "AF_IRDA", INT2NUM(AF_IRDA)); 966 | #endif 967 | #ifdef AF_NETDES 968 | rb_define_const(rb_cNetworkInterface, "AF_NETDES", INT2NUM(AF_NETDES)); 969 | #endif 970 | #ifdef AF_NETROM 971 | rb_define_const(rb_cNetworkInterface, "AF_NETROM", INT2NUM(AF_NETROM)); 972 | #endif 973 | #ifdef AF_BRIDGE 974 | rb_define_const(rb_cNetworkInterface, "AF_BRIDGE", INT2NUM(AF_BRIDGE)); 975 | #endif 976 | #ifdef AF_X25 977 | rb_define_const(rb_cNetworkInterface, "AF_X25", INT2NUM(AF_X25)); 978 | #endif 979 | #ifdef AF_ROSE 980 | rb_define_const(rb_cNetworkInterface, "AF_ROSE", INT2NUM(AF_ROSE)); 981 | #endif 982 | #ifdef AF_SECURITY 983 | rb_define_const(rb_cNetworkInterface, "AF_SECURITY", INT2NUM(AF_SECURITY)); 984 | #endif 985 | #ifdef AF_KEY 986 | rb_define_const(rb_cNetworkInterface, "AF_KEY", INT2NUM(AF_KEY)); 987 | #endif 988 | #ifdef AF_NETLINK 989 | rb_define_const(rb_cNetworkInterface, "AF_NETLINK", INT2NUM(AF_NETLINK)); 990 | #endif 991 | #ifdef AF_ASH 992 | rb_define_const(rb_cNetworkInterface, "AF_ASH", INT2NUM(AF_ASH)); 993 | #endif 994 | #ifdef AF_ECONET 995 | rb_define_const(rb_cNetworkInterface, "AF_ECONET", INT2NUM(AF_ECONET)); 996 | #endif 997 | #ifdef AF_PPPOX 998 | rb_define_const(rb_cNetworkInterface, "AF_PPPOX", INT2NUM(AF_PPPOX)); 999 | #endif 1000 | #ifdef AF_WANPIPE 1001 | rb_define_const(rb_cNetworkInterface, "AF_WANPIPE", INT2NUM(AF_WANPIPE)); 1002 | #endif 1003 | #ifdef AF_BLUETOOTH 1004 | rb_define_const(rb_cNetworkInterface, "AF_BLUETOOTH", INT2NUM(AF_BLUETOOTH)); 1005 | #endif 1006 | 1007 | } 1008 | 1009 | -------------------------------------------------------------------------------- /ext/network_interface_ext/netifaces.h: -------------------------------------------------------------------------------- 1 | #ifndef WIN32 2 | 3 | # include 4 | # include 5 | # include 6 | # include 7 | 8 | # if HAVE_SOCKET_IOCTLS 9 | # include 10 | # include 11 | # include 12 | #if defined(__sun) 13 | #include 14 | #include 15 | #include 16 | #endif 17 | # endif /* HAVE_SOCKET_IOCTLS */ 18 | 19 | /* For logical interfaces support we convert all names to same name prefixed with l */ 20 | #if HAVE_SIOCGLIFNUM 21 | #define CNAME(x) l##x 22 | #else 23 | #define CNAME(x) x 24 | #endif 25 | 26 | #if HAVE_NET_IF_DL_H 27 | # include 28 | #endif 29 | 30 | /* For Linux, include all the sockaddr 31 | definitions we can lay our hands on. */ 32 | #if !HAVE_SOCKADDR_SA_LEN 33 | +# include 34 | # if HAVE_NETASH_ASH_H 35 | # include 36 | # endif 37 | # if HAVE_NETATALK_AT_H 38 | # include 39 | # endif 40 | # if HAVE_NETAX25_AX25_H 41 | # include 42 | # endif 43 | # if HAVE_NETECONET_EC_H 44 | # include 45 | # endif 46 | # if HAVE_NETIPX_IPX_H 47 | # include 48 | # endif 49 | # if HAVE_NETPACKET_PACKET_H 50 | # include 51 | # endif 52 | # if HAVE_NETROSE_ROSE_H 53 | # include 54 | # endif 55 | # if HAVE_LINUX_IRDA_H 56 | # include 57 | # endif 58 | # if HAVE_LINUX_ATM_H 59 | # include 60 | # endif 61 | # if HAVE_LINUX_LLC_H 62 | # include 63 | # endif 64 | # if HAVE_LINUX_TIPC_H 65 | # include 66 | # endif 67 | # if HAVE_LINUX_DN_H 68 | # include 69 | # endif 70 | 71 | /* Map address families to sizes of sockaddr structs */ 72 | static int af_to_len(int af) 73 | { 74 | switch (af) 75 | { 76 | case AF_INET: return sizeof (struct sockaddr_in); 77 | #if defined(AF_INET6) && HAVE_SOCKADDR_IN6 78 | case AF_INET6: return sizeof (struct sockaddr_in6); 79 | #endif 80 | #if defined(AF_AX25) && HAVE_SOCKADDR_AX25 81 | # if defined(AF_NETROM) 82 | case AF_NETROM: /* I'm assuming this is carried over x25 */ 83 | # endif 84 | case AF_AX25: return sizeof (struct sockaddr_ax25); 85 | #endif 86 | #if defined(AF_IPX) && HAVE_SOCKADDR_IPX 87 | case AF_IPX: return sizeof (struct sockaddr_ipx); 88 | #endif 89 | #if defined(AF_APPLETALK) && HAVE_SOCKADDR_AT 90 | case AF_APPLETALK: return sizeof (struct sockaddr_at); 91 | #endif 92 | #if defined(AF_ATMPVC) && HAVE_SOCKADDR_ATMPVC 93 | case AF_ATMPVC: return sizeof (struct sockaddr_atmpvc); 94 | #endif 95 | #if defined(AF_ATMSVC) && HAVE_SOCKADDR_ATMSVC 96 | case AF_ATMSVC: return sizeof (struct sockaddr_atmsvc); 97 | #endif 98 | #if defined(AF_X25) && HAVE_SOCKADDR_X25 99 | case AF_X25: return sizeof (struct sockaddr_x25); 100 | #endif 101 | #if defined(AF_ROSE) && HAVE_SOCKADDR_ROSE 102 | case AF_ROSE: return sizeof (struct sockaddr_rose); 103 | #endif 104 | #if defined(AF_DECnet) && HAVE_SOCKADDR_DN 105 | case AF_DECnet: return sizeof (struct sockaddr_dn); 106 | #endif 107 | #if defined(AF_PACKET) && HAVE_SOCKADDR_LL 108 | case AF_PACKET: return sizeof (struct sockaddr_ll); 109 | #endif 110 | #if defined(AF_ASH) && HAVE_SOCKADDR_ASH 111 | case AF_ASH: return sizeof (struct sockaddr_ash); 112 | #endif 113 | #if defined(AF_ECONET) && HAVE_SOCKADDR_EC 114 | case AF_ECONET: return sizeof (struct sockaddr_ec); 115 | #endif 116 | #if defined(AF_IRDA) && HAVE_SOCKADDR_IRDA 117 | case AF_IRDA: return sizeof (struct sockaddr_irda); 118 | #endif 119 | } 120 | return sizeof (struct sockaddr); 121 | } 122 | 123 | #define SA_LEN(sa) af_to_len(sa->sa_family) 124 | #if HAVE_SIOCGLIFNUM 125 | #define SS_LEN(sa) af_to_len(sa->ss_family) 126 | #else 127 | #define SS_LEN(sa) SA_LEN(sa) 128 | #endif 129 | #else 130 | //remove a warning on openbsd 131 | #ifndef SA_LEN 132 | #define SA_LEN(sa) sa->sa_len 133 | #endif 134 | #endif /* !HAVE_SOCKADDR_SA_LEN */ 135 | 136 | # if HAVE_GETIFADDRS 137 | # include 138 | # endif /* HAVE_GETIFADDRS */ 139 | 140 | # if !HAVE_GETIFADDRS && (!HAVE_SOCKET_IOCTLS || !HAVE_SIOCGIFCONF) 141 | /* If the platform doesn't define, what we need, barf. If you're seeing this, 142 | it means you need to write suitable code to retrieve interface information 143 | on your system. */ 144 | # error You need to add code for your platform. 145 | # endif 146 | 147 | #else /* defined(WIN32) */ 148 | 149 | #include 150 | #include 151 | #include 152 | 153 | #endif /* defined(WIN32) */ 154 | 155 | #ifndef TRUE 156 | #define TRUE 1 157 | #endif 158 | 159 | #ifndef FALSE 160 | #define FALSE 0 161 | #endif 162 | 163 | /* On systems without AF_LINK (Windows, for instance), define it anyway, but 164 | give it a crazy value. On Linux, which has AF_PACKET but not AF_LINK, 165 | define AF_LINK as the latter instead. */ 166 | #ifndef AF_LINK 167 | # ifdef AF_PACKET 168 | # define AF_LINK AF_PACKET 169 | # else 170 | # define AF_LINK -1000 171 | # endif 172 | # define HAVE_AF_LINK 0 173 | #else 174 | # define HAVE_AF_LINK 1 175 | #endif 176 | 177 | 178 | //Prototypes 179 | //Get a list of the adresses for a network interface 180 | VALUE rbnetifaces_s_addresses (VALUE class, VALUE dev); 181 | //Get a list of the network interfaces 182 | VALUE rbnetifaces_s_interfaces (VALUE self); 183 | //This function is usefull only under windows to retrieve some additionnal interfaces informations 184 | VALUE rbnetifaces_s_interface_info (VALUE self, VALUE dev); 185 | 186 | void Init_network_interface_ext(); 187 | -------------------------------------------------------------------------------- /lib/network_interface.rb: -------------------------------------------------------------------------------- 1 | require 'network_interface/version' 2 | 3 | module NetworkInterface 4 | end 5 | 6 | require 'network_interface_ext' 7 | -------------------------------------------------------------------------------- /lib/network_interface/version.rb: -------------------------------------------------------------------------------- 1 | module NetworkInterface 2 | VERSION = "0.0.1" 3 | end 4 | -------------------------------------------------------------------------------- /network_interface.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'network_interface/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "network_interface" 8 | spec.version = NetworkInterface::VERSION 9 | spec.authors = ["Brandon Turner", "Lance Sanchez"] 10 | spec.email = ["lance.sanchez@rapid7.com", "brandon_turner@rapid7.com"] 11 | spec.summary = "A cross platform gem to help get network interface information" 12 | spec.description = %q{ 13 | This gem was originally added to the Metasploit Pcaprub gem. It's been spun 14 | out into its own gem for anyone who might want to programmatically get 15 | information on their network interfaces. } 16 | spec.homepage = "https://github.com/rapid7/network_interface" 17 | spec.license = "MIT" 18 | 19 | spec.files = `git ls-files`.split($/) 20 | spec.extensions = ['ext/network_interface_ext/extconf.rb'] 21 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 22 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) 23 | spec.require_paths = ["lib"] 24 | 25 | spec.add_development_dependency "bundler", "~> 1.3" 26 | spec.add_development_dependency "rake" 27 | spec.add_development_dependency "rake-compiler", ">= 0" 28 | spec.add_development_dependency "rspec" 29 | end 30 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/data/data/com.termux/files/usr/bin/bash 2 | #Instalation of searchsploit (exploitdb) 3 | function ssplt() { 4 | 5 | # check if searchsploit exists 6 | #which searchsploit > /dev/null 2>&1 7 | #if [ "$?" -eq "0" ]; then 8 | #echo -e $green "[ ✔ ] Searchsploit......................[ found ]" 9 | #echo "searchsploit" | tee -a "$config" "$log" > /dev/null 2>&1 10 | #echo "Searchsploit -> OK" >> "$inst" 11 | #sleep 1 12 | #else 13 | #echo -e $red "[ X ] searchsploit -> not found" 14 | #echo "" 15 | #echo -e $okegreen "Select one of the options bellow" 16 | #echo -e $orange "+-------------------------------------------------+" 17 | #echo -e $orange "|$white [$okegreen 1$white ]$yellow Setup Searchsploit Path Manually$orange |" 18 | #echo -e $orange "|$white [$okegreen 2$white ]$yellow Install Searchsploit from Kali Repository$orange |" 19 | #echo -e $orange "+-------------------------------------------------+" 20 | #echo "" 21 | #echo -ne $okegreen "Option : ";tput sgr0 22 | #read q1 23 | #case $q1 in 24 | 25 | #1) 26 | #echo "" 27 | #echo -e $green "Enter The Path of your Searchsploit instalation" 28 | #echo -e $cyan "ex : /opt/searchsploit/searchsploit" 29 | #echo "" 30 | #echo -ne $green "PATH : ";tput sgr0 31 | #read sspp 32 | #if [ ! -f $sspp ] 33 | #then 34 | #echo "" 35 | #echo -e $red "It was not possible to found searchsploit executable in : $sspp" 36 | #echo "" 37 | #echo -e $green "Make sure you write the right path of your instalation" 38 | #echo "" 39 | #echo -e $okegreen "Press [ENTER] key to try again ." 40 | #read cont 41 | #ssplt 42 | #else 43 | #echo "bash $sspp" | tee -a "$config" "$log" > /dev/null 2>&1 44 | #echo "Searchsploit -> OK" >> "$inst" 45 | #fi 46 | #;; 47 | 48 | #ok 49 | #2) 50 | #echo -e $yellow "[ ! ] Installing Searchsploit " 51 | #xterm -T "☣ INSTALL SEARCHSPLOIT ☣" -geometry 100x30 -e "sudo apt-get install exploitdb --force-yes -y" 52 | #which searchsploit > /dev/null 2>&1 53 | #if [ "$?" -eq "0" ]; then 54 | #echo -e $green "[ ✔ ] Searchsploit" 55 | #echo "searchsploit" | tee -a "$config" "$log" > /dev/null 2>&1 56 | #echo "Searchsploit -> OK" >> "$inst" 57 | #else 58 | #echo "0" > "$stp" 59 | #echo "Searchsploit -> Not OK" >> "$inst" 60 | #fi 61 | #;; 62 | #*) 63 | #ssplt 64 | #;; 65 | #esac 66 | #fi 67 | #echo "" 68 | #Go check the check file exists and read its value 69 | #chk=$path/logs/check 70 | #if [ -f "$chk" ] 71 | #then 72 | #ct=`sed -n 1p $chk` 73 | #if value of check is 0 theen some package was not installed sucefully 74 | #if [ "$ct" == "0" ]; then 75 | #clear 76 | #echo -e $red "Fatrat was not able to install some packages" 77 | #echo "" 78 | #echo -e $blue "Reactivating your original repositories" 79 | #rm -f /etc/apt/sources.list 80 | #mv /etc/apt/sources.list.backup /etc/apt/sources.list 81 | #now we can remove the emergency backup securely 82 | #rm -f /etc/apt/sources.list.fatrat 83 | #apt-get clean 84 | #xterm -T "☣ UPDATE YOUR REPO ☣" -geometry 100x30 -e "sudo apt-get update " 85 | #clear 86 | #rm -rf "$config" >/dev/null 2>&1 87 | # Currently building the diagnostic script 88 | #echo -e $okegreen "Starting diagnostics" 89 | #chmod +x diag.sh > /dev/null 2>&1 90 | #./diag.sh 91 | 92 | #Display to user the install.log file and inform him what to do 93 | #echo "Was not possible to install The Packages Labeled (Not Ok) in this list above" >> "$inst" 94 | #echo "Try : (apt-get remove --purge && apt-get autoremove && apt-get install -f)" >> "$inst" 95 | #echo "before running fatrat setup script again" >> "$inst" 96 | #cat "$inst" 97 | #exit 98 | #elif [ "$ct" == "1" ]; then 99 | #echo "" 100 | #value in check file is 1 , then everything is ok , delete install.log file and proceed to finish setup 101 | #rm -rf "$inst" >/dev/null 2>&1 102 | #fi 103 | #else 104 | #in case value in check file is not 0 or 1 then something is wrong 105 | #echo -e $okegreen "Something went very wrong , execute ./setup.sh again" 106 | #rm -rf "$config" >/dev/null 2>&1 107 | #echo "" 108 | #echo "Was not possible to install The Packages Labeled (Not Ok) in this list above" >> "$inst" 109 | #echo "Try : (apt-get remove --purge && apt-get autoremove && apt-get install -f)" >> "$inst" 110 | #echo "before running fatrat setup script again" >> "$inst" 111 | #echo "" >> "$inst" 112 | #echo "***********Your current sources.list***************" 113 | #sclst=`cat /etc/apt/sources.list` 114 | #echo $sclst >> "$inst" 115 | #echo "***************Finish sources.list*****************" >> "$inst" 116 | dist=`uname -a` 117 | echo "" >> "$inst" 118 | echo "Your linux distribution :" >> "$inst" 119 | echo $dist >> "$inst" 120 | cat "$inst" 121 | echo -e $lightgreen "This log file can be found in : $inst " 122 | exit 123 | #fi 124 | } 125 | 126 | #function bkf() { 127 | # Check if backdoor-factory exists 128 | 129 | #which backdoor-factory > /dev/null 2>&1 130 | #if [ "$?" -eq "0" ]; then 131 | #echo -e $green "[ ✔ ] Backdoor-Factory..................[ found ]" 132 | #echo "backdoor-factory" | tee -a "$config" "$log" > /dev/null 2>&1 133 | #echo "Backdoor-Factory -> OK" >> "$inst" 134 | #sleep 1 135 | #ssplt 136 | #else 137 | #echo -e $red "[ X ] backdoor-factory -> not found " 138 | #echo "" 139 | 140 | #echo "" 141 | #echo -e $green "Select one of the options bellow" 142 | #echo -e $orange "+-----------------------------------------------------+" 143 | #echo -e $orange "|$white [$okegreen 1$white ]$yellow Setup Backdoor-Factory Path Manually$orange |" 144 | #echo -e $orange "|$white [$okegreen 2$white ]$yellow Install Backdoor-Factory from Kali Repository$orange |" 145 | #echo -e $orange "+-----------------------------------------------------+" 146 | #echo "" 147 | #echo -ne $green "Option : ";tput sgr0 148 | #read q2 149 | #case $q2 in 150 | 151 | #1) 152 | #echo "" 153 | #echo -e $green "Enter The Path of your backdoor-factory instalation" 154 | #echo -e $cyan "ex : /opt/backdoor-factory/backdoor.py" 155 | #echo "" 156 | #echo -ne $green "PATH : ";tput sgr0 157 | #read msp 158 | #bkdf=$msp 159 | #if [ ! -f $bkdf ] 160 | #then 161 | #echo "" 162 | #echo -e $red "It was not possible to found backdoor-factory executable in : $bkdf" 163 | #echo "" 164 | #echo -e $green "Make sure you write the right path of your instalation" 165 | #echo "" 166 | #echo -e $green "Press [ENTER] key to try again ." 167 | #read cont 168 | #bkf 169 | #fi 170 | #echo "python2 $bkdf" | tee -a "$config" "$log" > /dev/null 2>&1 171 | #echo "Backdoor-factory -> OK" >> "$inst" 172 | #ssplt 173 | #;; 174 | 175 | #2) 176 | #echo -e $yellow "[ ! ] Installing backdoor-factory " 177 | #xterm -T "☣ INSTALL BACKDOOR-FACTORY ☣" -geometry 100x30 -e "sudo apt-get install backdoor-factory --force-yes -y" 178 | #which backdoor-factory > /dev/null 2>&1 179 | #if [ "$?" -eq "0" ]; then 180 | #echo -e $green "[ ✔ ] Backdoor-Factory -> OK" 181 | #echo "backdoor-factory" | tee -a "$config" "$log" > /dev/null 2>&1 182 | #echo "Backdoor-factory -> OK" >> "$inst" 183 | #else 184 | #echo -e $red "[ X ] backdoor-factory" 185 | #echo "0" > "$stp" 186 | #echo "Backdoor-factory -> Not OK" >> "$inst" 187 | #ssplt 188 | #fi 189 | #;; 190 | 191 | #*) 192 | #bkf 193 | #;; 194 | #esac 195 | #fi 196 | #} 197 | 198 | function mtspl() { 199 | # check if metasploit-framework its installed 200 | which msfconsole > /dev/null 2>&1 201 | if [ "$?" -eq "0" ]; then 202 | echo -e $green "[ ✔ ] Metasploit-Framework..............[ found ]" 203 | echo "msfconsole" | tee -a "$config" "$log" >> /dev/null 2>&1 204 | echo "msfvenom" | tee -a "$config" "$log" >> /dev/null 2>&1 205 | echo "Metasploit -> OK" >> "$inst" 206 | sleep 1 207 | bkf 208 | else 209 | echo -e $red "[ X ] metasploit-framework -> not found " 210 | 211 | # Providing manual input to user in case metasploit was installed from git and is not on system path 212 | 213 | echo "" 214 | echo -e $okegreen "Select one of the options bellow" 215 | echo -e $orange "+---------------------------------------------------------+" 216 | echo -e $orange "|$white [$okegreen 1$white ]$yellow Setup Metasploit Framework Path Manually$orange |" 217 | echo -e $orange "|$white [$okegreen 2$white ]$yellow Install Metasploit Framework from Kali Repository$orange |" 218 | echo -e $orange "+---------------------------------------------------------+" 219 | echo "" 220 | echo -ne $okegreen "Option : ";tput sgr0 221 | read q3 222 | case $q3 in 223 | 1) 224 | echo "" 225 | echo -e $green "Enter The Path of your metasploit instalation" 226 | echo -e $cyan "ex : /opt/metasploit-framework" 227 | echo "" 228 | echo -ne $green "PATH : ";tput sgr0 229 | read msp 230 | msfc=$msp/msfconsole 231 | msfv=$msp/msfvenom 232 | if [ ! -f $msfc ] 233 | then 234 | echo "" 235 | echo -e $red "It was not possible to found msfconsole in : $msfc" 236 | echo "" 237 | echo -e $green "Make sure you write the right path of your instalation" 238 | echo "" 239 | echo -e $green "Press [ENTER] key to try again ." 240 | read cont 241 | mtspl 242 | fi 243 | if [ ! -f $msfv ] 244 | then 245 | echo "" 246 | echo -e $red "It was not possible to found msfvenom in : $msfv" 247 | echo "" 248 | echo -e $green "Make sure you write the right path of your instalation" 249 | echo "" 250 | echo -e $green "Press [ENTER] key to try again ." 251 | read cont 252 | mtspl 253 | fi 254 | #Creation of symlinks to metasploit manual path in /usr/local/sbin to avoid changes in fatrat scripts 255 | 256 | unlink /usr/local/sbin/msfconsole > /dev/null 2>&1 257 | unlink /usr/local/sbin/msfvenom > /dev/null 2>&1 258 | ln -s $msfc /usr/local/sbin/msfconsole > /dev/null 2>&1 259 | ln -s $msfv /usr/local/sbin/msfvenom > /dev/null 2>&1 260 | echo "msfconsole" | tee -a "$config" "$log" > /dev/null 2>&1 261 | echo "msfvenom" | tee -a "$config" "$log" > /dev/null 2>&1 262 | echo "Metasploit -> OK" >> "$inst" 263 | bkf 264 | ;; 265 | 266 | 2) 267 | echo -e $yellow "[ ! ] Installing Metasploit-Framework " 268 | xterm -T "☣ INSTALL METASPLOIT-FRAMEWORK ☣" -geometry 100x30 -e "sudo apt-get install metasploit-framework --force-yes -y" 269 | which msfconsole > /dev/null 2>&1 270 | if [ "$?" -eq "0" ]; then 271 | echo -e $green "[ ✔ ] Metasploit (msfconsole) -> OK" 272 | echo "msfconsole" | tee -a "$config" "$log" > /dev/null 2>&1 273 | echo "Metasploit (msfconsole) -> OK" >> "$inst" 274 | else 275 | echo -e $red "[ x ] Metasploit (msfconsole)" 276 | echo "Metasploit (msfconsole) -> Not OK" >> "$inst" 277 | echo "0" > "$stp" 278 | fi 279 | which msfvenom > /dev/null 2>&1 280 | if [ "$?" -eq "0" ]; then 281 | echo -e $green "[ ✔ ] Metasploit (msfvenom) -> OK" 282 | echo "msfvenom" | tee -a "$config" "$log" > /dev/null 2>&1 283 | echo "Metasploit (msfvenom) -> OK" >> "$inst" 284 | else 285 | echo -e $red "[ x ] Metasploit (msfvenom)" 286 | echo "0" > "$stp" 287 | echo "Metasploit (msfvenom) -> Not OK" >> "$inst" 288 | fi 289 | bkf 290 | ;; 291 | *) 292 | mtspl 293 | ;; 294 | esac 295 | fi 296 | } 297 | 298 | 299 | function cont() { 300 | 301 | stp="logs/check" 302 | #remove any previous check file from previous attempts 303 | rm -rf "$stp" >/dev/null 2>&1 304 | #starting setup , input 1 value to check file 305 | echo "1" > "$stp" 306 | #remove any previous install.log file from previous attempts 307 | rm -rf "$inst" >/dev/null 2>&1 308 | 309 | #check if xterm is installed 310 | #which xterm > /dev/null 2>&1 311 | #if [ "$?" -eq "0" ]; then 312 | #echo -e $green "[ ✔ ] Xterm.............................[ found ]" 313 | #which xterm >> "$log" 2>&1 314 | #echo "xterm -> OK" > "$inst" 315 | #else 316 | #echo "" 317 | #echo -e $red "[ X ] Xterm -> not found! " 318 | #echo -e $yellow "[ ! ] Installing Xterm " 319 | #echo -e $green "" 320 | #sudo apt-get install xterm -y 321 | #which xterm >> "$log" 2>&1 322 | #if [ "$?" -eq "0" ]; then 323 | #echo -e $green "[ ✔ ] Xterm -> OK" 324 | #echo "Xterm -> OK" > "$inst" 325 | #else 326 | #echo -e $red "[ x ] Xterm" 327 | #echo "0" > "$stp" 328 | #echo "xterm -> Not OK" > "$inst" 329 | #fi 330 | #fi 331 | 332 | sleep 1 333 | #check if dig its installed 334 | which dig > /dev/null 2>&1 335 | if [ "$?" -eq "0" ]; then 336 | echo -e $green "[ ✔ ] Dns-Utils ........................[ found ]" 337 | which dig >> "$log" 2>&1 338 | echo "Dns-Utils -> OK" >> "$inst" 339 | else 340 | echo -e $red "[ X ] dnsutils -> not found! " 341 | echo -e $yellow "[ ! ] Installing dnsutils" 342 | echo "☣ INSTALL DNSUTILS ☣" 343 | apt-get install dnsutils -y 344 | which dig >> "$log" 2>&1 345 | if [ "$?" -eq "0" ]; then 346 | echo -e $green "[ ✔ ] Dns-Utils -> OK" 347 | echo "Dns-Utils -> OK" >> "$inst" 348 | else 349 | echo -e $red "[ x ] Dns-Utils" 350 | echo "0" > "$stp" 351 | echo "dns-utils -> Not OK" >> "$inst" 352 | fi 353 | fi 354 | sleep 1 355 | # check if gcc exists 356 | which gcc > /dev/null 2>&1 357 | if [ "$?" -eq "0" ]; then 358 | echo -e $green "[ ✔ ] Gcc compiler......................[ found ]" 359 | which gcc >> "$log" 2>&1 360 | echo "GCC -> OK" >> "$inst" 361 | else 362 | echo -e $red "[ X ] gcc compiler -> not found " 363 | echo -e $yellow "[ ! ] Installing gcc " 364 | echo "☣ INSTALL GCC COMPILLER ☣" 365 | apt-get install gcc -y 366 | which gcc >> "$log" 2>&1 367 | if [ "$?" -eq "0" ]; then 368 | echo -e $green "[ ✔ ] GCC -> OK" 369 | echo "GCC -> OK" >> "$inst" 370 | else 371 | echo -e $red "[ x ] GCC" 372 | echo "0" > "$stp" 373 | echo "gcc -> Not OK" >> "$inst" 374 | fi 375 | fi 376 | sleep 1 377 | #check if apache2 exists 378 | which apache2 > /dev/null 2>&1 379 | if [ "$?" -eq "0" ]; then 380 | echo -e $green "[ ✔ ] Apache2 ..........................[ found ]" 381 | which apache2 >> "$log" 2>&1 382 | echo "Apache2 -> OK" >> "$inst" 383 | else 384 | echo -e $red "[ X ] Apache2 -> not found " 385 | echo -e $yellow "[ ! ] Installing apache2 " 386 | echo "☣ INSTALL APACHE2 ☣" 387 | apt-get install apache2 -y 388 | which apache2 >> "$log" 2>&1 389 | if [ "$?" -eq "0" ]; then 390 | echo -e $green "[ ✔ ] Apache2 -> OK" 391 | echo "Apache2 -> OK" >> "$inst" 392 | else 393 | echo -e $red "[ x ] Apache2" 394 | echo "0" > "$stp" 395 | echo "apache2 -> Not OK" >> "$inst" 396 | fi 397 | fi 398 | sleep 1 399 | #check if gnome terminal exists 400 | #added this new install option because user may be running a distro that may not have gnome terminal installed by default 401 | #gnome terminal is used in main script to run searchsploit 402 | #which gnome-terminal > /dev/null 2>&1 403 | #if [ "$?" -eq "0" ]; then 404 | #echo -e $green "[ ✔ ] Gnome Terminal....................[ found ]" 405 | #which gnome-terminal >> "$log" 2>&1 406 | #echo "Gnome Terminal -> OK" >> "$inst" 407 | #else 408 | #echo -e $red "[ X ] Gnome-terminal-> not found " 409 | #echo -e $yellow "[ ! ] Installing gnome-terminal " 410 | #xterm -T "☣ INSTALL GNOME-TERMINAL ☣" -geometry 100x30 -e "sudo apt-get install gnome-terminal -y" 411 | #which gnome-terminal >> "$log" 2>&1 412 | #if [ "$?" -eq "0" ]; then 413 | #echo -e $green "[ ✔ ] Gnome Terminal -> OK" 414 | #echo "Gnome Terminal -> OK" >> "$inst" 415 | #else 416 | #echo -e $red "[ x ] Gnome Terminal" 417 | #echo "0" > "$stp" 418 | #echo "gnome-terminal -> Not OK" >> "$inst" 419 | #fi 420 | #fi 421 | 422 | #Checking if upx compressor exists 423 | sleep 1 424 | #which upx > /dev/null 2>&1 425 | #if [ "$?" -eq "0" ]; then 426 | #echo -e $green "[ ✔ ] UPX Compressor....................[ found ]" 427 | #which upx >> "$log" 2>&1 428 | #echo "UPX -> OK" >> "$inst" 429 | #else 430 | #echo -e $red "[ X ] Upx compressor -> not found " 431 | #echo -e $yellow "[ ! ] Installing upx-compressor " 432 | #xterm -T "☣ INSTALL UPX COMPRESSOR ☣" -geometry 100x30 -e "sudo apt-get install upx-ucl -y" 433 | #which upx >> "$log" 2>&1 434 | #if [ "$?" -eq "0" ]; then 435 | #echo -e $green "[ ✔ ] UPX Compressor -> OK" 436 | #echo "UPX -> OK" >> "$inst" 437 | #else 438 | #echo -e $red "[ x ] UPX Compressor" 439 | #echo "0" > "$stp" 440 | #echo "upx-ucl -> Not OK" >> "$inst" 441 | #fi 442 | #fi 443 | #sleep 1 444 | #Checking if Ruby exists 445 | which ruby > /dev/null 2>&1 446 | if [ "$?" -eq "0" ]; then 447 | echo -e $green "[ ✔ ] Ruby..............................[ found ]" 448 | which ruby >> "$log" 2>&1 449 | echo "Ruby -> OK" >> "$inst" 450 | else 451 | echo -e $red "[ X ] Ruby -> not found " 452 | echo -e $yellow "[ ! ] Installing Ruby " 453 | echo "☣ INSTALL Ruby ☣" 454 | apt-get install ruby -y && gem install nokogiri -- --use-system-libraries 455 | which ruby >> "$log" 2>&1 456 | if [ "$?" -eq "0" ]; then 457 | echo -e $green "[ ✔ ] Ruby -> OK" 458 | echo "Ruby -> OK" >> "$inst" 459 | else 460 | echo -e $red "[ x ] Ruby" 461 | echo "0" > "$stp" 462 | echo "ruby -> Not OK" >> "$inst" 463 | fi 464 | fi 465 | sleep 1 466 | #Checking if Openssl exists 467 | which openssl > /dev/null 2>&1 468 | if [ "$?" -eq "0" ]; then 469 | echo -e $green "[ ✔ ] Openssl...........................[ found ]" 470 | which openssl >> "$log" 2>&1 471 | echo "Openssl -> OK" >> "$inst" 472 | else 473 | echo -e $red "[ X ] Openssl -> not found " 474 | echo -e $yellow "[ ! ] Installing Openssl " 475 | echo "☣ INSTALL OPENSSL ☣" 476 | apt-get install openssl openssl-tool -y 477 | which openssl >> "$log" 2>&1 478 | if [ "$?" -eq "0" ]; then 479 | echo -e $green "[ ✔ ] Openssl -> OK" 480 | echo "Openssl -> OK" >> "$inst" 481 | else 482 | echo -e $red "[ x ] Openssl" 483 | echo "0" > "$stp" 484 | echo "openssl -> Not OK" >> "$inst" 485 | fi 486 | fi 487 | sleep 1 488 | #installing dependencies for ruby script 489 | echo -e $green "[ ! ] Installing tools dependencies" 490 | echo "☣ INSTALL DEPENDENCIES ☣" 491 | apt-get install imagemagick imagemagick-dev libllvm libllvm-dev ndk-multilib libc++ python2 python2-dev -y && pip2 install names 492 | sleep 1 493 | 494 | ################################# 495 | #inputrepo 496 | ################################# 497 | 498 | #cp /etc/apt/sources.list /etc/apt/sources.list.backup # backup 499 | # Second backup created in case user stops the script after this point , then on next startup this script will 500 | # copy the already changed sources file before as backup , and user lost his original sources lists 501 | #file="/etc/apt/sources.list.fatrat" 502 | #if [ -f "$file" ] 503 | #then 504 | #echo "" 505 | #else 506 | #cp /etc/apt/sources.list /etc/apt/sources.list.fatrat 507 | #fi 508 | #rm -f /etc/apt/sources.list 509 | #touch /etc/apt/sources.list 510 | #echo 'deb http://old.kali.org/kali sana main non-free contrib' >> /etc/apt/sources.list 511 | #echo 'deb-src http://old.kali.org/kali sana main non-free contrib' >> /etc/apt/sources.list 512 | #echo 'deb http://http.kali.org/kali kali-rolling main contrib non-free' >> /etc/apt/sources.list 513 | #echo 'deb-src http://http.kali.org/kali kali-rolling main contrib non-free' >> /etc/apt/sources.list 514 | #xterm -T "☣ UPDATING KALI REPO ☣" -geometry 100x30 -e "sudo apt-get update" 515 | #sleep 1 516 | # check if monodevelop exists 517 | #which monodevelop > /dev/null 2>&1 518 | #if [ "$?" -eq "0" ]; then 519 | #echo -e $green "[ ✔ ] Monodevelop ......................[ found ]" 520 | #which monodevelop >> "$log" 2>&1 521 | #echo "Monodevelop -> OK" >> "$inst" 522 | #else 523 | #echo -e $red "[ X ] Monodevelop -> not found " 524 | #echo -e $yellow "[ ! ] Installing monodevelop " 525 | #xterm -T "☣ INSTALL MONODEVELOP ☣" -geometry 100x30 -e "sudo apt-get install monodevelop --force-yes -y" 526 | #which monodevelop >> "$log" 2>&1 527 | #if [ "$?" -eq "0" ]; then 528 | #echo -e $green "[ ✔ ] Monodevelop -> OK" 529 | #echo "Monodevelop -> OK" >> "$inst" 530 | #else 531 | #echo -e $red "[ x ] Monodevelop" 532 | #echo "0" > "$stp" 533 | #echo "monodevelop -> Not OK" >> "$inst" 534 | #fi 535 | #fi 536 | #sleep 1 537 | #Checking if Jarsigner exists 538 | which jarsigner > /dev/null 2>&1 539 | if [ "$?" -eq "0" ]; then 540 | echo -e $green "[ ✔ ] Jarsigner (java)..................[ found ]" 541 | which jarsigner >> "$log" 2>&1 542 | echo "Jarsigner -> OK" >> "$inst" 543 | rm -f "$config" 544 | #Creating new config file 545 | touch "$config" 546 | echo "********************************************************************************************************" >> "$config" 547 | echo "** Configuration Paths for TheFatRat , do not delete anything from this file or program will not work **" >> "$config" 548 | echo "** if you need to reconfig your tools path , then run ./setup.sh in (TheFatRat directory) . **" >> "$config" 549 | echo "********************************************************************************************************" >> "$config" 550 | echo "jarsigner" | tee -a "$config" >> /dev/null 2>&1 551 | else 552 | echo -e $red "[ X ] Jarsigner (java) -> not found " 553 | echo -e $yellow "[ ! ] Installing Java " 554 | xterm -T "☣ INSTALL OPENJDK-8 ☣" -geometry 100x30 -e "sudo apt-get install openjdk-8-jdk openjdk-8-jre --force-yes -y " 555 | which jarsigner > /dev/null 2>&1 556 | if [ "$?" -eq "0" ]; then 557 | echo -e $green "[ ✔ ] Jarsigner -> OK" 558 | which jarsigner >> "$log" 2>&1 559 | echo "Jarsigner -> OK" >> "$inst" 560 | rm -f "$config" 561 | #Creating new config file 562 | touch "$config" 563 | echo "********************************************************************************************************" >> "$config" 564 | echo "** Configuration Paths for TheFatRat , do not delete anything from this file or program will not work **" >> "$config" 565 | echo "** if you need to reconfig your tools path , then run ./setup.sh in (TheFatRat directory) . **" >> "$config" 566 | echo "********************************************************************************************************" >> "$config" 567 | echo "jarsigner" | tee -a "$config" >> /dev/null 2>&1 568 | else 569 | echo -e $red "[ x ] Jarsigner" 570 | echo "0" > "$stp" 571 | echo "jarsigner (openjdk-8-jdk)-> Not OK" >> "$inst" 572 | fi 573 | fi 574 | sleep 1 575 | 576 | #Checking if Unzip exists 577 | which unzip > /dev/null 2>&1 578 | if [ "$?" -eq "0" ]; then 579 | echo -e $green "[ ✔ ] Unzip.............................[ found ]" 580 | which unzip >> "$log" 2>&1 581 | echo "unzip" | tee -a "$config" >> /dev/null 2>&1 582 | echo "Unzip -> OK" >> "$inst" 583 | else 584 | echo -e $red "[ X ] Unzip -> not found " 585 | echo -e $yellow "[ ! ] Installing Unzip " 586 | echo "☣ INSTALL UNZIP ☣" 587 | apt-get install unzip -y 588 | which unzip >> "$log" 2>&1 589 | if [ "$?" -eq "0" ]; then 590 | echo "unzip" | tee -a "$config" >> /dev/null 2>&1 591 | echo -e $green "[ ✔ ] Unzip -> OK" 592 | echo "Unzip -> OK" >> "$inst" 593 | else 594 | echo -e $red "[ x ] Unzip" 595 | echo "0" > "$stp" 596 | echo "unzip -> Not OK" >> "$inst" 597 | fi 598 | fi 599 | 600 | sleep 1 601 | #Checking if keytool exists 602 | which keytool > /dev/null 2>&1 603 | if [ "$?" -eq "0" ]; then 604 | echo -e $green "[ ✔ ] Keytool (java)....................[ found ]" 605 | which keytool >> "$log" 2>&1 606 | echo "keytool" | tee -a "$config" >> /dev/null 2>&1 607 | echo "Keytool -> OK" >> "$inst" 608 | else 609 | echo -e $red "[ X ] Keytool (java) -> not found " 610 | echo -e $yellow "[ ! ] Installing Java " 611 | xterm -T "☣ INSTALL JAVA ☣" -geometry 100x30 -e "sudo apt-get install openjdk-8-jdk --force-yes -y " 612 | which keytool >> "$log" 2>&1 613 | if [ "$?" -eq "0" ]; then 614 | echo "keytool" | tee -a "$config" >> /dev/null 2>&1 615 | echo -e $green "[ ✔ ] Keytool -> OK" 616 | echo "Keytool -> OK" >> "$inst" 617 | else 618 | echo -e $red "[ x ] Keytool" 619 | echo "0" > "$stp" 620 | echo "keytool -> Not OK" >> "$inst" 621 | fi 622 | fi 623 | 624 | sleep 1 625 | 626 | #Adding zipalign path to config 627 | echo -e $green "[ ✔ ] Zipalign " 628 | echo "$path/tools/android-sdk/zipalign" >> "$log" 2>&1 629 | echo "$path/tools/android-sdk/zipalign" | tee -a "$config" >> /dev/null 2>&1 630 | sleep 1 631 | 632 | 633 | #Adding Proguard path to config 634 | echo -e $green "[ ✔ ] Proguard " 635 | echo "$path/tools/proguard5.3.2/lib/proguard" >> "$log" 2>&1 636 | echo "$path/tools/proguard5.3.2/lib/proguard" | tee -a "$config" >> /dev/null 2>&1 637 | sleep 1 638 | 639 | # check if mingw32 or mingw-64 exists 640 | # Case not exists then reedirect to mingw instalation depending on arch 641 | 642 | #which x86_64-w64-mingw32-gcc >> /dev/null 2>&1 643 | #if [ "$?" -eq "0" ]; then 644 | #echo -e $green "[ ✔ ] Mingw-w64 Compiler................[ found ]" 645 | #which x86_64-w64-mingw32-gcc >> "$log" 2>&1 646 | #echo "Mingw64 -> OK" >> "$inst" 647 | #else 648 | #echo -e $red "[ X ] Mingw-w64 -> not found " 649 | #Powerstager requires mingw64 to work , mingw32 is required because powerfull.sh requires it for 32bit fud exe compiling 650 | # In case mingw64 not found then remove any previously mingw32 & 64 bit faulty instalations and install mingw64 651 | 652 | #xterm -T "☣ INSTALL MINGW64 COMPILLER ☣" -geometry 100x30 -e "sudo apt-get remove --purge mingw-w64 mingw32 -y && apt-get autoremove -y && apt-get install mingw-w64 mingw32 --force-yes -y" 653 | #which x86_64-w64-mingw32-gcc > /dev/null 2>&1 654 | #if [ "$?" -eq "0" ]; then 655 | #echo -e $green "[ ✔ ] Mingw-64 Compiler..................[ found ]" 656 | #which x86_64-w64-mingw32-gcc >> "$log" 2>&1 657 | #echo "Mingw64 -> OK" >> "$inst" 658 | #else 659 | #echo "0" > "$stp" 660 | #echo "mingw-w64 -> Not OK" >> "$inst" 661 | #fi 662 | #fi 663 | 664 | #Checking for DX and in case exists then check if it is version 1.8 used in fatrat (latest android sdk) 665 | which dx > /dev/null 2>&1 666 | if [ "$?" -eq "0" ]; then 667 | dxg=`dx --version 2>&1 | tee temp/dx` 668 | dxv=`cat temp/dx | awk '{print $3}'` 669 | case $dxv in 670 | 1.8) 671 | #DX exists and it is version 1.8 672 | rm -rf temp/dx >/dev/null 2>&1 673 | which dx >> "$log" 2>&1 674 | echo "dx" | tee -a "$config" >> /dev/null 2>&1 675 | echo -e $green "[ ✔ ] DX 1.8" 676 | echo "DX -> OK" >> "$inst" 677 | ;; 678 | *) 679 | #DX does not exists or is not 1.8 version 680 | echo "☣ Removing Your Current DX ☣" 681 | apt-get remove dx -y 682 | #unlink "/usr/local/sbin/dx" > /dev/null 2>&1 683 | ln -s "$path/tools/android-sdk/dx" "$PREFIX/bin/dx" > /dev/null 2>&1 684 | which dx > /dev/null 2>&1 685 | if [ "$?" -eq "0" ]; then 686 | which dx >> "$log" 2>&1 687 | echo "dx" | tee -a "$config" >> /dev/null 2>&1 688 | echo -e $green "[ ✔ ] DX 1.8" 689 | echo "DX -> OK" >> "$inst" 690 | else 691 | echo -e $red "[ x ] DX 1.8" 692 | echo "0" > "$stp" 693 | echo "dx -> Not OK" >> "$inst" 694 | fi 695 | ;; 696 | esac 697 | else 698 | unlink "/usr/local/sbin/dx" > /dev/null 2>&1 699 | ln -s "$path/tools/android-sdk/dx" "$PREFIX/bin/dx" > /dev/null 2>&1 700 | which dx > /dev/null 2>&1 701 | if [ "$?" -eq "0" ]; then 702 | which dx >> "$log" 2>&1 703 | echo "dx" | tee -a "$config" >> /dev/null 2>&1 704 | echo -e $green "[ ✔ ] DX 1.8" 705 | echo "DX -> OK" >> "$inst" 706 | else 707 | echo -e $red "[ x ] DX 1.8" 708 | echo "0" > "$stp" 709 | echo "dx -> Not OK" >> "$inst" 710 | fi 711 | fi 712 | # check if aapt exists and if it is version v0.2-3821160 used in fatrat (android sdk) 713 | rm $PREFIX/bin/aapt >/dev/null 2>&1 714 | which aapt > /dev/null 2>&1 715 | if [ "$?" -eq "0" ]; then 716 | aptv=`aapt v | awk '{print $5}'` 717 | case $aptv in 718 | v0.2-3821160) 719 | #exists and it is v0.2-3821160 720 | which aapt >> "$log" 2>&1 721 | echo "aapt" | tee -a "$config" >> /dev/null 2>&1 722 | echo -e $green "[ ✔ ] Aapt v0.2-3821160" 723 | echo "Aapt -> OK" >> "$inst" 724 | ;; 725 | *) 726 | #Aapt does not exists or is not the latest version used in fatrat (android sdk) 727 | echo "☣ Removing Your Current Aapt ☣" 728 | apt-get remove aapt -y" 729 | unlink "$PREFIX/bin/aapt" > /dev/null 2>&1 730 | ln -s "$path/tools/android-sdk/aapt" "$PREFIX/bin/aapt" > /dev/null 2>&1 731 | which aapt > /dev/null 2>&1 732 | if [ "$?" -eq "0" ]; then 733 | which aapt >> "$log" 2>&1 734 | echo "aapt" | tee -a "$config" >> /dev/null 2>&1 735 | echo -e $green "[ ✔ ] Aapt v0.2-3821160" 736 | echo "Aapt -> OK" >> "$inst" 737 | else 738 | echo -e $red "[ x ] Aapt v0.2-3821160" 739 | echo "0" > "$stp" 740 | echo "aapt -> Not OK" >> "$inst" 741 | fi 742 | ;; 743 | esac 744 | else 745 | unlink "$PREFIX/bin/aapt" > /dev/null 2>&1 746 | ln -s "$path/tools/android-sdk/aapt" "$PREFIX/bin/aapt" > /dev/null 2>&1 747 | which aapt > /dev/null 2>&1 748 | if [ "$?" -eq "0" ]; then 749 | which aapt >> "$log" 2>&1 750 | echo "aapt" | tee -a "$config" >> /dev/null 2>&1 751 | echo -e $green "[ ✔ ] Aapt v0.2-3821160" 752 | echo "Aapt -> OK" >> "$inst" 753 | else 754 | echo -e $red "[ x ] Aapt v0.2-3821160" 755 | echo "0" > "$stp" 756 | echo "aapt -> Not OK" >> "$inst" 757 | fi 758 | fi 759 | 760 | #Same procedure used for dx and aapt , but for apktool 2.2.2. 761 | which apktool > /dev/null 2>&1 762 | if [ "$?" -eq "0" ]; then 763 | apk=`apktool | sed -n 1p | awk '{print $2}'` > /dev/null 2>&1 764 | case $apk in 765 | v.2.2.2) 766 | which apktool >> "$log" 2>&1 767 | echo "apktool" | tee -a "$config" >> /dev/null 2>&1 768 | echo -e $green "[ ✔ ] Apktool v.2.2.2" 769 | echo "Apktool -> OK" >> "$inst" 770 | ;; 771 | *) 772 | #xterm -T "☣ REMOVE OLD APKTOOL ☣" -geometry 100x30 -e "sudo apt-get remove --purge apktool -y" 773 | #unlink "/usr/local/sbin/apktool" > /dev/null 2>&1 774 | ln -s "$path/tools/apktool2.2.2/apktool" "$PREFIX/bin/apktool" > /dev/null 2>&1 775 | which apktool > /dev/null 2>&1 776 | if [ "$?" -eq "0" ]; then 777 | echo -e $green "[ ✔ ] Apktool v.2.2.2" 778 | which apktool >> "$log" 2>&1 779 | echo "apktool" | tee -a "$config" >> /dev/null 2>&1 780 | echo "Apktool -> OK" >> "$inst" 781 | else 782 | echo -e $red "[ x ] Apktool v.2.2.2" 783 | echo "0" > "$stp" 784 | echo "apktool -> Not OK" >> "$inst" 785 | fi 786 | ;; 787 | esac 788 | else 789 | unlink "$PREFIX/bin/apktool" > /dev/null 2>&1 790 | ln -s "$path/tools/apktool2.2.2/apktool" "$PREFIX/bin/apktool" > /dev/null 2>&1 791 | which apktool > /dev/null 2>&1 792 | if [ "$?" -eq "0" ]; then 793 | which apktool >> "$log" 2>&1 794 | echo "apktool" | tee -a "$config" >> /dev/null 2>&1 795 | echo -e $green "[ ✔ ] Apktool v.2.2.2" 796 | echo "Apktool -> OK" >> "$inst" 797 | else 798 | echo -e $red "[ x ] Apktool v.2.2.2" 799 | echo "0" > "$stp" 800 | echo "apktool -> Not OK" >> "$inst" 801 | fi 802 | fi 803 | #Same as others before , but dex2jar in this case will be installed directly to user OS , instead be working in fatrat tools 804 | which d2j-dex2jar > /dev/null 2>&1 805 | if [ "$?" -eq "0" ]; then 806 | dex=`d2j-dex2jar 2>&1 | tee temp/dex` 807 | d2j=`cat temp/dex | sed -n 19p | awk '{print $2}' | cut -f1 -d','` 808 | case $d2j in 809 | reader-2.0) 810 | rm -rf temp/dex >/dev/null 2>&1 811 | which d2j-dex2jar >> "$log" 2>&1 812 | echo "d2j-dex2jar" | tee -a "$config" >> /dev/null 2>&1 813 | echo -e $green "[ ✔ ] Dex2Jar 2.0" 814 | echo "Dex2Jar -> OK" >> "$inst" 815 | ;; 816 | *) 817 | rm -rf temp/dex >/dev/null 2>&1 818 | #Dex2jar does not exists or it is not the 2.0 version , so uninstall it & copy dex2jar from 819 | #fatrat tools folder to /usr/local/sbin 820 | #xterm -T "☣ Removing Your Current Dex2Jar ☣" -geometry 100x30 -e "sudo apt-get remove --purge dex2jar --force-yes -y" 821 | cp $path/tools/dex2jar/* $PREFIX/bin/ > /dev/null 2>&1 822 | chmod +x $PREFIX/bin/d2j-baksmali > /dev/null 2>&1 823 | chmod +x $PREFIX/bin/d2j-dex-recompute-checksum > /dev/null 2>&1 824 | chmod +x $PREFIX/bin/d2j-dex2jar > /dev/null 2>&1 825 | chmod +x $PREFIX/bin/d2j-dex2smali > /dev/null 2>&1 826 | chmod +x $PREFIX/bin/d2j-jar2dex > /dev/null 2>&1 827 | chmod +x $PREFIX/bin/d2j-jar2jasmin > /dev/null 2>&1 828 | chmod +x $PREFIX/bin/d2j-jasmin2jar > /dev/null 2>&1 829 | chmod +x $PREFIX/bin/d2j-smali > /dev/null 2>&1 830 | chmod +x $PREFIX/bin/d2j-std-apk > /dev/null 2>&1 831 | # remove any previous version files from dex2jar lib from /usr/local/share 832 | # and copy the new ones to there from fatrat tools dir 833 | #rm -rf /usr/local/share/dex2jar > /dev/null 2>&1 834 | mkdir $PREFIX/share/dex2jar > /dev/null 2>&1 835 | cp -r $path/tools/dex2jar/lib $PREFIX/share/dex2jar/lib > /dev/null 2>&1 836 | which d2j-dex2jar > /dev/null 2>&1 837 | #After new instalation , check if dex2jar is working 838 | if [ "$?" -eq "0" ]; then 839 | #Dex2jar was suceffully installed 840 | echo -e $green "[ ✔ ] Dex2Jar 2.0" 841 | which d2j-dex2jar >> "$log" 2>&1 842 | echo "d2j-dex2jar" | tee -a "$config" >> /dev/null 2>&1 843 | echo "Dex2Jar -> OK" >> "$inst" 844 | else 845 | #After the instalation something did not worked , place the warnings in logs 846 | echo -e $red "[ x ] Dex2Jar 2.0" 847 | echo "0" > "$stp" 848 | echo "dex2jar -> Not OK" >> "$inst" 849 | fi 850 | ;; 851 | esac 852 | else 853 | #dex2jar does not exist in user linux OS , proceed with a clean manual installation 854 | cp $path/tools/dex2jar/* $PREFIX/bin/ > /dev/null 2>&1 855 | chmod +x $PREFIX/bin/d2j-baksmali > /dev/null 2>&1 856 | chmod +x $PREFIX/bin/d2j-dex-recompute-checksum > /dev/null 2>&1 857 | chmod +x $PREFIX/bin/d2j-dex2jar > /dev/null 2>&1 858 | chmod +x $PREFIX/bin/d2j-dex2smali > /dev/null 2>&1 859 | chmod +x $PREFIX/bin/d2j-jar2dex > /dev/null 2>&1 860 | chmod +x $PREFIX/bin/d2j-jar2jasmin > /dev/null 2>&1 861 | chmod +x $PREFIX/bin/d2j-jasmin2jar > /dev/null 2>&1 862 | chmod +x $PREFIX/bin/d2j-smali > /dev/null 2>&1 863 | chmod +x $PREFIX/bin/d2j-std-apk > /dev/null 2>&1 864 | rm -rf $PREFIX/share/dex2jar > /dev/null 2>&1 865 | mkdir $PREFIX/share/dex2jar > /dev/null 2>&1 866 | cp -r $path/tools/dex2jar/lib $PREFIX/share/dex2jar/lib > /dev/null 2>&1 867 | which d2j-dex2jar > /dev/null 2>&1 868 | if [ "$?" -eq "0" ]; then 869 | echo -e $green "[ ✔ ] Dex2Jar 2.0" 870 | which d2j-dex2jar >> "$log" 2>&1 871 | echo "d2j-dex2jar" | tee -a "$config" >> /dev/null 2>&1 872 | echo "Dex2Jar -> OK" >> "$inst" 873 | else 874 | echo -e $red "[ x ] Dex2Jar 2.0" 875 | echo "0" > "$stp" 876 | echo "dex2jar -> Not OK" >> "$inst" 877 | fi 878 | fi 879 | mtspl 880 | 881 | ################################ 882 | # rebackyo repo 883 | ################################ 884 | #echo -e $blue "Reactivating your original repositories" 885 | #rm -f /etc/apt/sources.list 886 | #mv /etc/apt/sources.list.backup /etc/apt/sources.list 887 | #now we can remove the emergency backup securely 888 | #rm -f /etc/apt/sources.list.fatrat 889 | #apt-get clean 890 | #xterm -T "☣ UPDATE YOUR REPO ☣" -geometry 100x30 -e "sudo apt-get update " 891 | #clear 892 | echo -e $okegreen "Do you want to create a shortcut for fatrat in your system" 893 | echo -e $okegreen "so you can run fatrat from anywhere in your terminal and desktop ?" 894 | echo "" 895 | echo -ne $cyan "Choose y/n : " 896 | read cho 897 | case $cho in 898 | 899 | y|Y|Yes|yes|YES) 900 | lnk=$? 901 | if [ $lnk == "0" ];then 902 | dir=`pwd` 903 | scrp="cd $dir && ./fatrat" 904 | rm -f $PREFIX/bin/fatrat 905 | touch $PREFIX/bin/fatrat 906 | echo "#!/data/data/com.termux/files/usr/bin/bash" > $PREFIX/bin/fatrat 907 | echo $scrp >> $PREFIX/bin/fatrat 908 | #cp $path/config/TheFatRat.desktop /usr/share/applications/TheFatRat.desktop 909 | #cp $path/icons/fatrat.ico /usr/share/icons/fatrat.ico 910 | chmod +x $PREFIX/bin/fatrat 911 | chmod +x fatrat 912 | chmod +x update 913 | chmod +x backdoor_apk 914 | chmod +x $path/tools/power.py 915 | chmod +x $path/tools/android-sdk/zipalign 916 | chmod +x $path/tools/proguard5.3.2/lib/proguard 917 | chmod +x $path/tools/android-sdk/dx 918 | chmod +x $path/tools/android-sdk/aapt 919 | chmod +x $path/tools/apktool2.2.2/apktool 920 | which fatrat >> "$log" 2>&1 921 | clear 922 | echo "" 923 | echo -e $green "Instalation completed , To execute fatrat write anywhere in your tefatra fatrat" 924 | fi 925 | ;; 926 | 927 | n|no|No|NO) 928 | chmod +x fatrat 929 | chmod +x update 930 | chmod +x backdoor_apk 931 | chmod +x $path/tools/power.py 932 | chmod +x $path/tools/android-sdk/zipalign 933 | chmod +x $path/tools/proguard5.3.2/lib/proguard 934 | chmod +x $path/tools/android-sdk/dx 935 | chmod +x $path/tools/android-sdk/aapt 936 | chmod +x $path/tools/apktool2.2.2/apktool 937 | clear 938 | echo "" 939 | echo -e $green "Instalation completed , To execute fatrat write in fatrat directory ,./fatrat" 940 | ;; 941 | 942 | *) 943 | chmod +x fatrat 944 | chmod +x update 945 | chmod +x backdoor_apk 946 | chmod +x $path/tools/power.py 947 | chmod +x $path/tools/android-sdk/zipalign 948 | chmod +x $path/tools/proguard5.3.2/lib/proguard 949 | chmod +x $path/tools/android-sdk/dx 950 | chmod +x $path/tools/android-sdk/aapt 951 | chmod +x $path/tools/apktool2.2.2/apktool 952 | clear 953 | echo "" 954 | echo -e $green "Instalation completed , To execute fatrat write in fatrat directory ./fatrat" 955 | ;; 956 | esac 957 | exit 958 | 959 | } 960 | #Case ping goggle hostname fails , the this function will load to check what is happening 961 | function chknet() { 962 | echo -e $red "[X] Your Internet is not working correctly!" 963 | sleep 1 964 | echo -e $cyan "[*] Checking ...." 965 | #ping hostname failed , so now will test ping google ip dns server 966 | ping -c 1 8.8.4.4 > /dev/null 2>&1 967 | png="$?" 968 | if [ $png == "0" ] 969 | then 970 | #Ping dns server worked , inform user what happened and proceed with setup 971 | echo -e $red "[X] Your linux OS is not able to resolve" 972 | echo -e $red "hostnames over terminal using ping !!" 973 | echo "" 974 | echo -e $yellow "Search on the web : unable to resolve hostnames ping to find a solution" 975 | echo "" 976 | echo -e $green "Setup will continue , but is not garantee that apt package management 977 | may work properly , or even if it can resolve hostnames ." 978 | echo "" 979 | echo -e $cyan "Setup will continue because :" 980 | echo -e $green "Ping google.com =$red Failed" 981 | echo -e $green "Ping google DNS = Success" 982 | echo "" 983 | echo -e $green "Press [ENTER] key to continue" 984 | read continue 985 | cont 986 | sleep 1 987 | elif [ $png == "1" ] 988 | then 989 | #user is only connected to lan and not to the web , abort setup 990 | echo -e $yellow "You are connected to your local network but not to the web ." 991 | echo -e $yellow "Check if your router/modem gateway is connected to the web ." 992 | echo "" 993 | echo -e $green "Setup will not continue , you are only connected to your local lan." 994 | echo "" 995 | echo -e $cyan "Setup will stop because :" 996 | echo -e $green "Ping google.com =$red Failed" 997 | echo -e $green "Ping google DNS =$red Failed" 998 | echo "" 999 | echo -e $green "Press [ENTER] key to continue" 1000 | read continue 1001 | exit 1 1002 | sleep 1 1003 | elif [ $png == "2" ] 1004 | then 1005 | # user is not connected to anywhere , web or lan , abort setup 1006 | echo -e $red "You are not connected to any network ." 1007 | echo "" 1008 | echo -e $cyan "Setup will stop because :" 1009 | echo -e $green "Ping google.com =$red Failed" 1010 | echo -e $green "Ping google DNS =$red Failed" 1011 | echo "" 1012 | echo -e $green "Press [ENTER] key to continue" 1013 | read continue 1014 | exit 1 1015 | sleep 1 1016 | fi 1017 | } 1018 | 1019 | # setup.sh Original Author : Edo maland ( Screetsec ) 1020 | # Script rebuilded by peterpt 1021 | # Install all dependencies nedded 1022 | # configuration all file for fixing all problems 1023 | # -------------------------------------------------------- 1024 | 1025 | 1026 | #Fail safe for original user sources.list in case setup was interrupted in middle last time 1027 | #file="/etc/apt/sources.list.fatrat" 1028 | #if [ -f "$file" ] 1029 | #then 1030 | #echo "Setup Detected that your previous run was interrupted in middle , fixing your original repositories list ." 1031 | #sleep 4s 1032 | #rm -f /etc/apt/sources.list 1033 | #mv /etc/apt/sources.list.fatrat /etc/apt/sources.list 1034 | #echo "Your Original repository list was recovered. ..... beginning setup" 1035 | #echo "" 1036 | #echo "Cleaning previous repositories cache & updating your repository ." 1037 | #echo -e $yellow "" 1038 | #sudo apt-get clean && apt-get update -y 1039 | #sleep 2 1040 | #else 1041 | #echo -e $green "" 1042 | #fi 1043 | #variables for logs and others 1044 | path=`pwd` 1045 | arch=`uname -m` 1046 | inst="$path/logs/install.log" 1047 | log="$path/logs/setup.log" 1048 | config="$path/config/config.path" 1049 | #Removing any previous setup log created 1050 | rm -rf "$log" > /dev/null 2>&1 1051 | rm -rf logs/check > /dev/null 2>&1 1052 | 1053 | #terminal text colours code 1054 | cyan='\e[0;36m' 1055 | green='\e[0;32m' 1056 | lightgreen='\e[0;32m' 1057 | white='\e[0;37m' 1058 | red='\e[0;31m' 1059 | yellow='\e[0;33m' 1060 | blue='\e[0;34m' 1061 | purple='\e[0;35m' 1062 | orange='\e[38;5;166m' 1063 | path=`pwd` 1064 | 1065 | #Check root dulu 1066 | if [ $(id -u) = "0" ]; then 1067 | echo -e $red [x]::[not root]: You need to be [root] to run this script.; 1068 | echo "" 1069 | sleep 1 1070 | exit 0 1071 | fi 1072 | #Many fresh installed linux distros do not come with sudo installed 1073 | #which sudo > /dev/null 2>&1 1074 | #if [ "$?" -eq "0" ]; then 1075 | #echo "" 1076 | #else 1077 | #apt-get install sudo -y 1078 | #fi 1079 | #echo "" 1080 | # Fixing any possible problems with packages missed/corrupted dependencies on user OS before proceed 1081 | #echo -e $green "[ * ] Fixing any possible broken packages in apt management" 1082 | #sleep 1 1083 | #echo -e $white "" 1084 | #sudo apt-get install -f -y && sudo apt-get autoremove -y 1085 | #sleep 1 1086 | echo "" 1087 | echo -e $yellow "[ ✔ ] Done ! ....Proceeding with setup" 1088 | echo "" 1089 | sleep 2 1090 | clear 1091 | #Banner dong biar keren 1092 | echo -e $green "" 1093 | echo "___________ __ __________ __ " 1094 | echo "\_ _____/_____ _/ |_\______ \_____ _/ |_ " 1095 | echo " | __) \__ \ \ __\| _/\__ \ \ __\ " 1096 | echo " | \ / __ \_| | | | \ / __ \_| | " 1097 | echo " \___ / (____ /|__| |____|_ /(____ /|__| " 1098 | echo " \/ \/ \/ \/ " 1099 | echo " ____ ________ " 1100 | echo " /_ | / __ \ " 1101 | echo " | | \____ / " 1102 | echo " | | / / " 1103 | echo " |___| /\ /____/ " 1104 | echo " \/ " 1105 | echo "" 1106 | echo -e $blue " Setup Script for FATRAT 1.9.5 " 1107 | echo "------------------------------------------------------" > "$log" 1108 | echo "| Tools paths configured in (setup.sh) for TheFatRat |" >> "$log" 1109 | echo "------------------------------------------------------" >> "$log" 1110 | echo " " >> "$log" 1111 | echo "" 1112 | #Detect if user OS is 32Bit or 64bit 1113 | case $arch in 1114 | x86_64|aarch64) 1115 | echo -e $yellow " 64Bit OS detected" 1116 | echo "" 1117 | ;; 1118 | i386|i486|i586|i686) 1119 | echo -e $yellow " 32Bit OS detected" 1120 | echo "" 1121 | ;; 1122 | *) 1123 | echo -e $red "Setup will not proceed because none of these archs were detected" 1124 | echo "" 1125 | echo -e $blue "x86_64|i386|i486|i586|i686|aarch64" 1126 | echo "" 1127 | echo -e $green "Report this arch: $blue $arch $green into fatrat issues on github" 1128 | echo "" 1129 | echo -e "Press any key to continue" 1130 | read abor 1131 | exit 0 1132 | ;; 1133 | esac 1134 | echo -e $green "Checking type of shell ...." 1135 | sleep 1 1136 | 1137 | #Check if user is using a remote shell or a local terminal 1138 | if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]; then 1139 | echo "[remote]" 1140 | echo "" 1141 | echo -e $red "Fatrat & Setup does not work over a remote secure shell ." 1142 | echo "" 1143 | echo -e $green "If you want to Install Fatrat on a remote computer then " 1144 | echo -e $green "use a remote desktop connection like (rdesktop) or (vnc) " 1145 | echo "" 1146 | echo -e $green "Press [ENTER] key to exit" 1147 | read abor 1148 | exit 1 1149 | else 1150 | echo [local] 1151 | case $(ps -o comm= -p $PPID) in 1152 | sshd|*/sshd) SESSION_TYPE=remote/ssh;; 1153 | esac 1154 | fi 1155 | 1156 | sleep 1 1157 | #First check of setup for internet connection by pinging google hostname 1158 | echo -e $green "[ * ] Checking for internet connection" 1159 | sleep 1 1160 | ping -c 1 google.com > /dev/null 2>&1 1161 | png="$?" 1162 | if [ $png == "0" ] 1163 | then 1164 | #ping google hostname was succefully , then proceed with setup 1165 | echo -e $green [ ✔ ]::[Internet Connection]: CONNECTED!; 1166 | sleep 1 1167 | cont 1168 | elif [ $png == "1" ] 1169 | then 1170 | #ping hostname failed , load chknet function 1171 | echo -e $yellow [ X ]::[Internet Connection]: LOCAL ONLY!; 1172 | chknet 1173 | sleep 1 1174 | elif [ $png == "2" ] 1175 | then 1176 | #ping hostname failed , load chknet function 1177 | echo -e $red [ X ]::[Internet Connection]: OFFLINE!; 1178 | chknet 1179 | sleep 1 1180 | fi 1181 | -------------------------------------------------------------------------------- /spec/netiface_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + '/spec_helper') 2 | 3 | describe NetworkInterface do 4 | 5 | describe "#interfaces" do 6 | it "should have the same interfaces as the system_interfaces" do 7 | NetworkInterface.interfaces.should include(*system_interfaces_with_addresses.keys) 8 | end 9 | end 10 | 11 | describe "#addresses" do 12 | system_interfaces_with_addresses.each do |interface, hash| 13 | describe "#{friendly_interface_names.key(interface)}" do 14 | if hash.has_key?(:ipv4) 15 | describe "ipv4" do 16 | it "should have an ipv4 address" do 17 | NetworkInterface.addresses(interface).should have_key NetworkInterface::AF_INET 18 | end 19 | it "should match the system interface of #{hash[:ipv4]}" do 20 | NetworkInterface.addresses(interface)[NetworkInterface::AF_INET][0]["addr"].should == hash[:ipv4] 21 | end 22 | end 23 | end 24 | if hash.has_key?(:ipv6) 25 | describe "ipv6" do 26 | it "should have an ipv6 address" do 27 | NetworkInterface.addresses(interface).should have_key NetworkInterface::AF_INET6 28 | end 29 | it "should match the system interface of #{hash[:ipv6]}" do 30 | NetworkInterface.addresses(interface)[NetworkInterface::AF_INET6][0]["addr"].should == hash[:ipv6] 31 | end 32 | end 33 | end 34 | if hash.has_key?(:mac) 35 | describe "MAC address" do 36 | it "should have a MAC address" do 37 | NetworkInterface.addresses(interface).should have_key NetworkInterface::AF_LINK 38 | end 39 | it "should match the system interface of #{hash[:mac]}" do 40 | NetworkInterface.addresses(interface)[NetworkInterface::AF_LINK][0]["addr"].should == hash[:mac] 41 | end 42 | end 43 | end 44 | end 45 | end 46 | 47 | end 48 | end -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.dirname(__FILE__)) 2 | $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib')) 3 | require 'network_interface' 4 | require 'rspec' 5 | require 'rspec/autorun' 6 | 7 | RSpec.configure do |config| 8 | end 9 | 10 | def friendly_interface_names 11 | interfaces = NetworkInterface.interfaces 12 | interface_names ||= begin 13 | h = {} 14 | interfaces.each do |interface| 15 | info = NetworkInterface.interface_info(interface) 16 | name = if info && info.has_key?('name') 17 | info['name'] 18 | else 19 | interface 20 | end 21 | h[name] = interface 22 | end 23 | h 24 | end 25 | interface_names 26 | end 27 | 28 | if RUBY_PLATFORM =~ /i386-mingw32/ 29 | def system_interfaces 30 | ipconfig = `ipconfig` 31 | ipconfig_array = ipconfig.split("\n").reject {|s| s.empty?} 32 | 33 | getmac = `getmac -nh` 34 | getmac_array = getmac.split("\n").reject {|s| s.empty?} 35 | getmac_array.map!{|element| element.split(" ")} 36 | getmac_hash = getmac_array.inject({}) do |hash, array| 37 | hash.merge!({array[1][/\{(.*)\}/,1] => array[0].gsub("-",":").downcase}) 38 | end 39 | 40 | interfaces = {} 41 | @key = nil 42 | ipconfig_array.each do |element| 43 | if element.start_with? " " 44 | case element 45 | when /IPv6 Address.*: (.*)/ 46 | # interfaces[@key][:ipv6] = $1 47 | when /IPv4 Address.*: (.*)/ 48 | interfaces[@key][:ipv4] = $1 49 | interfaces[@key][:mac] = getmac_hash[@key[/\{(.*)\}/,1]] 50 | end 51 | elsif element[/Windows IP Configuration/] 52 | elsif element[/Ethernet adapter (.*):/] 53 | @key = friendly_interface_names[$1] 54 | interfaces[@key] = {} 55 | else 56 | @key = element[/(.*):/,1] 57 | interfaces[@key] = {} 58 | end 59 | end 60 | 61 | interfaces 62 | end 63 | 64 | else 65 | def system_interfaces 66 | ifconfig = `/sbin/ifconfig` 67 | ifconfig_array = ifconfig.split("\n") 68 | ifconfig_array.map!{|element| element.split("\n")} 69 | ifconfig_array.flatten! 70 | interfaces = {} 71 | @key = nil 72 | ifconfig_array.each do |element| 73 | if element.start_with?("\t") || element.start_with?(" ") 74 | case element 75 | when /ether ((\w{2}\:){5}(\w{2}))/ 76 | interfaces[@key][:mac] = $1 77 | when /inet6 (.*) prefixlen/ 78 | interfaces[@key][:ipv6] = $1 79 | when /inet ((\d{1,3}\.){3}\d{1,3}).*broadcast ((\d{1,3}\.){3}\d{1,3})/ 80 | interfaces[@key][:ipv4] = $1 81 | interfaces[@key][:broadcast] = $3 82 | when /addr:((\d{1,3}\.){3}\d{1,3})\s+Bcast:((\d{1,3}\.){3}\d{1,3})/i 83 | interfaces[@key][:ipv4] = $1 84 | interfaces[@key][:broadcast] = $3 85 | end 86 | else 87 | @key = element.split(' ').first[/(\w*)/,1] 88 | interfaces[@key] = {} 89 | if element[/HWaddr ((\w{2}\:){5}(\w{2}))/] 90 | interfaces[@key][:mac] = $1 91 | end 92 | end 93 | end 94 | interfaces 95 | end 96 | 97 | end 98 | 99 | def system_interfaces_with_addresses 100 | interfaces = {} 101 | system_interfaces.each do |key, value| 102 | if value.has_key? :ipv4 103 | interfaces[key] = value 104 | end 105 | end 106 | interfaces 107 | end 108 | --------------------------------------------------------------------------------