내 코드가 실행될 때 wireshark와 함께 tcp 프로토콜의 3 방향 핸드 셰이크를 C++로 시뮬레이트합니다. 내 코드는 ip와 tcp 레이어에서 헤더를 만들고, 포장 한 다음 TCP 헤더의 SYN 플래그가 1로 설정된 http 서버로 보냅니다.원시 소켓을 사용하여 TCP 프로토콜 3 방향 핸드 셰이크를 올바르게 재현하는 방법은 무엇입니까?
ip와 tcp 헤더가있는 전체 데이터 그램을 wireshark에서 볼 수 있습니다. . 오류가없는 것 같습니다. 내 프로세스는 이미 보낸 패킷의 헤더에 포함 된 것과 동일한 주소와 포트로 소켓을 바인딩합니다.
Wireshark는 패킷이 성공적으로 전송되었음을 나타내지 만 서버에서 내 SYN을 확인하는 수입 패킷이 없습니다. 내가 뭘 잘못 했니?
저는 우분투 10.10, 2.6.35-23입니다.
코드가 엉망입니다. 죄송합니다. 테스트 용입니다.
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);
//이 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;
코드가 어떻게 보이는지 또는 패킷이 전송하는지 추측해야합니까? – Gabe
코드없이 야생의 추측 : ip 또는 포트에 엔디안 불일치가 있습니까? –
보내는 패킷의 디코딩 된 Wireshark 덤프를 게시합니다. – NPE