raw socket으로 패킷을 만들었는데 전송이 안되네요.
글쓴이: uddum / 작성시간: 월, 2008/11/17 - 1:07오후
3 #include <stdio.h> 4 #include <sys/socket.h> 5 #include <netinet/in.h> //for IPPROTO_RAW 6 #include <string.h> //for memset 7 8 #include "packet.h" 9 #include "error.h" 10 #include "chksum.h" 11 12 #define PACKETSIZE 40 13 14 int main(void) 15 { 16 int sockdesc; 17 struct iphdr * ipheader; //ipheader 18 struct tcphdr * tcpheader; //tcpheader 19 unsigned char packet[PACKETSIZE]; 20 int on = 1; 21 int i = 0; 22 int sock_option; 23 struct sockaddr_in address; 24 struct pseudohdr *pseudoheader; 25 //Create 'RAW socket' 26 sockdesc = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW); 27 sock_option = setsockopt(sockdesc, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)); 28 29 if (sockdesc < 0) 30 { 31 displayError(socketError); 32 } 33 34 if (setsockopt < 0) 35 { 36 displayError(socketoptionError); 37 } 38 39 ipheader = (struct iphdr *)packet; 40 tcpheader = (struct tcphdr *)(packet + 20); 41 42 memset(ipheader, 0, sizeof(struct iphdr)); 43 memset(tcpheader, 0, sizeof(struct tcphdr)); 44 45 ipheader->version = 4; //ip version 46 ipheader->ihl = 5; 47 ipheader->tos = 0x0; 48 ipheader->tot_len = 40; 49 ipheader->id = htons(777); 50 ipheader->ttl = 60; 51 ipheader->saddr = inet_addr("111.111.111.111"); 52 ipheader->daddr = inet_addr("222.222.222.222"); 53 ipheader->check = chksum((u_short *)ipheader, sizeof(struct iphdr)); 54 55 //pseudoheader = tcpheader - sizeof(struct pseudohdr); 56 pseudoheader = (struct pseudohdr *)((char *)tcpheader - sizeof(struct pseudohdr)); 57 pseudoheader->saddr = inet_addr("111.111.111.111"); 58 pseudoheader->daddr = inet_addr("222.222.222.222"); 59 pseudoheader->protocol = IPPROTO_TCP; 60 pseudoheader->tcplength = htons(sizeof(struct tcphdr)); 61 62 tcpheader->source = htons(11777); 63 tcpheader->dest = htons(800); 64 tcpheader->seq = htonl(123455); 65 tcpheader->ack_seq = htonl(123411); 66 tcpheader->doff = 5; 67 tcpheader->syn = 1; 68 tcpheader->window = htons(512); 69 tcpheader->check = chksum((u_short *)pseudoheader, sizeof(struct pseudohdr) + sizeof(struct tcphdr)); 70 71 address.sin_family = AF_INET; 72 address.sin_port = htons(800); 73 address.sin_addr.s_addr = inet_addr("222.222.222.222"); 74 75 while (i < 5) 76 { 77 //write(sockdesc, packet, PACKETSIZE); 78 sendto(sockdesc, &packet, sizeof(packet), 0,(struct sockaddr *)&address, sizeof(address)); 79 i++; 80 } 81 82 close(sockdesc); 83 return 0; 84 }
raw소켓을 이용해서 발신자주소가 111.111.111.111 도착지주소가 222.222.222.222로 만들어진 패킷을 5번 보내는 소스입니다.
vmware로 커널 2.6, 우분투, ISP업체로부터 private IP를 받아서 쓰고있고 패킷스니퍼로는 WireShark와 Tcpdump두개를 썼습니다.
1. 컴파일을 하고 실행(당연히 root로 했습니다)을 해도 패킷이 나가질 않네요. 실행을 시킬때마다 패킷이 5개가 나갑니다만 제가 만든 패킷은 아니더군요. 물론 도착지에서도 확인이 안됩니다. 제가 가지고 있는 정상적인 서버의 주소로 도착주소를 바꿔도 확인이 안되네요.
체크섬이 잘못됬다고 하더라도 나가는것은 확인이 되야하는데 그렇지도 않습니다. gdb로 packet의 값을 확인해봤는데 차근차근 잘 들어갔더군요. 도데체 뭐가 문제인지.. 제가 뭔가 놓치고 있는게 있는건가요?
2. 많은 패킷발생소스를 찾아보니 마지막 패킷을 전송할때는 struct sockaddr_in에 다시 주소를 넣어서 sendto를 쓰더군요. 하지만 패킷을 만들때 발신지주소와 수신지주소를 다 써넣어줬는데 구지 다시 struct sockaddr_in을 만들어서 sendto를 쓸 필요가 있나요? 그냥 write를 써서 보내버리면 안되는건가요?
읽어주셔서 감사합니다. 도움의 손길을 ㅠ_ㅠ
Forums:
댓글 달기