1/************************************************ 2 3 constants.c - 4 5 created at: Thu Mar 31 12:21:29 JST 1994 6 7 Copyright (C) 1993-2007 Yukihiro Matsumoto 8 9************************************************/ 10 11#include "rubysocket.h" 12 13static VALUE rb_mSockConst; 14 15#include "constdefs.c" 16 17static int 18constant_arg(VALUE arg, int (*str_to_int)(const char*, long, int*), const char *errmsg) 19{ 20 VALUE tmp; 21 char *ptr; 22 int ret; 23 24 if (SYMBOL_P(arg)) { 25 arg = rb_sym_to_s(arg); 26 goto str; 27 } 28 else if (!NIL_P(tmp = rb_check_string_type(arg))) { 29 arg = tmp; 30 str: 31 rb_check_safe_obj(arg); 32 ptr = RSTRING_PTR(arg); 33 if (str_to_int(ptr, RSTRING_LEN(arg), &ret) == -1) 34 rb_raise(rb_eSocket, "%s: %s", errmsg, ptr); 35 } 36 else { 37 ret = NUM2INT(arg); 38 } 39 return ret; 40} 41 42int 43rsock_family_arg(VALUE domain) 44{ 45 /* convert AF_INET, etc. */ 46 return constant_arg(domain, rsock_family_to_int, "unknown socket domain"); 47} 48 49int 50rsock_socktype_arg(VALUE type) 51{ 52 /* convert SOCK_STREAM, etc. */ 53 return constant_arg(type, rsock_socktype_to_int, "unknown socket type"); 54} 55 56int 57rsock_level_arg(int family, VALUE level) 58{ 59 /* convert SOL_SOCKET, IPPROTO_TCP, etc. */ 60 if (IS_IP_FAMILY(family)) { 61 return constant_arg(level, rsock_ip_level_to_int, "unknown protocol level"); 62 } 63 else { 64 return constant_arg(level, rsock_unknown_level_to_int, "unknown protocol level"); 65 } 66} 67 68int 69rsock_optname_arg(int family, int level, VALUE optname) 70{ 71 if (IS_IP_FAMILY(family)) { 72 switch (level) { 73 case SOL_SOCKET: 74 return constant_arg(optname, rsock_so_optname_to_int, "unknown socket level option name"); 75 case IPPROTO_IP: 76 return constant_arg(optname, rsock_ip_optname_to_int, "unknown IP level option name"); 77#ifdef IPPROTO_IPV6 78 case IPPROTO_IPV6: 79 return constant_arg(optname, rsock_ipv6_optname_to_int, "unknown IPv6 level option name"); 80#endif 81 case IPPROTO_TCP: 82 return constant_arg(optname, rsock_tcp_optname_to_int, "unknown TCP level option name"); 83 case IPPROTO_UDP: 84 return constant_arg(optname, rsock_udp_optname_to_int, "unknown UDP level option name"); 85 default: 86 return NUM2INT(optname); 87 } 88 } 89 else { 90 switch (level) { 91 case SOL_SOCKET: 92 return constant_arg(optname, rsock_so_optname_to_int, "unknown socket level option name"); 93 default: 94 return NUM2INT(optname); 95 } 96 } 97} 98 99int 100rsock_cmsg_type_arg(int family, int level, VALUE type) 101{ 102 if (IS_IP_FAMILY(family)) { 103 switch (level) { 104 case SOL_SOCKET: 105 return constant_arg(type, rsock_scm_optname_to_int, "unknown UNIX control message"); 106 case IPPROTO_IP: 107 return constant_arg(type, rsock_ip_optname_to_int, "unknown IP control message"); 108#ifdef INET6 109 case IPPROTO_IPV6: 110 return constant_arg(type, rsock_ipv6_optname_to_int, "unknown IPv6 control message"); 111#endif 112 case IPPROTO_TCP: 113 return constant_arg(type, rsock_tcp_optname_to_int, "unknown TCP control message"); 114 case IPPROTO_UDP: 115 return constant_arg(type, rsock_udp_optname_to_int, "unknown UDP control message"); 116 default: 117 return NUM2INT(type); 118 } 119 } 120 else { 121 switch (level) { 122 case SOL_SOCKET: 123 return constant_arg(type, rsock_scm_optname_to_int, "unknown UNIX control message"); 124 default: 125 return NUM2INT(type); 126 } 127 } 128} 129 130int 131rsock_shutdown_how_arg(VALUE how) 132{ 133 /* convert SHUT_RD, SHUT_WR, SHUT_RDWR. */ 134 return constant_arg(how, rsock_shutdown_how_to_int, "unknown shutdown argument"); 135} 136 137/* 138 * Socket::Constants module 139 */ 140void 141rsock_init_socket_constants(void) 142{ 143 /* constants */ 144 init_constants(); 145} 146