Я зарегистрировал фильтр WFP ядра в FWPM_LAYER_OUTBOUND_IPPACKET_V4, где я копирую каждый IPv4 NET_BUFFER_LIST в буфер и повторно вставляю его без изменений из рабочего потока. Я использую FWPM_SUBLAYER_UNIVERSAL в качестве подслоя. В принципе:
mdl = IoAllocateMdl(buffer, ...)
MmBuildMdlForNonPagedPool(mdl);
FwpsAllocateNetBufferAndNetBufferList0(..., mdl, ..., &nbl)
FwpsInjectNetworkSendAsync0(..., nbl, ...)
который возвращает 0, а также NET_BUFFER_LIST_STATUS() из обратного вызова sendComplete.
Это работает для UDP и ICMP (я получаю ответы), но не для TCP-пакетов. Я вижу, что SYN выходит в NetMon с виртуальной машины, на которой я тестирую, но NetMon не видит, что пакет выходит извне (на хост-машине). И, конечно же, никакого ответа от удаленного хоста.
Я попытался обновить контрольную сумму IP (которую я получаю как 0 в classifyFn), и это ничего не меняет. Контрольная сумма TCP уже верна, когда мой classifyFn ее получает (насколько может судить NetMon). Я посмотрел на исходный nbl, мой плоский буфер и вновь созданный nbl в WinDBG, и все они содержат IP-пакет (начиная с 0x45 и т. д.).
Нужно ли создавать новый подслой для фильтра? Пакеты отбрасываются, потому что я вызываю sendAsync из рабочего потока, связанного с системным процессом?