2012-11-29 2 views
0

수동으로 내 네트워크 패킷을 만들어야합니다. 모든 Protocol.i를 사용하여 클라이언트에 보내고 packet.Can any1을 사용하여 나를 분석하고 시작하고 어디에서 hpw를 도와야합니까 ??? 소켓 프로그래밍에 대한 아이디어가 있습니다.IP 네트워크 패킷 만들기

+0

정말 그렇게 나쁘지 않다. OSI 모델을 이해하고 있습니까? 그리고 IP 프로토콜이 어떻게 작동합니까? 당신을 위해 이것을 할 라이브러리가 있어야합니다 ... 그들에 대한 구글 –

답변

10

<linux/ip.h>에는 ip 패킷을 가리키는 구조가 있습니다. 또한 소켓을 사용할 수 있습니다.

예를 들면 다음과 같습니다. 이 예는 응답

/* send icmp packet example */ 
#include <stdio.h> 
#include <stdlib.h> 
#include <netdb.h> 
#include <linux/ip.h> 
#include <linux/icmp.h> 

int main(int argc, char* argv[]) 
{ 
    struct iphdr *ip, *ip_reply; 
    struct icmphdr* icmp; 
    struct sockaddr_in connection; 
    char *dst_addr="192.168.1.33"; 
    char *src_addr="192.168.1.34"; 
    char *packet, *buffer; 
    int sockfd, optval, addrlen; 

    packet = malloc(sizeof(struct iphdr) + sizeof(struct icmphdr)); 
    buffer = malloc(sizeof(struct iphdr) + sizeof(struct icmphdr)); 
    ip = (struct iphdr*) packet; 
    icmp = (struct icmphdr*) (packet + sizeof(struct iphdr)); 

    ip->ihl   = 5; 
    ip->version  = 4; 
    ip->tot_len  = sizeof(struct iphdr) + sizeof(struct icmphdr); 
    ip->protocol = IPPROTO_ICMP; 
    ip->saddr  = inet_addr(src_addr); 
    ip->daddr  = inet_addr(dst_addr); 
    ip->check = in_cksum((unsigned short *)ip, sizeof(struct iphdr)); 

    icmp->type  = ICMP_ECHO; 
    icmp->checksum = in_cksum((unsigned short *)icmp, sizeof(struct icmphdr)); 

    /* open ICMP socket */ 
    if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1) { 
     perror("socket"); 
     exit(EXIT_FAILURE); 
    } 
    /* IP_HDRINCL must be set on the socket so that the kernel does not attempt 
    * to automatically add a default ip header to the packet*/ 
    setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(int)); 

    connection.sin_family  = AF_INET; 
    connection.sin_addr.s_addr = ip->daddr; 
    sendto(sockfd, packet, ip->tot_len, 0, (struct sockaddr *)&connection, sizeof(struct sockaddr)); 
    printf("Sent %d byte packet to %s\n", ip->tot_len, dst_addr); 

    addrlen = sizeof(connection); 
    if (recvfrom(sockfd, buffer, sizeof(struct iphdr) + sizeof(struct icmphdr), 0, (struct sockaddr *)&connection, &addrlen) == -1) 
     { 
     perror("recv"); 
     } 
    else 
     { 
     char *cp; 
     ip_reply = (struct iphdr*) buffer; 
     cp = (char *)&ip_reply->saddr; 
     printf("Received %d byte reply from %u.%u.%u.%u:\n", ntohs(ip_reply->tot_len), cp[0]&0xff,cp[1]&0xff,cp[2]&0xff,cp[3]&0xff); 
     printf("ID: %d\n", ntohs(ip_reply->id)); 
     printf("TTL: %d\n", ip_reply->ttl); 
     } 

} 

unsigned short in_cksum(unsigned short *addr, int len) 
{ 
    register int sum = 0; 
    u_short answer = 0; 
    register u_short *w = addr; 
    register int nleft = len; 
    /* 
    * Our 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. 
    */ 
    while (nleft > 1) 
    { 
     sum += *w++; 
     nleft -= 2; 
    } 
    /* mop up an odd byte, if necessary */ 
    if (nleft == 1) 
    { 
     *(u_char *) (&answer) = *(u_char *) w; 
     sum += answer; 
    } 
    /* add back carry outs from top 16 bits to low 16 bits */ 
    sum = (sum >> 16) + (sum & 0xffff);  /* add hi 16 to low 16 */ 
    sum += (sum >> 16);    /* add carry */ 
    answer = ~sum;    /* truncate to 16 bits */ 
    return (answer); 
} 
+0

왜 당신은 패킷에 맥 헤더를 첨부하지 않았습니까? 커널에 의해 처리 되었습니까? –