2012-11-29 43 views
0

我必須手動創建我自己的網絡數據包使用任何Protocol.i應發送到客戶端並解析或分析數據包。可以any1幫助我與哪裏和hpw開始?我有關於套接字編程的想法..創建ip網絡數據包

+0

其實並沒有那麼糟糕。你瞭解OSI模型嗎?以及IP協議如何工作?應該有圖書館爲你做這個...谷歌爲他們 –

回答

10

您可以使用<linux/ip.h>它包含指向ip數據包的結構。你也可以使用套接字。

這裏後面的例子。這個例子發送一個ICMP ECHO數據包並等待響應

/* 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

爲什麼你沒有在數據包中附加mac頭文件?內核是否被照顧? –