Ruby 2.1.5p273(2014-11-13revision48405)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

option.c
Go to the documentation of this file.
1 #include "rubysocket.h"
2
3 VALUE rb_cSockOpt;
4
5 static VALUE
6 constant_to_sym(int constant, ID (*intern_const)(int))
7 {
8 ID name = intern_const(constant);
9 if (name) {
10 return ID2SYM(name);
11 }
12
13 return INT2NUM(constant);
14 }
15
16 static VALUE
17 optname_to_sym(int level, int optname)
18 {
19 switch (level) {
20 case SOL_SOCKET:
21 return constant_to_sym(optname, rsock_intern_so_optname);
22 case IPPROTO_IP:
23 return constant_to_sym(optname, rsock_intern_ip_optname);
24 #ifdef IPPROTO_IPV6
25 case IPPROTO_IPV6:
26 return constant_to_sym(optname, rsock_intern_ipv6_optname);
27 #endif
28 case IPPROTO_TCP:
29 return constant_to_sym(optname, rsock_intern_tcp_optname);
30 case IPPROTO_UDP:
31 return constant_to_sym(optname, rsock_intern_udp_optname);
32 default:
33 return INT2NUM(optname);
34 }
35 }
36
37 /*
38 * call-seq:
39 * Socket::Option.new(family, level, optname, data) => sockopt
40 *
41 * Returns a new Socket::Option object.
42 *
43 * sockopt = Socket::Option.new(:INET, :SOCKET, :KEEPALIVE, [1].pack("i"))
44 * p sockopt #=> #<Socket::Option: INET SOCKET KEEPALIVE 1>
45 *
46 */
47 static VALUE
48 sockopt_initialize(VALUE self, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE data)
49 {
50 int family = rsock_family_arg(vfamily);
51 int level = rsock_level_arg(family, vlevel);
52 int optname = rsock_optname_arg(family, level, voptname);
53 StringValue(data);
54 rb_ivar_set(self, rb_intern("family"), INT2NUM(family));
55 rb_ivar_set(self, rb_intern("level"), INT2NUM(level));
56 rb_ivar_set(self, rb_intern("optname"), INT2NUM(optname));
57 rb_ivar_set(self, rb_intern("data"), data);
58 return self;
59 }
60
61 VALUE
62 rsock_sockopt_new(int family, int level, int optname, VALUE data)
63 {
64 NEWOBJ_OF(obj, struct RObject, rb_cSockOpt, T_OBJECT);
65 StringValue(data);
66 sockopt_initialize((VALUE)obj, INT2NUM(family), INT2NUM(level), INT2NUM(optname), data);
67 return (VALUE)obj;
68 }
69
70 /*
71 * call-seq:
72 * sockopt.family => integer
73 *
74 * returns the socket family as an integer.
75 *
76 * p Socket::Option.new(:INET6, :IPV6, :RECVPKTINFO, [1].pack("i!")).family
77 * #=> 10
78 */
79 static VALUE
80 sockopt_family_m(VALUE self)
81 {
82 return rb_attr_get(self, rb_intern("family"));
83 }
84
85 static int
86 sockopt_level(VALUE self)
87 {
88 return NUM2INT(rb_attr_get(self, rb_intern("level")));
89 }
90
91 /*
92 * call-seq:
93 * sockopt.level => integer
94 *
95 * returns the socket level as an integer.
96 *
97 * p Socket::Option.new(:INET6, :IPV6, :RECVPKTINFO, [1].pack("i!")).level
98 * #=> 41
99 */
100 static VALUE
101 sockopt_level_m(VALUE self)
102 {
103 return INT2NUM(sockopt_level(self));
104 }
105
106 static int
107 sockopt_optname(VALUE self)
108 {
109 return NUM2INT(rb_attr_get(self, rb_intern("optname")));
110 }
111
112 /*
113 * call-seq:
114 * sockopt.optname => integer
115 *
116 * returns the socket option name as an integer.
117 *
118 * p Socket::Option.new(:INET6, :IPV6, :RECVPKTINFO, [1].pack("i!")).optname
119 * #=> 2
120 */
121 static VALUE
122 sockopt_optname_m(VALUE self)
123 {
124 return INT2NUM(sockopt_optname(self));
125 }
126
127 /*
128 * call-seq:
129 * sockopt.data => string
130 * sockopt.to_s => string
131 *
132 * returns the socket option data as a string.
133 *
134 * p Socket::Option.new(:INET6, :IPV6, :RECVPKTINFO, [1].pack("i!")).data
135 * #=> "\x01\x00\x00\x00"
136 */
137 static VALUE
138 sockopt_data(VALUE self)
139 {
140 VALUE v = rb_attr_get(self, rb_intern("data"));
141 StringValue(v);
142 return v;
143 }
144
145 /*
146 * call-seq:
147 * Socket::Option.byte(family, level, optname, integer) => sockopt
148 *
149 * Creates a new Socket::Option object which contains a byte as data.
150 *
151 * The size and endian is dependent on the platform.
152 *
153 * p Socket::Option.byte(:INET, :SOCKET, :KEEPALIVE, 1)
154 * #=> #<Socket::Option: INET SOCKET KEEPALIVE 1>
155 */
156 static VALUE
157 sockopt_s_byte(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE vint)
158 {
159 int family = rsock_family_arg(vfamily);
160 int level = rsock_level_arg(family, vlevel);
161 int optname = rsock_optname_arg(family, level, voptname);
162 unsigned char i = (unsigned char)NUM2CHR(vint);
163 return rsock_sockopt_new(family, level, optname, rb_str_new((char*)&i, sizeof(i)));
164 }
165
166 /*
167 * call-seq:
168 * sockopt.byte => integer
169 *
170 * Returns the data in _sockopt_ as an byte.
171 *
172 * The size and endian is dependent on the platform.
173 *
174 * sockopt = Socket::Option.byte(:INET, :SOCKET, :KEEPALIVE, 1)
175 * p sockopt.byte => 1
176 */
177 static VALUE
178 sockopt_byte(VALUE self)
179 {
180 unsigned char i;
181 VALUE data = sockopt_data(self);
182 StringValue(data);
183 if (RSTRING_LEN(data) != sizeof(i))
184 rb_raise(rb_eTypeError, "size differ. expected as sizeof(int)=%d but %ld",
185 (int)sizeof(i), (long)RSTRING_LEN(data));
186 return CHR2FIX(*RSTRING_PTR(data));
187 }
188
189 /*
190 * call-seq:
191 * Socket::Option.int(family, level, optname, integer) => sockopt
192 *
193 * Creates a new Socket::Option object which contains an int as data.
194 *
195 * The size and endian is dependent on the platform.
196 *
197 * p Socket::Option.int(:INET, :SOCKET, :KEEPALIVE, 1)
198 * #=> #<Socket::Option: INET SOCKET KEEPALIVE 1>
199 */
200 static VALUE
201 sockopt_s_int(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE vint)
202 {
203 int family = rsock_family_arg(vfamily);
204 int level = rsock_level_arg(family, vlevel);
205 int optname = rsock_optname_arg(family, level, voptname);
206 int i = NUM2INT(vint);
207 return rsock_sockopt_new(family, level, optname, rb_str_new((char*)&i, sizeof(i)));
208 }
209
210 /*
211 * call-seq:
212 * sockopt.int => integer
213 *
214 * Returns the data in _sockopt_ as an int.
215 *
216 * The size and endian is dependent on the platform.
217 *
218 * sockopt = Socket::Option.int(:INET, :SOCKET, :KEEPALIVE, 1)
219 * p sockopt.int => 1
220 */
221 static VALUE
222 sockopt_int(VALUE self)
223 {
224 int i;
225 VALUE data = sockopt_data(self);
226 StringValue(data);
227 if (RSTRING_LEN(data) != sizeof(int))
228 rb_raise(rb_eTypeError, "size differ. expected as sizeof(int)=%d but %ld",
229 (int)sizeof(int), (long)RSTRING_LEN(data));
230 memcpy((char*)&i, RSTRING_PTR(data), sizeof(int));
231 return INT2NUM(i);
232 }
233
234 /*
235 * call-seq:
236 * Socket::Option.bool(family, level, optname, bool) => sockopt
237 *
238 * Creates a new Socket::Option object which contains boolean as data.
239 * Actually 0 or 1 as int is used.
240 *
241 * p Socket::Option.bool(:INET, :SOCKET, :KEEPALIVE, true)
242 * #=> #<Socket::Option: INET SOCKET KEEPALIVE 1>
243 *
244 * p Socket::Option.bool(:INET, :SOCKET, :KEEPALIVE, false)
245 * #=> #<Socket::Option: AF_INET SOCKET KEEPALIVE 0>
246 *
247 */
248 static VALUE
249 sockopt_s_bool(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE vbool)
250 {
251 int family = rsock_family_arg(vfamily);
252 int level = rsock_level_arg(family, vlevel);
253 int optname = rsock_optname_arg(family, level, voptname);
254 int i = RTEST(vbool) ? 1 : 0;
255 return rsock_sockopt_new(family, level, optname, rb_str_new((char*)&i, sizeof(i)));
256 }
257
258 /*
259 * call-seq:
260 * sockopt.bool => true or false
261 *
262 * Returns the data in _sockopt_ as an boolean value.
263 *
264 * sockopt = Socket::Option.int(:INET, :SOCKET, :KEEPALIVE, 1)
265 * p sockopt.bool => true
266 */
267 static VALUE
268 sockopt_bool(VALUE self)
269 {
270 int i;
271 VALUE data = sockopt_data(self);
272 StringValue(data);
273 if (RSTRING_LEN(data) != sizeof(int))
274 rb_raise(rb_eTypeError, "size differ. expected as sizeof(int)=%d but %ld",
275 (int)sizeof(int), (long)RSTRING_LEN(data));
276 memcpy((char*)&i, RSTRING_PTR(data), sizeof(int));
277 return i == 0 ? Qfalse : Qtrue;
278 }
279
280 /*
281 * call-seq:
282 * Socket::Option.linger(onoff, secs) => sockopt
283 *
284 * Creates a new Socket::Option object for SOL_SOCKET/SO_LINGER.
285 *
286 * _onoff_ should be an integer or a boolean.
287 *
288 * _secs_ should be the number of seconds.
289 *
290 * p Socket::Option.linger(true, 10)
291 * #=> #<Socket::Option: UNSPEC SOCKET LINGER on 10sec>
292 *
293 */
294 static VALUE
295 sockopt_s_linger(VALUE klass, VALUE vonoff, VALUE vsecs)
296 {
297 VALUE tmp;
298 struct linger l;
299 memset(&l, 0, sizeof(l));
300 if (!NIL_P(tmp = rb_check_to_integer(vonoff, "to_int")))
301 l.l_onoff = NUM2INT(tmp);
302 else
303 l.l_onoff = RTEST(vonoff) ? 1 : 0;
304 l.l_linger = NUM2INT(vsecs);
305 return rsock_sockopt_new(AF_UNSPEC, SOL_SOCKET, SO_LINGER, rb_str_new((char*)&l, sizeof(l)));
306 }
307
308 /*
309 * call-seq:
310 * sockopt.linger => [bool, seconds]
311 *
312 * Returns the linger data in _sockopt_ as a pair of boolean and integer.
313 *
314 * sockopt = Socket::Option.linger(true, 10)
315 * p sockopt.linger => [true, 10]
316 */
317 static VALUE
318 sockopt_linger(VALUE self)
319 {
320 int level = sockopt_level(self);
321 int optname = sockopt_optname(self);
322 VALUE data = sockopt_data(self);
323 struct linger l;
324 VALUE vonoff, vsecs;
325
326 if (level != SOL_SOCKET || optname != SO_LINGER)
327 rb_raise(rb_eTypeError, "linger socket option expected");
328 if (RSTRING_LEN(data) != sizeof(l))
329 rb_raise(rb_eTypeError, "size differ. expected as sizeof(struct linger)=%d but %ld",
330 (int)sizeof(struct linger), (long)RSTRING_LEN(data));
331 memcpy((char*)&l, RSTRING_PTR(data), sizeof(struct linger));
332 switch (l.l_onoff) {
333 case 0: vonoff = Qfalse; break;
334 case 1: vonoff = Qtrue; break;
335 default: vonoff = INT2NUM(l.l_onoff); break;
336 }
337 vsecs = INT2NUM(l.l_linger);
338 return rb_assoc_new(vonoff, vsecs);
339 }
340
341 /*
342 * call-seq:
343 * Socket::Option.ipv4_multicast_loop(integer) => sockopt
344 *
345 * Creates a new Socket::Option object for IP_MULTICAST_LOOP.
346 *
347 * The size is dependent on the platform.
348 *
349 * sockopt = Socket::Option.int(:INET, :IPPROTO_IP, :IP_MULTICAST_LOOP, 1)
350 * p sockopt.int => 1
351 *
352 * p Socket::Option.ipv4_multicast_loop(10)
353 * #=> #<Socket::Option: INET IP MULTICAST_LOOP 10>
354 *
355 */
356 static VALUE
357 sockopt_s_ipv4_multicast_loop(VALUE klass, VALUE value)
358 {
359 #if defined(IPPROTO_IP) && defined(IP_MULTICAST_LOOP)
360 # if defined(__NetBSD__) || defined(__OpenBSD__)
361 unsigned char i = NUM2CHR(rb_to_int(value));
362 # else
363 int i = NUM2INT(rb_to_int(value));
364 # endif
365 return rsock_sockopt_new(AF_INET, IPPROTO_IP, IP_MULTICAST_LOOP,
366 rb_str_new((char*)&i, sizeof(i)));
367 #else
368 # error IPPROTO_IP or IP_MULTICAST_LOOP is not implemented
369 #endif
370 }
371
372 /*
373 * call-seq:
374 * sockopt.ipv4_multicast_loop => integer
375 *
376 * Returns the ipv4_multicast_loop data in _sockopt_ as a integer.
377 *
378 * sockopt = Socket::Option.ipv4_multicast_loop(10)
379 * p sockopt.ipv4_multicast_loop => 10
380 */
381 static VALUE
382 sockopt_ipv4_multicast_loop(VALUE self)
383 {
384 int family = NUM2INT(sockopt_family_m(self));
385 int level = sockopt_level(self);
386 int optname = sockopt_optname(self);
387
388 #if defined(IPPROTO_IP) && defined(IP_MULTICAST_LOOP)
389 if (family == AF_INET && level == IPPROTO_IP && optname == IP_MULTICAST_LOOP) {
390 # if defined(__NetBSD__) || defined(__OpenBSD__)
391 return sockopt_byte(self);
392 # else
393 return sockopt_int(self);
394 # endif
395 }
396 #endif
397 rb_raise(rb_eTypeError, "ipv4_multicast_loop socket option expected");
398 UNREACHABLE;
399 }
400
401 #if defined(__NetBSD__) || defined(__OpenBSD__)
402 # define inspect_ipv4_multicast_loop(a,b,c,d) inspect_byte(a,b,c,d)
403 #else
404 # define inspect_ipv4_multicast_loop(a,b,c,d) inspect_int(a,b,c,d)
405 #endif
406
407 /*
408 * call-seq:
409 * Socket::Option.ipv4_multicast_ttl(integer) => sockopt
410 *
411 * Creates a new Socket::Option object for IP_MULTICAST_TTL.
412 *
413 * The size is dependent on the platform.
414 *
415 * p Socket::Option.ipv4_multicast_ttl(10)
416 * #=> #<Socket::Option: INET IP MULTICAST_TTL 10>
417 *
418 */
419 static VALUE
420 sockopt_s_ipv4_multicast_ttl(VALUE klass, VALUE value)
421 {
422 #if defined(IPPROTO_IP) && defined(IP_MULTICAST_TTL)
423 # if defined(__NetBSD__) || defined(__OpenBSD__)
424 unsigned char i = NUM2CHR(rb_to_int(value));
425 # else
426 int i = NUM2INT(rb_to_int(value));
427 # endif
428 return rsock_sockopt_new(AF_INET, IPPROTO_IP, IP_MULTICAST_TTL,
429 rb_str_new((char*)&i, sizeof(i)));
430 #else
431 # error IPPROTO_IP or IP_MULTICAST_TTL is not implemented
432 #endif
433 }
434
435 /*
436 * call-seq:
437 * sockopt.ipv4_multicast_ttl => integer
438 *
439 * Returns the ipv4_multicast_ttl data in _sockopt_ as a integer.
440 *
441 * sockopt = Socket::Option.ipv4_multicast_ttl(10)
442 * p sockopt.ipv4_multicast_ttl => 10
443 */
444 static VALUE
445 sockopt_ipv4_multicast_ttl(VALUE self)
446 {
447 int family = NUM2INT(sockopt_family_m(self));
448 int level = sockopt_level(self);
449 int optname = sockopt_optname(self);
450
451 #if defined(IPPROTO_IP) && defined(IP_MULTICAST_TTL)
452 if (family == AF_INET && level == IPPROTO_IP && optname == IP_MULTICAST_TTL) {
453 # if defined(__NetBSD__) || defined(__OpenBSD__)
454 return sockopt_byte(self);
455 # else
456 return sockopt_int(self);
457 # endif
458 }
459 #endif
460 rb_raise(rb_eTypeError, "ipv4_multicast_ttl socket option expected");
461 UNREACHABLE;
462 }
463
464 #if defined(__NetBSD__) || defined(__OpenBSD__)
465 # define inspect_ipv4_multicast_ttl(a,b,c,d) inspect_byte(a,b,c,d)
466 #else
467 # define inspect_ipv4_multicast_ttl(a,b,c,d) inspect_int(a,b,c,d)
468 #endif
469
470 static int
471 inspect_int(int level, int optname, VALUE data, VALUE ret)
472 {
473 if (RSTRING_LEN(data) == sizeof(int)) {
474 int i;
475 memcpy((char*)&i, RSTRING_PTR(data), sizeof(int));
476 rb_str_catf(ret, " %d", i);
477 return 1;
478 }
479 else {
480 return 0;
481 }
482 }
483
484 #if defined(__NetBSD__) || defined(__OpenBSD__)
485 static int
486 inspect_byte(int level, int optname, VALUE data, VALUE ret)
487 {
488 if (RSTRING_LEN(data) == sizeof(unsigned char)) {
489 rb_str_catf(ret, " %d", (unsigned char)*RSTRING_PTR(data));
490 return 1;
491 }
492 else {
493 return 0;
494 }
495 }
496 #endif
497
498 static int
499 inspect_errno(int level, int optname, VALUE data, VALUE ret)
500 {
501 if (RSTRING_LEN(data) == sizeof(int)) {
502 int i;
503 char *err;
504 memcpy((char*)&i, RSTRING_PTR(data), sizeof(int));
505 err = strerror(i);
506 rb_str_catf(ret, " %s (%d)", err, i);
507 return 1;
508 }
509 else {
510 return 0;
511 }
512 }
513
514 #if defined(IPV6_MULTICAST_LOOP)
515 static int
516 inspect_uint(int level, int optname, VALUE data, VALUE ret)
517 {
518 if (RSTRING_LEN(data) == sizeof(int)) {
519 unsigned int i;
520 memcpy((char*)&i, RSTRING_PTR(data), sizeof(unsigned int));
521 rb_str_catf(ret, " %u", i);
522 return 1;
523 }
524 else {
525 return 0;
526 }
527 }
528 #endif
529
530 #if defined(SOL_SOCKET) && defined(SO_LINGER) /* POSIX */
531 static int
532 inspect_linger(int level, int optname, VALUE data, VALUE ret)
533 {
534 if (RSTRING_LEN(data) == sizeof(struct linger)) {
535 struct linger s;
536 memcpy((char*)&s, RSTRING_PTR(data), sizeof(s));
537 switch (s.l_onoff) {
538 case 0: rb_str_cat2(ret, " off"); break;
539 case 1: rb_str_cat2(ret, " on"); break;
540 default: rb_str_catf(ret, " on(%d)", s.l_onoff); break;
541 }
542 rb_str_catf(ret, " %dsec", s.l_linger);
543 return 1;
544 }
545 else {
546 return 0;
547 }
548 }
549 #endif
550
551 #if defined(SOL_SOCKET) && defined(SO_TYPE) /* POSIX */
552 static int
553 inspect_socktype(int level, int optname, VALUE data, VALUE ret)
554 {
555 if (RSTRING_LEN(data) == sizeof(int)) {
556 int i;
557 ID id;
558 memcpy((char*)&i, RSTRING_PTR(data), sizeof(int));
559 id = rsock_intern_socktype(i);
560 if (id)
561 rb_str_catf(ret, " %s", rb_id2name(id));
562 else
563 rb_str_catf(ret, " %d", i);
564 return 1;
565 }
566 else {
567 return 0;
568 }
569 }
570 #endif
571
572 static int
573 inspect_timeval_as_interval(int level, int optname, VALUE data, VALUE ret)
574 {
575 if (RSTRING_LEN(data) == sizeof(struct timeval)) {
576 struct timeval s;
577 memcpy((char*)&s, RSTRING_PTR(data), sizeof(s));
578 rb_str_catf(ret, " %ld.%06ldsec", (long)s.tv_sec, (long)s.tv_usec);
579 return 1;
580 }
581 else {
582 return 0;
583 }
584 }
585
586 /*
587 * socket option for IPv4 multicast is bit confusing.
588 *
589 * IP Multicast is implemented by Steve Deering at first:
590 * IP Multicast Extensions for 4.3BSD UNIX and related systems
591 * (MULTICAST 1.2 Release)
592 * http://www.kohala.com/start/mcast.api.txt
593 *
594 * There are 3 socket options which takes a struct.
595 *
596 * IP_MULTICAST_IF: struct in_addr
597 * IP_ADD_MEMBERSHIP: struct ip_mreq
598 * IP_DROP_MEMBERSHIP: struct ip_mreq
599 *
600 * But they uses an IP address to specify an interface.
601 * This means the API cannot specify an unnumbered interface.
602 *
603 * Linux 2.4 introduces struct ip_mreqn to fix this problem.
604 * struct ip_mreqn has imr_ifindex field to specify interface index.
605 *
606 * IP_MULTICAST_IF: struct ip_mreqn
607 * IP_ADD_MEMBERSHIP: struct ip_mreqn
608 * IP_DROP_MEMBERSHIP: struct ip_mreqn
609 *
610 * FreeBSD 7 obtained struct ip_mreqn for IP_MULTICAST_IF.
611 * http://www.FreeBSD.org/cgi/cvsweb.cgi/src/sys/netinet/in.h.diff?r1=1.99;r2=1.100
612 *
613 * Another hackish workaround is "RFC 1724 hack".
614 * RFC 1724 section 3.3 suggests unnumbered interfaces
615 * specified by pseudo address 0.0.0.0/8.
616 * NetBSD 4 and FreeBSD 5 documented it.
617 * http://cvsweb.netbsd.org/cgi-bin/cvsweb.cgi/src/share/man/man4/ip.4.diff?r1=1.16&r2=1.17
618 * http://www.FreeBSD.org/cgi/cvsweb.cgi/src/share/man/man4/ip.4.diff?r1=1.37;r2=1.38
619 * FreeBSD 7.0 removed it.
620 * http://www.FreeBSD.org/cgi/cvsweb.cgi/src/share/man/man4/ip.4.diff?r1=1.49;r2=1.50
621 *
622 * RFC 1724 hack is not supported by Socket::Option#inspect because
623 * it is not distinguishable by the size.
624 */
625
626 #ifndef HAVE_INET_NTOP
627 static const char *
628 inet_ntop(int af, const void *addr, char *numaddr, size_t numaddr_len)
629 {
630 #ifdef HAVE_INET_NTOA
631 struct in_addr in;
632 memcpy(&in.s_addr, addr, sizeof(in.s_addr));
633 snprintf(numaddr, numaddr_len, "%s", inet_ntoa(in));
634 #else
635 unsigned long x = ntohl(*(unsigned long*)addr);
636 snprintf(numaddr, numaddr_len, "%d.%d.%d.%d",
637 (int) (x>>24) & 0xff, (int) (x>>16) & 0xff,
638 (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff);
639 #endif
640 return numaddr;
641 }
642 #elif defined __MINGW64__
643 # define inet_ntop(f,a,n,l) rb_w32_inet_ntop(f,a,n,l)
644 #endif
645
646 /* Although the buffer size needed depends on the prefixes, "%u" may generate "4294967295". */
647 static int
648 rb_if_indextoname(const char *succ_prefix, const char *fail_prefix, unsigned int ifindex, char *buf, size_t len)
649 {
650 #if defined(HAVE_IF_INDEXTONAME)
651 char ifbuf[IFNAMSIZ];
652 if (if_indextoname(ifindex, ifbuf) == NULL)
653 return snprintf(buf, len, "%s%u", fail_prefix, ifindex);
654 else
655 return snprintf(buf, len, "%s%s", succ_prefix, ifbuf);
656 #else
657 # ifndef IFNAMSIZ
658 # define IFNAMSIZ (sizeof(unsigned int)*3+1)
659 # endif
660 return snprintf(buf, len, "%s%u", fail_prefix, ifindex);
661 #endif
662 }
663
664 #if defined(IPPROTO_IP) && defined(HAVE_TYPE_STRUCT_IP_MREQ) /* 4.4BSD, GNU/Linux */
665 static int
666 inspect_ipv4_mreq(int level, int optname, VALUE data, VALUE ret)
667 {
668 if (RSTRING_LEN(data) == sizeof(struct ip_mreq)) {
669 struct ip_mreq s;
670 char addrbuf[INET_ADDRSTRLEN];
671 memcpy((char*)&s, RSTRING_PTR(data), sizeof(s));
672 if (inet_ntop(AF_INET, &s.imr_multiaddr, addrbuf, (socklen_t)sizeof(addrbuf)) == NULL)
673 rb_str_cat2(ret, " invalid-address");
674 else
675 rb_str_catf(ret, " %s", addrbuf);
676 if (inet_ntop(AF_INET, &s.imr_interface, addrbuf, (socklen_t)sizeof(addrbuf)) == NULL)
677 rb_str_catf(ret, " invalid-address");
678 else
679 rb_str_catf(ret, " %s", addrbuf);
680 return 1;
681 }
682 else {
683 return 0;
684 }
685 }
686 #endif
687
688 #if defined(IPPROTO_IP) && defined(HAVE_TYPE_STRUCT_IP_MREQN) /* GNU/Linux, FreeBSD 7 */
689 static int
690 inspect_ipv4_mreqn(int level, int optname, VALUE data, VALUE ret)
691 {
692 if (RSTRING_LEN(data) == sizeof(struct ip_mreqn)) {
693 struct ip_mreqn s;
694 char addrbuf[INET_ADDRSTRLEN], ifbuf[32+IFNAMSIZ];
695 memcpy((char*)&s, RSTRING_PTR(data), sizeof(s));
696 if (inet_ntop(AF_INET, &s.imr_multiaddr, addrbuf, (socklen_t)sizeof(addrbuf)) == NULL)
697 rb_str_cat2(ret, " invalid-address");
698 else
699 rb_str_catf(ret, " %s", addrbuf);
700 if (inet_ntop(AF_INET, &s.imr_address, addrbuf, (socklen_t)sizeof(addrbuf)) == NULL)
701 rb_str_catf(ret, " invalid-address");
702 else
703 rb_str_catf(ret, " %s", addrbuf);
704 rb_if_indextoname(" ", " ifindex:", s.imr_ifindex, ifbuf, sizeof(ifbuf));
705 rb_str_cat2(ret, ifbuf);
706 return 1;
707 }
708 else {
709 return 0;
710 }
711 }
712 #endif
713
714 #if defined(IPPROTO_IP) && defined(HAVE_TYPE_STRUCT_IP_MREQ) /* 4.4BSD, GNU/Linux */
715 static int
716 inspect_ipv4_add_drop_membership(int level, int optname, VALUE data, VALUE ret)
717 {
718 if (RSTRING_LEN(data) == sizeof(struct ip_mreq))
719 return inspect_ipv4_mreq(level, optname, data, ret);
720 # if defined(HAVE_TYPE_STRUCT_IP_MREQN)
721 else if (RSTRING_LEN(data) == sizeof(struct ip_mreqn))
722 return inspect_ipv4_mreqn(level, optname, data, ret);
723 # endif
724 else
725 return 0;
726 }
727 #endif
728
729 #if defined(IPPROTO_IP) && defined(IP_MULTICAST_IF) && defined(HAVE_TYPE_STRUCT_IP_MREQN) /* 4.4BSD, GNU/Linux */
730 static int
731 inspect_ipv4_multicast_if(int level, int optname, VALUE data, VALUE ret)
732 {
733 if (RSTRING_LEN(data) == sizeof(struct in_addr)) {
734 struct in_addr s;
735 char addrbuf[INET_ADDRSTRLEN];
736 memcpy((char*)&s, RSTRING_PTR(data), sizeof(s));
737 if (inet_ntop(AF_INET, &s, addrbuf, (socklen_t)sizeof(addrbuf)) == NULL)
738 rb_str_cat2(ret, " invalid-address");
739 else
740 rb_str_catf(ret, " %s", addrbuf);
741 return 1;
742 }
743 else if (RSTRING_LEN(data) == sizeof(struct ip_mreqn)) {
744 return inspect_ipv4_mreqn(level, optname, data, ret);
745 }
746 else {
747 return 0;
748 }
749 }
750 #endif
751
752 #if defined(IPV6_MULTICAST_IF) /* POSIX, RFC 3493 */
753 static int
754 inspect_ipv6_multicast_if(int level, int optname, VALUE data, VALUE ret)
755 {
756 if (RSTRING_LEN(data) == sizeof(int)) {
757 char ifbuf[32+IFNAMSIZ];
758 unsigned int ifindex;
759 memcpy((char*)&ifindex, RSTRING_PTR(data), sizeof(unsigned int));
760 rb_if_indextoname(" ", " ", ifindex, ifbuf, sizeof(ifbuf));
761 rb_str_cat2(ret, ifbuf);
762 return 1;
763 }
764 else {
765 return 0;
766 }
767 }
768 #endif
769
770 #if defined(IPPROTO_IPV6) && defined(HAVE_TYPE_STRUCT_IPV6_MREQ) /* POSIX, RFC 3493 */
771 static int
772 inspect_ipv6_mreq(int level, int optname, VALUE data, VALUE ret)
773 {
774 if (RSTRING_LEN(data) == sizeof(struct ipv6_mreq)) {
775 struct ipv6_mreq s;
776 char addrbuf[INET6_ADDRSTRLEN], ifbuf[32+IFNAMSIZ];
777 memcpy((char*)&s, RSTRING_PTR(data), sizeof(s));
778 if (inet_ntop(AF_INET6, &s.ipv6mr_multiaddr, addrbuf, (socklen_t)sizeof(addrbuf)) == NULL)
779 rb_str_cat2(ret, " invalid-address");
780 else
781 rb_str_catf(ret, " %s", addrbuf);
782 rb_if_indextoname(" ", " interface:", s.ipv6mr_interface, ifbuf, sizeof(ifbuf));
783 rb_str_cat2(ret, ifbuf);
784 return 1;
785 }
786 else {
787 return 0;
788 }
789 }
790 #endif
791
792 #if defined(SOL_SOCKET) && defined(SO_PEERCRED) /* GNU/Linux, OpenBSD */
793 #if defined(__OpenBSD__)
794 #define RUBY_SOCK_PEERCRED struct sockpeercred
795 #else
796 #define RUBY_SOCK_PEERCRED struct ucred
797 #endif
798 static int
799 inspect_peercred(int level, int optname, VALUE data, VALUE ret)
800 {
801 if (RSTRING_LEN(data) == sizeof(RUBY_SOCK_PEERCRED)) {
802 RUBY_SOCK_PEERCRED cred;
803 memcpy(&cred, RSTRING_PTR(data), sizeof(RUBY_SOCK_PEERCRED));
804 rb_str_catf(ret, " pid=%u euid=%u egid=%u",
805 (unsigned)cred.pid, (unsigned)cred.uid, (unsigned)cred.gid);
806 rb_str_cat2(ret, " (ucred)");
807 return 1;
808 }
809 else {
810 return 0;
811 }
812 }
813 #endif
814
815 #if defined(LOCAL_PEERCRED) /* FreeBSD, MacOS X */
816 static int
817 inspect_local_peercred(int level, int optname, VALUE data, VALUE ret)
818 {
819 if (RSTRING_LEN(data) == sizeof(struct xucred)) {
820 struct xucred cred;
821 memcpy(&cred, RSTRING_PTR(data), sizeof(struct xucred));
822 if (cred.cr_version != XUCRED_VERSION)
823 return 0;
824 rb_str_catf(ret, " version=%u", cred.cr_version);
825 rb_str_catf(ret, " euid=%u", cred.cr_uid);
826 if (cred.cr_ngroups) {
827 int i;
828 const char *sep = " groups=";
829 for (i = 0; i < cred.cr_ngroups; i++) {
830 rb_str_catf(ret, "%s%u", sep, cred.cr_groups[i]);
831 sep = ",";
832 }
833 }
834 rb_str_cat2(ret, " (xucred)");
835 return 1;
836 }
837 else {
838 return 0;
839 }
840 }
841 #endif
842
843
844 /*
845 * call-seq:
846 * sockopt.inspect => string
847 *
848 * Returns a string which shows sockopt in human-readable form.
849 *
850 * p Socket::Option.new(:INET, :SOCKET, :KEEPALIVE, [1].pack("i")).inspect
851 * #=> "#<Socket::Option: INET SOCKET KEEPALIVE 1>"
852 *
853 */
854 static VALUE
855 sockopt_inspect(VALUE self)
856 {
857 int family = NUM2INT(sockopt_family_m(self));
858 int level = NUM2INT(sockopt_level_m(self));
859 int optname = NUM2INT(sockopt_optname_m(self));
860 VALUE data = sockopt_data(self);
861 VALUE v, ret;
862 ID family_id, level_id, optname_id;
863 int inspected;
864
865 StringValue(data);
866
867 ret = rb_sprintf("#<%s:", rb_obj_classname(self));
868
869 family_id = rsock_intern_family_noprefix(family);
870 if (family_id)
871 rb_str_catf(ret, " %s", rb_id2name(family_id));
872 else
873 rb_str_catf(ret, " family:%d", family);
874
875 if (level == SOL_SOCKET) {
876 rb_str_cat2(ret, " SOCKET");
877
878 optname_id = rsock_intern_so_optname(optname);
879 if (optname_id)
880 rb_str_catf(ret, " %s", rb_id2name(optname_id));
881 else
882 rb_str_catf(ret, " optname:%d", optname);
883 }
884 #ifdef HAVE_SYS_UN_H
885 else if (family == AF_UNIX) {
886 rb_str_catf(ret, " level:%d", level);
887
888 optname_id = rsock_intern_local_optname(optname);
889 if (optname_id)
890 rb_str_catf(ret, " %s", rb_id2name(optname_id));
891 else
892 rb_str_catf(ret, " optname:%d", optname);
893 }
894 #endif
895 else if (IS_IP_FAMILY(family)) {
896 level_id = rsock_intern_iplevel(level);
897 if (level_id)
898 rb_str_catf(ret, " %s", rb_id2name(level_id));
899 else
900 rb_str_catf(ret, " level:%d", level);
901
902 v = optname_to_sym(level, optname);
903 if (SYMBOL_P(v))
904 rb_str_catf(ret, " %s", rb_id2name(SYM2ID(v)));
905 else
906 rb_str_catf(ret, " optname:%d", optname);
907 }
908 else {
909 rb_str_catf(ret, " level:%d", level);
910 rb_str_catf(ret, " optname:%d", optname);
911 }
912
913 inspected = 0;
914
915 if (level == SOL_SOCKET)
916 family = AF_UNSPEC;
917 switch (family) {
918 case AF_UNSPEC:
919 switch (level) {
920 case SOL_SOCKET:
921 switch (optname) {
922 # if defined(SO_DEBUG) /* POSIX */
923 case SO_DEBUG: inspected = inspect_int(level, optname, data, ret); break;
924 # endif
925 # if defined(SO_ERROR) /* POSIX */
926 case SO_ERROR: inspected = inspect_errno(level, optname, data, ret); break;
927 # endif
928 # if defined(SO_TYPE) /* POSIX */
929 case SO_TYPE: inspected = inspect_socktype(level, optname, data, ret); break;
930 # endif
931 # if defined(SO_ACCEPTCONN) /* POSIX */
932 case SO_ACCEPTCONN: inspected = inspect_int(level, optname, data, ret); break;
933 # endif
934 # if defined(SO_BROADCAST) /* POSIX */
935 case SO_BROADCAST: inspected = inspect_int(level, optname, data, ret); break;
936 # endif
937 # if defined(SO_REUSEADDR) /* POSIX */
938 case SO_REUSEADDR: inspected = inspect_int(level, optname, data, ret); break;
939 # endif
940 # if defined(SO_KEEPALIVE) /* POSIX */
941 case SO_KEEPALIVE: inspected = inspect_int(level, optname, data, ret); break;
942 # endif
943 # if defined(SO_OOBINLINE) /* POSIX */
944 case SO_OOBINLINE: inspected = inspect_int(level, optname, data, ret); break;
945 # endif
946 # if defined(SO_SNDBUF) /* POSIX */
947 case SO_SNDBUF: inspected = inspect_int(level, optname, data, ret); break;
948 # endif
949 # if defined(SO_RCVBUF) /* POSIX */
950 case SO_RCVBUF: inspected = inspect_int(level, optname, data, ret); break;
951 # endif
952 # if defined(SO_DONTROUTE) /* POSIX */
953 case SO_DONTROUTE: inspected = inspect_int(level, optname, data, ret); break;
954 # endif
955 # if defined(SO_RCVLOWAT) /* POSIX */
956 case SO_RCVLOWAT: inspected = inspect_int(level, optname, data, ret); break;
957 # endif
958 # if defined(SO_SNDLOWAT) /* POSIX */
959 case SO_SNDLOWAT: inspected = inspect_int(level, optname, data, ret); break;
960 # endif
961 # if defined(SO_LINGER) /* POSIX */
962 case SO_LINGER: inspected = inspect_linger(level, optname, data, ret); break;
963 # endif
964 # if defined(SO_RCVTIMEO) /* POSIX */
965 case SO_RCVTIMEO: inspected = inspect_timeval_as_interval(level, optname, data, ret); break;
966 # endif
967 # if defined(SO_SNDTIMEO) /* POSIX */
968 case SO_SNDTIMEO: inspected = inspect_timeval_as_interval(level, optname, data, ret); break;
969 # endif
970 # if defined(SO_PEERCRED) /* GNU/Linux, OpenBSD */
971 case SO_PEERCRED: inspected = inspect_peercred(level, optname, data, ret); break;
972 # endif
973 }
974 break;
975 }
976 break;
977
978 case AF_INET:
979 #ifdef INET6
980 case AF_INET6:
981 #endif
982 switch (level) {
983 # if defined(IPPROTO_IP)
984 case IPPROTO_IP:
985 switch (optname) {
986 # if defined(IP_MULTICAST_IF) && defined(HAVE_TYPE_STRUCT_IP_MREQN) /* 4.4BSD, GNU/Linux */
987 case IP_MULTICAST_IF: inspected = inspect_ipv4_multicast_if(level, optname, data, ret); break;
988 # endif
989 # if defined(IP_ADD_MEMBERSHIP) /* 4.4BSD, GNU/Linux */
990 case IP_ADD_MEMBERSHIP: inspected = inspect_ipv4_add_drop_membership(level, optname, data, ret); break;
991 # endif
992 # if defined(IP_DROP_MEMBERSHIP) /* 4.4BSD, GNU/Linux */
993 case IP_DROP_MEMBERSHIP: inspected = inspect_ipv4_add_drop_membership(level, optname, data, ret); break;
994 # endif
995 # if defined(IP_MULTICAST_LOOP) /* 4.4BSD, GNU/Linux */
996 case IP_MULTICAST_LOOP: inspected = inspect_ipv4_multicast_loop(level, optname, data, ret); break;
997 # endif
998 # if defined(IP_MULTICAST_TTL) /* 4.4BSD, GNU/Linux */
999 case IP_MULTICAST_TTL: inspected = inspect_ipv4_multicast_ttl(level, optname, data, ret); break;
1000 # endif
1001 }
1002 break;
1003 # endif
1004
1005 # if defined(IPPROTO_IPV6)
1006 case IPPROTO_IPV6:
1007 switch (optname) {
1008 # if defined(IPV6_MULTICAST_HOPS) /* POSIX */
1009 case IPV6_MULTICAST_HOPS: inspected = inspect_int(level, optname, data, ret); break;
1010 # endif
1011 # if defined(IPV6_MULTICAST_IF) /* POSIX */
1012 case IPV6_MULTICAST_IF: inspected = inspect_ipv6_multicast_if(level, optname, data, ret); break;
1013 # endif
1014 # if defined(IPV6_MULTICAST_LOOP) /* POSIX */
1015 case IPV6_MULTICAST_LOOP: inspected = inspect_uint(level, optname, data, ret); break;
1016 # endif
1017 # if defined(IPV6_JOIN_GROUP) /* POSIX */
1018 case IPV6_JOIN_GROUP: inspected = inspect_ipv6_mreq(level, optname, data, ret); break;
1019 # endif
1020 # if defined(IPV6_LEAVE_GROUP) /* POSIX */
1021 case IPV6_LEAVE_GROUP: inspected = inspect_ipv6_mreq(level, optname, data, ret); break;
1022 # endif
1023 # if defined(IPV6_UNICAST_HOPS) /* POSIX */
1024 case IPV6_UNICAST_HOPS: inspected = inspect_int(level, optname, data, ret); break;
1025 # endif
1026 # if defined(IPV6_V6ONLY) /* POSIX */
1027 case IPV6_V6ONLY: inspected = inspect_int(level, optname, data, ret); break;
1028 # endif
1029 }
1030 break;
1031 # endif
1032
1033 # if defined(IPPROTO_TCP)
1034 case IPPROTO_TCP:
1035 switch (optname) {
1036 # if defined(TCP_NODELAY) /* POSIX */
1037 case TCP_NODELAY: inspected = inspect_int(level, optname, data, ret); break;
1038 # endif
1039 }
1040 break;
1041 # endif
1042 }
1043 break;
1044
1045 #ifdef HAVE_SYS_UN_H
1046 case AF_UNIX:
1047 switch (level) {
1048 case 0:
1049 switch (optname) {
1050 # if defined(LOCAL_PEERCRED)
1051 case LOCAL_PEERCRED: inspected = inspect_local_peercred(level, optname, data, ret); break;
1052 # endif
1053 }
1054 break;
1055 }
1056 break;
1057 #endif
1058 }
1059
1060 if (!inspected) {
1061 rb_str_cat2(ret, " ");
1062 rb_str_append(ret, rb_str_dump(data));
1063 }
1064
1065 rb_str_cat2(ret, ">");
1066
1067 return ret;
1068 }
1069
1070 /*
1071 * call-seq:
1072 * sockopt.unpack(template) => array
1073 *
1074 * Calls String#unpack on sockopt.data.
1075 *
1076 * sockopt = Socket::Option.new(:INET, :SOCKET, :KEEPALIVE, [1].pack("i"))
1077 * p sockopt.unpack("i") #=> [1]
1078 * p sockopt.data.unpack("i") #=> [1]
1079 */
1080 static VALUE
1081 sockopt_unpack(VALUE self, VALUE template)
1082 {
1083 return rb_funcall(sockopt_data(self), rb_intern("unpack"), 1, template);
1084 }
1085
1086 void
1087 rsock_init_sockopt(void)
1088 {
1089 /*
1090 * Document-class: Socket::Option
1091 *
1092 * Socket::Option represents a socket option used by
1093 * BasicSocket#getsockopt and BasicSocket#setsockopt. A socket option
1094 * contains the socket #family, protocol #level, option name #optname and
1095 * option value #data.
1096 */
1097 rb_cSockOpt = rb_define_class_under(rb_cSocket, "Option", rb_cObject);
1098 rb_define_method(rb_cSockOpt, "initialize", sockopt_initialize, 4);
1099 rb_define_method(rb_cSockOpt, "family", sockopt_family_m, 0);
1100 rb_define_method(rb_cSockOpt, "level", sockopt_level_m, 0);
1101 rb_define_method(rb_cSockOpt, "optname", sockopt_optname_m, 0);
1102 rb_define_method(rb_cSockOpt, "data", sockopt_data, 0);
1103 rb_define_method(rb_cSockOpt, "inspect", sockopt_inspect, 0);
1104
1105 rb_define_singleton_method(rb_cSockOpt, "int", sockopt_s_int, 4);
1106 rb_define_method(rb_cSockOpt, "int", sockopt_int, 0);
1107
1108 rb_define_singleton_method(rb_cSockOpt, "byte", sockopt_s_byte, 4);
1109 rb_define_method(rb_cSockOpt, "byte", sockopt_byte, 0);
1110
1111 rb_define_singleton_method(rb_cSockOpt, "bool", sockopt_s_bool, 4);
1112 rb_define_method(rb_cSockOpt, "bool", sockopt_bool, 0);
1113
1114 rb_define_singleton_method(rb_cSockOpt, "linger", sockopt_s_linger, 2);
1115 rb_define_method(rb_cSockOpt, "linger", sockopt_linger, 0);
1116
1117 rb_define_singleton_method(rb_cSockOpt, "ipv4_multicast_ttl", sockopt_s_ipv4_multicast_ttl, 1);
1118 rb_define_method(rb_cSockOpt, "ipv4_multicast_ttl", sockopt_ipv4_multicast_ttl, 0);
1119
1120 rb_define_singleton_method(rb_cSockOpt, "ipv4_multicast_loop", sockopt_s_ipv4_multicast_loop, 1);
1121 rb_define_method(rb_cSockOpt, "ipv4_multicast_loop", sockopt_ipv4_multicast_loop, 0);
1122
1123 rb_define_method(rb_cSockOpt, "unpack", sockopt_unpack, 1);
1124
1125 rb_define_method(rb_cSockOpt, "to_s", sockopt_data, 0); /* compatibility for ruby before 1.9.2 */
1126 }
1127
T_OBJECT
#define T_OBJECT
Definition: ruby.h:477
rsock_intern_family_noprefix
ID rsock_intern_family_noprefix(int val)
Definition: constdefs.c:6151
sockopt_unpack
static VALUE sockopt_unpack(VALUE self, VALUE template)
Definition: option.c:1081
INT2NUM
#define INT2NUM(x)
Definition: ruby.h:1288
sockopt_family_m
static VALUE sockopt_family_m(VALUE self)
Definition: option.c:80
NUM2INT
#define NUM2INT(x)
Definition: ruby.h:630
sockopt_bool
static VALUE sockopt_bool(VALUE self)
Definition: option.c:268
rb_define_singleton_method
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1655
Qtrue
#define Qtrue
Definition: ruby.h:426
rb_if_indextoname
static int rb_if_indextoname(const char *succ_prefix, const char *fail_prefix, unsigned int ifindex, char *buf, size_t len)
Definition: option.c:648
INET_ADDRSTRLEN
#define INET_ADDRSTRLEN
Definition: constdefs.h:1680
id
const int id
Definition: nkf.c:209
sockopt_inspect
static VALUE sockopt_inspect(VALUE self)
Definition: option.c:855
timeval::tv_sec
long tv_sec
Definition: ossl_asn1.c:17
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:548
optname_to_sym
static VALUE optname_to_sym(int level, int optname)
Definition: option.c:17
UNREACHABLE
#define UNREACHABLE
Definition: ruby.h:42
inspect_timeval_as_interval
static int inspect_timeval_as_interval(int level, int optname, VALUE data, VALUE ret)
Definition: option.c:573
SYM2ID
#define SYM2ID(x)
Definition: ruby.h:356
sockopt_linger
static VALUE sockopt_linger(VALUE self)
Definition: option.c:318
rb_funcall
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:775
rsock_intern_so_optname
ID rsock_intern_so_optname(int val)
Definition: constdefs.c:6196
rb_define_class_under
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:676
rb_to_int
VALUE rb_to_int(VALUE)
Definition: object.c:2679
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1857
rb_check_to_integer
VALUE rb_check_to_integer(VALUE, const char *)
Definition: object.c:2665
rb_obj_classname
const char * rb_obj_classname(VALUE)
Definition: variable.c:406
NEWOBJ_OF
#define NEWOBJ_OF(obj, type, klass, flags)
Definition: ruby.h:694
IPPROTO_TCP
#define IPPROTO_TCP
Definition: constdefs.h:610
sockopt_level_m
static VALUE sockopt_level_m(VALUE self)
Definition: option.c:101
INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN
Definition: constdefs.h:1687
sockopt_ipv4_multicast_ttl
static VALUE sockopt_ipv4_multicast_ttl(VALUE self)
Definition: option.c:445
sockopt_data
static VALUE sockopt_data(VALUE self)
Definition: option.c:138
rsock_family_arg
int rsock_family_arg(VALUE domain)
Definition: constants.c:43
rsock_sockopt_new
VALUE rsock_sockopt_new(int family, int level, int optname, VALUE data)
Definition: option.c:62
level
#define level
timeval::tv_usec
long tv_usec
Definition: ossl_asn1.c:18
sockopt_initialize
static VALUE sockopt_initialize(VALUE self, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE data)
Definition: option.c:48
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1553
inspect_errno
static int inspect_errno(int level, int optname, VALUE data, VALUE ret)
Definition: option.c:499
sockopt_s_bool
static VALUE sockopt_s_bool(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE vbool)
Definition: option.c:249
rb_str_cat2
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:2159
snprintf
#define snprintf
Definition: subst.h:6
NIL_P
#define NIL_P(v)
Definition: ruby.h:438
rsock_level_arg
int rsock_level_arg(int family, VALUE level)
Definition: constants.c:57
inspect_ipv4_multicast_loop
#define inspect_ipv4_multicast_loop(a, b, c, d)
Definition: option.c:404
IPPROTO_UDP
#define IPPROTO_UDP
Definition: constdefs.h:627
Qfalse
#define Qfalse
Definition: ruby.h:425
err
int err
Definition: win32.c:114
rb_cSocket
VALUE rb_cSocket
Definition: init.c:22
constant_to_sym
static VALUE constant_to_sym(int constant, ID(*intern_const)(int))
Definition: option.c:6
IS_IP_FAMILY
#define IS_IP_FAMILY(af)
Definition: rubysocket.h:154
RSTRING_LEN
#define RSTRING_LEN(str)
Definition: ruby.h:841
sockopt_optname
static int sockopt_optname(VALUE self)
Definition: option.c:107
timeval
Definition: ossl_asn1.c:16
socklen_t
int socklen_t
Definition: getaddrinfo.c:84
rsock_intern_iplevel
ID rsock_intern_iplevel(int val)
Definition: constdefs.c:6187
sockopt_s_byte
static VALUE sockopt_s_byte(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE vint)
Definition: option.c:157
rb_sprintf
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1250
NUM2CHR
#define NUM2CHR(x)
Definition: ruby.h:1329
rb_ivar_set
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1133
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
rb_assoc_new
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:616
ID
unsigned long ID
Definition: ruby.h:89
inet_ntop
static const char * inet_ntop(int af, const void *addr, char *numaddr, size_t numaddr_len)
Definition: option.c:628
rsock_intern_tcp_optname
ID rsock_intern_tcp_optname(int val)
Definition: constdefs.c:6223
VALUE
unsigned long VALUE
Definition: ruby.h:88
rsock_intern_local_optname
ID rsock_intern_local_optname(int val)
Definition: constdefs.c:6250
sockopt_ipv4_multicast_loop
static VALUE sockopt_ipv4_multicast_loop(VALUE self)
Definition: option.c:382
rsock_intern_socktype
ID rsock_intern_socktype(int val)
Definition: constdefs.c:6169
rb_str_dump
VALUE rb_str_dump(VALUE)
Definition: string.c:4899
sockopt_optname_m
static VALUE sockopt_optname_m(VALUE self)
Definition: option.c:122
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:845
rubysocket.h
inspect_int
static int inspect_int(int level, int optname, VALUE data, VALUE ret)
Definition: option.c:471
sockopt_int
static VALUE sockopt_int(VALUE self)
Definition: option.c:222
sockopt_s_int
static VALUE sockopt_s_int(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE vint)
Definition: option.c:201
CHR2FIX
#define CHR2FIX(x)
Definition: ruby.h:1331
rb_str_catf
VALUE rb_str_catf(VALUE str, const char *format,...)
Definition: sprintf.c:1290
sockopt_s_ipv4_multicast_loop
static VALUE sockopt_s_ipv4_multicast_loop(VALUE klass, VALUE value)
Definition: option.c:357
strerror
RUBY_EXTERN char * strerror(int)
Definition: strerror.c:11
RTEST
#define RTEST(v)
Definition: ruby.h:437
AF_UNSPEC
#define AF_UNSPEC
Definition: sockport.h:101
rsock_intern_udp_optname
ID rsock_intern_udp_optname(int val)
Definition: constdefs.c:6232
sockopt_s_linger
static VALUE sockopt_s_linger(VALUE klass, VALUE vonoff, VALUE vsecs)
Definition: option.c:295
rsock_optname_arg
int rsock_optname_arg(int family, int level, VALUE optname)
Definition: constants.c:69
rb_cSockOpt
VALUE rb_cSockOpt
Definition: option.c:3
name
const char * name
Definition: nkf.c:208
ID2SYM
#define ID2SYM(x)
Definition: ruby.h:355
rb_id2name
const char * rb_id2name(ID id)
Definition: ripper.c:17230
sockopt_level
static int sockopt_level(VALUE self)
Definition: option.c:86
RObject
Definition: ruby.h:762
IFNAMSIZ
#define IFNAMSIZ
rsock_init_sockopt
void rsock_init_sockopt(void)
Definition: option.c:1087
inspect_ipv4_multicast_ttl
#define inspect_ipv4_multicast_ttl(a, b, c, d)
Definition: option.c:467
IPPROTO_IP
#define IPPROTO_IP
Definition: constdefs.h:586
sockopt_byte
static VALUE sockopt_byte(VALUE self)
Definition: option.c:178
sockopt_s_ipv4_multicast_ttl
static VALUE sockopt_s_ipv4_multicast_ttl(VALUE klass, VALUE value)
Definition: option.c:420
rsock_intern_ipv6_optname
ID rsock_intern_ipv6_optname(int val)
Definition: constdefs.c:6214
rb_intern
#define rb_intern(str)
SYMBOL_P
#define SYMBOL_P(x)
Definition: ruby.h:354
NULL
#define NULL
Definition: _sdbm.c:103
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1488
rb_str_append
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2298
rb_attr_get
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1127
StringValue
#define StringValue(v)
Definition: ruby.h:539
rsock_intern_ip_optname
ID rsock_intern_ip_optname(int val)
Definition: constdefs.c:6205
rb_str_new
VALUE rb_str_new(const char *, long)
Definition: string.c:534