PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/IronPython_Main/Languages/Ruby/Libraries.LCA_RESTRICTED/socket/Socket.cs

#
C# | 739 lines | 595 code | 105 blank | 39 comment | 29 complexity | 75ab0179dd3a908766da76613fecf82a MD5 | raw file
Possible License(s): GPL-2.0, MPL-2.0-no-copyleft-exception, CPL-1.0, CC-BY-SA-3.0, BSD-3-Clause, ISC, AGPL-3.0, LGPL-2.1, Apache-2.0
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
  6. * copy of the license can be found in the License.html file at the root of this distribution. If
  7. * you cannot locate the Apache License, Version 2.0, please send an email to
  8. * ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. * by the terms of the Apache License, Version 2.0.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. #if !SILVERLIGHT
  16. using System;
  17. using System.Net;
  18. using System.Net.Sockets;
  19. using System.Reflection;
  20. using System.Runtime.InteropServices;
  21. using Microsoft.Scripting;
  22. using Microsoft.Scripting.Runtime;
  23. using IronRuby.Builtins;
  24. using IronRuby.Compiler;
  25. using IronRuby.Runtime;
  26. using System.IO;
  27. using Microsoft.Scripting.Math;
  28. namespace IronRuby.StandardLibrary.Sockets {
  29. [RubyClass("Socket", BuildConfig = "!SILVERLIGHT")]
  30. [Includes(typeof(SocketConstants), Copy = true)]
  31. public class RubySocket : RubyBasicSocket {
  32. #region Construction
  33. public RubySocket(RubyContext/*!*/ context, Socket/*!*/ socket)
  34. : base(context, socket) {
  35. }
  36. [RubyConstructor]
  37. public static RubySocket/*!*/ CreateSocket(ConversionStorage<MutableString>/*!*/ stringCast, ConversionStorage<int>/*!*/ fixnumCast,
  38. RubyClass/*!*/ self, [NotNull]object/*!*/ domain, [DefaultProtocol]int/*!*/ type, [DefaultProtocol]int protocol) {
  39. AddressFamily addressFamily = ConvertToAddressFamily(stringCast, fixnumCast, domain);
  40. return new RubySocket(self.Context, new Socket(addressFamily, (SocketType)type, (ProtocolType)protocol));
  41. }
  42. #endregion
  43. #region Public Singleton Methods
  44. [RubyMethod("getaddrinfo", RubyMethodAttributes.PublicSingleton)]
  45. public static RubyArray GetAddressInfo(
  46. ConversionStorage<MutableString>/*!*/ stringCast, ConversionStorage<int>/*!*/ fixnumCast,
  47. RubyClass/*!*/ self, object hostNameOrAddress, object port,
  48. [DefaultParameterValue(null)]object family,
  49. [DefaultParameterValue(0)]object socktype,
  50. [DefaultParameterValue(0)]object protocol,
  51. [DefaultParameterValue(null)]object flags) {
  52. RubyContext context = self.Context;
  53. IPHostEntry entry = (hostNameOrAddress != null) ?
  54. GetHostEntry(ConvertToHostString(stringCast, hostNameOrAddress), DoNotReverseLookup(context).Value) :
  55. MakeEntry(IPAddress.Any, DoNotReverseLookup(context).Value);
  56. int iPort = ConvertToPortNum(stringCast, fixnumCast, port);
  57. // TODO: ignore family, the only supported families are InterNetwork and InterNetworkV6
  58. ConvertToAddressFamily(stringCast, fixnumCast, family);
  59. int socketType = Protocols.CastToFixnum(fixnumCast, socktype);
  60. int protocolType = Protocols.CastToFixnum(fixnumCast, protocol);
  61. RubyArray results = new RubyArray(entry.AddressList.Length);
  62. for (int i = 0; i < entry.AddressList.Length; ++i) {
  63. IPAddress address = entry.AddressList[i];
  64. RubyArray result = new RubyArray(9);
  65. result.Add(ToAddressFamilyString(address.AddressFamily));
  66. result.Add(iPort);
  67. result.Add(HostNameToMutableString(context, IPAddressToHostName(address, DoNotReverseLookup(context).Value)));
  68. result.Add(MutableString.CreateAscii(address.ToString()));
  69. result.Add((int)address.AddressFamily);
  70. result.Add(socketType);
  71. // TODO: protocol type:
  72. result.Add(protocolType);
  73. results.Add(result);
  74. }
  75. return results;
  76. }
  77. [RubyMethod("gethostbyaddr", RubyMethodAttributes.PublicSingleton)]
  78. public static RubyArray GetHostByAddress(ConversionStorage<MutableString>/*!*/ stringCast, ConversionStorage<int>/*!*/ fixnumCast,
  79. RubyClass/*!*/ self, [DefaultProtocol, NotNull]MutableString/*!*/ address, [DefaultParameterValue(null)]object type) {
  80. // TODO: ignore family, the only supported families are InterNetwork and InterNetworkV6
  81. ConvertToAddressFamily(stringCast, fixnumCast, type);
  82. IPHostEntry entry = GetHostEntry(new IPAddress(address.ConvertToBytes()), DoNotReverseLookup(self.Context).Value);
  83. return CreateHostEntryArray(self.Context, entry, true);
  84. }
  85. [RubyMethod("gethostbyname", RubyMethodAttributes.PublicSingleton)]
  86. public static RubyArray/*!*/ GetHostByName(RubyClass/*!*/ self, int address) {
  87. return GetHostByName(self.Context, ConvertToHostString(address), true);
  88. }
  89. [RubyMethod("gethostbyname", RubyMethodAttributes.PublicSingleton)]
  90. public static RubyArray/*!*/ GetHostByName(RubyClass/*!*/ self, [NotNull]BigInteger/*!*/ address) {
  91. return GetHostByName(self.Context, ConvertToHostString(address), true);
  92. }
  93. [RubyMethod("gethostbyname", RubyMethodAttributes.PublicSingleton)]
  94. public static RubyArray/*!*/ GetHostByName(RubyClass/*!*/ self, [DefaultProtocol]MutableString name) {
  95. return GetHostByName(self.Context, ConvertToHostString(name), true);
  96. }
  97. [RubyMethod("gethostname", RubyMethodAttributes.PublicSingleton)]
  98. public static MutableString GetHostname(RubyClass/*!*/ self) {
  99. return HostNameToMutableString(self.Context, Dns.GetHostName());
  100. }
  101. private static readonly MutableString/*!*/ _DefaultProtocol = MutableString.CreateAscii("tcp").Freeze();
  102. [RubyMethod("getservbyname", RubyMethodAttributes.PublicSingleton)]
  103. public static int GetServiceByName(RubyClass/*!*/ self, [DefaultProtocol, NotNull]MutableString/*!*/ name,
  104. [DefaultProtocol, Optional]MutableString protocol) {
  105. if (protocol == null) {
  106. protocol = _DefaultProtocol;
  107. }
  108. ServiceName service = SearchForService(name, protocol);
  109. if (service != null) {
  110. return service.Port;
  111. }
  112. // Cannot use: object port = Protocols.TryConvertToInteger(context, name);
  113. // Since the conversion process returns 0 if the string is not a valid number
  114. try {
  115. return ParseInteger(self.Context, name.ConvertToString());
  116. } catch (InvalidOperationException) {
  117. throw SocketErrorOps.Create(MutableString.FormatMessage("no such service {0} {1}", name, protocol));
  118. }
  119. }
  120. /// <summary>
  121. /// Returns a pair of connected sockets
  122. /// [Not Implemented]
  123. /// </summary>
  124. [RubyMethod("socketpair", RubyMethodAttributes.PublicSingleton)]
  125. [RubyMethod("pair", RubyMethodAttributes.PublicSingleton)]
  126. public static RubyArray/*!*/ CreateSocketPair(RubyClass/*!*/ self, object domain, object type, object protocol) {
  127. throw new NotImplementedError();
  128. }
  129. [RubyMethod("getnameinfo", RubyMethodAttributes.PublicSingleton)]
  130. public static RubyArray/*!*/ GetNameInfo(ConversionStorage<MutableString>/*!*/ stringCast, ConversionStorage<int>/*!*/ fixnumCast,
  131. RubyClass/*!*/ self, [NotNull]RubyArray/*!*/ hostInfo, [Optional]object flags) {
  132. if (hostInfo.Count < 3 || hostInfo.Count > 4) {
  133. throw RubyExceptions.CreateArgumentError("First parameter must be a 3 or 4 element array");
  134. }
  135. RubyContext context = self.Context;
  136. // We only support AF_INET (IP V4) family
  137. AddressFamily addressFamily = ConvertToAddressFamily(stringCast, fixnumCast, hostInfo[0]);
  138. if (addressFamily != AddressFamily.InterNetwork) {
  139. throw new SocketException((int)SocketError.AddressFamilyNotSupported);
  140. }
  141. // Lookup the service name for the given port.
  142. int port = ConvertToPortNum(stringCast, fixnumCast, hostInfo[1]);
  143. ServiceName service = SearchForService(port);
  144. // hostInfo[2] should have a host name
  145. // if it exists and is not null hostInfo[3] should have an IP address
  146. // in that case we use that rather than the host name.
  147. object hostName = (hostInfo.Count > 3 && hostInfo[3] != null) ? hostInfo[3] : hostInfo[2];
  148. IPHostEntry entry = GetHostEntry(ConvertToHostString(stringCast, hostName), false);
  149. RubyArray result = new RubyArray(2);
  150. result.Add(HostNameToMutableString(context, entry.HostName));
  151. if (service != null) {
  152. result.Add(MutableString.Create(service.Name));
  153. } else {
  154. result.Add(port);
  155. }
  156. return result;
  157. }
  158. [RubyMethod("getnameinfo", RubyMethodAttributes.PublicSingleton)]
  159. public static RubyArray/*!*/ GetNameInfo(RubyClass/*!*/ self,
  160. [DefaultProtocol, NotNull]MutableString/*!*/ address, [Optional]object flags) {
  161. IPEndPoint ep = UnpackSockAddr(address);
  162. IPHostEntry entry = GetHostEntry(ep.Address, false);
  163. ServiceName service = SearchForService(ep.Port);
  164. RubyArray result = new RubyArray(2);
  165. result.Add(HostNameToMutableString(self.Context, entry.HostName));
  166. if (service != null) {
  167. result.Add(MutableString.Create(service.Name));
  168. } else {
  169. result.Add(ep.Port);
  170. }
  171. return result;
  172. }
  173. /// <summary>
  174. /// Returns the system dependent sockaddr structure packed into a string
  175. /// </summary>
  176. [RubyMethod("sockaddr_in", RubyMethodAttributes.PublicSingleton)]
  177. [RubyMethod("pack_sockaddr_in", RubyMethodAttributes.PublicSingleton)]
  178. public static MutableString/*!*/ PackInetSockAddr(ConversionStorage<MutableString>/*!*/ stringCast, ConversionStorage<int>/*!*/ fixnumCast,
  179. RubyClass/*!*/ self, object port, object hostNameOrAddress) {
  180. int iPort = ConvertToPortNum(stringCast, fixnumCast,port);
  181. IPAddress address = (hostNameOrAddress != null) ?
  182. GetHostAddress(ConvertToHostString(stringCast, hostNameOrAddress)) : IPAddress.Loopback;
  183. SocketAddress socketAddress = new IPEndPoint(address, iPort).Serialize();
  184. var result = MutableString.CreateBinary(socketAddress.Size);
  185. for (int i = 0; i < socketAddress.Size; i++) {
  186. result.Append(socketAddress[i]);
  187. }
  188. return result;
  189. }
  190. /// <summary>
  191. /// Returns the system dependent sockaddr structure packed into a string
  192. /// </summary>
  193. [RubyMethod("unpack_sockaddr_in", RubyMethodAttributes.PublicSingleton)]
  194. public static RubyArray/*!*/ UnPackInetSockAddr(RubyClass/*!*/ self,
  195. [DefaultProtocol, NotNull]MutableString/*!*/ address) {
  196. IPEndPoint ep = UnpackSockAddr(address);
  197. RubyArray result = new RubyArray(2);
  198. result.Add(ep.Port);
  199. result.Add(MutableString.CreateAscii(ep.Address.ToString()));
  200. return result;
  201. }
  202. internal static IPEndPoint/*!*/ UnpackSockAddr(MutableString/*!*/ stringAddress) {
  203. byte[] bytes = stringAddress.ConvertToBytes();
  204. SocketAddress addr = new SocketAddress(AddressFamily.InterNetwork, bytes.Length);
  205. for (int i = 0; i < bytes.Length; ++i) {
  206. addr[i] = bytes[i];
  207. }
  208. IPEndPoint ep = new IPEndPoint(0, 0);
  209. return (IPEndPoint)ep.Create(addr);
  210. }
  211. #endregion
  212. #region Public Instance Methods
  213. [RubyMethod("accept")]
  214. public static RubyArray/*!*/ Accept(RubyContext/*!*/ context, RubySocket/*!*/ self) {
  215. RubyArray result = new RubyArray(2);
  216. RubySocket s = new RubySocket(context, self.Socket.Accept());
  217. result.Add(s);
  218. SocketAddress addr = s.Socket.RemoteEndPoint.Serialize();
  219. result.Add(MutableString.CreateAscii(addr.ToString()));
  220. return result;
  221. }
  222. [RubyMethod("accept_nonblock")]
  223. public static RubyArray/*!*/ AcceptNonBlocking(RubyContext/*!*/ context, RubySocket/*!*/ self) {
  224. bool blocking = self.Socket.Blocking;
  225. try {
  226. self.Socket.Blocking = false;
  227. return Accept(context, self);
  228. } finally {
  229. // Reset the blocking
  230. self.Socket.Blocking = blocking;
  231. }
  232. }
  233. [RubyMethod("bind")]
  234. public static int Bind(RubyContext/*!*/ context, RubySocket/*!*/ self, MutableString sockaddr) {
  235. IPEndPoint ep = UnpackSockAddr(sockaddr);
  236. self.Socket.Bind(ep);
  237. return 0;
  238. }
  239. [RubyMethod("connect")]
  240. public static int Connect(RubyContext/*!*/ context, RubySocket/*!*/ self, MutableString sockaddr) {
  241. IPEndPoint ep = UnpackSockAddr(sockaddr);
  242. self.Socket.Connect(ep);
  243. return 0;
  244. }
  245. [RubyMethod("connect_nonblock")]
  246. public static int ConnectNonBlocking(RubyContext/*!*/ context, RubySocket/*!*/ self, MutableString sockaddr) {
  247. bool blocking = self.Socket.Blocking;
  248. try {
  249. self.Socket.Blocking = false;
  250. return Connect(context, self, sockaddr);
  251. } finally {
  252. // Reset the blocking
  253. self.Socket.Blocking = blocking;
  254. }
  255. }
  256. [RubyMethod("listen")]
  257. public static int Listen(RubyContext/*!*/ context, RubySocket/*!*/ self, int backlog) {
  258. self.Socket.Listen(backlog);
  259. return 0;
  260. }
  261. [RubyMethod("recvfrom")]
  262. public static RubyArray/*!*/ ReceiveFrom(ConversionStorage<int>/*!*/ fixnumCast, RubySocket/*!*/ self, int length) {
  263. return ReceiveFrom(fixnumCast, self, length, null);
  264. }
  265. [RubyMethod("recvfrom")]
  266. public static RubyArray/*!*/ ReceiveFrom(ConversionStorage<int>/*!*/ fixnumCast, RubySocket/*!*/ self,
  267. int length, object/*Numeric*/ flags) {
  268. SocketFlags sFlags = ConvertToSocketFlag(fixnumCast, flags);
  269. byte[] buffer = new byte[length];
  270. EndPoint fromEP = new IPEndPoint(IPAddress.Any, 0);
  271. int received = self.Socket.ReceiveFrom(buffer, sFlags, ref fromEP);
  272. MutableString str = MutableString.CreateBinary();
  273. str.Append(buffer, 0, received);
  274. str.IsTainted = true;
  275. return RubyOps.MakeArray2(str, self.GetAddressArray(fromEP));
  276. }
  277. [RubyMethod("sysaccept")]
  278. public static RubyArray/*!*/ SysAccept(RubyContext/*!*/ context, RubySocket/*!*/ self) {
  279. RubyArray result = new RubyArray(2);
  280. // TODO: Do we need some kind of strong reference to the socket
  281. // here to stop the RubySocket from being garbage collected?
  282. RubySocket s = new RubySocket(context, self.Socket.Accept());
  283. result.Add(s.GetFileDescriptor());
  284. SocketAddress addr = s.Socket.RemoteEndPoint.Serialize();
  285. result.Add(MutableString.CreateAscii(addr.ToString()));
  286. return result;
  287. }
  288. #endregion
  289. #region Constants
  290. [RubyModule("Constants", BuildConfig ="!SILVERLIGHT")]
  291. public class SocketConstants {
  292. #region Address Family
  293. [RubyConstant]
  294. public const int AF_APPLETALK = (int)AddressFamily.AppleTalk;
  295. [RubyConstant]
  296. public const int AF_ATM = (int)AddressFamily.Atm;
  297. [RubyConstant]
  298. public const int AF_CCITT = (int)AddressFamily.Ccitt;
  299. [RubyConstant]
  300. public const int AF_CHAOS = (int)AddressFamily.Chaos;
  301. [RubyConstant]
  302. public const int AF_DATAKIT = (int)AddressFamily.DataKit;
  303. [RubyConstant]
  304. public const int AF_DLI = (int)AddressFamily.DataLink;
  305. [RubyConstant]
  306. public const int AF_ECMA = (int)AddressFamily.Ecma;
  307. [RubyConstant]
  308. public const int AF_HYLINK = (int)AddressFamily.HyperChannel;
  309. [RubyConstant]
  310. public const int AF_IMPLINK = (int)AddressFamily.ImpLink;
  311. [RubyConstant]
  312. public const int AF_INET = (int)AddressFamily.InterNetwork;
  313. [RubyConstant]
  314. public const int AF_INET6 = (int)AddressFamily.InterNetworkV6;
  315. [RubyConstant]
  316. public const int AF_IPX = (int)AddressFamily.Ipx;
  317. [RubyConstant]
  318. public const int AF_ISO = (int)AddressFamily.Iso;
  319. [RubyConstant]
  320. public const int AF_LAT = (int)AddressFamily.Lat;
  321. [RubyConstant]
  322. public const int AF_MAX = (int)AddressFamily.Max;
  323. [RubyConstant]
  324. public const int AF_NETBIOS = (int)AddressFamily.NetBios;
  325. [RubyConstant]
  326. public const int AF_NS = (int)AddressFamily.NS;
  327. [RubyConstant]
  328. public const int AF_OSI = (int)AddressFamily.Osi;
  329. [RubyConstant]
  330. public const int AF_PUP = (int)AddressFamily.Pup;
  331. [RubyConstant]
  332. public const int AF_SNA = (int)AddressFamily.Sna;
  333. [RubyConstant]
  334. public const int AF_UNIX = (int)AddressFamily.Unix;
  335. [RubyConstant]
  336. public const int AF_UNSPEC = (int)AddressFamily.Unspecified;
  337. #endregion
  338. #region Flag Options for GetAddressInfo
  339. [RubyConstant]
  340. public const int AI_PASSIVE = 1;
  341. [RubyConstant]
  342. public const int AI_CANONNAME = 2;
  343. [RubyConstant]
  344. public const int AI_NUMERICHOST = 4;
  345. #endregion
  346. #region Error Return Codes from GetAddressInfo
  347. [RubyConstant]
  348. public const int EAI_AGAIN = 2;
  349. [RubyConstant]
  350. public const int EAI_BADFLAGS = 3;
  351. [RubyConstant]
  352. public const int EAI_FAIL = 4;
  353. [RubyConstant]
  354. public const int EAI_FAMILY = 5;
  355. [RubyConstant]
  356. public const int EAI_MEMORY = 6;
  357. [RubyConstant]
  358. public const int EAI_NODATA = 7;
  359. [RubyConstant]
  360. public const int EAI_NONAME = 8;
  361. [RubyConstant]
  362. public const int EAI_SERVICE = 9;
  363. [RubyConstant]
  364. public const int EAI_SOCKTYPE = 10;
  365. #endregion
  366. #region Addresses
  367. [RubyConstant]
  368. public const int IPPORT_RESERVED = 1024;
  369. [RubyConstant]
  370. public const int IPPORT_USERRESERVED = 5000;
  371. [RubyConstant]
  372. public const int INET_ADDRSTRLEN = 16;
  373. [RubyConstant]
  374. public const int INET6_ADDRSTRLEN = 46;
  375. [RubyConstant]
  376. public const uint INADDR_ALLHOSTS_GROUP = 0xe0000001;
  377. [RubyConstant]
  378. public const int INADDR_ANY = 0;
  379. [RubyConstant]
  380. public const uint INADDR_BROADCAST = 0xffffffff;
  381. [RubyConstant]
  382. public const int INADDR_LOOPBACK = 0x7F000001;
  383. [RubyConstant]
  384. public const uint INADDR_MAX_LOCAL_GROUP = 0xe00000ff;
  385. [RubyConstant]
  386. public const uint INADDR_NONE = 0xffffffff;
  387. [RubyConstant]
  388. public const uint INADDR_UNSPEC_GROUP = 0xe0000000;
  389. #endregion
  390. #region IP Protocol Constants
  391. [RubyConstant]
  392. public const int IP_DEFAULT_MULTICAST_TTL = 1;
  393. [RubyConstant]
  394. public const int IP_DEFAULT_MULTICAST_LOOP = 1;
  395. [RubyConstant]
  396. public const int IP_OPTIONS = 1;
  397. [RubyConstant]
  398. public const int IP_HDRINCL = 2;
  399. [RubyConstant]
  400. public const int IP_TOS = 3;
  401. [RubyConstant]
  402. public const int IP_TTL = 4;
  403. [RubyConstant]
  404. public const int IP_MULTICAST_IF = 9;
  405. [RubyConstant]
  406. public const int IP_MULTICAST_TTL = 10;
  407. [RubyConstant]
  408. public const int IP_MULTICAST_LOOP = 11;
  409. [RubyConstant]
  410. public const int IP_ADD_MEMBERSHIP = 12;
  411. [RubyConstant]
  412. public const int IP_DROP_MEMBERSHIP = 13;
  413. [RubyConstant]
  414. public const int IP_ADD_SOURCE_MEMBERSHIP = 15;
  415. [RubyConstant]
  416. public const int IP_DROP_SOURCE_MEMBERSHIP = 16;
  417. [RubyConstant]
  418. public const int IP_BLOCK_SOURCE = 17;
  419. [RubyConstant]
  420. public const int IP_UNBLOCK_SOURCE = 18;
  421. [RubyConstant]
  422. public const int IP_PKTINFO = 19;
  423. [RubyConstant]
  424. public const int IP_MAX_MEMBERSHIPS = 20;
  425. [RubyConstant]
  426. public const int IPPROTO_GGP = 3;
  427. [RubyConstant]
  428. public const int IPPROTO_ICMP = 1;
  429. [RubyConstant]
  430. public const int IPPROTO_IDP = 22;
  431. [RubyConstant]
  432. public const int IPPROTO_IGMP = 2;
  433. [RubyConstant]
  434. public const int IPPROTO_IP = 0;
  435. [RubyConstant]
  436. public const int IPPROTO_MAX = 256;
  437. [RubyConstant]
  438. public const int IPPROTO_ND = 77;
  439. [RubyConstant]
  440. public const int IPPROTO_PUP = 12;
  441. [RubyConstant]
  442. public const int IPPROTO_RAW = 255;
  443. [RubyConstant]
  444. public const int IPPROTO_TCP = 6;
  445. [RubyConstant]
  446. public const int IPPROTO_UDP = 17;
  447. [RubyConstant]
  448. public const int IPPROTO_AH = 51;
  449. [RubyConstant]
  450. public const int IPPROTO_DSTOPTS = 60;
  451. [RubyConstant]
  452. public const int IPPROTO_ESP = 50;
  453. [RubyConstant]
  454. public const int IPPROTO_FRAGMENT = 44;
  455. [RubyConstant]
  456. public const int IPPROTO_HOPOPTS = 0;
  457. [RubyConstant]
  458. public const int IPPROTO_ICMPV6 = 58;
  459. [RubyConstant]
  460. public const int IPPROTO_IPV6 = 41;
  461. [RubyConstant]
  462. public const int IPPROTO_NONE = 59;
  463. [RubyConstant]
  464. public const int IPPROTO_ROUTING = 43;
  465. [RubyConstant]
  466. public const int IPV6_JOIN_GROUP = 12;
  467. [RubyConstant]
  468. public const int IPV6_LEAVE_GROUP = 13;
  469. [RubyConstant]
  470. public const int IPV6_MULTICAST_HOPS = 10;
  471. [RubyConstant]
  472. public const int IPV6_MULTICAST_IF = 9;
  473. [RubyConstant]
  474. public const int IPV6_MULTICAST_LOOP = 11;
  475. [RubyConstant]
  476. public const int IPV6_UNICAST_HOPS = 4;
  477. [RubyConstant]
  478. public const int IPV6_PKTINFO = 19;
  479. #endregion
  480. #region Message Options
  481. [RubyConstant]
  482. public const int MSG_DONTROUTE = 4;
  483. [RubyConstant]
  484. public const int MSG_OOB = 1;
  485. [RubyConstant]
  486. public const int MSG_PEEK = 2;
  487. [RubyConstant]
  488. #endregion
  489. #region Name Info
  490. public const int NI_DGRAM = 16;
  491. [RubyConstant]
  492. public const int NI_MAXHOST = 1025;
  493. [RubyConstant]
  494. public const int NI_MAXSERV = 32;
  495. [RubyConstant]
  496. public const int NI_NAMEREQD = 4;
  497. [RubyConstant]
  498. public const int NI_NOFQDN = 1;
  499. [RubyConstant]
  500. public const int NI_NUMERICHOST = 2;
  501. [RubyConstant]
  502. public const int NI_NUMERICSERV = 8;
  503. #endregion
  504. #region Protocol Family
  505. [RubyConstant]
  506. public const int PF_APPLETALK = (int)ProtocolFamily.AppleTalk;
  507. [RubyConstant]
  508. public const int PF_ATM = (int)ProtocolFamily.Atm;
  509. [RubyConstant]
  510. public const int PF_CCITT = (int)ProtocolFamily.Ccitt;
  511. [RubyConstant]
  512. public const int PF_CHAOS = (int)ProtocolFamily.Chaos;
  513. [RubyConstant]
  514. public const int PF_DATAKIT = (int)ProtocolFamily.DataKit;
  515. [RubyConstant]
  516. public const int PF_DLI = (int)ProtocolFamily.DataLink;
  517. [RubyConstant]
  518. public const int PF_ECMA = (int)ProtocolFamily.Ecma;
  519. [RubyConstant]
  520. public const int PF_HYLINK = (int)ProtocolFamily.HyperChannel;
  521. [RubyConstant]
  522. public const int PF_IMPLINK = (int)ProtocolFamily.ImpLink;
  523. [RubyConstant]
  524. public const int PF_INET = (int)ProtocolFamily.InterNetwork;
  525. [RubyConstant]
  526. public const int PF_INET6 = (int)ProtocolFamily.InterNetworkV6;
  527. [RubyConstant]
  528. public const int PF_IPX = (int)ProtocolFamily.Ipx;
  529. [RubyConstant]
  530. public const int PF_ISO = (int)ProtocolFamily.Iso;
  531. [RubyConstant]
  532. public const int PF_LAT = (int)ProtocolFamily.Lat;
  533. [RubyConstant]
  534. public const int PF_MAX = (int)ProtocolFamily.Max;
  535. [RubyConstant]
  536. public const int PF_NS = (int)ProtocolFamily.NS;
  537. [RubyConstant]
  538. public const int PF_OSI = (int)ProtocolFamily.Osi;
  539. [RubyConstant]
  540. public const int PF_PUP = (int)ProtocolFamily.Pup;
  541. [RubyConstant]
  542. public const int PF_SNA = (int)ProtocolFamily.Sna;
  543. [RubyConstant]
  544. public const int PF_UNIX = (int)ProtocolFamily.Unix;
  545. [RubyConstant]
  546. public const int PF_UNSPEC = (int)ProtocolFamily.Unspecified;
  547. #endregion
  548. #region Socket Shutdown
  549. [RubyConstant]
  550. public const int SHUT_RD = (int)SocketShutdown.Receive;
  551. [RubyConstant]
  552. public const int SHUT_RDWR = (int)SocketShutdown.Both;
  553. [RubyConstant]
  554. public const int SHUT_WR = (int)SocketShutdown.Send;
  555. #endregion
  556. #region Socket Type
  557. [RubyConstant]
  558. public const int SOCK_DGRAM = (int)SocketType.Dgram;
  559. [RubyConstant]
  560. public const int SOCK_RAW = (int)SocketType.Raw;
  561. [RubyConstant]
  562. public const int SOCK_RDM = (int)SocketType.Rdm;
  563. [RubyConstant]
  564. public const int SOCK_SEQPACKET = (int)SocketType.Seqpacket;
  565. [RubyConstant]
  566. public const int SOCK_STREAM = (int)SocketType.Stream;
  567. #endregion
  568. #region Socket Option
  569. [RubyConstant]
  570. public const int SO_ACCEPTCONN = (int)SocketOptionName.AcceptConnection;
  571. [RubyConstant]
  572. public const int SO_BROADCAST = (int)SocketOptionName.Broadcast;
  573. [RubyConstant]
  574. public const int SO_DEBUG = (int)SocketOptionName.Debug;
  575. [RubyConstant]
  576. public const int SO_DONTROUTE = (int)SocketOptionName.DontRoute;
  577. [RubyConstant]
  578. public const int SO_ERROR = (int)SocketOptionName.Error;
  579. [RubyConstant]
  580. public const int SO_KEEPALIVE = (int)SocketOptionName.KeepAlive;
  581. [RubyConstant]
  582. public const int SO_LINGER = (int)SocketOptionName.Linger;
  583. [RubyConstant]
  584. public const int SO_OOBINLINE = (int)SocketOptionName.OutOfBandInline;
  585. [RubyConstant]
  586. public const int SO_RCVBUF = (int)SocketOptionName.ReceiveBuffer;
  587. [RubyConstant]
  588. public const int SO_RCVLOWAT = (int)SocketOptionName.ReceiveLowWater;
  589. [RubyConstant]
  590. public const int SO_RCVTIMEO = (int)SocketOptionName.ReceiveTimeout;
  591. [RubyConstant]
  592. public const int SO_REUSEADDR = (int)SocketOptionName.ReuseAddress;
  593. [RubyConstant]
  594. public const int SO_SNDBUF = (int)SocketOptionName.SendBuffer;
  595. [RubyConstant]
  596. public const int SO_SNDLOWAT = (int)SocketOptionName.SendLowWater;
  597. [RubyConstant]
  598. public const int SO_SNDTIMEO = (int)SocketOptionName.SendTimeout;
  599. [RubyConstant]
  600. public const int SO_TYPE = (int)SocketOptionName.Type;
  601. [RubyConstant]
  602. public const int SO_USELOOPBACK = (int)SocketOptionName.UseLoopback;
  603. #endregion
  604. [RubyConstant]
  605. public const int SOL_SOCKET = 65535;
  606. [RubyConstant]
  607. public const int SOMAXCONN = Int32.MaxValue;
  608. [RubyConstant]
  609. public const int TCP_NODELAY = 1;
  610. }
  611. #endregion
  612. #region Private Helpers
  613. private static int ParseInteger(RubyContext/*!*/ context, string/*!*/ str) {
  614. bool isNegative = false;
  615. if (str[0] == '-') {
  616. isNegative = true;
  617. str = str.Remove(0, 1);
  618. }
  619. Tokenizer tokenizer = new Tokenizer();
  620. tokenizer.Initialize(new StringReader(str));
  621. Tokens token = tokenizer.GetNextToken();
  622. TokenValue value = tokenizer.TokenValue;
  623. Tokens nextToken = tokenizer.GetNextToken();
  624. // We are only interested in the whole string being a valid Integer
  625. if (token == Tokens.Integer && nextToken == Tokens.Integer) {
  626. return isNegative ? -value.Integer1 : value.Integer1;
  627. } else {
  628. throw RubyExceptions.CreateTypeConversionError("String", "Integer");
  629. }
  630. }
  631. #endregion
  632. }
  633. }
  634. #endif