2011-08-09 2 views
1

c에서 패킷을 생성하는 방법을 알고 싶습니다.패킷 생성

struct ipheader { 
    int version; 
    int hdLen; 
    int tos; 
    int totLen; 
    int id; 
    ...... 
    int dstIp; 
} 

을 그리고 우리가 ipheader 유형이 있습니다 : 나는 "IP"에서 (단지 IP 헤더 부분) 패킷을 생성 할 수있는 방법

struct ipheader ip; 

//init the ip 
..... 

을 다음과 같이 우리가 유형이되어. 아무도 어떻게 보여줄 수 있습니까?

맥 주소, ip 헤더, tcp 헤더, 페이로드와 같은 정보로 패킷을 생성하고 싶습니다. 그런 다음 "pcap_sendpacket"함수를 사용하여 내가 생성 한 패킷을 보낼 수 있습니다. 누군가가 나에게 약간의 모범을 줄 수 있었 을까?

+1

"패킷 생성?" 이런 맥락에서 심지어 그 의미는 무엇입니까? – cdhowie

+0

필드의 길이를 올바르게 지정하지 않습니다 ... –

답변

2

아래와 같이 사용자 정의 IP 패킷을 생성 할 수 있습니다. 아래 코드 스 니펫은 ip 패킷 내부에있는 사용자 정의 TCP 부분도 만듭니다. 또한 사용자 정의 함수 체크섬은 패킷의 체크섬을 생성합니다. rawsocket을 사용하여이 패킷을 네트워크에 직접 보낼 수 있습니다. 코드는 쉽고 자명합니다. 문의 사항이 있으면 알려주십시오.

#include <netinet/ip.h> 
#include <netinet/tcp.h> 


**************************************** 
ipv4 packet structure 
**************************************** 
struct ipv4_packet { 
    struct iphdr iph; 
    struct tcphdr tcph; 
    void *data; 
}; 


**************************************** 
snippet of the IPV4 packet making code 
**************************************** 
struct iphdr ip_head; 
struct tcphdr tcp_head; 
struct sockaddr_in target; 
char packet[2048]; 
int i; 

struct tcp_pseudo /*the tcp pseudo header*/ 
{ 
    __u32 src_addr; 
    __u32 dst_addr; 
    __u8 dummy; 
    __u8 proto; 
    __u16 length; 
} pseudohead; 

struct help_checksum /*struct for checksum calculation*/ 
{ 
    struct tcp_pseudo pshd; 
    struct tcphdr tcphd; 
    char tcpdata[1024]; 
} tcp_chk_construct; 

/*Prepare IP header*/ 
ip_head.ihl = 5; /*headerlength with no options*/ 
ip_head.version = 4; 
ip_head.tos = 0; 
ip_head.tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr) + len); 
ip_head.id = htons(31337 + (rand() % 100)); 
ip_head.frag_off = 0; 
ip_head.ttl = 255; 
ip_head.protocol = IPPROTO_TCP; 
ip_head.check = 0; /*Fill in later*/ 
ip_head.saddr = htonl(src); 
ip_head.daddr = htonl(dst); 
ip_head.check = in_cksum((unsigned short *) &ip_head, sizeof(struct iphdr)); 

/*Prepare TCP header*/ 
tcp_head.source = htons(src_p); 
tcp_head.dest = htons(dst_p); 
tcp_head.seq = htonl(seq); 
tcp_head.ack_seq = htonl(ack); 
tcp_head.doff = 5; 

/* set or reset ack, fin or syn flags as needed */ 
tcp_head.ack = 0; 
tcp_head.syn = 0; 
tcp_head.fin = 0; 

tcp_head.res1 = 0; 
tcp_head.urg = 0; 
tcp_head.psh = 0; 
tcp_head.rst = 0; 
tcp_head.res2 = 0; 

tcp_head.window = htons(0x7c00); 
tcp_head.check = 0; /*Fill in later*/ 
tcp_head.urg_ptr = 0; 

/*Assemble structure for checksum calculation and calculate checksum*/ 
pseudohead.src_addr = ip_head.saddr; 
pseudohead.dst_addr = ip_head.daddr; 
pseudohead.dummy = 0; 
pseudohead.proto = ip_head.protocol; 
pseudohead.length = htons(sizeof(struct tcphdr) + len); 

tcp_chk_construct.pshd = pseudohead; 
tcp_chk_construct.tcphd = tcp_head; 
memcpy(tcp_chk_construct.tcpdata, buffer, len); 

tcp_head.check = in_cksum((unsigned short *) &tcp_chk_construct, 
     sizeof(struct tcp_pseudo) + sizeof(struct tcphdr) + len); 

/*Assemble packet*/ 
memcpy(packet, (char *) &ip_head, sizeof(ip_head)); 
memcpy(packet + sizeof(ip_head), (char *) &tcp_head, sizeof(tcp_head)); 
memcpy(packet + sizeof(ip_head) + sizeof(tcp_head), buffer, len); 

/*Send packet*/ 
target.sin_family = AF_INET; 
target.sin_addr.s_addr = ip_head.daddr; 
target.sin_port = tcp_head.dest; 
i = sendto(sfd, packet, sizeof(struct iphdr) + sizeof(struct tcphdr) + len, 
     0, (struct sockaddr *) &target, sizeof(struct sockaddr_in)); 
if (i < 0) 
    return (-1); /*Error*/ 
else 
    return (i); /*Return number of bytes sent*/ 


****************************************   
FUNCTION FOR CHECKSUM 
**************************************** 
/* function to calculate the checksum for the packet */ 
unsigned short in_cksum(unsigned short *ptr, int nbytes) { 

    register long sum; /* assumes long == 32 bits */ 
    u_short oddbyte; 
    register u_short answer; /* assumes u_short == 16 bits */ 
    /* 
    * the algorithm is simple, using a 32-bit accumulator (sum), 
    * we add sequential 16-bit words to it, and at the end, fold back 
    * all the carry bits from the top 16 bits into the lower 16 bits. 
    */ 
    sum = 0; 
    while (nbytes > 1) { 
     sum += *ptr++; 
     nbytes -= 2; 
    } 

    /* mop up an odd byte, if necessary */ 
    if (nbytes == 1) { 
     oddbyte = 0; /* make sure top half is zero */ 
     *((u_char *) &oddbyte) = *(u_char *) ptr; /* one byte only */ 
     sum += oddbyte; 
    } 

    /* 
    * Add back carry outs from top 16 bits to low 16 bits. 
    */ 
    sum = (sum >> 16) + (sum & 0xffff); /* add high-16 to low-16 */ 
    sum += (sum >> 16); /* add carry */ 
    answer = ~sum; /* ones-complement, then truncate to 16 bits */ 
    return (answer); 
} 
0

세부 사항을 지정하지 않았으므로 (의심스럽게도 나에게 숙제를하는 것처럼 보임) 포인터 만 제공하면됩니다.

  1. 구조가 메모리에 어떻게 형성되는지 찾아보십시오.
  2. IP 헤더에서 어떤 멤버가 있는지 보여줄 IP 헤더 형식을 찾습니다.
  3. Raw 소켓을 찾습니다.

구조체를 올바르게 구조하고 원시 소켓을 사용한다면이 구조체를 소켓에 써야합니다.