首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

控制网卡的程序思路,该怎么解决

2012-01-30 
控制网卡的程序思路我想实现的功能是:启动一个应用程序之后全权接管一个硬件网卡(无线)的收发数据。应用程

控制网卡的程序思路
我想实现的功能是:启动一个应用程序之后全权接管一个硬件网卡(无线)的收发数据。应用程序能够接收所有该网卡收到的网络传输层数据,同时也能够自己组数据包直接交给网卡发送。(注意:收发的数据非TCP或UDP等传统协议,没有端口的概念,属于IP层协议)。
另外如果能够实现其他程序无法绑定此网卡的Socket那么效果更佳。

现在问题是这方面的编程没有接触过,本人能够通过ioctlsocket()实现类似sniffer的监听功能,但是无法跳过IP层发送自定义数据包。请问要实现我说的功能都需要研究哪方面的技术?WDM?驱动?
希望高手们给点思路

[解决办法]
不知道winpcap的发包功能能否满足。
[解决办法]
可以用IP过滤钩子实现,比较简单,通过过滤IP数据包基本上可以完成要求:
示例代码:
PIRP nirp;
NTSTATUS status = STATUS_SUCCESS;
NTSTATUS waitStatus=STATUS_SUCCESS;
PFILE_OBJECT filtfileob;
UNICODE_STRING ntDeviceName;
PDEVICE_OBJECT filtdeviceob;
PF_SET_EXTENSION_HOOK_INFO filthook;
IO_STATUS_BLOCK filtstatus;
KEVENT event;
/*
注意:必须启动系统自带的ip过滤驱动,让它随机启动。
可通过修改注册表中
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/IpFilterDriver
中的Start为0x00000002完成
*/
RtlInitUnicodeString(&ntDeviceName,L "\\Device\\IPFILTERDRIVER ");
//获得系统ipfilterdriver驱动的设备指针
status = IoGetDeviceObjectPointer(&ntDeviceName,FILE_GENERIC_READ|FILE_GENERIC_WRITE,&filtfileob,&filtdeviceob);
KdPrint(( "status=0x%8x\n ",status));
if(NT_SUCCESS(status))
{
if(load)
{
//将钩子挂接函数放入结构中
filthook.ExtensionPointer = IpFilterHook;
KdPrint(( "filthook.ExtensionPointer=0x%8x\n ",filthook.ExtensionPointer));
}
else
{

//将钩子挂接函数放入结构中
filthook.ExtensionPointer = NULL;
KdPrint(( "filthook.ExtensionPointer=0x%8x\n ",filthook.ExtensionPointer));
}
KeInitializeEvent(&event, NotificationEvent, FALSE);
//构建过滤钩子驱动的控制IRP
nirp = IoBuildDeviceIoControlRequest(
IOCTL_PF_SET_EXTENSION_POINTER,
filtdeviceob,
&filthook,
sizeof(PF_SET_EXTENSION_HOOK_INFO),
NULL,
0,
FALSE,
&event,
&filtstatus);
if(nirp!=NULL)
{
//向下传递IRP
status=IoCallDriver(filtdeviceob,nirp);
if (status == STATUS_PENDING)
{
//等待完成
waitStatus = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);

if (waitStatus != STATUS_SUCCESS )
KdPrint(( "ndisfilter.sys: Error waiting for Ip Driver.\n "));
}

status = filtstatus.Status;
KdPrint(( "status=0x%8x\n ",status));

if(!NT_SUCCESS(status))
KdPrint(( "ndisfilter.sys: E/S error with Ip Driver\n "));

KeClearEvent(&event);

}
else
{
status = STATUS_INSUFFICIENT_RESOURCES;

KdPrint(( "ndisfilter.sys: Error creating the IRP\n "));
}
if(filtfileob != NULL)
ObDereferenceObject(filtfileob);

filtdeviceob = NULL;
filtfileob = NULL;
}
else
{
KdPrint(( "无法构建IRP\n "));
}


然后在过滤函数里面过滤数据包就可以了,过滤函数格式如下:
PF_FORWARD_ACTION
IpFilterHook(
unsigned char *PacketHeader,//IP包头
unsigned char *Packet, //数据部分
unsigned int PacketLength,
unsigned int RecvInterfaceIndex,
unsigned int SendInterfaceIndex,
IPAddr RecvLinkNextHop,
IPAddr SendLinkNextHop
)
{
//过滤钩子函数,这儿只简单判断属于TCP协议且数据是抵达而且带SYN标志则过滤。大家可以根据需要修改自己的过滤判断和处理。


if(((IPHeader *)PacketHeader)-> iph_protocol == PROT_TCP)
{
//Packet[13]==0x2就是TCP中SYN的标志
//SendInterfaceIndex==INVALID_PF_IF_INDEX说明包是抵达而不是发送的,因此这样过 滤就不会影响自己的包出去,但是外来带SYN请求的包则会拒绝。
if(Packet[13]==0x2 && SendInterfaceIndex==INVALID_PF_IF_INDEX)
return PF_DROP;
//如果是发送,则检查RecvInterfaceIndex,然后简单PF_DROP或PF_PASS或PF_FORWARD
}
}

热点排行