在 tcp 标头中设置最大段大小 [英] setting the maximum segment size in the tcp header

查看:32
本文介绍了在 tcp 标头中设置最大段大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在组装一个端口扫描器作为学习练习.我的问题是我试图在 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 标头中设置最大段大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆