Есть драйвер с PacketFilterExtensionPtr процедурой. Он должен проверять iph_dest пакетов на значения из списка и перенаправлять их по другому ip из списка. Контрольную сумму при изменении заголовка меняю, но почему-то эти пакеты все равно никуда не идут. Контрольная сумма вычисляется правильно, т.к я сделал ее пересчет на всех пакетах и без изменения iph_dest они нормально уходят. Может быть еще что-то нужно менять кроме iph_dest и iph_xsum? Ниже привожу код процедурки: Код (Text): PF_FORWARD_ACTION myHookProc( unsigned char *PacketHeader, unsigned char *Packet, unsigned int PacketLength, unsigned int RecvInterfaceIndex, unsigned int SendInterfaceIndex, IPAddr RecvLinkNextHop, IPAddr SendLinkNextHop) { KIRQL irql; IPAddr ip,redirect; PF_FORWARD_ACTION retVal; if (RecvInterfaceIndex!=INVALID_PF_IF_INDEX) { //recv retVal=PF_PASS; } else if(SendInterfaceIndex!=INVALID_PF_IF_INDEX) { IPHeader * ipHeader=(IPHeader *)PacketHeader; if (myAList!=NULL) { KeAcquireSpinLock(&myAList->myAddressSpinLock,&irql); LONG i=myAList->myAddressCount; while (i) { if(IsListEmpty(&myAList->myAddressListEntry)!=TRUE) { PLIST_ENTRY pLink = RemoveTailList(&myAList->myAddressListEntry); PADDRENTRY pElement = CONTAINING_RECORD(pLink,ADDRENTRY,myListEntry); ip=pElement->Addr.ip; redirect=pElement->Addr.redirect; ExFreeToNPagedLookasideList(myAList->myAddressList,pElement); pElement=(PADDRENTRY)ExAllocateFromNPagedLookasideList(myAList->myAddressList); if(pElement!=NULL) { RtlZeroMemory(pElement,sizeof(ADDRESS)); InsertHeadList(&myAList->myAddressListEntry,&pElement->myListEntry); pElement->Addr.ip=ip; pElement->Addr.redirect=redirect; } if (ip==ipHeader->iph_dest) { ipHeader->iph_dest=redirect; break; } } i--; } KeReleaseSpinLock(&myAList->myAddressSpinLock,irql); } //вычисляем контрольную сумму ULONG TmpXSum=0; PUSHORT WordPtr = (PUSHORT) ipHeader; BOOLEAN fOddLen = (BOOLEAN)((ipHeader->iph_length) & 1); int length=ipHeader->iph_length >>1; while(length--) { TmpXSum += *WordPtr; WordPtr++; } if(fOddLen) { TmpXSum += (USHORT)*((PUCHAR)WordPtr); } TmpXSum = (((TmpXSum >> 16) | (TmpXSum << 16)) + TmpXSum) >> 16; ipHeader->iph_xsum=~(USHORT)TmpXSum; retVal=PF_FORWARD; } return (retVal); }
Кажется я понял в чем тут дело. Нужно изменять и iph_src для получаемых пакетов опять-таки в соответствии со списком, т.к ждем то совершенно с другого адреса, но тут возникает другой вопрос: как узнать, что входящий пакет пришел с адреса, к которому мы перенаправили пакет, а не был сразу направлен на тот адрес?
Вот как выглядит перенаправление в tracert с www.mail.ru на www.yandex.ru. Если не делать подмену входящих пакетов - в последней строчке будет www.yandex.ru [87.250.251.3]. Tracing route to mail.ru [217.69.128.41] over a maximum of 30 hops: 1 * * * Request timed out. 2 1 ms <1 ms 1 ms 92.50.189.1.static.ufanet.ru [92.50.189.1] 3 1 ms <1 ms <1 ms ck165-1-eth1.ufa.ufanet.ru [92.50.190.101] 4 1 ms 1 ms 1 ms cmr4-1-te21.ufa.ufanet.ru [92.50.190.1] 5 1 ms 1 ms 1 ms b0-vlan35.ufa.ufanet.ru [92.50.190.194] 6 1 ms 1 ms 1 ms 82.96.211.37 7 26 ms 26 ms 26 ms msk-ix-gw.inet.euro-tel.ru [193.232.244.60] 8 29 ms 28 ms 29 ms msk-ix-m9.yandex.net [193.232.244.93] 9 27 ms 27 ms 27 ms gallium-vlan901.yandex.net [77.88.56.126] 10 27 ms 27 ms 27 ms l3-ugr2-ugr1.yandex.net [213.180.213.39] 11 27 ms 27 ms 27 ms l3link-iva1-ugr1.yandex.net [213.180.213.4] 12 26 ms 25 ms 26 ms mail.ru [217.69.128.41] Trace complete.
Господа, а вас вообще не смущает, что PacketFilterExtensionPtr может быть всего одна зарегистрирована в системе? Любой другой фильтр похерит все ваши выкрутасы. Изначально IP Filter Driver (ipfltdrv.sys) был написан для встроенного виндового фаервола, который впервые появился в Windows XP SP2. Подразумевалось, что он будет один в системе и только он будет использовать указанный интерфейс. Короче говоря, если вы уверены, что подобный фильтр будет один в системе - не вопрос, используйте, конечно, но кто ж такую гарантию-то даст?