现在的位置: 首页 > 综合 > 正文

获取网卡是否自动checksum

2012年11月28日 ⁄ 综合 ⁄ 共 3665字 ⁄ 字号 评论关闭

今天调试了个程序,居然发现NIC不支持上层校验,只好查资料了 吐舌头

先给上书的地址:

 http://read.pudn.com/downloads100/ebook/410039/ndis_driver_dev.pdf

 

1.读到下面就明白了(如果要想马上知道答案,就在打了蓝色标记那里)

2.还可以通过查询MPQueryInformation 函数获取

 

停用任务卸载能力
为了停用 NIC 的所有任务卸载能力,TCP/IP 传输层设置OID_TCP_TASK_OFFLOAD,
在InformationBuffer 中只传递一个NDIS_TASK_OFFLOAD_HEADER 结构。TCP/IP 传输层
将NDIS_TASK_OFFLOAD_HEADER 结构的OffsetFirstTask 成员置为0。
9.4 访问Per-Packet 信息
TCP/IP 传输层和微端口之间用包的Per-Packet 信息互相传递关于任务卸载操作的信息。
Per-Packet 信息是用NDIS_PACKET_EXTENSION 结构表示的带外信息,此结构的定义如下:
-1 5 7-
typedef struct _NDIS_PACKET_EXTENSION
{
PVOID NdisPacketInfo[MaxPerPacketInfo];
} NDIS_PACKET_EXTENSION,*PNDIS_PACKET_EXTENSION;
用 NdisAllocatePacket 分配的每个包描述信息都有一个相关的
NDIS_PACKET_EXTENSION 结构。此结构包含一个指针数组(PVOID),每个数组包含或
指向一个与包描述信息相关的Per-Packet 信息的特定类型。
驱 动 程 序 使 用 NDIS_PACKET_EXTENSION_FROM_PACKET 宏或
NDIS_PER_PACKET_INFO_FROM_PACKET 宏访问Per-Packet 信息。
NDIS_PACKET_EXTENSION_FROM_PACKET 宏的定义如下:
PNDIS_PACKET_EXTENSION
NDIS_PACKET_EXTENSION_FROM_PACKET(
IN PNDIS_PACKET Packet
);
此宏返回一个指向与给定包描述信息相关的 NDIS_PACKET_EXTENSION 结构的指针。
当驱动程序需要访问与包描述信息相关的多个类型的Per-Packet 信息时,它应调用此宏。在
获得指向NDIS_PACKET_EXTENSION 结构的指针后,驱动程序可以使用适当的数组索引
访问特定类型的Per-Packet 信息。属于卸载任务的索引值有:
TcpIpCheckSumPacketInfo
索引一个指向NDIS_TCP_IP_CHECKSUM_PACKET_INFO 结构的指针。此结构为卸载
的校验和操作向微端口指定Per-Packet 信息。
IpSecPacketInfo
索引一个指向NDIS_IPSEC_PACKET_INFO 结构的指针。此结构为IP 安全性操作向微
端口指定Per-Packet 信息。
TcpLargeSendPacketInfo
索引指向一个ULONG 值的指针。此值用于卸载大TCP 包分段。
NDIS_PER_PACKET_INFO_FROM_PACKET 宏定义如下:
PVOID
NDIS_PER_PACKET_INFO_FROM_PACKET(
IN PNDIS_PACKET Packet,
IN NDIS_PER_PACKET_INFO InfoType
);
此宏为指定包返回一个指向或包含 Per-Packet 信息的特定类型的指针。属于卸载任务的
InfoType 值有TcpIpCheckSumPacketInfo、IpSecPacketInfo,和TcpLargeSendPacketInfo。
这些值与上面描述的索引值一致。例如,若指定的InfoType 是TcpIpCheckSumPacketInfo,
此宏返回一个指向与给定包描述信息相关的NDIS_TCP_IP_CHECKSUM_PACKET_INFO结
构的指针。在驱动程序需要访问Per-Packet 信息的一个类型时, 它应调用
NDIS_PER_PACKET_INFO_FROM_PACKET 宏。
-1 5 8-
9.5 卸载TCP/IP 校验和任务
负载平衡微端口不能卸载 TCP/IP 校验和任务。负载平衡的更多信息参见第十章。
在向微端口传递一个包描述信息(微端口将要在此包上执行一个或多个校验任务)之前,
TCP/IP 传输层指定与此包描述信息相关的校验信息。此信息用
NDIS_TCP_IP_CHECKSUM_PACKET_INFO 结构表示,它是与包描述信息相关的Per-Packet
信息(扩展的带外信息)的一部分。
NDIS_TCP_IP_CHECKSUM_PACKET_INFO 结构的定义如下:
typedef struct _NDIS_TCP_IP_CHECKSUM_PACKET_INFO
{
union
{
struct
{
ULONG NdisPacketChecksumV4:1;
ULONG NdisPacketChecksumV6:1;
ULONG NdisPacketTcpChecksum;
ULONG NdisPacketUdpChecksum;
ULONG NdisPacketIpChecksum;
} Transmit;
struct
{
ULONG NdisPacketTcpChecksumFailed:1;
ULONG NdisPacketUdpChecksumFailed:1;
ULONG NdisPacketIpChecksumFailed:1;
ULONG NdisPacketTcpChecksumSucceeded:1;
ULONG NdisPacketUdpChecksumSucceeded:1;
ULONG NdisPacketIpChecksumSucceeded:1;
ULONG NdisPacketLoopback:1;
} Receive;
ULONG Value;
};
}NDIS_TCP_IP_CHECKSUM_PACKET_INFO,
*PNDIS_TCP_IP_CHECKSUM_PACKET_INFO;
在将对 TCP 包的校验和的计算卸载之前,TCP/IP 传输层为TCP 虚拟报头计算校验和。
TCP/IP 传输层的虚拟报头的校验和计算跨越了虚拟报头的所有字段,包括源IP 地址、目标
IP 地址、协议字段、和TCP 包的TCP 长度。TCP/IP 传输层将虚拟报头校验和放到TCP 报
头的校验和字段中。
TCP/IP 传输层提供的虚拟报头校验和是NIC 为发送包计算的实TCP 校验和的提前注入
量。为了计算实TCP 校验和,NIC 计算TCP 校验和(对TCP 报头和负载)的可变部分,将
-1 5 9-
此校验和加到TCP/IP 传输层计算的虚拟报头校验和上,然后为此校验和计算16 位的补码。
(计算这样的校验和的更多信息,参见RFC 793 和RFC 1122)。
在从 MiniportSend、MiniportSendPacket、和MiniportCoSendPacket 函数收到包描述信息
后,微端口一般进行以下校验和处理:
1.微端口调用NDIS_GET_PACKET_PROTOCOL_TYPE 宏确定包的协议。
2.如果宏返回的协议ID 不是NDIS_PROTOCOL_ID_TCP_IP,微端口的NIC 不应在此包上
进行任何校验操作。
3.如果返回的协议ID 是NDIS_PROTOCOL_ID_TCP_IP , 微端口调用
NDIS_PER_PACKET_INFO_FROM_PACKET 宏( 其中InfoType 值为
TcpIpCheckSumPacketInfo),获得一个指向NDIS_TCP_IP_CHECKSUM_PACKET_INFO
结构的指针。(或者微端口调用NDIS_PACKET_EXTENSION_FROM_PACKET 宏获得
一个指向NDIS_PACKET_EXTENSION 结构的指针。然后微端口使用
TcpIpCheckSumPacketInfo 数组索引获得一个指向
NDIS_TCP_IP_CHECKSUM_PACKET_INFO 结构的指针。)
4.微端口检查NDIS_TCP_IP_CHECKSUM_PACKET_INFO 结构中的
NdisPacketChecksumV4 标记。若未设置NdisPacketChecksumV4 标记,微端口的NIC 不
应在此包上进行任何校验操作。
5.若已设置NdisPacketChecksumV4 标记, 微端口检查MdisPacketTcpChecksum 、
MdisPacketUdpChecksum、和MdisPacketIpChecksum 标记,确定它的NIC 应为包计算哪
些校验和。
6.微端口将包传递给它的NIC,NIC 将为包计算适当的校验和。如果包既有一个隧道IP 报
头,又有一个传输IP 报头,那么支持IP 校验卸载的NIC 只在隧道报头上执行IP 校验任
务。TCP/IP 传输层在传输IP 报头上执行IP 校验任务。

 

 

抱歉!评论已关闭.