簡體   English   中英

即使我在計算之前已將校驗和等於0,TCP校驗和計算也返回0

[英]TCP checksum calculation return 0 even when I already set checksum equals to 0 before calculating

我正在編寫一個簡單的程序來發送/接收TCP數據包。 我被困在計算TCP數據包的校驗和。

對於校驗和功能,我重新使用如下代碼:

static int
in_cksum(u_short *addr, int len)
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short answer = 0;

/*
 * Our algorithm is simple, using a 32 bit accumulator (sum), we add
 * sequential 16 bit words to it, and at the end, fold back all the
 * carry bits from the top 16 bits into the lower 16 bits.
 */
while (nleft > 1)  {
    sum += *w++;
    nleft -= 2;
}

/* mop up an odd byte, if necessary */
if (nleft == 1) {
    *(u_char *)(&answer) = *(u_char *)w ;
    sum += answer;
}

/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16);         /* add carry */
answer = ~sum;              /* truncate to 16 bits */
return(answer);

}

我收到了一個數據包並存儲在char緩沖區[2048]。 為了獲得IP頭,我做:

struct iphdr* ip;
ip = (struct iphdr*) buffer;

以下是我獲取tcp標頭的方法:

tcp=(struct tcphdr*) (buffer+(4*ip->ihl));

這是我的偽TCP結構

struct tcp_pseudohdr{
   uint32_t tcp_ip_src, tcp_ip_dst;
   uint8_t tcp_reserved;
   uint8_t tcp_ip_protocol;
   uint16_t tcp_length;
   struct tcphdr tcp_hdr;
}
struct tcp_pseudohdr pseudo_tcp;
memset(&pseudo_tcp,0,sizeof(struct tcp_pseudohdr));

然后我填寫TCP偽結構並計算tcp校驗和,如下所示:

pseudo_tcp.tcp_ip_src = ip->saddr;
pseudo_tcp.tcp_ip_dst = ip->daddr;
pseudo_tcp.tcp_ip_protocol = ip->protocol;
pseudo_tcp.tcp_reserved = 0;
pseudo_tco.tcp_length = htons(ntohs(ip->tot_length)-(4*ip->ihl));
memcpy(&pseudo_tcp,tcp,ntohs(ip->tot_length)-(4*ip->ihl));

在此之后,我能夠准確地准備回偽信息在pseudo_tcp.tcp_hdr.source,pseudo_tcp.tcp_hdr.check等中。

然后我最終計算校驗和如下:

tcp->check=0;
tcp->check=in_cksum((unsigned short*)&pseudo_tcp, ntohs(ip->tot_length)-(4*ip->ihl)+12);

這個函數的輸出ntohs(tcp-> check)= 0.我覺得我很親密,但可能會遺漏一些東西。 通常,當我在計算之前沒有設置校驗和= 0時,cksum函數返回0。 但是,在這種情況下,我做了,並且不確定發生了什么。

我注意到的一件事是struct tcphdr的大小= 20,但是當我記憶時,這個ntohs(ip-> tot_length) - (4 * ip-> ihl)= 40因為它包含選項。 不知道這是否會導致問題或是否存在其他問題。

任何幫助將不勝感激。 先感謝您!

設置tcp->check = 0不會執行任何操作,因為您正在校驗偽pseudo_tcp,它是tcp的副本。 在將tcp復制到pseudo_tcp之前設置tcp->check = 0 ,或者將pseudo_tcp中的校驗和設置為0。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM