我正在组装一个端口扫描器作为学习练习.我的问题是我试图在 TCP 标头中设置最大段大小选项 (MSS).我查看了 tcp.h,但我无法弄清楚如何设置它.我希望会有这样的选择:
I am putting together a port scanner as a learning exercise. My problem is I'm trying to set the maximum segment size option(MSS) in the TCP header. I had a look at tcp.h, but I'm having trouble figuring out how to set it. I was hoping there would be an option like this:
tcp_header->mss(32000);
tcp.h 中有与上述类似的内容,但不在正确的结构中.诚然,我对阅读结构定义还是很陌生,我对 tcp.h 没有多大意义,所以最后我尝试将必要的字节添加到 TCP 标头的末尾:
Something similar to the above was in tcp.h but not in the right struct. Admittedly, I'm still fairly new to reading struct definitions and I couldn't make much sense out of tcp.h so in the end I tried just tacking on the necessary bytes to the end of the TCP header:
struct tcphdr *CreateTcpHeader() { struct tcphdr *tcp_header; tcp_header = (struct tcphdr *)malloc(sizeof(struct tcphdr)+4*sizeof(int)); tcp_header->source = htons(SRC_PORT); tcp_header->dest = htons(DST_PORT); tcp_header->seq = htonl(0); tcp_header->ack_seq = htonl(0); tcp_header->res1 = 0; tcp_header->doff = (sizeof(struct tcphdr))/4; tcp_header->syn = 1; tcp_header->window = htons(4096); tcp_header->check = 0; /* Will calculate the checksum with pseudo-header later */ tcp_header->urg_ptr = 0; /*memcpy the mss data onto the end of the tcp header. */ int mssCode = 2; int mssLength = 4; uint16_t mss = htonl(32000); int offset = sizeof(struct tcphdr); memcpy( (tcp_header+offset), &mssCode, 1 ); memcpy( (tcp_header+offset+1), &mssLength, 1 ); memcpy( (tcp_header+offset+2), &mss, 2); return (tcp_header); }但是在我写完之后很明显这不是一个真正的解决方案,而且它仍然不起作用:P 那么有更好的方法吗?
But after I wrote it it was clear that is wasn't a real solution, plus it still doesn't work :P So is there a better way?
推荐答案tcp.h 中的 struct tcphdr 定义了 TCP 标头的必需部分.(查看TCP 标头,您可以匹配struct tcphdr 到您要出现在标头中的实际位.)C 中的结构具有恒定大小,但 TCP 允许可选数据.标头长度字段(结构中的doff)是标头的总长度,包括选项,因此您需要添加一个字来说明 MSS 选项:
The struct tcphdr in tcp.h defines the mandatory part of the TCP header. (Look at the TCP header and you can match the definitions in struct tcphdr to your the actual bits to appear in the header.) Structs in C have a constant size, but TCP allows optional data. The header length field (doff in the structure) is the total length of the header, including options, so you'll need to add one word to account for the MSS option:
tcp_header->doff = (sizeof(struct tcphdr))/4 + 1;让我们为 MSS 选项定义一个结构:
Let's define a structure for the MSS option:
struct tcp_option_mss { uint8_t kind; /* 2 */ uint8_t len; /* 4 */ uint16_t mss; } __attribute__((packed));现在您可以按正确的顺序填充结构:
Now you can populate the structure, in the right order:
/*memcpy the mss data onto the end of the tcp header. */ struct tcp_option_mss mss; mss.kind = 2; mss.len = 4; mss.mss = htons(32000);让我们更进一步,为你的数据包定义一个单一的结构,让编译器帮助我们:
Let's go one step further and define a single structure for your packet, to let the compiler help us out:
struct tcphdr_mss { struct tcphdr tcp_header; struct tcp_option_mss mss; };(您可能需要在末尾添加一个 end-of-option-list 选项,并使用 nop 选项将选项列表填充到 8 个字节.)
(You may need to add an end-of-option-list option at the end, and nop options to pad the option list to 8 bytes.)
现在我们可以把所有的部分放在一起:
Now we can put all the pieces together:
struct tcphdr *CreateTcpHeader() { struct tcphdr_mss *tcp_header; tcp_header = malloc(sizeof(struct tcphdr_mss)); tcp_header->tcp_header.source = htons(SRC_PORT); tcp_header->tcp_header.dest = htons(DST_PORT); tcp_header->tcp_header.seq = htonl(0); tcp_header->tcp_header.ack_seq = htonl(0); tcp_header->tcp_header.res1 = 0; tcp_header->tcp_header.doff = (sizeof(struct tcphdr_mss))/4; tcp_header->tcp_header.syn = 1; tcp_header->tcp_header.window = htons(4096); tcp_header->tcp_header.check = 0; /* Will calculate the checksum with pseudo-header later */ tcp_header->tcp_header.urg_ptr = 0; tcp_header->mss.kind = 2; tcp_header->mss.len = 2; tcp_header->mss.mss = htons(32000); return (tcp_header); }更多推荐
在 tcp 标头中设置最大段大小
发布评论