network_interface 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+