<질문>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를 보내게 되서 연결이 끊어지게 되네요...
이 부분을 수정해야겠는데... 도무지 이유를 몰라서 올린 글입니다...ㅠ
어떻게 해야하는지 조언 좀 부탁드립니다~
제발.. 이거에 대한 답변좀 달아주세요
ㅜㅜ
댓글 달기