2015-04-26 93 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

回答

相关问题