1f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/* 2f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * 4f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * Use of this source code is governed by a BSD-style license 5f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 6f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 7f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * in the file PATENTS. All contributing project authors may 8f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org */ 10f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 11f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/winping.h" 12f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 13f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <assert.h> 14f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <Iphlpapi.h> 15f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 16ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org#include <algorithm> 17ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org 18f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/byteorder.h" 19f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/common.h" 20f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/ipaddress.h" 21f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/logging.h" 22f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/nethelpers.h" 23f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/socketaddress.h" 24f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 25f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgnamespace rtc { 26f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 27f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org////////////////////////////////////////////////////////////////////// 28f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Found in IPExport.h 29f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org////////////////////////////////////////////////////////////////////// 30f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 31f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgtypedef struct icmp_echo_reply { 32f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ULONG Address; // Replying address 33f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ULONG Status; // Reply IP_STATUS 34f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ULONG RoundTripTime; // RTT in milliseconds 35f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org USHORT DataSize; // Reply data size in bytes 36f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org USHORT Reserved; // Reserved for system use 37f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org PVOID Data; // Pointer to the reply data 38f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org struct ip_option_information Options; // Reply options 39f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} ICMP_ECHO_REPLY, * PICMP_ECHO_REPLY; 40f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 41f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgtypedef struct icmpv6_echo_reply_lh { 42f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org sockaddr_in6 Address; 43f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ULONG Status; 44f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unsigned int RoundTripTime; 45f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} ICMPV6_ECHO_REPLY, *PICMPV6_ECHO_REPLY; 46f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 47f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 48f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// IP_STATUS codes returned from IP APIs 49f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 50f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 51f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_STATUS_BASE 11000 52f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 53f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_SUCCESS 0 54f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_BUF_TOO_SMALL (IP_STATUS_BASE + 1) 55f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_DEST_NET_UNREACHABLE (IP_STATUS_BASE + 2) 56f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_DEST_HOST_UNREACHABLE (IP_STATUS_BASE + 3) 57f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_DEST_PROT_UNREACHABLE (IP_STATUS_BASE + 4) 58f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_DEST_PORT_UNREACHABLE (IP_STATUS_BASE + 5) 59f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_NO_RESOURCES (IP_STATUS_BASE + 6) 60f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_BAD_OPTION (IP_STATUS_BASE + 7) 61f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_HW_ERROR (IP_STATUS_BASE + 8) 62f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_PACKET_TOO_BIG (IP_STATUS_BASE + 9) 63f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_REQ_TIMED_OUT (IP_STATUS_BASE + 10) 64f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_BAD_REQ (IP_STATUS_BASE + 11) 65f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_BAD_ROUTE (IP_STATUS_BASE + 12) 66f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_TTL_EXPIRED_TRANSIT (IP_STATUS_BASE + 13) 67f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_TTL_EXPIRED_REASSEM (IP_STATUS_BASE + 14) 68f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_PARAM_PROBLEM (IP_STATUS_BASE + 15) 69f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_SOURCE_QUENCH (IP_STATUS_BASE + 16) 70f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_OPTION_TOO_BIG (IP_STATUS_BASE + 17) 71f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_BAD_DESTINATION (IP_STATUS_BASE + 18) 72f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 73f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_ADDR_DELETED (IP_STATUS_BASE + 19) 74f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_SPEC_MTU_CHANGE (IP_STATUS_BASE + 20) 75f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_MTU_CHANGE (IP_STATUS_BASE + 21) 76f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_UNLOAD (IP_STATUS_BASE + 22) 77f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_ADDR_ADDED (IP_STATUS_BASE + 23) 78f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_MEDIA_CONNECT (IP_STATUS_BASE + 24) 79f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_MEDIA_DISCONNECT (IP_STATUS_BASE + 25) 80f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_BIND_ADAPTER (IP_STATUS_BASE + 26) 81f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_UNBIND_ADAPTER (IP_STATUS_BASE + 27) 82f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_DEVICE_DOES_NOT_EXIST (IP_STATUS_BASE + 28) 83f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_DUPLICATE_ADDRESS (IP_STATUS_BASE + 29) 84f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_INTERFACE_METRIC_CHANGE (IP_STATUS_BASE + 30) 85f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_RECONFIG_SECFLTR (IP_STATUS_BASE + 31) 86f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_NEGOTIATING_IPSEC (IP_STATUS_BASE + 32) 87f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_INTERFACE_WOL_CAPABILITY_CHANGE (IP_STATUS_BASE + 33) 88f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_DUPLICATE_IPADD (IP_STATUS_BASE + 34) 89f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 90f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_GENERAL_FAILURE (IP_STATUS_BASE + 50) 91f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define MAX_IP_STATUS IP_GENERAL_FAILURE 92f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_PENDING (IP_STATUS_BASE + 255) 93f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 94f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 95f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Values used in the IP header Flags field. 96f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 97f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_FLAG_DF 0x2 // Don't fragment this packet. 98f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 99f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 100f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Supported IP Option Types. 101f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 102f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// These types define the options which may be used in the OptionsData field 103f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// of the ip_option_information structure. See RFC 791 for a complete 104f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// description of each. 105f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 106f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_OPT_EOL 0 // End of list option 107f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_OPT_NOP 1 // No operation 108f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_OPT_SECURITY 0x82 // Security option 109f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_OPT_LSRR 0x83 // Loose source route 110f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_OPT_SSRR 0x89 // Strict source route 111f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_OPT_RR 0x7 // Record route 112f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_OPT_TS 0x44 // Timestamp 113f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_OPT_SID 0x88 // Stream ID (obsolete) 114f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define IP_OPT_ROUTER_ALERT 0x94 // Router Alert Option 115f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 116f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define MAX_OPT_SIZE 40 // Maximum length of IP options in bytes 117f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 118f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org////////////////////////////////////////////////////////////////////// 119f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Global Constants and Types 120f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org////////////////////////////////////////////////////////////////////// 121f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 122f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgconst char * const ICMP_DLL_NAME = "Iphlpapi.dll"; 123f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgconst char * const ICMP_CREATE_FUNC = "IcmpCreateFile"; 124f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgconst char * const ICMP_CLOSE_FUNC = "IcmpCloseHandle"; 125f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgconst char * const ICMP_SEND_FUNC = "IcmpSendEcho"; 126f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgconst char * const ICMP6_CREATE_FUNC = "Icmp6CreateFile"; 127f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgconst char * const ICMP6_SEND_FUNC = "Icmp6SendEcho2"; 128f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 1290c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströminline uint32_t ReplySize(uint32_t data_size, int family) { 130f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (family == AF_INET) { 131f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // A ping error message is 8 bytes long, so make sure we allow for at least 132f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // 8 bytes of reply data. 1330c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström return sizeof(ICMP_ECHO_REPLY) + std::max<uint32_t>(8, data_size); 134f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (family == AF_INET6) { 135f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Per MSDN, Send6IcmpEcho2 needs at least one ICMPV6_ECHO_REPLY, 136f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // 8 bytes for ICMP header, _and_ an IO_BLOCK_STATUS (2 pointers), 137f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // in addition to the data size. 138f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return sizeof(ICMPV6_ECHO_REPLY) + data_size + 8 + (2 * sizeof(DWORD*)); 139f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 140f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 141f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 142f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 143f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 144f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org////////////////////////////////////////////////////////////////////// 145f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// WinPing 146f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org////////////////////////////////////////////////////////////////////// 147f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 148f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgWinPing::WinPing() 149f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org : dll_(0), hping_(INVALID_HANDLE_VALUE), create_(0), close_(0), send_(0), 150f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org create6_(0), send6_(0), data_(0), dlen_(0), reply_(0), 151f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org rlen_(0), valid_(false) { 152f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 153f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org dll_ = LoadLibraryA(ICMP_DLL_NAME); 154f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!dll_) { 155f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LERROR) << "LoadLibrary: " << GetLastError(); 156f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 157f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 158f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 159f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org create_ = (PIcmpCreateFile) GetProcAddress(dll_, ICMP_CREATE_FUNC); 160f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org close_ = (PIcmpCloseHandle) GetProcAddress(dll_, ICMP_CLOSE_FUNC); 161f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org send_ = (PIcmpSendEcho) GetProcAddress(dll_, ICMP_SEND_FUNC); 162f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!create_ || !close_ || !send_) { 163f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LERROR) << "GetProcAddress(ICMP_*): " << GetLastError(); 164f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 165f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 166f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org hping_ = create_(); 167f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (hping_ == INVALID_HANDLE_VALUE) { 168f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LERROR) << "IcmpCreateFile: " << GetLastError(); 169f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 170f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 171f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 172f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (HasIPv6Enabled()) { 173f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org create6_ = (PIcmp6CreateFile) GetProcAddress(dll_, ICMP6_CREATE_FUNC); 174f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org send6_ = (PIcmp6SendEcho2) GetProcAddress(dll_, ICMP6_SEND_FUNC); 175f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!create6_ || !send6_) { 176f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LERROR) << "GetProcAddress(ICMP6_*): " << GetLastError(); 177f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 178f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 179f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org hping6_ = create6_(); 180f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (hping6_ == INVALID_HANDLE_VALUE) { 181f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LERROR) << "Icmp6CreateFile: " << GetLastError(); 182f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 183f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 184f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 185f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org dlen_ = 0; 186f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org rlen_ = ReplySize(dlen_, AF_INET); 187f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org data_ = new char[dlen_]; 188f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org reply_ = new char[rlen_]; 189f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 190f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org valid_ = true; 191f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 192f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 193f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgWinPing::~WinPing() { 194f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((hping_ != INVALID_HANDLE_VALUE) && close_) { 195f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!close_(hping_)) 196f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(WARNING) << "IcmpCloseHandle: " << GetLastError(); 197f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 198f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((hping6_ != INVALID_HANDLE_VALUE) && close_) { 199f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!close_(hping6_)) { 200f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(WARNING) << "Icmp6CloseHandle: " << GetLastError(); 201f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 202f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 203f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 204f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (dll_) 205f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org FreeLibrary(dll_); 206f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 207f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete[] data_; 208f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete[] reply_; 209f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 210f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 2110c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter BoströmWinPing::PingResult WinPing::Ping(IPAddress ip, 2120c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t data_size, 2130c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t timeout, 2140c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint8_t ttl, 2150c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström bool allow_fragments) { 216f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (data_size == 0 || timeout == 0 || ttl == 0) { 217f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LERROR) << "IcmpSendEcho: data_size/timeout/ttl is 0."; 218f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return PING_INVALID_PARAMS; 219f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 220f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 221f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org assert(IsValid()); 222f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 223f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org IP_OPTION_INFORMATION ipopt; 224f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memset(&ipopt, 0, sizeof(ipopt)); 225f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!allow_fragments) 226f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ipopt.Flags |= IP_FLAG_DF; 227f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ipopt.Ttl = ttl; 228f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 2290c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t reply_size = ReplySize(data_size, ip.family()); 230f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 231f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (data_size > dlen_) { 232f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete [] data_; 233f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org dlen_ = data_size; 234f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org data_ = new char[dlen_]; 235f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memset(data_, 'z', dlen_); 236f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 237f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 238f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (reply_size > rlen_) { 239f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete [] reply_; 240f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org rlen_ = reply_size; 241f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org reply_ = new char[rlen_]; 242f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 243f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org DWORD result = 0; 244f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (ip.family() == AF_INET) { 2450c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström result = send_(hping_, ip.ipv4_address().S_un.S_addr, data_, 2460c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint16_t(data_size), &ipopt, reply_, reply_size, timeout); 247f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (ip.family() == AF_INET6) { 248f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org sockaddr_in6 src = {0}; 249f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org sockaddr_in6 dst = {0}; 250f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org src.sin6_family = AF_INET6; 251f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org dst.sin6_family = AF_INET6; 252f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org dst.sin6_addr = ip.ipv6_address(); 2530c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström result = send6_(hping6_, NULL, NULL, NULL, &src, &dst, data_, 2540c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int16_t(data_size), &ipopt, reply_, reply_size, timeout); 255f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 256f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (result == 0) { 257f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org DWORD error = GetLastError(); 258f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (error == IP_PACKET_TOO_BIG) 259f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return PING_TOO_LARGE; 260f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (error == IP_REQ_TIMED_OUT) 261f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return PING_TIMEOUT; 262f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LERROR) << "IcmpSendEcho(" << ip.ToSensitiveString() 263f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org << ", " << data_size << "): " << error; 264f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return PING_FAIL; 265f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 266f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 267f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return PING_SUCCESS; 268f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 269f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 270f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org////////////////////////////////////////////////////////////////////// 271f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Microsoft Documenation 272f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org////////////////////////////////////////////////////////////////////// 273f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 274f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Routine Name: 275f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 276f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// IcmpCreateFile 277f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 278f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Routine Description: 279f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 280f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Opens a handle on which ICMP Echo Requests can be issued. 281f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 282f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Arguments: 283f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 284f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// None. 285f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 286f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Return Value: 287f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 288f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// An open file handle or INVALID_HANDLE_VALUE. Extended error information 289f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// is available by calling GetLastError(). 290f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 291f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org////////////////////////////////////////////////////////////////////// 292f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 293f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Routine Name: 294f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 295f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// IcmpCloseHandle 296f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 297f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Routine Description: 298f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 299f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Closes a handle opened by ICMPOpenFile. 300f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 301f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Arguments: 302f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 303f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// IcmpHandle - The handle to close. 304f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 305f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Return Value: 306f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 307f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// TRUE if the handle was closed successfully, otherwise FALSE. Extended 308f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// error information is available by calling GetLastError(). 309f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 310f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org////////////////////////////////////////////////////////////////////// 311f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 312f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Routine Name: 313f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 314f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// IcmpSendEcho 315f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 316f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Routine Description: 317f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 318f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Sends an ICMP Echo request and returns any replies. The 319f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// call returns when the timeout has expired or the reply buffer 320f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// is filled. 321f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 322f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Arguments: 323f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 324f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// IcmpHandle - An open handle returned by ICMPCreateFile. 325f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 326f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// DestinationAddress - The destination of the echo request. 327f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 328f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// RequestData - A buffer containing the data to send in the 329f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// request. 330f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 331f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// RequestSize - The number of bytes in the request data buffer. 332f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 333f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// RequestOptions - Pointer to the IP header options for the request. 334f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// May be NULL. 335f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 336f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// ReplyBuffer - A buffer to hold any replies to the request. 337f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// On return, the buffer will contain an array of 338f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// ICMP_ECHO_REPLY structures followed by the 339f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// options and data for the replies. The buffer 340f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// should be large enough to hold at least one 341f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// ICMP_ECHO_REPLY structure plus 342f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// MAX(RequestSize, 8) bytes of data since an ICMP 343f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// error message contains 8 bytes of data. 344f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 345f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// ReplySize - The size in bytes of the reply buffer. 346f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 347f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Timeout - The time in milliseconds to wait for replies. 348f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 349f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Return Value: 350f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 351f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Returns the number of ICMP_ECHO_REPLY structures stored in ReplyBuffer. 352f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// The status of each reply is contained in the structure. If the return 353f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// value is zero, extended error information is available via 354f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// GetLastError(). 355f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 356f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org////////////////////////////////////////////////////////////////////// 357f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 358f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} // namespace rtc 359