Making sure mono_marshal_free is used instead of g_free in mono_string_builder_to_utf8
[mono.git] / mcs / class / referencesource / System / net / System / Net / NetworkInformation / PingReply.cs
1 using System.Net.Sockets;
2 using System.Runtime.InteropServices;
3
4 namespace System.Net.NetworkInformation
5 {
6     
7     public class PingReply
8     {
9         IPAddress address;
10         PingOptions options;
11         IPStatus ipStatus;  // the status code returned by icmpsendecho, or the icmp status field on the raw socket
12         long rtt;  // the round trip time.
13         byte[] buffer; //buffer of the data
14
15
16         internal PingReply(){
17         }
18
19         internal PingReply (IPStatus ipStatus) {
20             this.ipStatus = ipStatus;
21             buffer = new byte[0];
22         }
23
24         // The downlevel constructor. 
25         internal PingReply (byte[] data, int dataLength, IPAddress address, int time) {
26             this.address = address;
27             rtt = time;
28
29
30             ipStatus = GetIPStatus ((IcmpV4Type)data[20],(IcmpV4Code) data[21]);
31
32             if (ipStatus == IPStatus.Success) {
33                 buffer = new byte[dataLength - 28];
34                 Array.Copy (data, 28, buffer, 0, dataLength - 28);
35             }
36             else
37                 buffer = new byte[0];
38         }
39
40
41         // the main constructor for the icmpsendecho apis
42         internal PingReply (IcmpEchoReply reply) {
43             address = new IPAddress (reply.address);
44             ipStatus = (IPStatus)reply.status; //the icmpsendecho ip status codes
45
46             //only copy the data if we succeed w/ the ping operation
47             if (ipStatus == IPStatus.Success) {
48                 rtt = (long)reply.roundTripTime;
49                 buffer = new byte[reply.dataSize];
50                 Marshal.Copy (reply.data, buffer, 0, reply.dataSize);
51                 options = new PingOptions (reply.options);
52             }
53             else
54                 buffer = new byte[0];
55
56         }
57
58                 // the main constructor for the icmpsendecho apis
59         internal PingReply (Icmp6EchoReply reply, IntPtr dataPtr, int sendSize) {
60             
61             address = new IPAddress(reply.Address.Address,reply.Address.ScopeID);
62             ipStatus = (IPStatus)reply.Status; //the icmpsendecho ip status codes
63
64             //only copy the data if we succeed w/ the ping operation
65             if (ipStatus == IPStatus.Success) {
66                 rtt = (long)reply.RoundTripTime;
67                 buffer = new byte[sendSize];
68                 Marshal.Copy (IntPtrHelper.Add(dataPtr, 36), buffer, 0, sendSize);
69                 //options = new PingOptions (reply.options);
70             }
71             else
72                 buffer = new byte[0];
73
74         }
75
76
77  
78         //translates the relevant icmpsendecho codes to a ipstatus code
79         private IPStatus GetIPStatus (IcmpV4Type type, IcmpV4Code code) {
80             switch (type) {
81                 case IcmpV4Type.ICMP4_ECHO_REPLY:
82                     return IPStatus.Success;
83                 case IcmpV4Type.ICMP4_SOURCE_QUENCH:
84                     return IPStatus.SourceQuench;
85                 case IcmpV4Type.ICMP4_PARAM_PROB:
86                     return IPStatus.ParameterProblem;
87                 case IcmpV4Type.ICMP4_TIME_EXCEEDED:
88                    return IPStatus.TtlExpired;
89
90                 case IcmpV4Type.ICMP4_DST_UNREACH:
91                 {
92                     switch (code) {
93                         case  IcmpV4Code.ICMP4_UNREACH_NET:
94                             return IPStatus.DestinationNetworkUnreachable;
95                         case  IcmpV4Code.ICMP4_UNREACH_HOST:
96                             return IPStatus.DestinationHostUnreachable;
97                         case  IcmpV4Code.ICMP4_UNREACH_PROTOCOL:
98                             return IPStatus.DestinationProtocolUnreachable;
99                         case  IcmpV4Code.ICMP4_UNREACH_PORT:
100                             return IPStatus.DestinationPortUnreachable;
101                         case  IcmpV4Code.ICMP4_UNREACH_FRAG_NEEDED:
102                             return IPStatus.PacketTooBig;
103                         default:
104                             return IPStatus.DestinationUnreachable;
105                     }
106                 }
107             }
108             return IPStatus.Unknown;
109         }
110
111         //the basic properties
112         public IPStatus Status { get { return ipStatus; } }
113         public IPAddress Address { get { return address; } }
114         public long RoundtripTime { get { return rtt; } }
115         public PingOptions Options { 
116             get {
117                 return options; 
118             } 
119         }
120         public byte[] Buffer { get { return buffer; } }
121     }
122 }