2009-08-18 93 views
2

我正在组合一个端口扫描程序作为学习练习。我的问题是我试图在TCP头中设置最大段大小选项(MSS)。我看了一下tcp.h,但是我很难弄清楚如何设置它。我希望会有这样一个选项:在tcp头文件中设置最大段大小

tcp_header->mss(32000);

类似的东西上面是tcp.h中而不是在正确的结构。不可否认,我对于读取结构定义仍然相当陌生,而且我从tcp.h中得不到多少意义,所以最后我试图在TCP标头末尾加上必要的字节:

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那么还有更好的方法吗?

+0

你如何使用这个头?你使用libnet发送它吗? – Jonathan 2009-08-18 20:30:39

+0

我只是使用原始套接字。虽然即使使用新的mss选项,尽管它与nmap的实际相同,但我的数据包仍然被忽略。任何想法的人? – CalumMcCall 2009-08-18 22:38:26

+0

根据你正在学习的东西 - C或网络,你可能想看看http://www.secdev.org/projects/scapy/ – 2009-08-19 15:17:32

回答

5

tcp.h中的struct tcphdr定义了TCP报头的强制部分。 (请查看TCP header,您可以将struct tcphdr中的定义与您在头中出现的实际位相匹配。)C中的结构体具有恒定大小,但TCP允许可选数据。头长度字段(doff的结构)是标题,包括期权的总长度,所以你需要添加一个字占MSS选项:

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

让我们定义为一个结构MSS选项:

struct tcp_option_mss { 
    uint8_t kind; /* 2 */ 
    uint8_t len; /* 4 */ 
    uint16_t mss; 
} __attribute__((packed)); 

现在你可以填充结构,以正确的顺序:

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

让我们走一步,并为您的PA的单一结构cket,让编译器 帮助我们:

struct tcphdr_mss { 
    struct tcphdr tcp_header; 
    struct tcp_option_mss mss; 
}; 

(您可能需要在末尾添加结束选项列表的选项,NOP选项来填充选项列表为8个字节)

现在我们可以把所有的拼在一起:

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); 
} 
+0

啊这一切现在都有道理。谢谢一堆。 – CalumMcCall 2009-08-18 21:24:04

相关问题