繁体中文
设为首页
加入收藏
当前位置:.Net技术首页 >> 远程及网络应用 >> 再给大家一个国外的类。超级好的东西。呵呵。

再给大家一个国外的类。超级好的东西。呵呵。

2004-10-01 08:26:10  作者:  来源:互联网  浏览次数:52  文字大小:【】【】【
简介:/****************************************************************************************************************** *    Class:        &...

/******************************************************************************************************************

* Class: Trace

* Description: Traces path of an ip packet with its respond time

* Author: Sanjay Ahuja

* Date: 5/15/2002

* Copyright? ?2002, Sanjay Ahuja (lparam@hotmail.com). Use it as you want till you leave my name intact

/******************************************************************************************************************/

using System;

using System.Net;

using System.Net.Sockets;

//ICMP constants

struct ICMPConstants

{

public const int ICMP_ECHOREPLY= 0; // Echo reply query

public const int ICMP_TIMEEXCEEDED= 11; // TTL exceeded error

public const int ICMP_ECHOREQ= 8; // Echo request query

public const int MAX_TTL= 256; // Max TTL

}

//ICMP header, size is 8 bytes

struct ICMP

{

public byte type; // Type

public byte code; // Code

public ushort checksum; // Checksum

public ushort id; // Identification

public ushort seq; // Sequence

}

// ICMP Echo Request, size is 12+ 32 (PACKET_SIZE as defined in class Trace)= 44 bytes

struct REQUEST

{

public ICMP m_icmp;

public byte []m_data;

}

class Trace

{

const int PACKET_SIZE= 32;

public static void Main(string[] args)

{

try

{

//verify command line

if(args.Length== 0)

{

Console.WriteLine("usage: trace ");

return;

}

//Create Raw ICMP Socket

Socket s= new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);

//destination

IPEndPoint ipdest= new IPEndPoint(Dns.Resolve(args[0]).AddressList[0],80);

//Source

IPEndPoint ipsrc= new IPEndPoint(Dns.GetHostByName(Dns.GetHostName()).AddressList[0],80);

EndPoint epsrc= (EndPoint)ipsrc;

ICMP ip= new ICMP();

ip.type = ICMPConstants.ICMP_ECHOREQ;

ip.code = 0;

ip.checksum = 0;

ip.id = (ushort)DateTime.Now.Millisecond; //any number you feel is kinda unique :)

ip.seq = 0;

REQUEST req= new REQUEST();

req.m_icmp= ip;

req.m_data = new Byte[PACKET_SIZE];

//Initialize data

for (int i = 0; i < req.m_data.Length; i++)

{

req.m_data[i] = (byte)'S';

}

//this function would gets byte array from the REQUEST structure

Byte[] ByteSend= CreatePacket(req);

//send requests with increasing number of TTL

for(int ittl=1; ittl<= ICMPConstants.MAX_TTL; ittl++)

{

Byte[] ByteRecv = new Byte[256];

//Socket options to set TTL and Timeouts

s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, ittl);

s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout,10000);

s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout,10000);

//Get current time

DateTime dt= DateTime.Now;

//Send Request

int iRet= s.SendTo(ByteSend, ByteSend.Length, SocketFlags.None, ipdest);

//check for Win32 SOCKET_ERROR

if(iRet== -1)

Console.WriteLine("error sending data");

//Receive

iRet= s.ReceiveFrom(ByteRecv, ByteRecv.Length, SocketFlags.None, ref epsrc);

//Calculate time required

TimeSpan ts= DateTime.Now- dt;;

//check if response is OK

if(iRet== -1)

Console.WriteLine("error getting data");

Console.WriteLine("TTL= {0,-5} IP= {1,-20} Time= {2,3}ms",ittl,((IPEndPoint)epsrc).Address,ts.Milliseconds);

//reply size should be sizeof REQUEST + 20 (i.e sizeof IP header),it should be an echo reply

//and id should be same

if((iRet == PACKET_SIZE+ 8 +20)&& (BitConverter.ToInt16(ByteRecv,24) == BitConverter.ToInt16(ByteSend,4))&& (ByteRecv[20] == ICMPConstants.ICMP_ECHOREPLY))

break;

//time out

if(ByteRecv[20] != ICMPConstants.ICMP_TIMEEXCEEDED)

{

Console.WriteLine("unexpected reply, quitting...");

break;

}

}

}

catch(SocketException e)

{

Console.WriteLine(e.Message);

}

catch(Exception e)

{

Console.WriteLine(e.Message);

}

}

public static byte[] CreatePacket( REQUEST req )

{

Byte[] ByteSend= new Byte[PACKET_SIZE+ 8];

//Create Byte array from REQUEST structure

ByteSend[0]= req.m_icmp.type;

ByteSend[1]= req.m_icmp.code;

Array.Copy(BitConverter.GetBytes(req.m_icmp.checksum), 0, ByteSend, 2, 2);

Array.Copy(BitConverter.GetBytes(req.m_icmp.id), 0, ByteSend, 4, 2);

Array.Copy(BitConverter.GetBytes(req.m_icmp.seq), 0, ByteSend, 6, 2);

for(int i=0; i< req.m_data.Length; i++)

ByteSend[i+8]= req.m_data[i];

//calculate checksum

int iCheckSum = 0;

for (int i= 0; i < ByteSend.Length; i+= 2)

iCheckSum += Convert.ToInt32( BitConverter.ToUInt16(ByteSend,i));

iCheckSum = (iCheckSum >> 16) + (iCheckSum & 0xffff);

iCheckSum += (iCheckSum >> 16);

//update byte array to reflect checksum

Array.Copy(BitConverter.GetBytes((ushort)~iCheckSum), 0, ByteSend, 2, 2);

return ByteSend;

}

}

责任编辑:admin
相关文章