[英]TCP checksum is 0
I have the followiing code for tcp header: 我有tcp标头的以下代码:
struct tcp_header {
uint16_t tcp_sport;
uint16_t tcp_dport;
uint32_t tcp_th_seq;
uint32_t tcp_ack;
uint8_t tcp_off:4;
uint8_t tcp_res:6;
uint8_t tcp_uf:1, tcp_af:1, tcp_pf:1, tcp_rf:1, tcp_sf:1, tcp_ff:1;
uint16_t tcp_win;
uint16_t tcp_sum;
uint16_t tcp_urp;
};
...
void decode_tcp(const unsigned char *header_start) {
const struct tcp_header *tcp_hdr;
tcp_hdr = (const struct tcp_header *)(header_start + ETHERNET_HEADER_SIZE + IP_HEADER_SIZE);
printf("\n TCP Header\n");
printf("\tSource Port : %u\n", ntohs(tcp_hdr->tcp_sport));
printf("\tDestination Port : %u\n", ntohs(tcp_hdr->tcp_dport));
printf("\tSequence number : %u\n", ntohl(tcp_hdr->tcp_th_seq));
printf("\tAcknowledge number: %u\n", ntohl(tcp_hdr->tcp_ack));
printf("\tOffset : %d\n", tcp_hdr->tcp_off);
printf("\tReserved : %d\n", (unsigned int)tcp_hdr->tcp_res);
printf("\tUrgent Flag : %d\n", (unsigned int)tcp_hdr->tcp_uf);
printf("\tAcknoledge Flag : %d\n", (unsigned int)tcp_hdr->tcp_af);
printf("\tPush Flag : %d\n", (unsigned int)tcp_hdr->tcp_pf);
printf("\tReset Flag : %d\n", (unsigned int)tcp_hdr->tcp_rf);
printf("\tSynchronise Flag : %d\n", (unsigned int)tcp_hdr->tcp_sf);
printf("\tFinish Flag : %d\n", (unsigned int)tcp_hdr->tcp_ff);
printf("\tWindow : %d\n", ntohs(tcp_hdr->tcp_win));
printf("\tChecksum : %d\n", ntohs(tcp_hdr->tcp_sum));
printf("\tUrgent Pointer : %d", ntohs(tcp_hdr->tcp_urp));
}
The output I get is 我得到的输出是
CHecksum is 0, so I think something is false. CHecksum是0,所以我认为有些事情是错误的。 Can you guys spot the mistake? 你们能发现错误吗? Or canchecksum should be 0? 或者canchecksum应该是0?
Also can sourceport be 22? sourceport也可以22?
Most of the conversion specifiers used are wrong here: 这里使用的大多数转换说明符都是错误的:
printf("\tSource Port : %u\n", ntohs(tcp_hdr->tcp_sport));
printf("\tDestination Port : %u\n", ntohs(tcp_hdr->tcp_dport));
printf("\tSequence number : %u\n", ntohl(tcp_hdr->tcp_th_seq));
printf("\tAcknowledge number: %u\n", ntohl(tcp_hdr->tcp_ack));
printf("\tOffset : %d\n", tcp_hdr->tcp_off);
printf("\tReserved : %d\n", (unsigned int)tcp_hdr->tcp_res);
printf("\tUrgent Flag : %d\n", (unsigned int)tcp_hdr->tcp_uf);
printf("\tAcknoledge Flag : %d\n", (unsigned int)tcp_hdr->tcp_af);
printf("\tPush Flag : %d\n", (unsigned int)tcp_hdr->tcp_pf);
printf("\tReset Flag : %d\n", (unsigned int)tcp_hdr->tcp_rf);
printf("\tSynchronise Flag : %d\n", (unsigned int)tcp_hdr->tcp_sf);
printf("\tFinish Flag : %d\n", (unsigned int)tcp_hdr->tcp_ff);
printf("\tWindow : %d\n", ntohs(tcp_hdr->tcp_win));
printf("\tChecksum : %d\n", ntohs(tcp_hdr->tcp_sum));
printf("\tUrgent Pointer : %d", ntohs(tcp_hdr->tcp_urp));
It should be: 它应该是:
printf("\tSource Port : %hu\n", ntohs(tcp_hdr->tcp_sport));
printf("\tDestination Port : %hu\n", ntohs(tcp_hdr->tcp_dport));
printf("\tSequence number : %u\n", ntohl(tcp_hdr->tcp_th_seq));
printf("\tAcknowledge number: %u\n", ntohl(tcp_hdr->tcp_ack));
printf("\tOffset : %hhu\n", tcp_hdr->tcp_off);
printf("\tReserved : %u\n", (unsigned int)tcp_hdr->tcp_res);
printf("\tUrgent Flag : %u\n", (unsigned int)tcp_hdr->tcp_uf);
printf("\tAcknoledge Flag : %u\n", (unsigned int)tcp_hdr->tcp_af);
printf("\tPush Flag : %u\n", (unsigned int)tcp_hdr->tcp_pf);
printf("\tReset Flag : %u\n", (unsigned int)tcp_hdr->tcp_rf);
printf("\tSynchronise Flag : %u\n", (unsigned int)tcp_hdr->tcp_sf);
printf("\tFinish Flag : %u\n", (unsigned int)tcp_hdr->tcp_ff);
printf("\tWindow : %hu\n", ntohs(tcp_hdr->tcp_win));
printf("\tChecksum : %hu\n", ntohs(tcp_hdr->tcp_sum));
printf("\tUrgent Pointer : %hu", ntohs(tcp_hdr->tcp_urp));
If you'd removed all those castings to unsigned int
you could use hhu
as conversion specifier for printf()
ing, as all those variables are defined to be unsigned
8-bit values. 如果你将所有这些转换删除为unsigned int
你可以使用hhu
作为printf()
转换说明符,因为所有这些变量都被定义为unsigned
8位值。
Your code has some problems: 您的代码有一些问题:
__attribute__((__packed__))
annotation). 确保结构被打包(例如通过__attribute__((__packed__))
注释)。 ABI can add padding between attributes else. ABI可以在其他属性之间添加填充。 tcp_hdr = (const struct tcp_header *)(header_start
can cause misaligned access when reading/writing tcp_hdr
fields. The __packed__
annotation above can prevent this; alternatively, you can copy content in a (correctly aligned) local variable. tcp_hdr = (const struct tcp_header *)(header_start
在读取/写入tcp_hdr
字段时可能导致错位访问。上面的__packed__
注释可以防止这种情况;或者,您可以复制(正确对齐的)局部变量中的内容。 I would add some sanity checks like 我会添加一些健全性检查
BUILD_BUG_ON(offsetof(struct tcp_header, tcp_sum) != 0x10));
(please check in tcp rfc whether tcp_sum is really at position 0x10!) (请检查tcp rfc tcp_sum是否确实位于0x10位置!)
I think your TCP header definiton has problem (which is 24 bytes but standard header is 20). 我认为你的TCP头定义有问题(这是24字节,但标准头是20)。 Use standard declaration on system which also considers alignment: 在系统上使用标准声明,也考虑对齐:
#include <netinet/tcp.h>
tcp header definition: tcp头定义:
struct tcphdr {
u_short th_sport; /* source port */
u_short th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
#if __BYTE_ORDER == __LITTLE_ENDIAN
u_int th_x2:4, /* (unused) */
th_off:4; /* data offset */
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
u_int th_off:4, /* data offset */
th_x2:4; /* (unused) */
#endif
u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG)
u_short th_win; /* window */
u_short th_sum; /* checksum */
u_short th_urp; /* urgent pointer */
};
Inbound or outbound? 入境或出境? The outbound checksum can be 0 if checksum offloading to the NIC is enabled... 如果启用了校验和卸载到NIC,则出站校验和可以为0 ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.