Home › Forums › Discussions › Support › Modifying IPv6 packets
- This topic has 3 replies, 2 voices, and was last updated 18 years ago by Vadim Smirnov.
-
AuthorPosts
-
November 16, 2006 at 12:06 pm #5071
Hi all,
I have a question about winpkfilter (version 3.0).
My “ultimate” goal is to patch the ethertype of incoming packets. I have a network equipment (that I can’t modify) which generates bad IPv6 packets. All the packet is correct except the ethertype, which is 0x0800 (IP) instead of 0x86dd (IPv6).I made some tests and I can’t understand why some cases are working and some other don’t. I used the PassThru.cpp sample as a starting point. You can find the whole code at the end of the message.
I have 5 test cases:
1/ Modify ethertype from 0x0800 to anything else in case of ICMPv4. The packet should be dropped by the stack. Indeed, if I launch the program, I cannot ping the machine anymore. [OK]
2/ Modify incoming ICMPv4 payload without breaking the chksum. The answer has not the same payload and ping display it. [OK]
3/ Modify ethertype of v6 packet to a wrong one. The packet should be dropped by the stack, but it is not. [FAILED]
4/ Modify content of a v6 packet. The packet should be dropped by the stack, but it is not. [FAILED]
5/ Don’t give v6 packets to stack. When I launch a ping6 to this machine, it still works. [FAILED]
So, it acts as if v6 packets are only received in my program but without the ability to modify them (perhaps like in FILTER mode).
Did I do something wrong, or there an explaination for this behaviour ?
Thanks a lot.
Olivier
/*************************************************************************/
/* Copyright (c) 2000-2004 NT Kernel Resources. */
/* All Rights Reserved. */
/* http://www.ntkernel.com */
/* ndisrd@ntkernel.com */
/* */
/*************************************************************************/
// Modified version of PassThru.cpp sample code
//
#include "stdafx.h"
#define ETH_P_IPV6 0x86dd /* ipv6 ethertype */
TCP_AdapterList AdList;
DWORD iIndex;
CNdisApi api;
ETH_REQUEST Request;
INTERMEDIATE_BUFFER PacketBuffer;
HANDLE hEvent;
USHORT ntohs( USHORT netshort )
{
PUCHAR pBuffer;
USHORT nResult;
nResult = 0;
pBuffer = (PUCHAR )&netshort;
nResult = ( (pBuffer[ 0 ] << 8) & 0xFF00 )
| ( pBuffer[ 1 ] & 0x00FF );
return( nResult );
}
#define htons(x) ntohs(x)
void ReleaseInterface()
{
// This function releases packets in the adapter queue and stops listening the interface
ADAPTER_MODE Mode;
Mode.dwFlags = 0;
Mode.hAdapterHandle = (HANDLE)AdList.m_nAdapterHandle[iIndex];
// Set NULL event to release previously set event object
api.SetPacketEvent(AdList.m_nAdapterHandle[iIndex], NULL);
// Close Event
if (hEvent)
CloseHandle ( hEvent );
// Set default adapter mode
api.SetAdapterMode(&Mode);
// Empty adapter packets queue
api.FlushAdapterPacketQueue (AdList.m_nAdapterHandle[iIndex]);
}
int main(int argc, char* argv[])
{
ether_header* pEthHeader = NULL;
UINT i=0, k=0;
UINT testnum=0;
if (argc < 3)
{
printf ("Command line syntax:ntPassThru.exe index numntindex - network interface index.ntnum - number or packets to filterntYou can use ListAdapters to determine correct index.n");
return 0;
}
iIndex = atoi(argv[1]) - 1;
testnum = atoi(argv[2]);
if(!api.IsDriverLoaded())
{
printf ("Driver not installed on this system of failed to load.n");
return 0;
}
api.GetTcpipBoundAdaptersInfo ( &AdList );
if ( iIndex + 1 > AdList.m_nAdapterCount )
{
printf("There is no network interface with such index on this system.n");
return 0;
}
ADAPTER_MODE Mode;
Mode.dwFlags = MSTCP_FLAG_RECV_TUNNEL;
Mode.hAdapterHandle = (HANDLE)AdList.m_nAdapterHandle[iIndex];
// Create notification event
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
// Set event for helper driver
if ((!hEvent)||(!api.SetPacketEvent((HANDLE)AdList.m_nAdapterHandle[iIndex], hEvent)))
{
printf ("Failed to create notification event or set it for driver.n");
return 0;
}
atexit (ReleaseInterface);
// Initialize Request
ZeroMemory ( &Request, sizeof(ETH_REQUEST) );
ZeroMemory ( &PacketBuffer, sizeof(INTERMEDIATE_BUFFER) );
Request.EthPacket.Buffer = &PacketBuffer;
Request.hAdapterHandle = (HANDLE)AdList.m_nAdapterHandle[iIndex];
api.SetAdapterMode(&Mode);
while (1)
{
WaitForSingleObject ( hEvent, INFINITE );
ResetEvent(hEvent);
while(api.ReadPacket(&Request))
{
pEthHeader = (ether_header*)PacketBuffer.m_IBuffer;
/* Display packet info */
printf ("%4.4d: proto %4.4x ", i, ntohs(pEthHeader->h_proto));
printf ("%.2X:%.2X:%.2X:%.2X:%.2X:%.2X -> ",
pEthHeader->h_source[0],
pEthHeader->h_source[1],
pEthHeader->h_source[2],
pEthHeader->h_source[3],
pEthHeader->h_source[4],
pEthHeader->h_source[5]);
printf ("%.2X:%.2X:%.2X:%.2X:%.2X:%.2Xn",
pEthHeader->h_dest[0],
pEthHeader->h_dest[1],
pEthHeader->h_dest[2],
pEthHeader->h_dest[3],
pEthHeader->h_dest[4],
pEthHeader->h_dest[5]);
switch(testnum) {
case 1: /* works */
/* Modify ethertype of ICMPv4 to a wrong one. The packet should be dropped by the stack */
if(ntohs(pEthHeader->h_proto) == ETH_P_IP) {
if (PacketBuffer.m_Length >= 0x17) {
if (PacketBuffer.m_IBuffer[0x17] == 0x01) { /* type == icmp */
PacketBuffer.m_IBuffer[12] = 0x12;
PacketBuffer.m_IBuffer[13] = 0x34;
printf("packet %d PATCHED (ethertype)n",i);
}
}
}
break;
case 2: /* works */
/* Modify incoming ICMPv4 payload without breaking the chksum. The answer will not have
* the same payload and ping will display it. */
if(ntohs(pEthHeader->h_proto) == ETH_P_IP) {
if (PacketBuffer.m_Length >= 0x61) {
if (PacketBuffer.m_IBuffer[0x17] == 0x01) { /* type == icmp */
PacketBuffer.m_IBuffer[0x5f] = 0x34;
PacketBuffer.m_IBuffer[0x61] = 0x38;
printf("packet %d PATCHED (icmp)n",i);
}
}
}
break;
case 3: /* does not work */
/* Modify ethertype of v6 packet to a wrong one. The packet should be dropped by the stack */
if(ntohs(pEthHeader->h_proto) == ETH_P_IPV6) {
if (PacketBuffer.m_Length >= 13) {
PacketBuffer.m_IBuffer[12] = 0x12;
PacketBuffer.m_IBuffer[13] = 0x34;
printf("packet %d PATCHED (ethertype)n",i);
}
}
break;
case 4: /* does not work */
/* Modify content of a v6 packet. The packet should be dropped by the stack */
if(ntohs(pEthHeader->h_proto) == ETH_P_IPV6) {
if (PacketBuffer.m_Length >= 20) {
for (k=16; k<20; k++) {
PacketBuffer.m_IBuffer[k] = 0xFF;
}
printf("packet %d PATCHED (IPv6)n",i);
}
}
break;
case 5: /* does not work */
/* Don't give v6 packets to stack */
if(ntohs(pEthHeader->h_proto) == ETH_P_IPV6) {
i++;
printf("packet %d droppedn",i);
continue;
}
break;
default:
printf("There's no test %dn", testnum);
return 1;
}
// Indicate packet to MSTCP
api.SendPacketToMstcp(&Request);
i++;
}
}
return 0;
}
November 17, 2006 at 4:33 pm #6177Well, first of all WinpkFilter x86 standard build (NDIS hook based) you probably downloaded from this site ignores IPv6 protocol (you still can see incoming IPv6 packets as they are also delivered to IPv4) and works with IPv4 only. Though it can be easily extended to support IPv6, but it require rebuilding driver binary. Such sort of modification is available to licensed users.
x64 standard build also available from this site is based on NDIS IM driver and by default it works with both IPv6 and IPv4.
November 17, 2006 at 9:02 pm #6178Hi SerpentFly, thanks for your answer.
For my culture, can you please tell me more between an NDIS hook based build and an NDIS IM based build ? I would be quite interrested in understanding better “where” are these hooks in windows… By the way, do you also provide a kernel API to filter and modify packets directly in ring 0 ?
But I suppose all of this is quite long to explain and I can find a good documentation on the internet…
Anyway, thanks for the support.
November 17, 2006 at 10:26 pm #6179Some filtering techniques overview can be found here http://www.ntkernel.com/w&p.php?id=14
You can use drivers IOCTL interface in kernel mode, though it would be far easier to modify the original driver to add the functionality you need.
-
AuthorPosts
- You must be logged in to reply to this topic.