dahubaobao
驱动牛犊
驱动牛犊
  • 注册日期2004-09-25
  • 最后登录2012-03-14
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望80点
  • 贡献值0点
  • 好评度44点
  • 原创分0分
  • 专家分0分
阅读:2008回复:2

NDISWANIP不能设置为混杂模式?

楼主#
更多 发布于:2007-05-04 05:48
  用协议驱动绑定NDISWANIP,然后将其设置为混杂模式,可以嗅探到发出去的包,而嗅探不到接收的包,也就是说上不了网! 具体问题如下:

1,ADSL拨号过程可以嗅探,而且过程没有异常. PPP/LCP/IPCP等协议都可以抓到. 拨号后访问网页什么的就不行了.

2,绑定NDISWANIP但不设置混杂模式,上网正常(但也嗅探不到数据包了).

3,发出去的包可以嗅探到.我访问一个网页,可以抓到发送的域名解析包,之后就没有任何回应.

如果绑定其他NIC,设置为混杂模式,则没有任何问题,可以抓到完成的PPPoE包,上网正常. 惟独不能设置NDISWANIP为混杂模式. 这是为什么?

下面是我收包的代码:
NTSTATUS PacketRead (IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp)
{
    NTSTATUS ntStatus=STATUS_SUCCESS;
    POPEN_INSTANCE Open=NULL;
    PNDIS_PACKET pPacket=NULL;
    PIO_STACK_LOCATION IrpStack=NULL;

    if (DeviceObject==NULL || DeviceObject->DeviceExtension==NULL || pIrp==NULL || pIrp->MdlAddress==NULL)
        return STATUS_INVALID_PARAMETER;

    IrpStack=IoGetCurrentIrpStackLocation(pIrp);
    Open=DeviceObject->DeviceExtension;
    IoReferenceCount(Open);

    if (!(Open->Bound))
    {
        ntStatus=STATUS_DEVICE_NOT_READY;
        goto COMPLETION;
    }

    if (Open->CmnOidStatus==NDIS_STATUS_SUCCESS)
    {
        if (Open->CmnOidGenData.MediaConnStatus==NdisMediaStateDisconnected)
        {
            ntStatus=STATUS_INVALID_CONNECTION;
            goto COMPLETION;
        }
    }

    if (IrpStack->Parameters.Read.Length < ETHERNET_HEADER_LENGTH)
    {
        ntStatus=STATUS_BUFFER_TOO_SMALL;
        goto COMPLETION;
    }

    NdisAllocatePacket(&ntStatus,&pPacket,Open->RecvPacketPool);
    if (ntStatus!=NDIS_STATUS_SUCCESS)
    {
        ntStatus=STATUS_INSUFFICIENT_RESOURCES;
        goto COMPLETION;
    }

    RESERVED(pPacket)->pIrp=pIrp;
    RESERVED(pPacket)->pMdl=NULL;

    IoMarkIrpPending(pIrp);
    IoSetCancelRoutine(pIrp,PacketCancelRoutine);

    ExInterlockedInsertTailList(&(Open->RecvList),&(RESERVED(pPacket)->ListElement),&(Open->RecvSpinLock));
    return STATUS_PENDING;

COMPLETION:
    pIrp->IoStatus.Status=ntStatus;
    IoCompleteRequest(pIrp,IO_NO_INCREMENT);
    IoDeferenceCount(Open);
    return ntStatus;
}

NDIS_STATUS
PtReceive (
    IN NDIS_HANDLE ProtocolBindingContext,
    IN NDIS_HANDLE MacReceiveContext,
    IN PVOID HeaderBuffer,
    IN UINT  HeaderBufferSize,
    IN PVOID LookAheadBuffer,
    IN UINT  LookaheadBufferSize,
    IN UINT  PacketSize)
{
    NTSTATUS ntStatus=STATUS_SUCCESS;
    POPEN_INSTANCE Open=NULL;
    PPACKET_RESERVED pRsvd=NULL;

    PNDIS_PACKET pPacket=NULL;
    PLIST_ENTRY PacketEntry=NULL;

    PIO_STACK_LOCATION IrpStack=NULL;
    PIRP pIrp=NULL;

    if (HeaderBufferSize != ETHERNET_HEADER_LENGTH)
        return NDIS_STATUS_NOT_ACCEPTED;

    Open=(POPEN_INSTANCE)ProtocolBindingContext;
    PacketEntry=ExInterlockedRemoveHeadList(&(Open->RecvList),&(Open->RecvSpinLock));

    if (PacketEntry==NULL)
        return NDIS_STATUS_NOT_ACCEPTED;

    pRsvd=CONTAINING_RECORD(PacketEntry,PACKET_RESERVED,ListElement);
    pPacket=CONTAINING_RECORD(pRsvd,NDIS_PACKET,ProtocolReserved);

    pIrp=RESERVED(pPacket)->pIrp;
    IrpStack=IoGetCurrentIrpStackLocation(pIrp);
    IoSetCancelRoutine(pIrp,NULL);

    if (PacketSize==LookaheadBufferSize)
    {
        PVOID RecvData=MmGetSystemAddressForMdlSafe(pIrp->MdlAddress,NormalPagePriority);
        NdisMoveMappedMemory(RecvData,HeaderBuffer,HeaderBufferSize);
        NdisCopyLookaheadData((TCHAR *)RecvData + HeaderBufferSize,LookAheadBuffer,LookaheadBufferSize,Open->CmnOidGenData.MacOptions);

        PtTransferDataComplete(Open,pPacket,NDIS_STATUS_SUCCESS,PacketSize);
        return NDIS_STATUS_SUCCESS;
    }
    else
    {
        ULONG BufferLength=0;
        ULONG LengthTransfer=0;
        UINT  BytesTransfer=0;
        PMDL pMdl=NULL;

        BufferLength=IrpStack->Parameters.Read.Length - ETHERNET_HEADER_LENGTH;
        LengthTransfer=(PacketSize < BufferLength) ? PacketSize : BufferLength;

        NdisMoveMappedMemory(MmGetSystemAddressForMdlSafe(pIrp->MdlAddress,NormalPagePriority),HeaderBuffer,HeaderBufferSize);
        pMdl=IoAllocateMdl(MmGetMdlVirtualAddress(pIrp->MdlAddress),MmGetMdlByteCount(pIrp->MdlAddress),FALSE,FALSE,NULL);
    
        if (pMdl==NULL)
        {
            PtTransferDataComplete(Open,pPacket,NDIS_STATUS_RESOURCES,0);
            return NDIS_STATUS_SUCCESS;
        }

        IoBuildPartialMdl(pIrp->MdlAddress,pMdl,((UCHAR *)MmGetMdlVirtualAddress(pIrp->MdlAddress)) + ETHERNET_HEADER_LENGTH,0);
        pMdl->Next=NULL;
        RESERVED(pPacket)->pMdl=pMdl;

        NdisChainBufferAtFront(pPacket,pMdl);
        NdisTransferData(&ntStatus,Open->AdapterHandle,MacReceiveContext,0,LengthTransfer,pPacket,&BytesTransfer);

        if (ntStatus!=NDIS_STATUS_PENDING)
        {
            PtTransferDataComplete(Open,pPacket,ntStatus,BytesTransfer);
        }
    }

    return ntStatus;
}

VOID
PtTransferDataComplete(
    IN NDIS_HANDLE  ProtocolBindingContext,
    IN PNDIS_PACKET pPacket,
    IN NDIS_STATUS  Status,
    IN UINT BytesTransferred)
{
    PIRP pIrp=NULL;
    PIO_STACK_LOCATION IrpStack=NULL;

    pIrp=RESERVED(pPacket)->pIrp;  
    IrpStack=IoGetCurrentIrpStackLocation(pIrp);

    if (RESERVED(pPacket)->pMdl)
    {
        IoFreeMdl(RESERVED(pPacket)->pMdl);
        RESERVED(pPacket)->pMdl=NULL;
    }

    if (pPacket)
    {
        NdisFreePacket(pPacket);
    }

    if (Status==NDIS_STATUS_SUCCESS)
    {
        pIrp->IoStatus.Status=STATUS_SUCCESS;
        pIrp->IoStatus.Information=BytesTransferred + ETHERNET_HEADER_LENGTH;
    }
    else
    {
        pIrp->IoStatus.Status=Status;
        pIrp->IoStatus.Information=0L;
    }

    IoCompleteRequest(pIrp,IO_NO_INCREMENT);
    IoDeferenceCount((POPEN_INSTANCE)ProtocolBindingContext);
}
dahubaobao
驱动牛犊
驱动牛犊
  • 注册日期2004-09-25
  • 最后登录2012-03-14
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望80点
  • 贡献值0点
  • 好评度44点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-05-05 16:46
帮帮忙啊!
dahubaobao
驱动牛犊
驱动牛犊
  • 注册日期2004-09-25
  • 最后登录2012-03-14
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望80点
  • 贡献值0点
  • 好评度44点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-05-07 20:12
帮帮忙啊!  这个问题我都研究好几天了  真的不怎么怎么解决!
游客

返回顶部