2015-04-26 100 views
0

我正在向同一網絡中的網絡服務器發送TCP SYN數據包(無負載)。我正在使用sniffex.c 捕獲數據包。使用RAW套接字發送SYN後未收到SYN/ACK

問題是,我發送一個SYN數據包後,我沒有收到來自服務器的SYN/ACK數據包。

在sniffex.c: 我用我的LAN IP作爲源IP。 我已將過濾器設置爲「tcp」。 我發送到端口80

當我打印發送的數據包的字段後,我使用sniffex捕獲它,所有字段打印正確,因此我假設發送數據包的結構是這樣的服務器可以明白它。

當我使用瀏覽器連接到網絡服務器時,成功接收到SYN/ACK。

另一個相關查詢:我怎麼設置過濾器,這樣我得到有關這次談話的數據包(B/W我的電腦和網絡服務器)僅

我使用Ubuntu 14.04

編輯: C文件與我試圖發送數據包

#define __USE_BSD /* use bsd'ish ip header */ 
#include <sys/socket.h> /* these headers are for a Linux system, but */ 
#include <netinet/in.h> /* the names on other systems are easy to guess.. */ 
#include <netinet/ip.h> 
#define __FAVOR_BSD /* use bsd'ish tcp header */ 
#include <netinet/tcp.h> 
#include <unistd.h> 
#include<stdio.h> 
#include<stdlib.h> 
#include<memory.h> 
#include<errno.h> 
#include<sys/socket.h> 
#include<sys/types.h> 

#define P 80  /* lets flood the sendmail port */ 

unsigned short  /* this function generates header checksums */ 
csum (unsigned short *buf, int nwords) 
{ 
    unsigned long sum; 
    for (sum = 0; nwords > 0; nwords--) 
    sum += *buf++; 
    sum = (sum >> 16) + (sum & 0xffff); 
    sum += (sum >> 16); 
    return ~sum; 
} 

int 
main (void) 
{ 
    int s = socket (AF_INET, SOCK_RAW, IPPROTO_TCP); 
    printf("s=%d\n",s); /* open raw socket */ 
    char datagram[4096]; /* this buffer will contain ip header, tcp header, 
       and payload. we'll point an ip header structure 
       at its beginning, and a tcp header structure after 
       that to write the header values into it */ 
    struct ip *iph = (struct ip *) datagram; 
    struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof (struct ip)); 
    struct sockaddr_in sin; 
      /* the sockaddr_in containing the dest. address is used 
       in sendto() to determine the datagrams path */ 

    sin.sin_family = AF_INET; 
    sin.sin_port = htons (P);/* you byte-order >1byte header values to network 
        byte order (not needed on big endian machines) */ 
    sin.sin_addr.s_addr = inet_addr ("xxx.xxx.xxx.xxx"); 

    memset (datagram, 0, 4096); /* zero out the buffer */ 

/* we'll now fill in the ip/tcp header values, see above for explanations */ 
    iph->ip_hl = 5; 
    iph->ip_v = 4; 
    iph->ip_tos = 0; 
    iph->ip_len = sizeof (struct ip) + sizeof (struct tcphdr); /* no payload */ 
    iph->ip_id = htonl (54321); /* the value doesn't matter here */ 
    iph->ip_off = 0; 
    iph->ip_ttl = 255; 
    iph->ip_p = 6; 
    iph->ip_sum = 0;  /* set it to 0 before computing the actual checksum later */ 
    iph->ip_src.s_addr = inet_addr ("xxx.xxx.xxx.xxx");/* SYN's can be blindly spoofed */ 
    iph->ip_dst.s_addr = sin.sin_addr.s_addr; 
    tcph->th_sport = htons (2000); /* arbitrary port */ 
    tcph->th_dport = htons (P); 
    tcph->th_seq = random();/* in a SYN packet, the sequence is a random */ 
    tcph->th_ack = 0;/* number, and the ack sequence is 0 in the 1st packet */ 
    tcph->th_x2 = 5; 
    tcph->th_off = 5;  /* first and only tcp segment */ 
    tcph->th_flags = TH_SYN; /* initial connection request */ 
    tcph->th_win = htonl (65535); /* maximum allowed window size */ 
    tcph->th_sum = 0;/* if you set a checksum to zero, your kernel's IP stack 
       should fill in the correct checksum during transmission */ 
    tcph->th_urp = 0; 

    iph->ip_sum = csum ((unsigned short *) datagram, iph->ip_len >> 1); 

/* finally, it is very advisable to do a IP_HDRINCL call, to make sure 
    that the kernel knows the header is included in the data, and doesn't 
    insert its own header into the packet before our data */ 

       /* lets do it the ugly way.. */ 
    int one = 1; 
    // const int *val = &one; 
    if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, &one, sizeof (one)) < 0) 
     printf ("Warning: Cannot set HDRINCL!\terrno = %d\n",errno); 




// while (1) 
    // { 
     if (sendto (s,  /* our socket */ 
      datagram, /* the buffer containing headers and data */ 
      iph->ip_len, /* total length of our datagram */ 
      0,  /* routing flags, normally always 0 */ 
      (struct sockaddr *) &sin, /* socket addr, just like in */ 
      sizeof (sin)) < 0)  /* a normal send() */ 
    printf ("error\n"); 
     else 
    printf ("SUCCESS\n\n\n\n"); 
    //} 
char buffer[8192]; 
memset (buffer, 0, 8192); 
int n; 
//while(n=read (s, buffer, 8192) > 0) 
//{ 
//printf("n=%d\n",n); 

//printf ("Caught tcp packet: %s\n", buffer); 
//memset (buffer, 0, 8192); 
//} 

    return 0; 
} 
+0

您的第一步應該是使用wireshark或tcpdump等其他程序來檢查(1)您的數據包是否實際上正在連線,以及(2)是否實際發送回覆。然後你應該顯示你的實際代碼。 –

+0

@JohnHascall我這樣做只是知道,並不能在wireshark中找到該數據包。但sniffex能夠捕獲數據包並正確顯示所有字段。請再次看看問題,我已添加了發送數據包的c文件。 – jps

+0

如果sniffex捕獲了我發送的數據包,它不能確保數據包擊中電線? – jps

回答

相關問題