network_interface 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,11 @@
1
+ *.bundle
2
+ *.sw?
3
+ *~
4
+ .DS_Store
5
+ coverage
6
+ rdoc
7
+ pkg
8
+ tmp
9
+ *.so
10
+ .ruby-gemset
11
+ .ruby-version
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in network_interface.gemspec
4
+ gemspec
@@ -0,0 +1,30 @@
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
data/LICENSE ADDED
@@ -0,0 +1,45 @@
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.
@@ -0,0 +1,29 @@
1
+ # NetworkInterface
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'network_interface'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install network_interface
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1,11 @@
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]
@@ -0,0 +1,95 @@
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)
@@ -0,0 +1,1008 @@
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
+