javascript - 使用 WFP 重定向 DNS 流量
问题描述
我是 StackOverflow 的新手。现在我面临着这篇文章中描述的类似问题:Cisco AnyConnect VPN 兼容性问题。我试图应用那里发布的解决方案,但我无法让它发挥作用,所以我希望能得到一些关于可能发生的事情以及如何让它发挥作用的指针。让我描述一下我正在尝试做的事情:
void classifyFunc(...)
{
NET_BUFFER_LIST * netBufferList = (NET_BUFFER_LIST *)layerData;
// Verify that the packet wasn't injected before
FWPS_PACKET_INJECTION_STATE packetState = FwpsQueryPacketInjectionState(injectionNetworkHandle, netBufferList, NULL);
if (packetState == FWPS_PACKET_INJECTED_BY_SELF || packetState == FWPS_PACKET_PREVIOUSLY_INJECTED_BY_SELF)
{
classifyOut->actionType = FWP_ACTION_PERMIT;
if (filter->flags & FWPS_FILTER_FLAG_CLEAR_ACTION_RIGHT)
{
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
}
return;
}
MetadataValues* metadataValues = ExAllocatePoolWithTag(NonPagedPool, sizeof(MetadataValues), SOME_TAG);
// Get all information needed for redirection (compartmentId, interfaceIndex, subInterfaceIndex, IpHeaderSize, etc) and stored it on metadataValues
// Block-adsorb the original NET_BUFFER_LIST and queued it to be processed by a worker thread
FwpsReferenceNetBufferList(netBufferList, TRUE);
classifyOut->actionType = FWP_ACTION_BLOCK;
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
classifyOut->flags |= FWPS_CLASSIFY_OUT_FLAG_ABSORB;
// Queue the packet to be modified out of bounds by a worker thread.
addPacketToWorkerQueue(netBufferList, metadataValues);
}
void workerThreadFunc(NET_BUFFER_LIST * netBufferList, MetadataValues * metadataValues) //this Is the function that the worker thread executes to modify and re-inject the packet
{
//Retread the NET_BUFFER_LIST by the amount specified in inMetadataValues->ipHeaderSize
// Cloned it and advance the original NET_BUFFER_LIST to its original position.
NET_BUFFER_LIST * clonedBufferList;
NDIS_STATUS ndis_status = NdisRetreatNetBufferListDataStart(netBufferList, metadataValues->ipHeaderSize, 0, NULL, NULL);
status = FwpsAllocateCloneNetBufferList(netBufferList, NULL, NULL, 0, &clonedBufferList);
NdisAdvanceNetBufferListDataStart(netBufferList, metadataValues->ipHeaderSize, FALSE, NULL);
// Advance the cloned NET_BUFFER_LIST to the transport header
NET_BUFFER * netBuffer = NET_BUFFER_LIST_FIRST_NB(clonedBufferList);
NdisAdvanceNetBufferDataStart(netBuffer, metadataValues->ipHeaderSize, FALSE, NULL);
// Get the UDP header and modify the source port
UDP_HEADER * udpHeader = (UDP_HEADER *)NdisGetDataBuffer(netBuffer, sizeof(UDP_HEADER), NULL, sizeof(UINT16), 0);
udpHeader->srcPort = RtlUshortByteSwap(53);
// Go back to the beginning of the IP Header
ndis_status = NdisRetreatNetBufferDataStart(netBuffer, metadataValues->ipHeaderSize, 0, NULL);
// Get the IP header and modify the source and destination ip addresses
UINT32 source = RtlUlongByteSwap(originalDNS);
UINT32 destiny = RtlUlongByteSwap(nicIpAddress);
IP_HEADER_V4 * ipHeader = (IP_HEADER_V4 *)NdisGetDataBuffer(netBuffer, metadataValues->ipHeaderSize, NULL, sizeof(UINT16), 0);
RtlCopyMemory(ipHeader->pSourceAddress, &source, sizeof(UINT32));
RtlCopyMemory(ipHeader->pDestinationAddress, &destiny, sizeof(UINT32));
// Finally fix the IpHeader Checksum
fixIpChecksum(ipHeader, metadataValues->ipHeaderSize);
//Inject the modified NET_BUFFER_LIST
FwpsInjectNetworkReceiveAsync(
injectionNetworkHandle, //This injection handle was created using the FWPS_INJECTION_TYPE_NETWORK flag
NULL,
0,
metadataValues->compartmentId,
metadataValues->interfaceIndex,
metadataValues->subInterfaceIndex,
clonedBuffer,
InjectToDNSClientCompleteFunc,
NULL);
}
To recalculate the Ip Header checksum I am using this function:
void fixIpChecksum(IP_HEADER_V4* ipHeader, UINT32 size)
{
UINT32 sum = 0;
UINT32 words = size / 2;
UINT16 UNALIGNED* pStart = (UINT16*)ipHeader;
ipHeader->checksum = 0;
for (UINT8 i = 0; i < words; i++)
{
sum += pStart[i];
}
sum = (sum & 0x0000ffff) + (sum >> 16);
sum += (sum >> 16);
ipHeader->checksum = (UINT16)~sum;
}
解决方案
推荐阅读
- python-3.x - 没有名为 distutils 的模块....但是安装了 distutils 吗?
- drupal-7 - 带有 $menu_tree 的下拉菜单
- r - R Dataframe:当其他两个值匹配时组合行/值
- javascript - 在不使用 YouTube API 的情况下更改当前 YouTube 视频时间
- catboost - 同时对多个目标进行分位数回归
- go - 如果处理程序不返回,golang中的grpc流会导致内存/性能问题
- sql-server - 派生列映射失败
- python - Python - 将两个文件读入两个字典并比较键
- nginx - 启用 TLSv1.3 时,是否可以在 Qualys SSL 服务器测试中获得密码强度最高分?
- html - 将十字 png 居中到 css 网格中