阅读:1218回复:8
请教一个问题
各位高手,我现在做一个无线网卡的软驱动,相当于低层的 防火墙,现在可以把收到的和发送的数据给显示出来,可是我要对发送的数据进行更改,包括格式,和发送字节数都要改变,现在知道怎么得到这些数据,就是不知道这些数据放在什么地方,通过NdisQueryBufferSafe()来得到发送的数据,也就是说,数据已经存放在自己开辟的内存块中,现在的问题是如何去更改发送的数据,牵涉的数据结构如下:
typedef struct _NDIS_PACKET { NDIS_PACKET_PRIVATE Private; union { struct { UCHAR MiniportReserved[2*sizeof(PVOID)]; UCHAR WrapperReserved[2*sizeof(PVOID)]; }; struct { UCHAR MiniportReservedEx[3*sizeof(PVOID)]; UCHAR WrapperReservedEx[sizeof(PVOID)]; }; struct { UCHAR MacReserved[4*sizeof(PVOID)]; }; }; ULONG_PTR Reserved[2]; UCHAR ProtocolReserved[1]; } NDIS_PACKET, *PNDIS_PACKET, **PPNDIS_PACKET; typedef struct _NDIS_PACKET_PRIVATE { UINT PhysicalCount; // number of physical pages in packet. UINT TotalLength; // Total amount of data in the packet. PNDIS_BUFFER Head; // first buffer in the chain PNDIS_BUFFER Tail; // last buffer in the chain // if Head is NULL the chain is empty; Tail doesn\'t have to be NULL also PNDIS_PACKET_POOL Pool; // so we know where to free it back to UINT Count; ULONG Flags; BOOLEAN ValidCounts; UCHAR NdisPacketFlags; // See fPACKET_xxx bits below USHORT NdisPacketOobOffset; } NDIS_PACKET_PRIVATE, * PNDIS_PACKET_PRIVATE; typedef MDL NDIS_BUFFER, *PNDIS_BUFFER; typedef struct _MDL { struct _MDL *MdlNext; short MdlSize; short MdlFlags; struct _EPROCESS *Process; ULONG *lpMappedSystemVa; ULONG *lpStartVa; ULONG ByteCount; ULONG ByteOffset; } MDL; typedef MDL *PMDL; 这里我看是有一点问题,可是运行程序是没问题的,比如在MDL结构中是不存在Next指针的,总之我现在是看不出来如何修改数据,希望高手给予指点,谢谢!!! |
|
论坛版主
![]() |
沙发#
发布于:2004-01-07 19:28
:)你都把数据考出来了,怎么改是你自己的事啊:)你想怎么改就怎么改的麻,只不过改完了再把这段数据用NdisChainBufferAtXXX链到你新分配的一个PACKET中,然后在发送或递交上层。
|
|
板凳#
发布于:2004-01-07 22:29
请问你知道如何设置网卡为混杂模式的吗,也就是对发往该局域网内的任何机子的信息都可以接收,谢谢!!!最好是用手工方式的。
还有就是,机子上有两个网卡,发送时如何区分是发往那一个网卡的,谢谢!!! |
|
地板#
发布于:2004-01-07 23:02
我现在得到的字符串的形式PUCHAR,而用NdisChainBufferAtXXX()必须是PNDIS_BUFFER结构,那么要把这些字符放入PNDIS_BUFFER结构中的什么位置,如何去找到啊。谢谢
|
|
论坛版主
![]() |
地下室#
发布于:2004-01-09 11:17
设置成混杂模式这个你要查MAC控制器的控制寄存器的DATASHEET吧,肯定就是设置某个位,我没试过,不好意思。手工可能不行,不过好像有很多工具可以改,这儿的论坛有很多人讲过,你查查。
如果有两个网卡,那么在上层协议绑定到下层NIC的时候确定绑定到哪个NIC。 在放到PACKET前,先用NdisAllocateBuffer分配一个MDL描述你的缓冲区内容,然后就可以了。用法查查DDK就知道。 |
|
5楼#
发布于:2004-01-09 22:30
关于设置混杂模式这个问题我现在找到了一些原代码,不过不是很理想,我只有两个无线网卡,为了能作到模拟多个网卡,我在一个网卡上对发送的所有数据的mac地址进行了更改,就改前六个字节,我在另一个网卡上设置为混合模式,可是只能收到本网卡发送的数据,而另一个网卡上发送的数据都收不到,不知道为什么.当然不设置为混杂模式连本网卡发送的数据也收不到.
另一个问题是,在接收端收到的不是packet数据包格式,而是PUCHAR字符串,也就是说,ndis驱动中PtReceive()函数收到的数据包packet都是空的(NULL),只有 NdisMEthIndicateReceive(pAdapt->MiniportHandle, MacReceiveContext, HeaderBuffer, HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize, PacketSize); 这个函数可以收到数据,同样可以得到mac头和网络层的数据,都是在HeadBuffer指针中的, 请问我现在该如何分析啊,谢谢!!! |
|
6楼#
发布于:2004-01-09 22:34
还有一个问题,以太网中,mac头是14个字节,可是我现在做的无线网卡必须给改为30个字节,有没有控制字可以做到更改mac头长度,谢谢指点!!!
|
|
论坛版主
![]() |
7楼#
发布于:2004-01-12 16:37
无线网卡和有线的在MAC层用的协议不一样,转换的工作你要自己做啊,802。11的帧格式是什么就用什么啊,NDIS应该再绑定的时候就知道你的MEDIUM类型了,它封装的帧就是802.11的吧,你还要转换什么?实在想要自己做协议转换也可以
你设成混杂模式,看看802。11是不是对共享介质上的包有什么规定,两个网卡很近,他们发的包应该都可以互相收到的(混杂模式),不过这也是我的个人臆测:)兄弟再试试 |
|
8楼#
发布于:2004-01-13 22:42
我问了厂家的技术支持部门,他们说是无线网卡不支持混杂模式,所以现在说什么都没有用了,就是有一点想不通,802。11中介绍的mac侦格式是30个字节的,可是我对现在无线网卡上接收的mac头是14个字节,这是不是意味着这个无线网卡不支持802。11呢,当然802。11中是说要通过AP的,我这里是没有AP,就是两个无线网卡直接通信,不知道这种情况下mac头结构就是14字节?
还有我用了ndis中NdisChainBufferAtFront()这个函数,代码如下: MPSendOnePacket( IN NDIS_HANDLE MiniportAdapterContext, IN PNDIS_PACKET Packet, IN UINT Flags ) { PADAPT pAdapt = (PADAPT)MiniportAdapterContext; NDIS_STATUS Status; PNDIS_PACKET MyPacket; PNDIS_BUFFER pNext = NULL; PUCHAR ch = NULL; PRSVD Rsvd; PVOID MediaSpecificInfo = NULL; ULONG MediaSpecificInfoSize = 0; UINT i=0; UCHAR AddHead[16]; NDIS_BUFFER insert_buffer; if (IsIMDeviceStateOn (pAdapt) == FALSE) return NDIS_STATUS_FAILURE; if(Packet == NULL) DbgPrint(\"MPSendOnepacket Packet is NULL\\n\"); else { //调用自定义函数对发送的数据进行处理 MPDowithSendMessage(Packet,AddHead,&insert_buffer); } NdisAllocatePacket(&Status, &MyPacket, pAdapt->SendPacketPoolHandle); if (Status == NDIS_STATUS_SUCCESS) { PNDIS_PACKET_EXTENSION Old, New; Rsvd = (PRSVD)(MyPacket->ProtocolReserved); Rsvd->OriginalPkt = Packet; MyPacket->Private.Flags = Flags; MyPacket->Private.Head = Packet->Private.Head; MyPacket->Private.Tail = Packet->Private.Tail; NdisSetPacketFlags(MyPacket, NDIS_FLAGS_DONT_LOOPBACK); NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPacket), NDIS_OOB_DATA_FROM_PACKET(Packet), sizeof(NDIS_PACKET_OOB_DATA)); NdisIMCopySendPerPacketInfo(MyPacket, Packet); NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO( Packet, &MediaSpecificInfo, &MediaSpecificInfoSize); if (MediaSpecificInfo || MediaSpecificInfoSize) { NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO( MyPacket, MediaSpecificInfo, MediaSpecificInfoSize); } NdisSend(&Status, pAdapt->BindingHandle, MyPacket); if (Status != NDIS_STATUS_PENDING) { NdisIMCopySendCompletePerPacketInfo(Packet, MyPacket); NdisFreePacket(MyPacket); //PrintPacket(Packet); } } return(Status); } NDIS_STATUS MPDowithSendMessage(IN PNDIS_PACKET Packet, IN OUT PUCHAR AddHead, IN OUT PNDIS_BUFFER insert_buffer) { //插入一个NDIS_BUFFER NDIS_STATUS status = NDIS_STATUS_SUCCESS; PNDIS_BUFFER pNext = NULL; //PUCHAR AddHead = NULL; PUCHAR Mac1; //这是本机上无线网卡mac地址 UCHAR Mac2[6] = {0x00,0x06,0xf4,0x03,0x13,0x88}; PUCHAR ch = NULL; UINT i = 0,j = 0; //得到发送数据的网卡mac地址 pNext = Packet->Private.Head; Mac1 = pNext->MappedSystemVa; Mac1 = Mac1 +6; //调用自定义函数来判断是否需要对发送数据进行处理通过比较发送网卡的mac地址来区别 if(!Compare_Mac_Address(Mac1,Mac2)) return status; //调用自定义函数构造头结构 Format_Mac_Head(pNext->MappedSystemVa,AddHead); //对insert_buffer赋值 pNext = Packet->Private.Head; insert_buffer->MappedSystemVa = AddHead; insert_buffer->ByteCount = 16; insert_buffer->StartVa = NULL; insert_buffer->ByteOffset = 0; insert_buffer->Size = 32; insert_buffer->MdlFlags = 0; insert_buffer->Next = NULL; insert_buffer->Process = pNext->Process; //将自己构造的头加入数据包中 NdisChainBufferAtFront(Packet,insert_buffer); //把数据包内容从Packet拷贝到pPacketContent pNext = Packet->Private.Head; j=0; for(;;) { //显示数据 DbgPrint(\"\\n\\n\\nSend MappedSystemVa data %d:\\n\",j); ch = pNext->MappedSystemVa; DbgPrint(\"%d:\\n\",pNext->ByteCount); for(i = 0; i<pNext->ByteCount; i++) { if(pNext->MappedSystemVa != NULL) DbgPrint(\"0x%x.\",ch); else { DbgPrint(\"\\npNext->MappedSystemVa is NULL\\n\"); break; } if((i+1)%10 == 0) DbgPrint(\"\\n\"); } DbgPrint(\"\\n\\n\\n\"); if(pNext == Packet->Private.Tail) break; pNext = pNext->Next; //指针后移 if(pNext == NULL) break; //NdisQueryBufferSafe(pNext,&pBuf,&BufLength,32); //NdisMoveMemory(pPacketContent+TotalLength,pBuf,BufLength); //TotalLength+=BufLength; j++; } return NDIS_STATUS_SUCCESS; } BOOLEAN Compare_Mac_Address(IN PUCHAR Mac1,IN PUCHAR Mac2) { UINT i = 0; for(i = 0;i<6;i++) if(Mac1 != Mac2) return FALSE; return TRUE; } VOID Format_Mac_Head(IN PUCHAR head,IN OUT PUCHAR AddHead) { UINT i = 0; for(;i<16;i++) if(i<12) AddHead = head; else AddHead = 0xff; AddHead[12] = 0xaa; AddHead[13] = 0x01; } 请各位高手指点,我猜是调用NdisChainBufferAtFront(Packet,insert_buffer); 时出错的,大概原因是,在MPSendOnePacket( IN NDIS_HANDLE MiniportAdapterContext, IN PNDIS_PACKET Packet, IN UINT Flags ) 函数中定义了变量AddHead[16]和insert_buffer,而在该函数结束时这两个变量要“消失”,可是系统对发送的数据包还没处理完,在这个时候产生冲突,导致机子重启,我是这样想的,到现在还不知道原因,请各位高手指点,多谢!!! |
|