我的ICMP为什么老收不到数据 ( 积分: 100 )

  • 主题发起人 主题发起人 HUAGUAN
  • 开始时间 开始时间
H

HUAGUAN

Unregistered / Unconfirmed
GUEST, unregistred user!
这是我从C翻译过来的,为什么C可以运行而下面的程序一运行到recvfrom就超时

unit Uping;

interface
uses Windows, SysUtils, winsock;
const
SOCKET_ERROR = -1;
ICMP_ECHO = 8;
ICMP_MIN = 8;
ICMP_ECHOREPLY = 0;
MAX_IP_HDR_SIZE = 60;
MAX_PACKET = 1024;

SOL_SOCKET = $FFFF;
SOMAXCONN = $7FFFFFFF;

WSA_FLAG_OVERLAPPED = $1;
MAX_PROTOCOL_CHAIN = 7;
WSAPROTOCOL_LEN = 255;

IP_RECORD_ROUTE = $07;

type
WSAPROTOCOLCHAIN = record
ChainLen: Integer;
ChainEntries: array[0..MAX_PROTOCOL_CHAIN - 1] of DWORD;
end;

TWSAData = record
wVersion: WORD;
wHighVersion: WORD;
szDescription: array[0..WSADESCRIPTION_LEN] of Char;
szSystemStatus: array[0..WSASYS_STATUS_LEN] of Char;
iMaxSockets: Word;
iMaxUdpDg: Word;
lpVendorInfo: PChar;
end;

PWSAPROTOCOL_INFO = ^WSAPROTOCOL_INFO;
WSAPROTOCOL_INFO = record
dwServiceFlags1: DWORD;
dwServiceFlags2: DWORD;
dwServiceFlags3: DWORD;
dwServiceFlags4: DWORD;
dwProviderFlags: DWORD;
ProviderId: TGUID;
dwCatalogEntryId: DWORD;
ProtocolChain: WSAPROTOCOLCHAIN;
iVersion: Integer;
iAddressFamily: Integer;
iMaxSockAddr: Integer;
iMinSockAddr: Integer;
iSocketType: Integer;
iProtocol: Integer;
iProtocolMaxOffset: Integer;
iNetworkByteOrder: Integer;
iSecurityScheme: Integer;
dwMessageSize: DWORD;
dwProviderReserved: DWORD;
szProtocol: array[0..WSAPROTOCOL_LEN] of WideChar;
end;
PIpOptionHeader = ^TIpOptionHeader;
TIpOptionHeader = record
code: Byte;
len: Byte;
ptr: Byte;
addr: array[0..8] of ULONG; // List of IP addrs
end;
PIpHeader = ^TIpHeader;
TIpHeader = record
h_len: DWORD;
version: DWORD;
tos: Byte;
total_len: Word;
ident: Word;
FragAndFlags: Word;
ttl: Byte;
proto: Byte;
checksum: Word;
sourceIP: DWORD;
destIP: DWORD;
end;

PIcmpHeader = ^TIcmpHeader;
TIcmpHeader = record
i_type: Byte;
i_code: Byte;
i_cksum: Word;
i_id: Word;
i_seq: Word;
timestamp: ULONG;
end;
TPacketBuffer = array[0..Max_Packet - 1] of byte;

function WSASocket(af, type_, protocol: Integer; lpProtocolInfo: PWSAPROTOCOL_INFO;
g: Cardinal; dwFlags: DWORD): TSocket; stdcall;
function setsockopt(s: TSocket; level, optname: Integer; optval: PChar; optlen: Integer): Integer; stdcall;
function WSAGetLastError: Integer; stdcall;
procedure Ping;
implementation

function WSASocket; external 'ws2_32.dll' name 'WSASocketW';
function setsockopt; external 'ws2_32.dll' name 'setsockopt';
function WSAGetLastError; external 'ws2_32.dll' name 'WSAGetLastError';

function MAKEWORD(low, high: Word): Word;
begin
Result := low or (high shr 8);
end;

function CreateSock: TSocket;
var wsData: WSAData;
begin
if (WSAStartup(MAKEWORD(2, 2), wsData) = 0) then
Result := WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, nil, 0,
WSA_FLAG_OVERLAPPED)
else Result := INVALID_SOCKET;
end;

procedure DestraySock(ASK: TSocket);
begin
if ASK <> INVALID_SOCKET then closesocket(ASK);
WSACleanup;
end;

procedure FillICMPData(icmp_data: PChar; datasize: Integer);
var
icmp_hdr: PIcmpHeader;
datapart: PChar;
begin
icmp_hdr := PIcmpHeader(icmp_data);
icmp_hdr^.i_type := ICMP_ECHO;
icmp_hdr^.i_code := 0;
icmp_hdr^.i_id := Word(GetCurrentProcessId());
icmp_hdr^.i_cksum := 0;
icmp_hdr^.i_seq := 0;

datapart := icmp_data + sizeof(TIcmpHeader);
FillChar(datapart^, datasize - sizeof(TIcmpHeader), 'E');
end;

function checksum(var buffer; size: Integer): Word;
var cksum: LongWord;
i: Integer;
P: PChar;
begin
cksum := 0;
p := @buffer;
for i := 0 to size - 1 do
cksum := cksum + word((p + i)^);
if (size mod 2) = 1 then cksum := cksum + byte((P + size)^);
cksum := (cksum shr 16) + (cksum and $FFFF);
cksum := cksum + (cksum shr 16);
Result := word(cksum);
end;

procedure DecodeIPOptions(buf: PChar; bytes: Integer);
var
ipopt: PIpOptionHeader;
inaddr: TInAddr;
i: Integer;
host: Phostent;
begin

end;

procedure DecodeICMPHeader(buf: PChar; bytes: Integer; from: PSockAddrIn);
var
iphdr: PIpHeader;
icmphdr: PIcmpHeader;
iphdrlen: Word;
tick: DWORD;
icmpcount: Integer;
begin

end;

procedure Ping;
var SK: TSocket;
M_ipopt: TIpOptionHeader;
TimeOut: Integer;
SouIp, DestIp: TSockAddrIn;
DataSize, bwrote, FromLen: Integer;
seq_no: Word;
icmp_data, recvbuf: TPacketBuffer;
begin
SK := CreateSock;
if SK = INVALID_SOCKET then Exit;
{ M_ipopt.code := IP_RECORD_ROUTE;
M_ipopt.len :=39;
M_ipopt.ptr := 4;
bwrote := setsockopt(SK, IPPROTO_IP, IP_OPTIONS, PChar(@M_ipopt), sizeof(M_ipopt));
if bwrote = SOCKET_ERROR then Exit;
//设置记录路由 }
TimeOut := 1000;
if setsockopt(SK, SOL_SOCKET, SO_RCVTIMEO, PChar(@TimeOut), sizeof(TimeOut)) = SOCKET_ERROR then Exit;
//设置接收超时
if setsockopt(SK, SOL_SOCKET, SO_SNDTIMEO, PChar(@TimeOut), sizeof(TimeOut)) = SOCKET_ERROR then Exit;
//设置发送超时
DestIp.sin_family := AF_INET;
DestIp.sin_addr.S_addr := inet_addr('192.168.1.28');
DataSize := 23 + sizeof(TIcmpHeader);
seq_no := 0;

FillChar(icmp_data, MAX_PACKET, 0);
FillICMPData(@icmp_data, datasize);

inc(seq_no);
PIcmpHeader(@icmp_data).timestamp := GetTickCount();
PIcmpHeader(@icmp_data).i_seq := seq_no;
PIcmpHeader(@icmp_data).i_cksum := checksum(icmp_data, datasize);

bwrote := sendto(SK, icmp_data, DataSize, 0, DestIp, sizeof(DestIp));
if bwrote = SOCKET_ERROR then
begin
raise Exception.Create(format('%d', [WSAGetLastError]));
Exit;
end;
FromLen := sizeof(SouIp);
while true do
begin
bwrote := recvfrom(SK, recvbuf, MAX_PACKET, 0, SouIp, FromLen);
if (bwrote = SOCKET_ERROR) then
if (WSAGetLastError() = WSAETIMEDOUT) then continue
else
begin
raise Exception.Create(format('%d', [WSAGetLastError]));
Exit;
end;
end;

DestraySock(SK);
end;
end.
 
这是我从C翻译过来的,为什么C可以运行而下面的程序一运行到recvfrom就超时

unit Uping;

interface
uses Windows, SysUtils, winsock;
const
SOCKET_ERROR = -1;
ICMP_ECHO = 8;
ICMP_MIN = 8;
ICMP_ECHOREPLY = 0;
MAX_IP_HDR_SIZE = 60;
MAX_PACKET = 1024;

SOL_SOCKET = $FFFF;
SOMAXCONN = $7FFFFFFF;

WSA_FLAG_OVERLAPPED = $1;
MAX_PROTOCOL_CHAIN = 7;
WSAPROTOCOL_LEN = 255;

IP_RECORD_ROUTE = $07;

type
WSAPROTOCOLCHAIN = record
ChainLen: Integer;
ChainEntries: array[0..MAX_PROTOCOL_CHAIN - 1] of DWORD;
end;

TWSAData = record
wVersion: WORD;
wHighVersion: WORD;
szDescription: array[0..WSADESCRIPTION_LEN] of Char;
szSystemStatus: array[0..WSASYS_STATUS_LEN] of Char;
iMaxSockets: Word;
iMaxUdpDg: Word;
lpVendorInfo: PChar;
end;

PWSAPROTOCOL_INFO = ^WSAPROTOCOL_INFO;
WSAPROTOCOL_INFO = record
dwServiceFlags1: DWORD;
dwServiceFlags2: DWORD;
dwServiceFlags3: DWORD;
dwServiceFlags4: DWORD;
dwProviderFlags: DWORD;
ProviderId: TGUID;
dwCatalogEntryId: DWORD;
ProtocolChain: WSAPROTOCOLCHAIN;
iVersion: Integer;
iAddressFamily: Integer;
iMaxSockAddr: Integer;
iMinSockAddr: Integer;
iSocketType: Integer;
iProtocol: Integer;
iProtocolMaxOffset: Integer;
iNetworkByteOrder: Integer;
iSecurityScheme: Integer;
dwMessageSize: DWORD;
dwProviderReserved: DWORD;
szProtocol: array[0..WSAPROTOCOL_LEN] of WideChar;
end;
PIpOptionHeader = ^TIpOptionHeader;
TIpOptionHeader = record
code: Byte;
len: Byte;
ptr: Byte;
addr: array[0..8] of ULONG; // List of IP addrs
end;
PIpHeader = ^TIpHeader;
TIpHeader = record
h_len: DWORD;
version: DWORD;
tos: Byte;
total_len: Word;
ident: Word;
FragAndFlags: Word;
ttl: Byte;
proto: Byte;
checksum: Word;
sourceIP: DWORD;
destIP: DWORD;
end;

PIcmpHeader = ^TIcmpHeader;
TIcmpHeader = record
i_type: Byte;
i_code: Byte;
i_cksum: Word;
i_id: Word;
i_seq: Word;
timestamp: ULONG;
end;
TPacketBuffer = array[0..Max_Packet - 1] of byte;

function WSASocket(af, type_, protocol: Integer; lpProtocolInfo: PWSAPROTOCOL_INFO;
g: Cardinal; dwFlags: DWORD): TSocket; stdcall;
function setsockopt(s: TSocket; level, optname: Integer; optval: PChar; optlen: Integer): Integer; stdcall;
function WSAGetLastError: Integer; stdcall;
procedure Ping;
implementation

function WSASocket; external 'ws2_32.dll' name 'WSASocketW';
function setsockopt; external 'ws2_32.dll' name 'setsockopt';
function WSAGetLastError; external 'ws2_32.dll' name 'WSAGetLastError';

function MAKEWORD(low, high: Word): Word;
begin
Result := low or (high shr 8);
end;

function CreateSock: TSocket;
var wsData: WSAData;
begin
if (WSAStartup(MAKEWORD(2, 2), wsData) = 0) then
Result := WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, nil, 0,
WSA_FLAG_OVERLAPPED)
else Result := INVALID_SOCKET;
end;

procedure DestraySock(ASK: TSocket);
begin
if ASK <> INVALID_SOCKET then closesocket(ASK);
WSACleanup;
end;

procedure FillICMPData(icmp_data: PChar; datasize: Integer);
var
icmp_hdr: PIcmpHeader;
datapart: PChar;
begin
icmp_hdr := PIcmpHeader(icmp_data);
icmp_hdr^.i_type := ICMP_ECHO;
icmp_hdr^.i_code := 0;
icmp_hdr^.i_id := Word(GetCurrentProcessId());
icmp_hdr^.i_cksum := 0;
icmp_hdr^.i_seq := 0;

datapart := icmp_data + sizeof(TIcmpHeader);
FillChar(datapart^, datasize - sizeof(TIcmpHeader), 'E');
end;

function checksum(var buffer; size: Integer): Word;
var cksum: LongWord;
i: Integer;
P: PChar;
begin
cksum := 0;
p := @buffer;
for i := 0 to size - 1 do
cksum := cksum + word((p + i)^);
if (size mod 2) = 1 then cksum := cksum + byte((P + size)^);
cksum := (cksum shr 16) + (cksum and $FFFF);
cksum := cksum + (cksum shr 16);
Result := word(cksum);
end;

procedure DecodeIPOptions(buf: PChar; bytes: Integer);
var
ipopt: PIpOptionHeader;
inaddr: TInAddr;
i: Integer;
host: Phostent;
begin

end;

procedure DecodeICMPHeader(buf: PChar; bytes: Integer; from: PSockAddrIn);
var
iphdr: PIpHeader;
icmphdr: PIcmpHeader;
iphdrlen: Word;
tick: DWORD;
icmpcount: Integer;
begin

end;

procedure Ping;
var SK: TSocket;
M_ipopt: TIpOptionHeader;
TimeOut: Integer;
SouIp, DestIp: TSockAddrIn;
DataSize, bwrote, FromLen: Integer;
seq_no: Word;
icmp_data, recvbuf: TPacketBuffer;
begin
SK := CreateSock;
if SK = INVALID_SOCKET then Exit;
{ M_ipopt.code := IP_RECORD_ROUTE;
M_ipopt.len :=39;
M_ipopt.ptr := 4;
bwrote := setsockopt(SK, IPPROTO_IP, IP_OPTIONS, PChar(@M_ipopt), sizeof(M_ipopt));
if bwrote = SOCKET_ERROR then Exit;
//设置记录路由 }
TimeOut := 1000;
if setsockopt(SK, SOL_SOCKET, SO_RCVTIMEO, PChar(@TimeOut), sizeof(TimeOut)) = SOCKET_ERROR then Exit;
//设置接收超时
if setsockopt(SK, SOL_SOCKET, SO_SNDTIMEO, PChar(@TimeOut), sizeof(TimeOut)) = SOCKET_ERROR then Exit;
//设置发送超时
DestIp.sin_family := AF_INET;
DestIp.sin_addr.S_addr := inet_addr('192.168.1.28');
DataSize := 23 + sizeof(TIcmpHeader);
seq_no := 0;

FillChar(icmp_data, MAX_PACKET, 0);
FillICMPData(@icmp_data, datasize);

inc(seq_no);
PIcmpHeader(@icmp_data).timestamp := GetTickCount();
PIcmpHeader(@icmp_data).i_seq := seq_no;
PIcmpHeader(@icmp_data).i_cksum := checksum(icmp_data, datasize);

bwrote := sendto(SK, icmp_data, DataSize, 0, DestIp, sizeof(DestIp));
if bwrote = SOCKET_ERROR then
begin
raise Exception.Create(format('%d', [WSAGetLastError]));
Exit;
end;
FromLen := sizeof(SouIp);
while true do
begin
bwrote := recvfrom(SK, recvbuf, MAX_PACKET, 0, SouIp, FromLen);
if (bwrote = SOCKET_ERROR) then
if (WSAGetLastError() = WSAETIMEDOUT) then continue
else
begin
raise Exception.Create(format('%d', [WSAGetLastError]));
Exit;
end;
end;

DestraySock(SK);
end;
end.
 
这是C的源程序
#include &quot;winsock2.h&quot;

#include &quot;ws2tcpip.h&quot;
#include &quot;stdio.h&quot;
#include &quot;stdlib.h&quot;

#define WIN32_LEAN_AND_MEAN

#define IP_RECORD_ROUTE 0x7

#pragma comment(lib, &quot;ws2_32.lib&quot;)
//
// IP header structure
//
typedef struct _iphdr
{
unsigned int h_len:4; // Length of the header
unsigned int version:4; // Version of IP
unsigned char tos; // Type of service
unsigned short total_len; // Total length of the packet
unsigned short ident; // Unique identifier
unsigned short frag_and_flags; // Flags
unsigned char ttl; // Time to live
unsigned char proto; // Protocol (TCP, UDP etc)
unsigned short checksum; // IP checksum

unsigned int sourceIP;
unsigned int destIP;
} IpHeader;

#define ICMP_ECHO 8
#define ICMP_ECHOREPLY 0
#define ICMP_MIN 8 // Minimum 8-byte ICMP packet (header)

//
// ICMP header structure
//
typedef struct _icmphdr
{
BYTE i_type;
BYTE i_code; // Type sub code
USHORT i_cksum;
USHORT i_id;
USHORT i_seq;
// This is not the standard header, but we reserve space for time
ULONG timestamp;
} IcmpHeader;

//
// IP option header - use with socket option IP_OPTIONS
//
typedef struct _ipoptionhdr
{
unsigned char code; // Option type
unsigned char len; // Length of option hdr
unsigned char ptr; // Offset into options
unsigned long addr[9]; // List of IP addrs
} IpOptionHeader;

#define DEF_PACKET_SIZE 32 // Default packet size
#define MAX_PACKET 1024 // Max ICMP packet size
#define MAX_IP_HDR_SIZE 60 // Max IP header size w/options

BOOL bRecordRoute;
int datasize;
char *lpdest;

//
// Function: usage
//
// Description:
// Print usage information
//
void usage(char *progname)
{
printf(&quot;usage: ping -r <host> [data size]/n&quot;);
printf(&quot; -r record route/n&quot;);
printf(&quot; host remote machine to ping/n&quot;);
printf(&quot; datasize can be up to 1KB/n&quot;);
ExitProcess(-1);
}

//
// Function: FillICMPData
//
// Description:
// Helper function to fill in various fields for our ICMP request
//
void FillICMPData(char *icmp_data, int datasize)
{
IcmpHeader *icmp_hdr = NULL;
char *datapart = NULL;

icmp_hdr = (IcmpHeader*)icmp_data;
icmp_hdr->i_type = ICMP_ECHO; // Request an ICMP echo
icmp_hdr->i_code = 0;
icmp_hdr->i_id = (USHORT)GetCurrentProcessId();
icmp_hdr->i_cksum = 0;
icmp_hdr->i_seq = 0;

datapart = icmp_data + sizeof(IcmpHeader);
//
// Place some junk in the buffer
//
memset(datapart,'E', datasize - sizeof(IcmpHeader));
}

//
// Function: checksum
//
// Description:
// This function calculates the 16-bit one's complement sum
// of the supplied buffer (ICMP) header
//
USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;

while (size > 1)
{
cksum += *buffer++;
size -= sizeof(USHORT);
}
if (size)
{
cksum += *(UCHAR*)buffer;
}
cksum = (cksum >> 16) + (cksum &amp; 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}

//
// Function: DecodeIPOptions
//
// Description:
// If the IP option header is present, find the IP options
// within the IP header and print the record route option
// values
//
void DecodeIPOptions(char *buf, int bytes)
{
IpOptionHeader *ipopt = NULL;
IN_ADDR inaddr;
int i;
HOSTENT *host = NULL;

ipopt = (IpOptionHeader *)(buf + 20);

printf(&quot;RR: &quot;);
for(i = 0; i < (ipopt->ptr / 4) - 1; i++)
{
inaddr.S_un.S_addr = ipopt->addr;
if (i != 0)
printf(&quot; &quot;);
host = gethostbyaddr((char *)&amp;inaddr.S_un.S_addr,
sizeof(inaddr.S_un.S_addr), AF_INET);
if (host)
printf(&quot;(%-15s) %s/n&quot;, inet_ntoa(inaddr), host->h_name);
else
printf(&quot;(%-15s)/n&quot;, inet_ntoa(inaddr));
}
return;
}

//
// Function: DecodeICMPHeader
//
// Description:
// The response is an IP packet. We must decode the IP header to
// locate the ICMP data.
//
void DecodeICMPHeader(char *buf, int bytes,
struct sockaddr_in *from)
{
IpHeader *iphdr = NULL;
IcmpHeader *icmphdr = NULL;
unsigned short iphdrlen;
DWORD tick;
static int icmpcount = 0;

iphdr = (IpHeader *)buf;
// Number of 32-bit words * 4 = bytes
iphdrlen = iphdr->h_len * 4;
tick = GetTickCount();

if ((iphdrlen == MAX_IP_HDR_SIZE) &amp;&amp; (!icmpcount))
DecodeIPOptions(buf, bytes);

if (bytes < iphdrlen + ICMP_MIN)
{
printf(&quot;Too few bytes from %s/n&quot;,
inet_ntoa(from->sin_addr));
}
icmphdr = (IcmpHeader*)(buf + iphdrlen);

if (icmphdr->i_type != ICMP_ECHOREPLY)
{
printf(&quot;nonecho type %d recvd/n&quot;, icmphdr->i_type);
return;
}
// Make sure this is an ICMP reply to something we sent!
//
if (icmphdr->i_id != (USHORT)GetCurrentProcessId())
{
printf(&quot;someone else's packet!/n&quot;);
return ;
}
printf(&quot;%d bytes from %s:&quot;, bytes, inet_ntoa(from->sin_addr));
printf(&quot; icmp_seq = %d. &quot;, icmphdr->i_seq);
printf(&quot; time: %d ms&quot;, tick - icmphdr->timestamp);
printf(&quot;/n&quot;);

icmpcount++;
return;
}

void ValidateArgs(int argc, char **argv)
{
int i;

bRecordRoute = FALSE;
lpdest = NULL;
datasize = DEF_PACKET_SIZE;

for(i = 1; i < argc; i++)
{
if ((argv[0] == '-') || (argv[0] == '/'))
{
switch (tolower(argv[1]))
{
case 'r': // Record route option
bRecordRoute = TRUE;
break;
default:
usage(argv[0]);
break;
}
}
else if (isdigit(argv[0]))
datasize = atoi(argv);
else
lpdest = argv;
}
}

//
// Function: main
//
// Description:
// Setup the ICMP raw socket, and create the ICMP header. Add
// the appropriate IP option header, and start sending ICMP
// echo requests to the endpoint. For each send and receive,
// we set a timeout value so that we don't wait forever for a
// response in case the endpoint is not responding. When we
// receive a packet decode it.
//
int main(int argc, char **argv)
{

WSADATA wsaData;
SOCKET sockRaw = INVALID_SOCKET;
struct sockaddr_in dest,
from;
int bread,
fromlen = sizeof(from),
timeout = 1000,
ret;
char *icmp_data = NULL,
*recvbuf = NULL;
unsigned int addr = 0;
USHORT seq_no = 0;
struct hostent *hp = NULL;
IpOptionHeader ipopt;


if (WSAStartup(MAKEWORD(2, 2), &amp;wsaData) != 0)
{
printf(&quot;WSAStartup() failed: %d/n&quot;, GetLastError());
return -1;
}
ValidateArgs(argc, argv);

//
// WSA_FLAG_OVERLAPPED flag is required for SO_RCVTIMEO,
// SO_SNDTIMEO option. If NULL is used as last param for
// WSASocket, all I/O on the socket is synchronous, the
// internal user mode wait code never gets a chance to
// execute, and therefore kernel-mode I/O blocks forever.
// A socket created via the socket function has the over-
// lapped I/O attribute set internally. But here we need
// to use WSASocket to specify a raw socket.
//
// If you want to use timeout with a synchronous
// nonoverlapped socket created by WSASocket with last
// param set to NULL, you can set the timeout by using
// the select function, or you can use WSAEventSelect and
// set the timeout in the WSAWaitForMultipleEvents
// function.
//
sockRaw = WSASocket (AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0,
WSA_FLAG_OVERLAPPED);
if (sockRaw == INVALID_SOCKET)
{
printf(&quot;WSASocket() failed: %d/n&quot;, WSAGetLastError());
return -1;
}
bRecordRoute=1;
if (bRecordRoute)
{
// Setup the IP option header to go out on every ICMP packet
//
ZeroMemory(&amp;ipopt, sizeof(ipopt));
ipopt.code = IP_RECORD_ROUTE; // Record route option
ipopt.ptr = 4; // Point to the first addr offset
ipopt.len = 39; // Length of option header

ret = setsockopt(sockRaw, IPPROTO_IP, IP_OPTIONS,
(char *)&amp;ipopt, sizeof(ipopt));
if (ret == SOCKET_ERROR)
{
printf(&quot;setsockopt(IP_OPTIONS) failed: %d/n&quot;,
WSAGetLastError());
}
}
// Set the send/recv timeout values
//
bread = setsockopt(sockRaw, SOL_SOCKET, SO_RCVTIMEO,
(char*)&amp;timeout, sizeof(timeout));
if(bread == SOCKET_ERROR)
{
printf(&quot;setsockopt(SO_RCVTIMEO) failed: %d/n&quot;,
WSAGetLastError());
return -1;
}
timeout = 1000;
bread = setsockopt(sockRaw, SOL_SOCKET, SO_SNDTIMEO,
(char*)&amp;timeout, sizeof(timeout));
if (bread == SOCKET_ERROR)
{
printf(&quot;setsockopt(SO_SNDTIMEO) failed: %d/n&quot;,
WSAGetLastError());
return -1;
}
memset(&amp;dest, 0, sizeof(dest));
//
// Resolve the endpoint's name if necessary
//
dest.sin_family = AF_INET;
lpdest=&quot;202.101.103.55&quot;;
if ((dest.sin_addr.s_addr = inet_addr(lpdest)) == INADDR_NONE)
{
if ((hp = gethostbyname(lpdest)) != NULL)
{
memcpy(&amp;(dest.sin_addr), hp->h_addr, hp->h_length);
dest.sin_family = hp->h_addrtype;
printf(&quot;dest.sin_addr = %s/n&quot;, inet_ntoa(dest.sin_addr));
}
else
{
printf(&quot;gethostbyname() failed: %d/n&quot;,
WSAGetLastError());
return -1;
}
}

//
// Create the ICMP packet
//
datasize=23;
datasize += sizeof(IcmpHeader);

icmp_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
MAX_PACKET);
recvbuf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
MAX_PACKET);
if (!icmp_data)
{
printf(&quot;HeapAlloc() failed: %d/n&quot;, GetLastError());
return -1;
}
memset(icmp_data,0,MAX_PACKET);
FillICMPData(icmp_data,datasize);
//
// Start sending/receiving ICMP packets
//
while(1)
{
static int nCount = 0;
int bwrote;

if (nCount++ == 4)
break;

((IcmpHeader*)icmp_data)->i_cksum = 0;
((IcmpHeader*)icmp_data)->timestamp = GetTickCount();
((IcmpHeader*)icmp_data)->i_seq = seq_no++;
((IcmpHeader*)icmp_data)->i_cksum =
checksum((USHORT*)icmp_data, datasize);

bwrote = sendto(sockRaw, icmp_data, datasize, 0,
(struct sockaddr*)&amp;dest, sizeof(dest));
if (bwrote == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAETIMEDOUT)
{
printf(&quot;timed out/n&quot;);
continue;
}
printf(&quot;sendto() failed: %d/n&quot;, WSAGetLastError());
return -1;
}
if (bwrote < datasize)
{
printf(&quot;Wrote %d bytes/n&quot;, bwrote);
}
bread = recvfrom(sockRaw, recvbuf, MAX_PACKET, 0,
(struct sockaddr*)&amp;from, &amp;fromlen);
if (bread == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAETIMEDOUT)
{
printf(&quot;timed out/n&quot;);
continue;
}
printf(&quot;recvfrom() failed: %d/n&quot;, WSAGetLastError());
return -1;
}
DecodeICMPHeader(recvbuf, bread, &amp;from);

Sleep(1000);
}
// Cleanup
//
if (sockRaw != INVALID_SOCKET)
closesocket(sockRaw);
HeapFree(GetProcessHeap(), 0, recvbuf);
HeapFree(GetProcessHeap(), 0, icmp_data);

WSACleanup();
return 0;
}
 
所有的RECORD前面都加PACKED试试!
 
接受答案了.
 

Similar threads

I
回复
0
查看
674
import
I
I
回复
0
查看
667
import
I
I
回复
0
查看
1K
import
I
后退
顶部