Returned PingResult.data is only valid when PingResult.type is 0
| 184 | |
| 185 | // Returned PingResult.data is only valid when PingResult.type is 0 |
| 186 | ICMP_Session::PingResult* ICMP_Session::Ping::Recv() |
| 187 | { |
| 188 | #ifdef _WIN32 |
| 189 | if (WaitForSingleObject(icmpEvent, 0) == WAIT_OBJECT_0) |
| 190 | { |
| 191 | ResetEvent(icmpEvent); |
| 192 | |
| 193 | const int count = IcmpParseReplies(icmpResponseBuffer.get(), icmpResponseBufferLen); |
| 194 | pxAssert(count <= 1); |
| 195 | |
| 196 | // Timeout |
| 197 | if (count == 0) |
| 198 | { |
| 199 | result.type = -2; |
| 200 | result.code = 0; |
| 201 | return &result; |
| 202 | } |
| 203 | |
| 204 | // Rely on implicit object creation |
| 205 | const ICMP_ECHO_REPLY* pingRet = reinterpret_cast<ICMP_ECHO_REPLY*>(icmpResponseBuffer.get()); |
| 206 | |
| 207 | // Map status to ICMP type/code |
| 208 | switch (pingRet->Status) |
| 209 | { |
| 210 | case (IP_SUCCESS): |
| 211 | result.type = 0; |
| 212 | result.code = 0; |
| 213 | break; |
| 214 | case (IP_DEST_NET_UNREACHABLE): |
| 215 | result.type = 3; |
| 216 | result.code = 0; |
| 217 | break; |
| 218 | case (IP_DEST_HOST_UNREACHABLE): |
| 219 | result.type = 3; |
| 220 | result.code = 1; |
| 221 | break; |
| 222 | case (IP_DEST_PROT_UNREACHABLE): |
| 223 | result.type = 3; |
| 224 | result.code = 2; |
| 225 | break; |
| 226 | case (IP_DEST_PORT_UNREACHABLE): |
| 227 | result.type = 3; |
| 228 | result.code = 3; |
| 229 | break; |
| 230 | case (IP_PACKET_TOO_BIG): |
| 231 | result.type = 3; |
| 232 | result.code = 4; |
| 233 | break; |
| 234 | case (IP_BAD_ROUTE): // Bad source route |
| 235 | result.type = 3; |
| 236 | result.code = 5; |
| 237 | break; |
| 238 | case (IP_BAD_DESTINATION): |
| 239 | /* |
| 240 | * I think this could be mapped to either |
| 241 | * Destination network unknown |
| 242 | * or |
| 243 | * Destination host unknown |
nothing calls this directly
no test coverage detected