tcp 连接校验和注意点
- psd结构体
struct psd_header
{
unsigned int saddr; //源地址 大端
unsigned int daddr; //目的地址 大端
char mbz; //强制置空
char ptcl; //协议类型
unsigned short tcpl; //TCP长度 大端
}; - tcp 头结构体
/**
- TCP Header
*/
struct rte_tcp_hdr {
rte_be16_t src_port; /< TCP source port. */
rte_be16_t dst_port; /< TCP destination port. */
rte_be32_t sent_seq; /< TX data sequence number. */
rte_be32_t recv_ack; /< RX data acknowledgment sequence number. */
uint8_t data_off; /< Data offset. */
uint8_t tcp_flags; /< TCP flags */
rte_be16_t rx_win; /< RX flow control window. */
rte_be16_t cksum; /< TCP checksum. */
rte_be16_t tcp_urp; /**< TCP urgent pointer, if any. */
} __rte_packed;
-
发送SYN包时,校验和需要注意OPTION选项值,必须要加上,见下图标记
-
发送SYN包计算校验和示例
unsigned char tcp_opt_test[]={0x02 ,0x04 ,0x05 ,0xb4 ,0x01 ,0x03 ,0x03 ,0x02 ,0x01 ,0x01 ,0x04 ,0x02};
uint16_t option_len = sizeof(tcp_opt_test);
unsigned char psd[512] = {0};
*(uint32_t *)(psd) = src_addr;
*(uint32_t *)(psd + 4) = dst_addr;
*(unsigned char *)(psd + 8) = 0;
*(unsigned char *)(psd + 9) = IPPROTO_TCP;
*(uint16_t )(psd + 10) = rte_cpu_to_be_16(sizeof(struct rte_tcp_hdr)+option_len);
(struct rte_tcp_hdr)(psd + 12) = tcp_hdr; //tcp 头部参数
unsigned char psd_p = (unsigned char)(psd + 12 + sizeof(struct rte_tcp_hdr));
for (auto i = 0; i != sizeof(tcp_opt); ++i)
{
*(psd_p + i) = tcp_opt [i];
}uint16_t check_sum = 0; check_sum = ip_sum((uint16_t *)psd, sizeof(struct rte_tcp_hdr) + sizeof(struct psd_header) + option_len); //tcp 校验和
以上有借鉴,需要删除请指出。