laxend 发表于 2014-08-10 15:21

為甚麼tcp檢驗和老是算不對?

本帖最后由 laxend 于 2014-08-10 15:29 编辑

10.10.99.100.43333 > www2635.sakura.ne.jp.http: Flags , cksum 0xa6c2 (incorrect -> 0xa6b0), seq 123456789, win 8192, options , length 0
上面是tcpdump的輸出結果
總是a6c2,而不是a6b0,yun
下面是計算檢驗和的代碼(ip頭部,tcp選項什麼的就不貼出來了,沒問題的)
struct tcp_psd_hdr {
        struct in_addr        p_src;
        struct in_addrp_dst;
        uint8_t                        p_zero;
        uint8_t                        p_proto;
        uint16_t                p_off;
};

int build_tcp_raw(struct tcphdr *tcp, int sport, int dport, struct in_addr *src, struct in_addr *dst) {
        char *ptr;
        struct tcp_opt *opt;
        char sumbuf;
        struct tcp_psd_hdr *tph;
       
        tcp->th_sport = htons(43333);
        tcp->th_dport = htons(dport);
        tcp->th_seq = htonl(123456789);
        tcp->th_ack = htonl(0);
        tcp->th_off = 6;
        tcp->th_flags = TH_SYN;
        tcp->th_win = htons(8192);
        tcp->th_sum = 0;
        tcp->th_urp = 0;
       
        ptr = (char *)tcp + sizeof(struct tcphdr);
        opt = (struct tcp_opt*)ptr;
        build_tcp_opt_mss(opt);
       
        tph = (struct tcp_psd_hdr*)sumbuf;
        if (src != NULL)
                tph->p_src = *src;
        else
                tph->p_src.s_addr = inet_addr("10.10.99.100");
        tph->p_dst = *dst;
        tph->p_proto = IPPROTO_TCP;
        tph->p_zero = 0;
        tph->p_off = htons(6);
        memcpy(sumbuf+sizeof(*tph), tcp, sizeof(*tcp));
        memcpy(sumbuf+sizeof(*tph)+sizeof(*tcp), opt, sizeof(*opt));
       
        tcp->th_sum = in_cksum((uint16_t *)sumbuf, sizeof(sumbuf));
        //tcp->th_sum = 0xb0a6;
        printf("TCP: %x\n", tcp->th_sum);
        return 0;
}
到底是哪裏有問題?求教,感激不盡。
页: [1]
查看完整版本: 為甚麼tcp檢驗和老是算不對?