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