NDIS Intrmediate Filter Driver Question.

HI ALL,
We are writing some ndis Im driver.
Our objective is to encrypt the data before sending to miniport driver.
We modified MPSend function of the passthru sample.
We encripted the data in this function before calling NDISSend api.
We recalulated the IP and TCP checksums too.
We were able to install my driver and we have written a socket sample to check the functionality.
On one machine we installed our driver and on other machine we haven’t.
We expected that socket program running on destination machine will receive encrypted data . But this is not happening.
It is getting original data(data before encryption).
Here with we are attaching code snapshot .
Please let us know what cause the problem.

  1. Can we change data content pointing at virtual address in the new packet what we created?

  2. or do we need to call NdisAllocatememorywithTag(),NdisAllocateBuffer(),NdisChainBufferAtFront() in sequence ?..before calling NdisSend() ?

  3. Where can we get the information about developing NDIS Intermediate Driver ?..tutorials ?..NDIS IM Driver(Encryption/decryption) samples ?

Thanks in Advance

Tataji & Nayak Vinay
Bangalore -India


Do you Yahoo!?
The New Yahoo! Shopping - with improved product search

HI ALL,
We are writing some ndis Im driver.
Our objective is to encrypt the data before sending to miniport driver.
We modified MPSend function of the passthru sample.
We encripted the data in this function before calling NDISSend api.
We recalulated the IP and TCP checksums too.
We were able to install my driver and we have written a socket sample to check the functionality.
On one machine we installed our driver and on other machine we haven’t.
We expected that socket program running on destination machine will receive encrypted data . But this is not happening.
It is getting original data(data before encryption).
Here with we are attaching code snapshot .
Please let us know what cause the problem.

  1. Can we change data content pointing at virtual address in the new packet what we created?

  2. or do we need to call NdisAllocatememorywithTag(),NdisAllocateBuffer(),NdisChainBufferAtFront() in sequence ?..before calling NdisSend() ?

  3. Where can we get the information about developing NDIS Intermediate Driver ?..tutorials ?..NDIS IM Driver(Encryption/decryption) samples ?
    here is the Code snip.

NDIS_STATUS
MPSend(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet,
IN UINT Flags
)
/*++
Routine Description:
Send handler. Just re-wrap the packet and send it below. Re-wrapping is necessary since
NDIS uses the WrapperReserved for its own use.
LBFO- All sends will be done in the secondary miniport of the bundle.
We are using the Secondary Miniport as the Send path. All sends should use that pAdapt structure.
Arguments:
MiniportAdapterContext Pointer to the adapter
Packet Packet to send
Flags Unused, passed down below
Return Value:
Return code from NdisSend
–*/
{
PADAPT pAdapt = (PADAPT)MiniportAdapterContext;
NDIS_STATUS Status;
PNDIS_PACKET MyPacket;
PRSVD Rsvd;
PVOID MediaSpecificInfo = NULL;
ULONG MediaSpecificInfoSize = 0;
// ADDED BY CAIR
// retrieve the IP packet header information
#define szPayloadCopy ETH_MAX_PACKET_SIZE
char PayloadCopy[szPayloadCopy];
pEthHdr pETH;
pIPHdr pIPH;
pTCPHdr pTCPH;
pEncapPktHdr pEncPkt;
NDIS_STATUS lclStatus;
USHORT usIPHdr,usTCPHdr,usNewHdrs;
ULONG ulOrigPayload;

//
// According to our LBFO design, all sends will be performed on the secondary miniport
// However, the must be completed on the primary’s miniport handle
//
ASSERT (pAdapt->pSecondaryAdapt);
pAdapt = pAdapt->pSecondaryAdapt;

if (IsIMDeviceStateOn (pAdapt) == FALSE)
{
return NDIS_STATUS_FAILURE;
}

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);
//
// Copy the OOB Offset from the original packet to the new
// packet.
//
NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPacket),
NDIS_OOB_DATA_FROM_PACKET(Packet),
sizeof(NDIS_PACKET_OOB_DATA));

//
// Copy the per packet info into the new packet
// This includes ClassificationHandle, etc.
// Make sure other stuff is not copied !!!
//
NdisIMCopySendPerPacketInfo(MyPacket, Packet);

//
// Copy the Media specific information
//
NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(Packet,
&MediaSpecificInfo,
&MediaSpecificInfoSize);
if (MediaSpecificInfo || MediaSpecificInfoSize)
{
NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(MyPacket,
MediaSpecificInfo,
MediaSpecificInfoSize);
}
// ADDED BY
// retrieve the IP packet header information
GetPktPayload(MyPacket, // Copy payload
PayloadCopy, // to area.
szPayloadCopy, // Amount of space in area.
&ulOrigPayload // Return number of bytes in packet.
);

pIPH = (pIPHdr)(PayloadCopy + // Point to IP header in local copy of payload.
sizeof(EthHdr));

usIPHdr = pIPH->IPHdrLen * 4; // Get length of IP header.

pTCPH = // Point to TCP datagram (header + data) in local copy of payload.
(pTCPHdr)(PayloadCopy +
sizeof(EthHdr) +
usIPHdr);

usTCPHdr = pTCPH->DataOffset * 4; // Length of this TCP header, which will be largely duplicated.

DBGPRINT(“**************NEW *****IPPACKET HEADER INFO************”);
{
char msg[256];
// char TempMsg[256];
memset(msg,0,256);
// memset(TempMsg,0,256);

sprintf(msg,“Total Length %d”,pIPH->TotalLength);
DBGPRINT(msg);

sprintf(msg,“Source Address %u”,pIPH->SourceAddress);
DBGPRINT(msg);

sprintf(msg,“Destination Address %u”,pIPH->DestinationAddress);
DBGPRINT(msg);

if(pIPH->DestinationAddress == 2868904065)
{

UCHAR Data[256];
UCHAR Data1[256];
UCHAR Data2[256];
PUCHAR pData ;
ULONG ulDataLen;
DBGPRINT(“SENDING PACKET TO GFPC005”);
ulDataLen = ulOrigPayload - sizeof(EthHdr) - usIPHdr - usTCPHdr;
sprintf(msg,“Data Length %u”,ulDataLen-1);
DBGPRINT(msg);

if((int)ulDataLen != 0)
{
UINT index = 0;
pData = (char *)(pTCPH+usTCPHdr);

memcpy(Data,pData+1,ulDataLen-3);

DBGPRINT(“*** NEW DISPLAYING SOCKET DATA****”);
sprintf(msg,“The Socket Data is %s”,Data);
DBGPRINT(msg);

DBGPRINT(“%s”,Data);

DBGPRINT(“**************NEW BEFORE ENCRYPTION *****”);
sprintf(msg,“%s”,Data);
DBGPRINT(msg);

DbgPrint(“%s”,pData);
for(index ; index < ulDataLen-3;index++)
{
pData[index + 1] = pData[index + 1] + 1;
}
DBGPRINT(“**************NEW AFTER ENCRIPTION *****”);
sprintf(msg,“%s”,Data);
DBGPRINT(msg);
DbgPrint(“%s”,pData);
sprintf(msg," Old IP Checksum is %u",pIPH->Checksum);
DBGPRINT(msg);
sprintf(msg," Old TCP Checksum is %u",pTCPH->Checksum);
DBGPRINT(msg);
DBGPRINT(“**************RECALCULATING CHECKSUMS *****”);
pIPH->Checksum = 0; // Clear old IP checksum value.
pIPH->Checksum = // Get new IP checksum value, which depends on new IP header only.
GetIPChecksum((PUSHORT)pIPH, usIPHdr);

sprintf(msg," new IP Checksum is %u",pIPH->Checksum);
DBGPRINT(msg);

pTCPH->Checksum = 0; // Clear TCP checksum.

pTCPH->Checksum = // Get new TCP checksum.
GetTCPChecksum((PUSHORT)pTCPH,
(PUSHORT)&pIPH->SourceAddress,
(PUSHORT)&pIPH->DestinationAddress,
(USHORT)(RtlUshortByteSwap(pIPH->TotalLength) - usIPHdr)
);
sprintf(msg," new TCP Checksum is %u",pTCPH->Checksum);
DBGPRINT(msg);
}
}
DBGPRINT(“**************NEW IPPACKET HEADER INFO END*********”);
}
// CAIR END
NdisSend(&Status,
pAdapt->BindingHandle,
MyPacket);

if (Status != NDIS_STATUS_PENDING)
{
NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket);
NdisFreePacket(MyPacket);
}
}
else
{
//
// We are out of packets. Silently drop it. Alternatively we can deal with it:
// - By keeping separate send and receive pools
// - Dynamically allocate more pools as needed and free them when not needed
//
}
return(Status);
}

Thanks in advance.
Nayak Vinay.
Bangalore


Do you Yahoo!?
The New Yahoo! Shopping - with improved product search

I don’t see you calling NdisAllocateBuffer, or NdisChainBufferAtFront. How
are you hooking the new buffer to
your new packet descriptor?

Also, your packet calculations may not work all the time. Look through
TCP/IP Illustrated by Stevens for
a complete description of the different types of ethernet header. 802.3
versus DIX to be exact.

-Jeff

-----Original Message-----
From: vinaya chandra [mailto:xxxxx@yahoo.com]
Sent: Friday, September 26, 2003 7:19 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] NDIS Intrmediate Filter Driver Question.

HI ALL,
We are writing some ndis Im driver.
Our objective is to encrypt the data before sending to miniport driver.
We modified MPSend function of the passthru sample.
We encripted the data in this function before calling NDISSend api.
We recalulated the IP and TCP checksums too.
We were able to install my driver and we have written a socket sample to
check the functionality.
On one machine we installed our driver and on other machine we haven’t.
We expected that socket program running on destination machine will receive
encrypted data . But this is not happening.
It is getting original data(data before encryption).
Here with we are attaching code snapshot .
Please let us know what cause the problem.

  1. Can we change data content pointing at virtual address in the new packet
    what we created?

  2. or do we need to call
    NdisAllocatememorywithTag(),NdisAllocateBuffer(),NdisChainBufferAtFront() in
    sequence ?..before calling NdisSend() ?

  3. Where can we get the information about developing NDIS Intermediate
    Driver ?..tutorials ?..NDIS IM Driver(Encryption/decryption) samples ?
    here is the Code snip.

NDIS_STATUS
MPSend(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet,
IN UINT Flags
)
/*++
Routine Description:
Send handler. Just re-wrap the packet and send it below. Re-wrapping is
necessary since
NDIS uses the WrapperReserved for its own use.
LBFO- All sends will be done in the secondary miniport of the bundle.
We are using the Secondary Miniport as the Send path. All sends should use
that pAdapt structure.
Arguments:
MiniportAdapterContext Pointer to the adapter
Packet Packet to send
Flags Unused, passed down below
Return Value:
Return code from NdisSend
–*/
{
PADAPT pAdapt = (PADAPT)MiniportAdapterContext;
NDIS_STATUS Status;
PNDIS_PACKET MyPacket;
PRSVD Rsvd;
PVOID MediaSpecificInfo = NULL;
ULONG MediaSpecificInfoSize = 0;
// ADDED BY CAIR
// retrieve the IP packet header information
#define szPayloadCopy ETH_MAX_PACKET_SIZE
char PayloadCopy[szPayloadCopy];
pEthHdr pETH;
pIPHdr pIPH;
pTCPHdr pTCPH;
pEncapPktHdr pEncPkt;
NDIS_STATUS lclStatus;
USHORT usIPHdr,usTCPHdr,usNewHdrs;
ULONG ulOrigPayload;

//
// According to our LBFO design, all sends will be performed on the
secondary miniport
// However, the must be completed on the primary’s miniport handle
//
ASSERT (pAdapt->pSecondaryAdapt);
pAdapt = pAdapt->pSecondaryAdapt;

if (IsIMDeviceStateOn (pAdapt) == FALSE)
{
return NDIS_STATUS_FAILURE;
}

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);
//
// Copy the OOB Offset from the original packet to the new
// packet.
//
NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPacket),
NDIS_OOB_DATA_FROM_PACKET(Packet),
sizeof(NDIS_PACKET_OOB_DATA));

//
// Copy the per packet info into the new packet
// This includes ClassificationHandle, etc.
// Make sure other stuff is not copied !!!
//
NdisIMCopySendPerPacketInfo(MyPacket, Packet);

//
// Copy the Media specific information
//
NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(Packet,
&MediaSpecificInfo,
&MediaSpecificInfoSize);
if (MediaSpecificInfo || MediaSpecificInfoSize)
{
NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(MyPacket,
MediaSpecificInfo,
MediaSpecificInfoSize);
}
// ADDED BY
// retrieve the IP packet header information
GetPktPayload(MyPacket, // Copy payload
PayloadCopy, // to area.
szPayloadCopy, // Amount of space in
area.
&ulOrigPayload // Return number of
bytes in packet.
);

pIPH = (pIPHdr)(PayloadCopy + // Point to IP header in local
copy of payload.
sizeof(EthHdr));

usIPHdr = pIPH->IPHdrLen * 4; // Get length of IP header.

pTCPH = // Point t! o TCP datagram
(header + data) in local copy of payload.
(pTCPHdr)(PayloadCopy +
sizeof(EthHdr) +
usIPHdr);

usTCPHdr = pTCPH->DataOffset * 4; // Length of this TCP header,
which will be largely duplicated.

DBGPRINT(“**************NEW *****IPPACKET HEADER INFO************”);
{
char msg[256];
// char TempMsg[256];
memset(msg,0,256);
// memset(TempMsg,0,256);

sprintf(msg,“Total Length %d”,pIPH->TotalLength);
DBGPRINT(msg);

sprintf(msg,“Source Address %u”,pIPH->SourceAddress);
DBGPRINT(msg);

sprintf(msg,“Destination Address %u”,pIPH->DestinationAddress);
DBGPRINT(msg);

if(pIPH->DestinationAddress == 2868904065)
{

UCHAR Data[256];
UCHAR Data1[256];
UCHAR Data2[256];
PUCHAR pData ;
ULONG ulDataLen;
DBGPRINT(“SENDING PACKET TO GFPC005”);
ulDataLen = ulOrigPayload - sizeof(EthHdr) - usIPHdr - usTCPHdr;
sprintf(msg,“Data Length %u”,ulDataLen-1);
DBGPRINT(msg);

if((int)ulDataLen != 0)
{
UINT index = 0;
pData = (char *)(pTCPH+usTCPHdr);

memcpy(Data,pData+1,ulDataLen-3);

DBGPRINT(“*** NEW DISPLAYING SOCKET DATA****”);
sprintf(msg,“The Socket Data is %s”,Data);
DBGPRINT(msg);

DBGPRINT(“%s”,Data);

DBGPRINT(“**************NEW BEFORE ENCRYPTION *****”);
sprintf(msg,“%s”,Data);
DBGPRINT(msg);

DbgPrint(“%s”,pData);
for(index ; index < ulDataLen-3;index++)
{
pData[index + 1] = pData[index + 1] + 1;
}
DBGPRINT(“**************NEW AFTER ENCRIPTION *****”);
sprintf(msg,“%s”,Data);
DBGPRINT(msg);
DbgPrint(“%s”,pData);
sprintf(msg," Old IP Checksum is %u",pIPH->Checksum);
DBGPRINT(msg);
sprintf(msg," Old TCP Checksum is %u",pTCPH->Checksum);
DBGPRINT(msg);
DBGPRINT(“**************RECALCULATING CHECKSUMS *****”);
pIPH->Checksum = 0; // Clear old IP
checksum value.
pIPH->Checksum = // Get new IP checksum value,
which depends on new IP header only.
GetIPChecksum((PUSHORT)pIPH, usIPHdr);

sprintf(msg," new IP Checksum is %u",pIPH->Checksum);
DBGPRINT(msg);

pTCPH->Checksum = 0; // Clear TCP checksum.

pTCPH->Checksum = // Get new TCP checksum.
GetTCPChecksum((PUSHORT)pTCPH,
(PUSHORT)&pIPH->SourceAddress,
(PUSHORT)&pIPH->DestinationAddress,
(USHORT)(RtlUshortByteSwap(pIPH->TotalLeng!
th) - usIPHdr)
);
sprintf(msg," new TCP Checksum is %u",pTCPH->Checksum);
DBGPRINT(msg);
}
}
DBGPRINT(“**************NEW IPPACKET HEADER INFO END*********”);
}
// CAIR END
NdisSend(&Status,
pAdapt->BindingHandle,
MyPacket);

if (Status != NDIS_STATUS_PENDING)
{
NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket);
NdisFreePacket(MyPacket);
}
}
else
{
//
// We are out of packets. Silently drop it. Alternatively we can deal with
it:
// - By keeping separate send and receive pools
// - Dynamically allocate more pools as needed and free them when not
needed
//
}
return(Status);
}

Thanks in advance.
Nayak Vinay.
Bangalore


Do you Yahoo!?
The
http:%2Csec%3Amail> New Yahoo! Shopping - with improved product search —
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256 You are currently subscribed to
ntdev as: xxxxx@concord.com To unsubscribe send a blank email to
xxxxx@lists.osr.com


This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager.
This footnote also confirms that this email message has been swept by
the latest virus scan software available for the presence of computer
viruses.
</http:>

If you don’t have your IM driver on both sides, I don’t your sockets
program will see encrypted data. The reason is that it is very likely
the size of the arriving packet will differ from what the receiving
TCP/IP expects (the indicated-up packet will violate TCP/IP’s
window/sequence number), so that the receiving TCP/IP will simply ignore
(“drop”) the packet. Eventually, the sending TCP/IP will get impatient
and will send again. If your IM driver is still encrypting and thus
messing up the window/sequence number dance, this process can go on for
a long time.

I have sent “encapsulated” packets (I notice you’ve used my published
example) without having a receiving IM driver, but all I saw, and all I
expected to see, was the encapsulated packet reaching NetMon, which (I
believe; this was a while ago) complained about the window/sequence
number violation or some such. That is, I succeeded in sending a changed
(and enlarged) packet across the wire; but without a receiving IM
driver, there was no hope it would reach my socket program. That I later
did do, by the way, when I had a receiving IM driver in place. The
receiving driver had to undo everything, so that the receiving TCP/IP
saw just what it expected to see in terms of checksum, sequence number,
size and so forth.

But, as you say, your receiving sockets program sees the original
packet. The question is, however, what goes across the wire? You could
be running into the problem of the receiving TCP/IP simply ignoring an
altered packet. Investigate how the original is sent. See if – as
viewed by NetMon on the receiving side (and remember that NetMon is
earlier than the IM driver on the sending side and later than the IM
driver on the receiving side) – the packet of interest, namely, the
packet with the specific sequence number for the IP address/port number
combo, is being sent more than once. It may be that the packet is sent
once in encrypted form, later in original form. If TCP/IP is sending it
more than once, is your sending IM driver handling it the same way the
second time as it did the first, or is the driver allowing the packet
through unchanged on the second occasion? Another thing to examine is
whether you’re propagating the OriginalPacketInfo field in the
NDIS_PACKET extension. I know for a fact that on the receiving side, to
propagate that field to the new NDIS_PACKET will cause the original
packet to be sent up. I have unable (working with someone who is
probably one of your team) to produce the same result (original packet
being used) when I propagated the OriginalPacketInfo field in a new
NDIS_PACKET on the sending side, but I wouldn’t rule out propagation
causing the original packet to be sent down in some circumstances.

In short, the original contents are coming from somewhere. Try to narrow
down where that is.

Oh yes! Before I forget, worry about packet fragmentation, especially if
your changed packet is near the MTU. It is possible that is your
problem, and it is certainly going to bite you when eventually, with
your IM driver on each side, you send changed packets over a real
network (as opposed a lab network).

Finally, no, there’s no documentation, no tutorials. No no-cost samples
(other than mine) of changing packets. I think that Thomas Divine of
PCAUSA may have code, for a fee. He does good work. (Disclaimer: He and
I are collaborating on an article about handling packets, albeit not
about changed packets.)

vinaya chandra wrote:

We expected that socket program running on destination machine will
receive encrypted data . But this is not happening.
It is getting original data(data before encryption).


If replying by e-mail, please remove “nospam.” from the address.

James Antognini
Windows DDK MVP

Hi … James Antognini ,
I am realy thankful to u for sending such valuable information regarding modifing packet data.
Now i have few more queries…
As u said we need to have IM Driver installed on the reciving end and it should perform decryption operation i gess. Now while decrypting do we need to create a temporary packet and then copy the original packet and then decrypt ? or can we decrypt the packet directly as we receve ?..
As u have given in your sample u r decrypting the data in protocolrecivepacket function…which is a optional function. In which function we have to write the decryption code either in ProtocolReceive() or in ProtocolReceivePacket() ?.
What is the the difference between thease two functions ?.In which situation the ProtocolReceivePacket() gets called as compared to its counter part…ProtocolReceive().

Thanks in advance.

Nayak vinay
Bangalore.

James Antognini wrote:
If you don’t have your IM driver on both sides, I don’t your sockets
program will see encrypted data. The reason is that it is very likely
the size of the arriving packet will differ from what the receiving
TCP/IP expects (the indicated-up packet will violate TCP/IP’s
window/sequence number), so that the receiving TCP/IP will simply ignore
(“drop”) the packet. Eventually, the sending TCP/IP will get impatient
and will send again. If your IM driver is still encrypting and thus
messing up the window/sequence number dance, this process can go on for
a long time.

I have sent “encapsulated” packets (I notice you’ve used my published
example) without having a receiving IM driver, but all I saw, and all I
expected to see, was the encapsulated packet reaching NetMon, which (I
believe; this was a while ago) complained about the window/sequence
number violation or some such. That is, I succeeded in sending a changed
(and enlarged) packet across the wire; but without a receiving IM
driver, there was no hope it would reach my socket program. That I later
did do, by the way, when I had a receiving IM driver in place. The
receiving driver had to undo everything, so that the receiving TCP/IP
saw just what it expected to see in terms of checksum, sequence number,
size and so forth.

But, as you say, your receiving sockets program sees the original
packet. The question is, however, what goes across the wire? You could
be running into the problem of the receiving TCP/IP simply ignoring an
altered packet. Investigate how the original is sent. See if – as
viewed by NetMon on the receiving side (and remember that NetMon is
earlier than the IM driver on the sending side and later than the IM
driver on the receiving side) – the packet of interest, namely, the
packet with the specific sequence number for the IP address/port number
combo, is being sent more than once. It may be that the packet is sent
once in encrypted form, later in original form. If TCP/IP is sending it
more than once, is your sending IM driver handling it the same way the
second time as it did the first, or is the driver allowing the packet
through unchanged on the second occasion? Another thing to examine is
whether you’re propagating the OriginalPacketInfo field in the
NDIS_PACKET extension. I know for a fact that on the receiving side, to
propagate that field to the new NDIS_PACKET will cause the original
packet to be sent up. I have unable (working with someone who is
probably one of your team) to produce the same result (original packet
being used) when I propagated the OriginalPacketInfo field in a new
NDIS_PACKET on the sending side, but I wouldn’t rule out propagation
causing the original packet to be sent down in some circumstances.

In short, the original contents are coming from somewhere. Try to narrow
down where that is.

Oh yes! Before I forget, worry about packet fragmentation, especially if
your changed packet is near the MTU. It is possible that is your
problem, and it is certainly going to bite you when eventually, with
your IM driver on each side, you send changed packets over a real
network (as opposed a lab network).

Finally, no, there’s no documentation, no tutorials. No no-cost samples
(other than mine) of changing packets. I think that Thomas Divine of
PCAUSA may have code, for a fee. He does good work. (Disclaimer: He and
I are collaborating on an article about handling packets, albeit not
about changed packets.)

vinaya chandra wrote:

> We expected that socket program running on destination machine will
> receive encrypted data . But this is not happening.
> It is getting original data(data before encryption).


If replying by e-mail, please remove “nospam.” from the address.

James Antognini
Windows DDK MVP


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@yahoo.com
To unsubscribe send a blank email to xxxxx@lists.osr.co

---------------------------------
Do you Yahoo!?
The New Yahoo! Shopping - with improved product search

You always need your own packet as decrypt target. You cannot update the data in the original NDIS_PACKET in any way.

Even if you pass the unmodified NDIS_PACKET up, you will need to allocate a second NDIS_PACKET and copy the buffer chain and per-packet info there. The exception from this is “packet stacking” features in XP and above.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From: vinaya chandra
To: Windows System Software Devs Interest List
Sent: Saturday, September 27, 2003 11:42 AM
Subject: [ntdev] Re: NDIS Intrmediate Filter Driver Question.

Hi … James Antognini ,
I am realy thankful to u for sending such valuable information regarding modifing packet data.
Now i have few more queries…
As u said we need to have IM Driver installed on the reciving end and it should perform decryption operation i gess. Now while decrypting do we need to create a temporary packet and then copy the original packet and then decrypt ? or can we decrypt the packet directly as we receve ?..
As u have given in your sample u r decrypting the data in protocolrecivepacket function…which is a optional function. In which function we have to write the decryption code either in ProtocolReceive() or in ProtocolReceivePacket() ?.
What is the the difference between thease two functions ?.In which situation the ProtocolReceivePacket() gets called as compared to its counter part…ProtocolReceive().

Thanks in advance.

Nayak vinay
Bangalore.

James Antognini wrote:
If you don’t have your IM driver on both sides, I don’t your sockets
program will see encrypted data. The reason is that it is very likely
the size of the arriving packet will differ from what the receiving
TCP/IP expects (the indicated-up packet will violate TCP/IP’s
window/sequence number), so that the receiving TCP/IP will simply ignore
(“drop”) the packet. Eventually, the sending TCP/IP will get impatient
and will send again. If your IM driver is still encrypting and thus
messing up the window/sequence number dance, this process can go on for
a long time.

I have sent “encapsulated” packets (I notice you’ve used my published
example) without having a receiving IM driver, but all I saw, and all I
expected to see, was the encapsulated packet reaching NetMon, which (I
believe; this was a while ago) complained about the window/sequencenumber violation or some such. That is, I succeeded in sending a changed
(and enlarged) packet across the wire; but without a receiving IM
driver, there was no hope it would reach my socket program. That I later
did do, by the way, when I had a receiving IM driver in place. The
receiving driver had to undo everything, so that the receiving TCP/IP
saw just what it expected to see in terms of checksum, sequence number,
size and so forth.

But, as you say, your receiving sockets program sees the original
packet. The question is, however, what goes across the wire? You could
be running into the problem of the receiving TCP/IP simply ignoring an
altered packet. Investigate how the original is sent. See if – as
viewed by NetMon on the receiving side (and remember that NetMon is
earlier than the IM driver on the sending side and later than the IM
driver on the receiving side) – the packet of interest, namely, the
packet with the specific seq! uence number for the IP address/port number
combo, is being sent more than once. It may be that the packet is sent
once in encrypted form, later in original form. If TCP/IP is sending it
more than once, is your sending IM driver handling it the same way the
second time as it did the first, or is the driver allowing the packet
through unchanged on the second occasion? Another thing to examine is
whether you’re propagating the OriginalPacketInfo field in the
NDIS_PACKET extension. I know for a fact that on the receiving side, to
propagate that field to the new NDIS_PACKET will cause the original
packet to be sent up. I have unable (working with someone who is
probably one of your team) to produce the same result (original packet
being used) when I propagated the OriginalPacketInfo field in a new
NDIS_PACKET on the sending side, but I wouldn’t rule out propagation
causing the original packet to be sent down in some circumstances.

In shor! t, the original contents are coming from somewhere. Try to narrow
down where that is.

Oh yes! Before I forget, worry about packet fragmentation, especially if
your changed packet is near the MTU. It is possible that is your
problem, and it is certainly going to bite you when eventually, with
your IM driver on each side, you send changed packets over a real
network (as opposed a lab network).

Finally, no, there’s no documentation, no tutorials. No no-cost samples
(other than mine) of changing packets. I think that Thomas Divine of
PCAUSA may have code, for a fee. He does good work. (Disclaimer: He and
I are collaborating on an article about handling packets, albeit not
about changed packets.)

vinaya chandra wrote:

> We expected that socket program running on destination machine will
> receive encrypted data . But this is not happening.
> It is getting original data(data before encryption).


If replyin! g by e-mail, please remove “nospam.” from the address.

James Antognini
Windows DDK MVP


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@yahoo.com
To unsubscribe send a blank email to xxxxx@lists.osr.co

------------------------------------------------------------------------------
Do you Yahoo!?
The New Yahoo! Shopping - with improved product search — Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256 You are currently subscribed to ntdev as: xxxxx@storagecraft.com To unsubscribe send a blank email to xxxxx@lists.osr.com

First, let’s see if I can write a reply without dropping words, as I did
last time.

Now, as Max indicated, if you are changing a packet, you must employ
(allocate and later recycle) a new packet descriptor (NDIS_PACKET),
buffer descriptor (NDIS_BUFFER) and payload. Don’t try to use the
originals, but don’t forget to indicate at the appropriate time that the
original packet descriptor, etc., have been processed, to avoid a memory
leak accruing to whoever allocated the original stuff. I believe this is
shown in the sample I published.

In any case, you need to do the decrypting in both ProtocolReceive and
ProtocolReceivePacket. The latter is supposedly optional, but I don’t
know what would happen if your IM driver did not provide it. Probably
degraded performance is the least you should expect (I’ve heard it said
that “modern” NIC drivers always use the latter, but I’ve seen lots of
use of the former in my test systems). Besides, since you must provide
ProtocolReceive, you may as well provide ProtocolReceivePacket, as the
former is harder to do. It is harder because you may not be able to get
a full packet without resorting to NdisTransferData, which would mean
you have to handle asynchronous completion of the transfer request.

It’s all a pain in the neck, and I haven’t even discussed the problem of
packet fragmentation, which is at least as hard as handling things
through ProtocolReceive. But that’s life in NDIS.

vinaya chandra wrote:

As u said we need to have IM Driver installed on the reciving end and
it should perform decryption operation i gess. Now while decrypting do
we need to create a temporary packet and then copy the original packet
and then decrypt ? or can we decrypt the packet directly as we receve
?..As u have given in your sample u r decrypting the data in
protocolrecivepacket function…which is a optional function. In which
function we have to write the decryption code either in
ProtocolReceive() or in ProtocolReceivePacket() ?.What is the the
difference between thease two functions ?.In which situation the
ProtocolReceivePacket() gets called as compared to its counter
part…ProtocolReceive().


If replying by e-mail, please remove “nospam.” from the address.

James Antognini
Windows DDK MVP