在我向关闭的端口发送几个 SYN 数据包后,我试图接收发送到我的程序的 RST 数据包,情况是我看到任何 RST 段正在发送或接收,正如我通过 Wireshark 确认的那样。 这是 SYN 段配置:
char packet[BUF_SIZE];
struct iphdr* ip_h = (struct iphdr*) packet;
struct tcphdr* tcp_h = (struct tcphdr*) (packet + sizeof(struct iphdr));
struct pseudo_header ps_h;
ip_h->ihl = 5;
ip_h->version = 4;
ip_h->tos = 0;
ip_h->tot_len = sizeof (struct iphdr) + sizeof (struct tcphdr);
ip_h->id = htons(54321);
ip_h->frag_off = 0;
ip_h->ttl = 255;
ip_h->protocol = IPPROTO_TCP;
ip_h->check = 0;
ip_h->saddr = inet_addr(cf->src_ip);
ip_h->daddr = inet_addr(cf->server_ip);
tcp_h->source = htons(12345);
tcp_h->dest = htons(dest_port);
tcp_h->seq = 0;
tcp_h->ack_seq = 0;
tcp_h->doff = 5;
tcp_h->fin = 0;
tcp_h->syn = 1;
tcp_h->rst = 0;
tcp_h->psh = 0;
tcp_h->ack = 0;
tcp_h->urg = 0;
tcp_h->check = 0;
tcp_h->window = htons (5840);
tcp_h->urg_ptr = 0;
memset(&ps_h, 0, sizeof(ps_h));
ps_h.source_address = inet_addr("192.168.128.2");
ps_h.dest_address = inet_addr(cf->server_ip);
ps_h.placeholder = 0;
ps_h.protocol = IPPROTO_TCP;
ps_h.tcp_length = htons(sizeof(struct tcphdr));
int pseudo_size = sizeof(struct pseudo_header) + sizeof(struct tcphdr);
char *pseudo_packet = malloc(pseudo_size);
memcpy(pseudo_packet, (char *) &ps_h, sizeof(struct pseudo_header));
memcpy(pseudo_packet + sizeof(struct pseudo_header), tcp_h, sizeof(struct tcphdr));
tcp_h->check = checksum(pseudo_packet, pseudo_size);
ip_h->check = checksum(packet, ip_h->tot_len);
伪标题
struct pseudo_header {
u_int32_t source_address;
u_int32_t dest_address;
u_int8_t placeholder;
u_int8_t protocol;
u_int16_t tcp_length;
};
校验和算法:
unsigned short checksum(const char *buf, unsigned size) {
unsigned sum = 0, i;
/* Accumulate checksum */
for (i = 0; i < size - 1; i += 2) {
unsigned short word16 = *(unsigned short *) &buf[i];
sum += word16;
}
/* Handle odd-sized case */
if (size & 1) {
unsigned short word16 = (unsigned char) buf[i];
sum += word16;
}
/* Fold to get the ones-complement result */
while (sum >> 16) sum = (sum & 0xFFFF)+(sum >> 16);
/* Invert to get the negative in ones-complement arithmetic */
return ~sum;
}
另外,当我通过Wireshark检查SYN段时,这对我来说有点奇怪,因为ECN和CWR不应该被设置,包括保留,但我不认为我能够手动设置他们在节目中消失了。
目前,我只能想到两个问题,要么是我的 SYN 段设置不正确,但对我来说看起来不错。或者服务器根本不发送RST,为此,我尝试使用
nc -l -p 9999
(发送SYN的目标端口)在服务器端打开此端口,希望它发送SYN-ACK,但仍然没有响应。
我以某种方式解决了问题所在,即我的 ip 和 tcp 标头长度计算不正确,由这个 project 给出,除了长度之外还应该有一个 OPT_SIZE 。