<질문>raw socket을 활용한 3way handshake
글쓴이: interestdream / 작성시간: 화, 2013/02/19 - 3:59오후
안녕하세요!
제가 지금 raw socket을 사용해서 서버와 connection을 맺으려고 합니다.
지금까지 여기저기서 주워온 코드로 일단 syn, syn/ack을 주고 받고 까지는 했는데...
그 다음으로 제가 서버로 ack를 보내야하는데...
실력이 너무 하수라... 어느부분에 어떤 형식으로 코딩을 해야할지 모르겠더라고요...
구글과 싸우다가 너무 힘들어서... 지원요청합니다 ㅠ
고수님들 좋은 답변들 부탁드립니다!
*아래 코드는 해커스스쿨에서 참조한 내용입니다.
// 체크섬 루틴이 추가된 raw_socket.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <arpa/inet.h> #include <netinet/in.h> #include <linux/ip.h> #include <linux/tcp.h> // 체크섬을 구하는 함수 선언/정의. unsigned short in_cksum(u_short *addr, int len) { int sum=0; int nleft=len; u_short *w=addr; u_short answer=0; while (nleft > 1){ sum += *w++; nleft -= 2; } if (nleft == 1){ *(u_char *)(&answer) = *(u_char *)w ; sum += answer; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = ~sum; return(answer); } // 가상 헤더 구조체 선언 struct pseudohdr { u_int32_t saddr; u_int32_t daddr; u_int8_t useless; u_int8_t protocol; u_int16_t tcplength; }; int main() { unsigned char packet[40]; int raw_socket; int on = 1 ; struct iphdr *iphdr; struct tcphdr *tcphdr; // 주소 정보를 담을 변수. 매번 IP를 적기 귀찮으니 변수로 사용합니다. struct in_addr source_address, dest_address; struct sockaddr_in address; // 가상 헤더의 구조체 변수. struct pseudohdr *pseudo_header; source_address.s_addr = inet_addr( "115.145.179.46" ); dest_address.s_addr = inet_addr( "222.122.134.138" ); raw_socket = socket( AF_INET, SOCK_RAW, IPPROTO_RAW ); setsockopt( raw_socket, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)); iphdr = (struct iphdr *)packet; memset( (char *)iphdr, 0, 20 ); tcphdr = (struct tcphdr *)(packet + 20 ); memset( (char *)tcphdr, 0, 20 ); tcphdr->source = htons( 60861 ); tcphdr->dest = htons( 80 ); tcphdr->seq = htonl( 0 ); tcphdr->ack_seq = htonl( 0 ); tcphdr->doff = 5; tcphdr->syn = 1; tcphdr->window = htons( 5840 ); // 가상 헤더 생성. pseudo_header = (struct pseudohdr *)((char*)tcphdr-sizeof(struct pseudohdr)); pseudo_header->saddr = source_address.s_addr; pseudo_header->daddr = dest_address.s_addr; pseudo_header->protocol = IPPROTO_TCP; pseudo_header->tcplength = htons( sizeof(struct tcphdr) ); // TCP 체크섬 계산. tcphdr->check = in_cksum( (u_short *)pseudo_header, sizeof(struct pseudohdr) + sizeof(struct tcphdr) ); iphdr->version = 4; iphdr->ihl = 5; iphdr->protocol = IPPROTO_TCP; iphdr->tot_len = 40; iphdr->id = htons( 65139 ); iphdr->ttl = 64; iphdr->saddr = source_address.s_addr; iphdr->daddr = dest_address.s_addr; // IP 체크섬 계산. iphdr->check = in_cksum( (u_short *)iphdr, sizeof(struct iphdr)); address.sin_family = AF_INET; address.sin_port = htons( 80 ); address.sin_addr.s_addr = dest_address.s_addr; sendto( raw_socket, &packet, sizeof(packet), 0x0, (struct sockaddr *)&address, sizeof(address)); }
Forums:
글쓰고 보니까 이상하네요... 여기 제 글 수정할 수 없나요..?
글쓰고 보니 이상하네요 ... syn/ack을 받고 ack를 제가 보낸다니...
ack를 보내는게 아니라 ack를 보낼 차례인데 rst를 보내게 되서 연결이 끊어지게 되네요...
이 부분을 수정해야겠는데... 도무지 이유를 몰라서 올린 글입니다...ㅠ
어떻게 해야하는지 조언 좀 부탁드립니다~
제발.. 이거에 대한 답변좀 달아주세요
ㅜㅜ
댓글 달기