2012-10-09 45 views
0

幾天前,我寫了一篇關於從sendto()返回的錯誤的帖子。 它返回我0字節書面強硬我傳遞一個非空值作爲長度。Sendto()仍然返回我0字節發送

void caught_packet(u_char *user_args,const struct pcap_pkthdr *cap_header,const u_char *packet){ 
    int bcount,sockfd; //Bytes written and Socket Descriptor 
    char new_packet[sizeof(struct ip_hdr) + sizeof(struct tcp_hdr)]; //New Packet 
    struct ip_hdr *iphdr; //IP Header 
    struct tcp_hdr *tcphdr; //TCP Header 
    struct ip_hdr *iphdr_new; //New IP Header 
    struct tcp_hdr *tcphdr_new; //New TCP Header 
    struct sockaddr_in sin; //sockaddr_in 
    u_long src_ip,dest_ip; //source ip,dest ip 
    int src_port,dest_port; //source port,dest port 

    //Initialize New_Packer 
    memset(new_packet,0,(sizeof(struct ip_hdr) + sizeof(struct tcp_hdr))); 

    //Assign to sockfd argument passed by callback function 
    sockfd = *((int *)user_args); 

    //Assign old header to iphdr and tcphdr 
    iphdr = (struct ip_hdr *)(packet + sizeof(struct ether_header)); 
    tcphdr = (struct tcp_hdr *)(packet + sizeof(struct ether_header) + sizeof(struct ip_hdr)); 

    //Assign new header to buffer new_packet converting its address in structs 
    iphdr_new = (struct ip_hdr *) new_packet; 
    tcphdr_new = (struct tcp_hdr *) (new_packet + sizeof(struct ip_hdr)); 
    src_ip = ntohl(iphdr -> ip_src_addr); 
    dest_ip = ntohl(iphdr -> ip_dest_addr); 
    src_port = ntohs(tcphdr -> tcp_src_port); 
    dest_port = ntohs(tcphdr -> tcp_dest_port); 
    sin.sin_family = AF_INET; 

    //pretends to be source port 
    sin.sin_port = htons(src_port); 

    //pretends to be source address 
    sin.sin_addr.s_addr = inet_addr(inet_ntoa(*((struct in_addr *)&src_ip))); 

    //Filling up new_iphdr 
    //TOS 
    iphdr_new->ip_tos = IPTOS_LOWDELAY; 
    //TOT_LEN 
    iphdr_new->ip_len = sizeof(struct ip_hdr)+sizeof(struct tcp_hdr); 
    //ID 
    iphdr_new->ip_id = htons((u_int16_t)random_number(3)); 
    //FRAG_OFF 
    iphdr_new->ip_frag_offset = htons((u_int16_t)random_number(3)); 
    //TTL 
    iphdr_new->ip_ttl = IPDEFTTL; 
    //PROTOCOL 
    iphdr_new->ip_type = IPPROTO_TCP; 
    //Source address (Dest) <--> 
    iphdr_new->ip_src_addr = htonl(dest_ip); 
    //Destination address (Source) <--> 
    iphdr_new->ip_dest_addr = htonl(src_ip); 

    //Filling up new_tcphdr 
    //Source port (Dest) <--> 
    tcphdr_new->tcp_src_port = htons(dest_port); 
    //Destination port (Source) <--> 
    tcphdr_new->tcp_dest_port = htons(src_port); 
    //SEQ (ACK) <--> 
    tcphdr_new->tcp_seq = tcphdr->tcp_ack; 
    //ACK (SEQ) <--> 
    tcphdr_new->tcp_ack = (tcphdr->tcp_seq + 1) ; 
    //Flags 
    tcphdr_new->tcp_flags = TCP_SYN|TCP_ACK; 
    //Window Size 
    tcphdr_new->tcp_window = htons((u_int16_t)random_number(3)); 
    //Checksum (Done by Kernel) 
    tcphdr_new->tcp_checksum = 0; 
    //Urgent Pointer 
    tcphdr_new->tcp_urgent = 0; 
    //CheckSum Ip header 
    iphdr_new->ip_checksum = csum((unsigned short *)new_packet,sizeof(struct ip_hdr) + sizeof(struct tcp_hdr)); 

    //Deliver packet to destination 
    if(bcount = sendto (sockfd,new_packet,iphdr_new->ip_len,0,(struct sockaddr *)&sin,sizeof(sin))<0) 
     printf("Couldn't send RESET Packet\n"); 
    else{ 
     printf("Bing! "); 
     printf("(%d) bytes sent \n",bcount); 
    } 
} 

這是我的代碼。 ip_hdr和tcp_hdr結構是我的一個簡單的ip和tcp頭結構。 這很奇怪,它一直在其他軟件中工作。 請幫幫我。

+0

究竟是什麼打印? 「(0)字節發送」? – CrazyCasta

+2

你爲什麼要製作自己的TCP數據包,而不是用'connect(2)'建立連接並用'send(2)'發送? –

+0

編輯標題 – REmaxer

回答

4

你忘了括號:

if((bcount = sendto (sockfd,new_packet,iphdr_new->ip_len,0,(struct sockaddr *)&sin,sizeof(sin))<0)) 

因爲賦值運算符(=)具有比較小的比運算符(<),爲'

表達

if (bcount = sendto(..) < 0) 

等於優先級低

if (bcount = (sendto(..) < 0)) 

並且由於大於零的字節小號被送往,它等於

if (bcount = 0) 
2

bcount = sendto (sockfd,new_packet,iphdr_new->ip_len,0,(struct sockaddr *)&sin,sizeof(sin))<0

問題是由運算符優先級引起的,你需要括號。

(bcount = sendto (sockfd,new_packet,iphdr_new->ip_len,0,(struct sockaddr *)&sin,sizeof(sin))) < 0

相關問題