Setting max segment size in tcp header

I am building a port scanner as a training exercise. My problem is I am trying to set the maximum segment size (MSS) option in the TCP header. I looked at tcp.h but I am having a hard time figuring out how to install it. I was hoping there would be an option like this:


Something similar above was in tcp.h, but not in the correct structure. Admittedly, I'm still pretty new to reading structure descriptions and I couldn't understand much from tcp.h, so at the end I tried to just bind the required 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);


But after I wrote this, it was clear that this is not a real solution, plus it still doesn't work: P So, the best way?


source to share

1 answer

struct tcphdr

in tcp.h defines the required part of the TCP header. (Look at the TCP header , and you can match the definitions in struct tcphdr

with your actual bits, which will appear in the header.) Structures in C are constant in size, but TCP allows for more data. The header length field ( doff

in structure) is the total length of the header including parameters, so you need to add one account word for the MSS option:

tcp_header->doff = (sizeof(struct tcphdr))/4 + 1;


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 fill in the structure in the correct 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);


Take one more step and define a single structure for your package so the compiler can help us:

struct tcphdr_mss {
    struct tcphdr tcp_header;
    struct tcp_option_mss mss;


(You may need to add an end of option list option at the end and nop options to insert an 8 byte option list.)

Now we can collect all the parts:

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);




All Articles