网络第三课(2)--解包(dns域名解析)

来源:互联网 发布:天堂网,网络祭祀 编辑:程序博客网 时间:2024/05/11 14:36

上一课和这一课:

实现一个抓包,解包的过程:微笑

这里我们把上一课的内容 中抓到的数据,拿来解析。

一个解包的过程:mac/ip/udp/dns(这就是应用层,也是我们的数据。)

#include <stdio.h>

#include <linux/ip.h>
#include <linux/udp.h>

//#pragma pack(1)//以一个字节对齐
struct machdr{//mac地址结构
    unsigned char dest[6];
    unsigned char source[6];
    unsigned short proto;

};
struct sdnhdr{//sdn,域名结构
    unsigned short id;
    unsigned short flag;
    unsigned short question;
    unsigned short num;
    unsigned short authen;
    unsigned short source_num;
};

void get_mac(unsigned char *data);
void get_ip(unsigned char *data);
void get_udp(unsigned char *data);
void get_tcp(unsigned char *data);
void get_app(unsigned char *data);


int main()
{

    unsigned char buff[1024] = {

//mac

        0xd8, 0x5d, 0x4c, 0x64, 0xaa, 0x6e, 0x0 , 0x24,

        0x1d, 0x3b, 0x93, 0x3b, 0x8 , 0x0 ,

//ip

        0x45, 0x0 ,

        0x0 , 0x3a, 0xf0, 0x10, 0x40, 0x0 , 0x40, 0x11,
        0x17, 0xa4, 0xc0, 0xa8, 0x32, 0x86, 0x3d, 0x8b,

        0x2 , 0x45,

//udp

       0xbf, 0x34, 0x0 , 0x35, 0x0 , 0x26,

        0x69, 0xfc,

//dns数据;前面12个字节是dns报文的格式。后面的0x3是代表后面有三个数据;三个数据后的0x4是代表其后有4个数据。直到最后为0.

0x5f, 0x1b, 0x1 , 0x0 , 0x0 , 0x1 ,

        0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 ,

        0x3 , 0x77,

        0x77, 0x77, 0x4 , 0x63, 0x73, 0x64, 0x6e, 0x3 ,
        0x6e, 0x65, 0x74, 0x0 , 0x0 , 0x1 , 0x0 , 0x1
    };
    
    get_mac(buff);//解析mac
}

void get_mac(unsigned char *data)
{
    printf("-----------mac header------------\n");
    struct machdr *mac = (struct machdr *)data;
    printf("dest mac is %02x:%x:%x:%x:%x:%x\n",
        mac->dest[0], mac->dest[1],
        mac->dest[2], mac->dest[3],
        mac->dest[4], mac->dest[5]
        );
    printf("source mac is %02x:%x:%x:%x:%x:%x\n",
        mac->source[0], mac->source[1],
        mac->source[2], mac->source[3],
        mac->source[4], mac->source[5]
        );
    printf("protocol is %x\n", ntohs(mac->proto));
    

    if(ntohs(mac->proto) == 0x0800)//判断mac协议中帧类型。如果为0x0800=》ip;0x0806=》arp


        get_ip(data + sizeof(struct machdr));
    else
        printf("unknow mac protocol\n");
}

void get_ip(unsigned char *data)
{
    printf("------------ip header----------------\n");
    struct iphdr *ip = (struct iphdr *)data;
    printf("version is %d\n", ip->version);
    printf("ip header len is %d\n", ip->ihl * 4);
    printf("total len is %d\n", ntohs(ip->tot_len));
    printf("ttl is %d\n", ip->ttl);
    printf("protocol is %d\n", ip->protocol);
    printf("check sum is %x\n", ntohs(ip->check));
    
    char *sip = inet_ntoa(ip->saddr);
    //printf("source ip is %s\n", inet_ntoa(ip->saddr));
    printf("source ip is %s\n", sip);

    char *dip = inet_ntoa(ip->daddr);
    //printf("dest ip is %s\n", inet_ntoa(ip->daddr));
    printf("dest ip is %s\n", dip);
    
    if(ip->protocol == 6)//在ip协议中判断上一层的协议是什么;
        get_tcp(data + sizeof(struct iphdr));
    else if(ip->protocol == 17)
        get_udp(data + sizeof(struct iphdr));
    else
        printf("unknown trans protocol\n");
}

void get_udp(unsigned char *data)
{
    printf("---------------udp header-------------\n");
    struct udphdr *udp = (struct udphdr *)data;
    printf("source port is %d\n", ntohs(udp->source));
    printf("dest port is %d\n", ntohs(udp->dest));
    printf("len is %d\n", ntohs(udp->len));
    printf("check is %x\n", ntohs(udp->check));

    get_app(data + sizeof(struct udphdr));//dns是应用层协议

}

void get_tcp(unsigned char *data)
{
}

void get_app(unsigned char *data)//上面抓的是?网站是数据,最后根据sdn的协议,我们抓的是csdn网站。(最后解析:www.csdn.net)

{
    printf("-------------dns data----------\n");
        
    unsigned  char  *buff = (data+sizeof(struct sdnhdr));
    unsigned char sdn[1024] = {0};
    unsigned char *psdn = sdn;
    int len = 0,i=0;
    while(1)
    {
        len = *buff;
        if(len == 0)
            break;
        buff++;        
        for(i=0;i<len;i++)
        {
            psdn[i] = buff[i];    
        }
        psdn[i]    = '.';
            
        psdn += len+1;    
        buff += len;
    
    }
    *(psdn-1) = 0;
    
    printf("sdn:%s\n",sdn);
    
    
}