2010-12-14 2 views
2

Im simulant la prise de contact à 3 voies du protocole tcp en C++, avec wireshark comme mon code s'exécute. Mon code crée les en-têtes des couches ip et tcp, les emballe et les envoie à un serveur http avec l'indicateur SYN de l'en-tête tcp défini sur 1.Comment reproduire correctement le protocole TCP Prise de contact à 3 voies avec des sockets raw?

Je peux voir sur wireshark le datagramme complet avec les en-têtes ip et tcp ok . Semble être pas d'erreurs. Mon processus lie un socket avec la même adresse et le même port que ceux contenus dans l'en-tête du paquet déjà envoyé. Wireshark montre que le paquet a été envoyé avec succès mais qu'il n'y a pas de paquet de revenu provenant du serveur accusant réception de mon SYN. Qu'est-ce que je fais de mal? J'ai sous Ubuntu 10.10, 2.6.35-23.

Le code est désordonné, désolé pour cela. C'est juste pour tester.

main.cpp:

char host[100],buf[1000],*data=NULL,source_ip[20]; //buf is the complete packet 
sockaddr_in dest; 
hostent *server; 
IPV4_HDR *v4hdr=NULL; 
TCP_HDR *tcphdr=NULL; 
memset(&buf, 0, sizeof(buf)); 

cout << "Creating RAW socket..." << endl; 
int s; 
if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) == -1) { 
    cout << "Error creating socket: " << errno << endl; 
    return 1; 
} 

cout << "Setting the socket in RAW mode..." << endl; 
int optval = 1; 
if ((setsockopt(s, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(optval))) == -1) { 
    cout << "Failed to set socket in RAW mode..." << endl; 
    return 1; 
} 
cout << "Successful.\n"; 

cout << "nResolving Hostname..." << endl; 
if((server=gethostbyname("www.site.com"))==0) 
{ 
    cout << "Unable to resolve." << endl; 
    return 1; 
} 
dest.sin_family = AF_INET; 
dest.sin_port = htons(50000); 
memcpy(&dest.sin_addr.s_addr,server->h_addr,server->h_length); 
cout << "Resolved." << endl; 

v4hdr = (IPV4_HDR *)buf; //lets point to the ip header portion 
v4hdr->ip_version=4; 
v4hdr->ip_header_len=5; 
v4hdr->ip_tos = 16; 
v4hdr->ip_total_length = htons (sizeof(IPV4_HDR) + sizeof(TCP_HDR)); 
v4hdr->ip_id = htons(2); 
v4hdr->ip_frag_offset = 0; 
v4hdr->ip_frag_offset1 = 0; 
v4hdr->ip_reserved_zero = 0; 
v4hdr->ip_dont_fragment = 1; 
v4hdr->ip_more_fragment = 0; 
v4hdr->ip_ttl = 64; 
v4hdr->ip_protocol = IPPROTO_TCP; 
v4hdr->ip_srcaddr = inet_addr("192.168.0.103"); 
v4hdr->ip_destaddr = inet_addr(inet_ntoa(dest.sin_addr)); 
v4hdr->ip_checksum = 0; 

tcphdr = (TCP_HDR *)&buf[sizeof(IPV4_HDR)]; //get the pointer to the tcp header in the packet 

tcphdr->source_port = htons(52000); 
tcphdr->dest_port = htons(80); 
tcphdr->window = htons(5840); 
tcphdr->acknowledge = 0; 
tcphdr->data_offset = 8; 
tcphdr->urg=0; 
tcphdr->ack=0; 
tcphdr->psh=0; 
tcphdr->rst=0; 
tcphdr->syn=1; 
tcphdr->fin=0; 
tcphdr->options1=htonl(0x020405b4); 
tcphdr->options2=htonl(0x04020103); 
tcphdr->options3=htonl(0x03060000); 

cout << sizeof(*tcphdr) << endl; 

//tcphdr->ns=0; 

tcphdr->checksum = csum((unsigned short *) buf, (sizeof(ip_hdr) + sizeof(tcp_header)));; 
int bytes = 0; 
if((bytes = sendto(s , buf , sizeof(IPV4_HDR)+sizeof(TCP_HDR), 0, 
(sockaddr *)&dest, sizeof(dest)))==-1) 
{ 
    cout << "Error sending packet: " << errno << endl; 
    return 1; 
} 
cout << bytes << " bytes sent!" << endl; 
close(s); 

// C'est tcp.h ...

typedef struct ip_hdr 
{ 
unsigned char ip_header_len:4; // 4-bit header length (in 32-bit words) 

           // normally=5 (Means 20 Bytes may be 24 also) 

unsigned char ip_version :4; // 4-bit IPv4 version 

unsigned char ip_tos;   // IP type of service 

unsigned short ip_total_length; // Total length 

unsigned short ip_id;   // Unique identifier 


unsigned char ip_frag_offset :5; // Fragment offset field 


unsigned char ip_more_fragment :1; 
unsigned char ip_dont_fragment :1; 
unsigned char ip_reserved_zero :1; 

unsigned char ip_frag_offset1; //fragment offset 


unsigned char ip_ttl;   // Time to live 

unsigned char ip_protocol;  // Protocol(TCP,UDP etc) 

unsigned short ip_checksum; // IP checksum 

unsigned int ip_srcaddr;  // Source address 

unsigned int ip_destaddr;  // Source address 

} IPV4_HDR; 


// TCP header 

typedef struct tcp_header 
{ 
unsigned short source_port; // source port 

unsigned short dest_port;  // destination port 

unsigned int sequence;  // sequence number - 32 bits 

unsigned int acknowledge;  // acknowledgement number - 32 bits 

unsigned char reserved_part1:4; //according to rfc 
unsigned char data_offset:4; /*The number of 32-bit words 
            in the TCP header. 
            This indicates where the data begins. 
            The length of the TCP header 
            is always a multiple 
            of 32 bits.*/ 

unsigned char fin :1; //Finish Flag 

unsigned char syn :1; //Synchronise Flag 

unsigned char rst :1; //Reset Flag 

unsigned char psh :1; //Push Flag 

unsigned char ack :1; //Acknowledgement Flag 

unsigned char urg :1; //Urgent Flag 

unsigned char reserved_part2:2; 

unsigned short window :16; // window 




//unsigned char ns :1;   //Nonce Sum Flag Added in RFC 3540. 

//unsigned char ecn :1; //ECN-Echo Flag 

//unsigned char cwr :1; //Congestion Window Reduced Flag 


//////////////////////////////// 


unsigned short checksum; // checksum 

unsigned short urgent_pointer; // urgent pointer 

unsigned int options1; 
unsigned int options2; 
unsigned int options3; 

} TCP_HDR; 
+4

Sommes-nous censés deviner à quoi ressemble votre code ou les paquets qu'il envoie? – Gabe

+0

Sans code, une conjecture sauvage: Y a-t-il une discordance d'endian dans l'IP ou le port? –

+0

Publiez le fichier Wireshark décodé du paquet que vous avez envoyé. – NPE

Répondre

3

Vous n'êtes pas encore arrivé jusqu'ici, mais vous aurez besoin de pare-feu local port que vous utilisez pour que le noyau ne réponde pas à SYN/ACK avec un RST.

+0

N'avez pas eu là, mais je vous remercie pour le point. – kaneda

+1

@Joshua Comment exactement nous pouvons définir cette règle? – Reflection

Questions connexes