我正在模擬 TCP,現在我堅持使用確認號處理。
tcph->seq 收到序列號,我將它分配給 tcp->ack_seq 這是確認號,如
tcp->ack_seq=htons(ntohs(tcph->seq) 1);
但是考慮到上面的代碼,似乎有一些固有的錯誤,tcph->seq 和 tcph 是網路位元組順序,這應該是因為我從緩沖區轉換并分配給 tcph 指標
這是我的簡單執行緒函式,它讀取接收到的緩沖區提取 tcthdr(struct tcph)并調整值或分配值以發送 tcphdr(struct tcp)
它只是做了它所做的我真的有問題。我不斷收到錯誤的確認號碼(并沒有真正反映我如何增加序列號并將其分配給確認號)。任何人都可以看看這個,所以我終于讓TCP握手成功了。問題來了,我發送 SYN ACK 資料包,我的客戶端重新傳輸 SYN 資料包,這個回圈污染了我的wireshark 視圖沒有任何用處,只是大量的 SYN 戰利品并從我的代碼中回應 SYN ACK
void * receiver(void *data)
{
//struct sockaddr_in cliaddr = {0};
int recvlen = -1;
int writelen = -1;
//socklen_t clilen = sizeof(cliaddr);
while (!_do_exit)
{
//recvlen = rrecvfrom(_udp_fd, buf, sizeof(buf), 0, (struct sockaddr*)&cliaddr, &clilen);
char buf[VPN_MAX_MTU] = {0};
char buf_1[VPN_MAX_MTU] = {0};
memset(buf,0,VPN_MAX_MTU);
memset(buf_1,0,VPN_MAX_MTU);
memset(buf,0,VPN_MAX_MTU);
memset(buf_1,0,VPN_MAX_MTU);
char *str_source=malloc(18);
char *str_dest=malloc(18);
memset(str_source,0,18);
memset(str_dest,0,18);
recvlen=read(_tun_fd,buf,VPN_MAX_MTU);
if(recvlen>0)
{
//BUFFER received here
struct iphdr *iph=(struct iphdr *)buf;
struct iphdr *ip=(struct iphdr *)buf_1;
int y=0;
for(int b=0;b<(sizeof(struct iphdr) sizeof(struct tcphdr));b )
{
if(y==20)
{
y=0;
//printf("\n");
}
//printf("%x ",buf[b]<<24);
y ;
}
// tcph->check=(tcp_chksum(iph,tcph));
//iph->check = csum(iph, sizeof(*iph));
char str_src[18]={0};
char str_dest_t[18]={0};
//printf("IN %s %s\n",get_ip_str_1(iph->saddr,str_src),get_ip_str_1(iph->daddr,str_dest_t));
memcpy(&ip->daddr,&iph->saddr,sizeof(uint32_t));
memcpy(&ip->saddr,&iph->daddr,sizeof(uint32_t));
//printf("OUT %s %s\n",get_ip_str_1(ip->saddr,str_src),get_ip_str_1(ip->daddr,str_dest_t));
//Create ip
//DOUBLE CHECK FOR BYTE ORDER
//ip->tot_len=iph->tot_len;
populate_ip_some(iph,ip);
ip->tos=0;
ip->tos=iph->tos;
ip->ihl = 5;
ip->version = 4;
ip->tot_len = htons(sizeof(struct iphdr) sizeof(struct tcphdr));
ip->protocol = 6;
ip->check=0;
//DOUBLE CHECK FOR BYTE ORDER
ip->id=htons(100);
ip->check = htons(csum(ip, sizeof(*ip)));
//printf("before %d \n",htons(iph->check));
iph->check=0;
//printf("middle %d\n",iph->check);
//DOUBLE CHECK FOR BYTE ORDER
iph->check = htons(csum(iph, sizeof(*iph)));
int i=iph->ihl*4;
struct tcphdr *tcph=(struct tcphdr *)(buf i);
//printf("tcp before %x\n",htons(tcph->check));
tcph->check=0;
printf("TCP START\n");
tcph->check=(tcp_chksum(iph,tcph));
printf("TCP END\n");
//printf("tcp after %d\n",(tcph->check));
//printf("i == %d\n",i);
//POSSIBLY PRINT IPH for fun
//for(int a=0;a<recvlen;a )
//printf("%x\n",buf[a]);
//GET ihl SEND -- tcp
int j=(ip->ihl*4);
//printf("j == %d\n",j);
int x=0;
//SEEK filling
struct tcphdr *tcp=(struct tcphdr *)(buf_1 20);
//populate_tcp_some(tcph,tcp);//Do LOOK AT THIS FUNCTION TO [SEE/CORRECT IT] >:)
seq ;
if(tcph->syn==1)
{
printf("WHAT THE HELL THEN WHY\n");
printf("syn\n");
//populate_tcp_some(tcph,tcp);
tcp->seq=htons(seq);
//tcp->ack_seq=htons(ntohs(tcph->seq) 1);
printf("seq = %d | ack_seq = %d\n",ntohs(tcph->seq),ntohs(tcp->ack_seq));
tcp->syn=1;
tcp->ack=1;
tcp->res1=0;
tcp->res1=0;
tcp->urg=0;
tcp->psh=0;
tcp->fin=0;
tcp->doff=5;
tcp->source=htons(80);
tcp->dest=tcph->source;
tcp->ack_seq=htons(ntohs(tcph->seq) 1);//htons(ntohs(tcph->seq) 1);
// printf("received tcp syn = %d\n",tcph->syn);
}
else if(tcph->syn==0 && tcph->ack==1){
printf("WHAT THE HELL THEN COOL\n");
printf("syn\n");
// populate_tcp_some(tcph,tcp);
//tcp->seq=htons(1);
tcp->seq=htons(seq);
tcp->ack_seq=tcph->seq;
tcp->syn=0;
tcp->ack=1;
tcp->res1=0;
tcp->res1=0;
tcp->urg=0;
tcp->psh=0;
tcp->fin=0;
tcp->doff=5;
tcp->source=htons(80);
tcp->dest=tcph->source;
//tcp->ack_seq=tcph->seq;//htons(ntohs(tcph->seq) 1);
tcp->ack_seq=htons(ntohs(tcph->seq) 1);
}
else
{
populate_tcp_some(tcph,tcp);
tcp->syn=0;
tcp->ack=1;
//tcp->seq=htons(1);
tcp->seq=htons(seq);
tcp->res1=0;
tcp->res1=0;
tcp->urg=0;
tcp->psh=0;
tcp->fin=0;
tcp->doff=5;
tcp->source=htons(80);
tcp->dest=tcph->source;
tcp->ack_seq=htons(ntohs(tcph->seq) 1);//tcp->ack_seq=tcph->seq;//htons(ntohs(tcph->seq) 1);
// printf("sending tcp syn = %d ack = %d\n",tcp->syn,tcp->ack);
}
printf("syn=%d | ack = %d | fin = %d | %d seq = %d ack_seq = %d | urg = %d | doff = %d | psh = %d rst = %d | rst2 = %d\n",tcp->syn,tcp->ack,tcp->fin,tcp->seq,tcp->ack_seq,tcp->urg,tcp->doff,tcp->psh,tcp->res1,tcp->res2);
//populate_tcp_some(tcph,tcp);
tcp->dest=tcph->source;
tcp->window=tcph->window;
//
//printf("%d %d SOURCE PORT \n",ntohs(tcph->source),ntohs(tcp->dest));
tcp->source=htons(80);
printf("%d %d PORTS \n",ntohs(tcp->source),ntohs(tcp->dest));
tcp->check=0;
//TCP CHECKSUM ABOUT TRIPPLE WOW
tcp->check=htons(tcp_chksum(ip,tcp));
//printf("tcpH = %d | tcp = %d\n",tcph->check,htons(tcp->check));
//IF needed make payload data
//WRITE
if (recvlen > 0)
{
printf("\n-WOW WOW WOW received seq = %d ack == %d",ntohs(tcph->seq),ntohs(tcp->ack_seq));
writelen = write(_tun_fd, buf_1, sizeof(struct iphdr) sizeof(struct tcphdr));
//exit(0);
// sleep(2);
//debug("SR:d\n", recvlen);
//debug("TW:d\n", writelen);
if (writelen < 0)
{
//debug("%s: rwrite() %s [%d]\n", _progname, strerror(errno), errno);
//break;//NO NEED
}
}
else if (recvlen < 0)
{
//debug("%s: rrecvfrom() %s\n", _progname, strerror(errno));
//break;//NO NEED
}
else if (recvlen == 0)
{
//why
}
//FINALLY THEN SEND || DO WIRE SHARK
}
// ...:)__ :) __:) ___:)___ (: __(:__ (;...
}
debug("** Receiver ending.\n");
pthread_exit(NULL);
}
更新
現在我的 ACK SYN 資料包沒有捕獲到 TCP 最后一個段
這是收到的SYN
0000 45 00 00 3c c5 18 40 00 40 06 e0 2f c0 a8 0a 14
0010 c0 a8 0a 0f bc b2 00 50 f0 32 1f de 00 00 00 00
0020 a0 02 fa f0 c6 93 00 00 02 04 05 b4 04 02 08 0a
0030 95 a6 8e 4d 00 00 00 00 01 03 03 07
這是 SYN ACK
0000 45 00 00 28 00 64 40 00 40 06 a4 f8 c0 a8 0a 0f
0010 c0 a8 0a 14 00 50 bc b2 86 e8 00 00 f0 32 1f df
0020 50 12 fa f0 cb 70 00 00
這是 SYN AGAIN
0000 45 00 00 3c c5 19 40 00 40 06 e0 2e c0 a8 0a 14
0010 c0 a8 0a 0f bc b2 00 50 f0 32 1f de 00 00 00 00
0020 a0 02 fa f0 c2 9c 00 00 02 04 05 b4 04 02 08 0a
0030 95 a6 92 44 00 00 00 00 01 03 03 07
在這個資料包的行中再次 SYN 我得到訊息最后一段未捕獲
0000 45 00 00 28 00 64 40 00 40 06 a4 f8 c0 a8 0a 0f
0010 c0 a8 0a 14 00 50 bc b2 86 e9 00 00 f0 32 1f df
0020 50 12 fa f0 cb 6f 00 00
這是我更新2本
同步
0000 45 00 00 3c 9f 75 40 00 40 06 05 d3 c0 a8 0a 14
0010 c0 a8 0a 0f bc b8 00 50 55 a8 f4 2c 00 00 00 00
0020 a0 02 fa f0 83 25 00 00 02 04 05 b4 04 02 08 0a
0030 96 60 97 37 00 00 00 00 01 03 03 07
同步 確認
0000 45 00 00 28 00 64 40 00 40 06 a4 f8 c0 a8 0a 0f
0010 c0 a8 0a 14 00 50 bc b8 00 00 00 03 55 a8 f4 2d
0020 50 12 fa f0 18 8c 00 00
這是SYN agian retramit
0000 45 00 00 3c 9f 76 40 00 40 06 05 d2 c0 a8 0a 14
0010 c0 a8 0a 0f bc b8 00 50 55 a8 f4 2c 00 00 00 00
0020 a0 02 fa f0 7f 38 00 00 02 04 05 b4 04 02 08 0a
0030 96 60 9b 24 00 00 00 00 01 03 03 07
uj5u.com熱心網友回復:
序列號和確認號是 32 位值:
因此這一行:
tcp->ack_seq=htons(ntohs(tcph->seq) 1);//htons(ntohs(tcph->seq) 1);
正在使用 htons/ntohs,它們是交換 16 位整數位元組的函式。您需要更改它才能使用htonl和ntohl
那可能不是您唯一的錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/400315.html
