IPEndPoint.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. //
  2. // System.Net.IPEndPoint.cs
  3. //
  4. // Author:
  5. // Miguel de Icaza ([email protected])
  6. //
  7. // (C) Ximian, Inc. http://www.ximian.com
  8. //
  9. using System.Net.Sockets;
  10. namespace System.Net {
  11. [Serializable]
  12. public class IPEndPoint : EndPoint {
  13. private IPAddress address;
  14. private int port;
  15. public const int MaxPort = 65535;
  16. public const int MinPort = 0;
  17. public IPEndPoint (IPAddress address, int port)
  18. {
  19. if (address == null)
  20. throw new ArgumentNullException ("Value cannot be null");
  21. Address = address;
  22. Port = port;
  23. }
  24. public IPEndPoint (long iaddr, int port) : this (new IPAddress (iaddr), port)
  25. {
  26. }
  27. public IPAddress Address {
  28. get {
  29. return (address);
  30. }
  31. set {
  32. address=value;
  33. }
  34. }
  35. public override AddressFamily AddressFamily {
  36. get {
  37. return address.AddressFamily;
  38. }
  39. }
  40. public int Port {
  41. get {
  42. return port;
  43. }
  44. set {
  45. // LAMESPEC: no mention of sanity checking
  46. // PS: MS controls the range when setting the value
  47. if (value < MinPort || value > MaxPort)
  48. throw new ArgumentOutOfRangeException ("Invalid port");
  49. port = value;
  50. }
  51. }
  52. // bytes 2 and 3 store the port, the rest
  53. // stores the address
  54. public override EndPoint Create(SocketAddress sockaddr) {
  55. int size=sockaddr.Size;
  56. // LAMESPEC: no mention of what to do if
  57. // sockaddr is bogus
  58. if(size<8) {
  59. // absolute minimum amount needed for
  60. // an address family, buffer size,
  61. // port and address
  62. return(null);
  63. }
  64. AddressFamily family=(AddressFamily)sockaddr[0];
  65. int port;
  66. IPEndPoint ipe = null;
  67. switch(family)
  68. {
  69. case AddressFamily.InterNetwork:
  70. port = (((int)sockaddr[2])<<8) + (int)sockaddr[3];
  71. long address=(((long)sockaddr[7])<<24) +
  72. (((long)sockaddr[6])<<16) +
  73. (((long)sockaddr[5])<<8) +
  74. (long)sockaddr[4];
  75. ipe = new IPEndPoint(address, port);
  76. break;
  77. #if NET_1_1
  78. case AddressFamily.InterNetworkV6:
  79. port = (((int)sockaddr[2])<<8) + (int)sockaddr[3];
  80. /// maybe flowid ?
  81. int unknown = (int)sockaddr[4] +
  82. (((int)sockaddr[5])<<8) +
  83. (((int)sockaddr[6])<<16) +
  84. (((int)sockaddr[7])<<24);
  85. int scopeId = (int)sockaddr[24] +
  86. (((int)sockaddr[25])<<8) +
  87. (((int)sockaddr[26])<<16) +
  88. (((int)sockaddr[27])<<24);
  89. ushort[] addressData = new ushort[8];
  90. for(int i=0; i<8; i++)
  91. addressData[i] = (ushort)((sockaddr[8+i*2] << 8) + sockaddr[8+i*2+1]);
  92. ipe = new IPEndPoint (new IPAddress(addressData, scopeId), port);
  93. break;
  94. #endif
  95. default:
  96. return null;
  97. }
  98. return(ipe);
  99. }
  100. public override SocketAddress Serialize() {
  101. SocketAddress sockaddr = null;
  102. switch (address.AddressFamily)
  103. {
  104. case AddressFamily.InterNetwork:
  105. // .net produces a 16 byte buffer, even though
  106. // only 8 bytes are used. I guess its just a
  107. // holdover from struct sockaddr padding.
  108. sockaddr = new SocketAddress(AddressFamily.InterNetwork, 16);
  109. // bytes 2 and 3 store the port, the rest
  110. // stores the address
  111. sockaddr [2] = (byte) ((port>>8) & 0xff);
  112. sockaddr [3] = (byte) (port & 0xff);
  113. sockaddr [4] = (byte) (address.Address & 0xff);
  114. sockaddr [5] = (byte) ((address.Address >> 8) & 0xff);
  115. sockaddr [6] = (byte) ((address.Address >> 16) & 0xff);
  116. sockaddr [7] = (byte) ((address.Address >> 24) & 0xff);
  117. break;
  118. #if NET_1_1
  119. case AddressFamily.InterNetworkV6:
  120. sockaddr = new SocketAddress(AddressFamily.InterNetworkV6, 28);
  121. sockaddr [2] = (byte) ((port>>8) & 0xff);
  122. sockaddr [3] = (byte) (port & 0xff);
  123. byte[] addressBytes = address.GetAddressBytes();
  124. for(int i=0; i<16; i++)
  125. sockaddr[8+i] = addressBytes[i];
  126. sockaddr [24] = (byte) (address.ScopeId & 0xff);
  127. sockaddr [25] = (byte) ((address.ScopeId >> 8) & 0xff);
  128. sockaddr [26] = (byte) ((address.ScopeId >> 16) & 0xff);
  129. sockaddr [27] = (byte) ((address.ScopeId >> 24) & 0xff);
  130. break;
  131. #endif
  132. }
  133. return(sockaddr);
  134. }
  135. public override string ToString() {
  136. return(address.ToString() + ":" + port);
  137. }
  138. public override bool Equals (Object obj)
  139. {
  140. IPEndPoint p = obj as IPEndPoint;
  141. return p != null &&
  142. p.port == port &&
  143. p.address.Equals (address);
  144. }
  145. public override int GetHashCode ()
  146. {
  147. return address.GetHashCode () + port;
  148. }
  149. }
  150. }