读书人

怎么用rawsocket接收tcp数据包

发布时间: 2011-12-24 23:03:24 作者: rapoo

如何用rawsocket接收tcp数据包
我是个初学者,对网络编程比较感兴趣,我想用c#rawsocket方式监视进出网卡的tcp数据包,想了解tcp包里面的内容,请各位高手老师给个实现的思路和实现的方法。

[解决办法]
tcp数据包应该有头的,也就是说一个包的开始几个Byte应该把它所在的这个包的大小和起始终了都描述清楚. 如果没有这个头,包之间就很难分开了.

头的定义最简单的方法是: 最开始两个Byte定义为包开始的特征字,比如00,然后规定若干位,比如4表示整个包的长度.

通常的手法是把每次得到的byte[] 放到加到一个缓存里,比如一个List <byte> , 然后靠每个包的头把各个包拆出来.


[解决办法]
//This file contains the RawSocket class. The goal of this class is to have a generic packet
//sniffing kind of class that fires events when an incoming IP packet is received. The event
//gives the user access to everything contained in the IP packet and hopefully makes creating
//your own packet sniffer quite easy. The event args returned with the event give the user of
//the class access to things like the from and to IP address, ports, protocol, etc. and even the
//contents of the message in the form of a byte array.

/******************************************
* Fixed Some Problem
* Modify By Red_angelX
* Build 2007.4.24
*****************************************/


namespace QQFamilyAnalytics
{
using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Windows.Forms;

[StructLayout(LayoutKind.Explicit)]
public struct IPHeader
{
[FieldOffset(0)] public byte ip_verlen; //IP version and IP Header length Combined
[FieldOffset(1)] public byte ip_tos; //Type of Service
[FieldOffset(2)] public ushort ip_totallength; //Total Packet Length
[FieldOffset(4)] public ushort ip_id; //Unique ID
[FieldOffset(6)] public ushort ip_offset; //Flags and Offset
[FieldOffset(8)] public byte ip_ttl; //Time To Live
[FieldOffset(9)] public byte ip_protocol; //Protocol (TCP, UDP, ICMP, Etc.)
[FieldOffset(10)] public ushort ip_checksum; //IP Header Checksum
[FieldOffset(12)] public uint ip_srcaddr; //Source IP Address
[FieldOffset(16)] public uint ip_destaddr; //Destination IP Address
}

public class RawSocket
{
private bool error_occurred;
public bool KeepRunning;
private static int len_receive_buf;
byte [] receive_buf_bytes;
private Socket socket = null;
private static string localip;

public RawSocket()
{
error_occurred=false;
len_receive_buf = 4096;
receive_buf_bytes = new byte[len_receive_buf];
}

public void CreateAndBindSocket(string IP)
{
localip = IP;
socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
socket.Blocking = false;
socket.Bind(new IPEndPoint(IPAddress.Parse(IP), 0));

if (SetSocketOption()==false) error_occurred=true;
}

public void Shutdown()
{
if(socket != null)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}

private bool SetSocketOption()
{
bool ret_value = true;
try
{
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, 1);

byte []IN = new byte[4]{1, 0, 0, 0};
byte []OUT = new byte[4];
int SIO_RCVALL = unchecked((int)0x98000001);
int ret_code = socket.IOControl(SIO_RCVALL, IN, OUT);
ret_code = OUT[0] + OUT[1] + OUT[2] + OUT[3];
if(ret_code != 0) ret_value = false;
}
catch(SocketException)
{
ret_value = false;
}
return ret_value;


}

public bool ErrorOccurred
{
get
{
return error_occurred;
}
}

unsafe private void Receive(byte [] buf, int len)
{
byte temp_protocol=0;
uint temp_version=0;
uint temp_ip_srcaddr=0;
uint temp_ip_destaddr=0;
short temp_srcport=0;
short temp_dstport=0;
IPAddress temp_ip;

PacketArrivedEventArgs e=new PacketArrivedEventArgs();

fixed(byte *fixed_buf = buf)
{
IPHeader * head = (IPHeader *) fixed_buf;
e.HeaderLength=(uint)(head-> ip_verlen & 0x0F) < < 2;

temp_protocol = head-> ip_protocol;
switch(temp_protocol)
{
case 1: e.Protocol= "ICMP "; break;
case 2: e.Protocol= "IGMP "; break;
case 6: e.Protocol= "TCP "; break;
case 17: e.Protocol= "UDP "; break;
default: e.Protocol= "UNKNOWN "; break;
}

temp_version =(uint)(head-> ip_verlen & 0xF0) > > 4;
e.IPVersion = temp_version.ToString();

temp_ip_srcaddr = head-> ip_srcaddr;
temp_ip_destaddr = head-> ip_destaddr;
temp_ip = new IPAddress(temp_ip_srcaddr);
e.OriginationAddress =temp_ip.ToString();
temp_ip = new IPAddress(temp_ip_destaddr);
e.DestinationAddress = temp_ip.ToString();

temp_srcport = *(short *)&fixed_buf[e.HeaderLength];
temp_dstport = *(short *)&fixed_buf[e.HeaderLength+2];
e.OriginationPort=IPAddress.NetworkToHostOrder(temp_srcport).ToString();
e.DestinationPort=IPAddress.NetworkToHostOrder(temp_dstport).ToString();

e.PacketLength =(uint)len;
e.MessageLength =(uint)len - e.HeaderLength;
//这里确定长度
e.MessageBuffer = new byte[e.MessageLength];
e.MessageData = new byte[e.MessageLength - 8];

e.ReceiveBuffer=buf;
Array.Copy(buf,0,e.IPHeaderBuffer,0,(int)e.HeaderLength);
Array.Copy(buf,(int)e.HeaderLength,e.MessageBuffer,0,(int)e.MessageLength);
Array.Copy(e.MessageBuffer, 8, e.MessageData, 0, e.MessageData.Length);
}

OnPacketArrival(e);
}

读书人网 >C#

热点推荐