上一课和这一课:
实现一个抓包,解包的过程:
这里我们把上一课的内容 中抓到的数据,拿来解析。
一个解包的过程: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
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
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);
}