```
/
/
Allocate TAP packet memory
tapPacket
=
(PTAP_PACKET )NdisAllocateMemoryWithTagPriority(
Adapter
-
>MiniportAdapterHandle,
TAP_PACKET_SIZE (packetLength
+
addHeaderSize),
TAP_PACKET_TAG,
NormalPoolPriority
);
/
/
提取Buf数据
packetData
=
NdisGetDataBuffer(NetBuffer,packetLength,tapPacket
-
>m_Data
+
addHeaderSize,
1
,
0
);
/
/
拷贝数据到tapPacket
+
addHeaderSize后的位置,预留出来addHeaderSize
if
(packetData !
=
(tapPacket
-
>m_Data
+
addHeaderSize))
{
/
/
Packet data was contiguous
and
not
yet copied to m_Data.
NdisMoveMemory(tapPacket
-
>m_Data
+
addHeaderSize,packetData,packetLength);
}
/
/
填充addHeaderSize大小数据
if
(addHeaderSize >
0
)
{
/
/
Add an
802.1Q
header between the ethernet header
and
the payload
NdisMoveMemory(tapPacket
-
>m_Data,tapPacket
-
>m_Data
+
addHeaderSize,ETHERNET_HEADER_SIZE
-
2
);
PETH_HEADER header
=
(PETH_HEADER)tapPacket
-
>m_Data;
PETH_8021Q_HEADER tag
=
(PETH_8021Q_HEADER)(header
+
1
);
header
-
>proto
=
htons(
0x8100
);
USHORT tagValue
=
0
;
tagValue |
=
packetPriority.TagHeader.UserPriority<<
13
;
tagValue |
=
packetPriority.TagHeader.VlanId &
0xFFF
;
tag
-
>Tag
=
tagValue;
packetLength
+
=
addHeaderSize;
}
/
/
DHCP的处理从数据链路层(ETH_HEADER) 到 网络层(IP_HDR) 到 UDPHDR(传输层) DHCP
......
const ETH_HEADER
*
eth
=
(ETH_HEADER
*
) tapPacket
-
>m_Data;
const IPHDR
*
ip
=
(IPHDR
*
) (tapPacket
-
>m_Data
+
sizeof (ETH_HEADER));
const UDPHDR
*
udp
=
(UDPHDR
*
) (tapPacket
-
>m_Data
+
sizeof (ETH_HEADER)
+
sizeof (IPHDR));
......
else
if
(packetLength >
=
sizeof (ETH_HEADER)
+
sizeof (IPHDR)
+
sizeof (UDPHDR)
+
sizeof (DHCP)
&& eth
-
>proto
=
=
htons (NDIS_ETH_TYPE_IPV4)
&& ip
-
>version_len
=
=
0x45
/
/
IPv4,
20
byte header
&& ip
-
>protocol
=
=
IPPROTO_UDP
&& udp
-
>dest
=
=
htons (BOOTPS_PORT)
)
......
/
/
首先要从Ethernet
-
>proto确认协议
ETH_HEADER
*
e;
e
=
(ETH_HEADER
*
) tapPacket
-
>m_Data;
switch (ntohs (e
-
>proto))
/
/
ARP处理
if
(packetLength !
=
sizeof (ARP_PACKET))
{
goto no_queue;
}
ProcessARP (
Adapter,
(PARP_PACKET) tapPacket
-
>m_Data,
Adapter
-
>m_localIP,
Adapter
-
>m_remoteNetwork,
Adapter
-
>m_remoteNetmask,
Adapter
-
>m_TapToUser.dest
);
/
/
ipv4
/
ipv6处理
case NDIS_ETH_TYPE_IPV4:
/
/
Make sure that packet
is
large enough to be IPv4.
if
(packetLength < (ETHERNET_HEADER_SIZE
+
IP_HEADER_SIZE))
{
goto no_queue;
}
/
/
Only accept directed packets,
not
broadcasts.
if
(memcmp (e, &Adapter
-
>m_TapToUser, ETHERNET_HEADER_SIZE))
{
goto no_queue;
}
/
/
Packet looks like IPv4, queue it. :
-
)
tapPacket
-
>m_SizeFlags |
=
TP_TUN;
break
;
case NDIS_ETH_TYPE_IPV6:
/
/
Make sure that packet
is
large enough to be IPv6.
if
(packetLength < (ETHERNET_HEADER_SIZE
+
IPV6_HEADER_SIZE))
{
goto no_queue;
}
/
/
Broadcasts
and
multicasts are handled specially
/
/
(to be implemented)
/
/
Neighbor discovery packets to fe80::
8
are special
/
/
OpenVPN sets this
next
-
hop to signal
"handled by tapdrv"
if
( HandleIPv6NeighborDiscovery(Adapter,tapPacket
-
>m_Data,
packetLength) )
{
goto no_queue;
}
/
/
Packet looks like IPv6, queue it. :
-
)
tapPacket
-
>m_SizeFlags |
=
TP_TUN;
}
```