下面是对抓取到的数据包进行解析,分2层以太网的解析,3层ip,icmp的解析,4层tcp,udp的解析
注:print是我自定义的宏,相当于printf
/******************************************************************************
文 件 名 : callback.c
版 本 号 : V1.1
负 责 人 : Sophisticated
生成日期 : 2018年9月28日
最近修改 :
文件描述 : 解析数据包的回调函数
函数列表 :
arp_callback
ethernet_callback
icmp_callback
ip_callback
pppoe_callback
tcp_callback
tcp_flag
udp_callback
修改历史 :
1.日 期 : 2018年9月28日
作 者 : Sophisticated
修改内容 : 创建文件
******************************************************************************/
#include
#include
#include
#include
#include
#include
#include"head.h"
#include"callback.h"
char *tcp_flag(const u_char tcp_flags);
void pppoe_callback(u_char *arg, const struct pcap_pkthdr *pcap_pkt,const u_char *packet);
/*过滤条件*/
extern char filter_exp[128];
/*抓包设备名称*/
extern char *dev;
/*****************************************************************************
函 数 名 : ethernet_callback
功能描述 : 以太网数据包头分析
输入参数 : u_char *arg
const struct pcap_pkthdr *pcap_pkt
const u_char *packet
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2018年9月28日
作 者 : Sophisticated
审 核 人 : #
修改内容 : 新生成函数
*****************************************************************************/
void ethernet_callback(u_char *arg, const struct pcap_pkthdr *pcap_pkt,const u_char *packet)
{
struct ethernet *ethheader;
struct ip *ipptr;
u_short protocol;
u_int *id = (u_int *)arg;
u_char *time = ctime((const time_t*)&pcap_pkt->ts.tv_sec);
print("---------------Device : %s--------------\n",dev);
print("---------------Filter: %s---------------\n",filter_exp);
print("-----------------Analyze Info---------------\n");
print("Id: %d\n",++(*id));
print("Packet length: %d\n",pcap_pkt->len);
print("Number of bytes: %d\n",pcap_pkt->caplen);
print("Receive time: %s\n",time);
int k;
for (k = 0; k < pcap_pkt->len; k++)
{
/*表示以16进制的格式输出整数类型的数值,
输出域宽为2,右对齐,不足的用字符0替代*/
print(" %02x",packet[k]);
if ((k + 1) % 16 == 0)
{
print("\n");
}
}
print("\n\n");
ethheader = (struct ethernet*)packet;
print("---------------Data Link Layer-----------\n");
print("Mac Src Address: ");
int i;
for (i = 0; i < ETHERNET_ADDR_LEN; i++)
{
if (ETHERNET_ADDR_LEN - 1 == i)
{
print("%02x\n",ethheader->ether_shost[i]);
}
else
{
print("%02x:",ethheader->ether_shost[i]);
}
}
print("Mac Dst Address: ");
int j;
for (j = 0; j < ETHERNET_ADDR_LEN; j++)
{
if (ETHERNET_ADDR_LEN - 1 == j)
{
print("%02x\n",ethheader->ether_dhost[j]);
}
else
{
print("%02x:",ethheader->ether_dhost[j]);
}
}
protocol = ntohs(ethheader->ether_type);
/*对pppoe报文的处理*/
if (0x8863 == protocol)
{
print("PPPOE Discovery");
pppoe_callback(arg, pcap_pkt, packet);
}
if (0x8864 == protocol)
{
print("PPPOE Session");
pppoe_callback(arg, pcap_pkt, packet);
}
print("----------------Network Layer-------------\n");
switch (protocol)
{
case 0x0800:
print("IPv4 protocol!\n");
ip_callback(arg, pcap_pkt, packet);
break;
case 0x0806:
print("ARP protocol!\n");
arp_callback(arg, pcap_pkt, packet);
break;
case 0x8035:
print("RARP protocol!\n");
break;
case 0x86DD:
print("IPv6 protocol!\n");
break;
case 0x880B:
print("PPP protocol!\n");
print("There is no function to process PPP packet!!!");
break;
default:
print("Other Network Layer protocol is used!\n");
break;
}
print("---------------------Done--------------------\n\n\n");
}
/*****************************************************************************
函 数 名 : pppoe_callback
功能描述 : pppoe数据包处理函数
输入参数 : u_char *arg
const struct pcap_pkthdr *pcap_pkt
const u_char *packet
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2018年10月8日
作 者 : Sophisticated
审 核 人 : #
修改内容 : 新生成函数
*****************************************************************************/
void pppoe_callback(u_char *arg, const struct pcap_pkthdr *pcap_pkt,const u_char *packet)
{
struct pppoe *pppoeheader = (struct pppoe *)(packet + ETHERNET_HEAD_SIZE);
print("Version: %d\n",(pppoeheader->pppoe_vtype & 0xf0) >> 4);
print("Type: %d\n",pppoeheader->pppoe_vtype & 0x0f);
print("Code: %d\n",pppoeheader->pppoe_code);
print("Session ID: %d\n",ntohs(pppoeheader->pppoe_s_id));
print("Payload Length: %d\n",ntohs(pppoeheader->pppoe_len));
}
/*****************************************************************************
函 数 名 : ip_callback
功能描述 : ip数据包分析
输入参数 : u_char *arg
const struct pcap_pkthdr *pcap_pkt
const u_char *packet
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2018年9月29日
作 者 : Sophisticated
审 核 人 : #
修改内容 : 新生成函数
*****************************************************************************/
void ip_callback(u_char *arg, const struct,pcap_pkthdr *pcap_pkt,const u_char *packet)
{
u_char protocol;
struct ip *ipheader;
ipheader = (struct ip *)(packet + ETHERNET_HEAD_SIZE);
print("Version: %d\n", (ipheader->ip_hlv & 0xf0) >> 4); //取hlv高4位
print("Header Length: %d\n",ipheader->ip_hlv & 0x0f); //取hlv低4位
print("Type of Service: %x\n",ipheader->ip_tos);
print("Total Length: %d\n",ntohs(ipheader->ip_len));
print("Indentification: %x\n",ntohs(ipheader->ip_id));
print("Offset: %d\n",ntohs(ipheader->ip_off));
print("TTL: %d\n",ipheader->ip_ttl);
print("Protocol: %d\n",ipheader->ip_protocol);
print("CheckSum: %d\n",ntohs(ipheader->ip_sum));
int i = 0;
print("IP Src Address: ");
for (i = 0; i < IP_ADDR_LEN; i++)
{
print("%d.",ipheader->ip_src[i]);
}
print("\nIP Dst Address: ");
for (i = 0; i < IP_ADDR_LEN; i++)
{
print("%d.",ipheader->ip_dst[i]);
}
print("\n");
protocol = ipheader->ip_protocol;
if (0x01 == protocol)
{
print("ICMP Protocol!\n");
icmp_callback(arg, pcap_pkt, packet);
}
print("----------------Transport Layer--------------\n");
switch (protocol)
{
case 0x06:
print("TCP Protocol!\n");
tcp_callback(arg, pcap_pkt, packet);
break;
case 0x11:
print("UDP Protocol!\n");
udp_callback(arg, pcap_pkt, packet);
break;
case 0x02:
print("IGMP Protocol!\n");
print("There is no function to process IGMP packet!!!");
break;
default:
print("Other Transport Layer protocol is used!\n");
break;
}
}
/*****************************************************************************
函 数 名 : tcp_callback
功能描述 : TCP数据包分析
输入参数 : u_char *arg
const struct pcap_pkthdr *pcap_pkt
const u_char *packet
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2018年9月28日
作 者 : Sophisticated
审 核 人 : #
修改内容 : 新生成函数
*****************************************************************************/
void tcp_callback(u_char *arg, const struct pcap_pkthdr *pcap_pkt,const u_char *packet)
{
struct tcp *tcpheader = (struct tcp *)(packet + ETHERNET_HEAD_SIZE + IP_HEAD_SIZE(packet));
print("Src Port: %d\n",ntohs(tcpheader->tcp_sport));
print("Dst Port: %d\n",ntohs(tcpheader->tcp_dport));
print("Squence Number: %d\n",ntohs(tcpheader->tcp_seqe));
print("ACK Number: %d\n",ntohs(tcpheader->tcp_ack));
print("Header Length: %d\n",(tcpheader->tcp_hre & 0xf0) >> 4);
print("FLAG: %d\n",tcpheader->tcp_flag);
print("Flag: %s\n",tcp_flag(tcpheader->tcp_flag));
print("Window Size: %d\n",ntohs(tcpheader->tcp_win));
print("Checksum: %d\n",ntohs(tcpheader->tcp_sum));
print("Urgent Pointer: %d\n",ntohs(tcpheader->tcp_urp));
}
/*****************************************************************************
函 数 名 : tcpflag
功能描述 : 判断TCP协议的标志位
输入参数 : const u_char tcp_flags
输出参数 : 无
返 回 值 : u_char
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2018年9月29日
作 者 : Sophisticated
审 核 人 : #
修改内容 : 新生成函数
*****************************************************************************/
char *tcp_flag(const u_char tcp_flags)
{
char flags[100] = "-";
if ((TCP_CWR & tcp_flags) == TCP_CWR)
{
strncat(flags, "CWR ", 100);
}
if ((TCP_ECE & tcp_flags) == TCP_ECE)
{
strncat(flags, "ECE ", 100);
}
if ((TCP_URG & tcp_flags) == TCP_URG)
{
strncat(flags, "URG ", 100);
}
if ((TCP_ACK & tcp_flags) == TCP_ACK)
{
strncat(flags, "ACK ", 100);
}
if ((TCP_PUSH & tcp_flags) == TCP_PUSH)
{
strncat(flags, "PUSH ", 100);
}
if ((TCP_RST & tcp_flags) == TCP_RST)
{
strncat(flags, "RST ", 100);
}
if ((TCP_SYN & tcp_flags) == TCP_SYN)
{
strncat(flags, "SYN ", 100);
}
if ((TCP_FIN & tcp_flags) == TCP_FIN)
{
strncat(flags, "FIN ", 100);
}
return flags;
}
/*****************************************************************************
函 数 名 : icmp_callback
功能描述 : ICMP数据包分析
输入参数 : u_char *arg
const struct pcap_pkthdr *pcap_pkt
const u_char *packet
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2018年9月29日
作 者 : Sophisticated
审 核 人 : #
修改内容 : 新生成函数
*****************************************************************************/
void icmp_callback(u_char *arg, const struct pcap_pkthdr *pcap_pkt,const u_char *packet)
{
struct icmp *icmpheader = (struct icmp *)(packet + ETHERNET_HEAD_SIZE + IP_HEAD_SIZE(packet));
u_char icmp_type = icmpheader->icmp_type;
print("ICMP Type: %d ",icmpheader->icmp_type);
switch (icmp_type)
{
case 0x08:
print("(ICMP Request)\n");
break;
case 0x00:
print("(ICMP Response)\n");
break;
case 0x11:
print("(Timeout!!!)\n");
break;
}
print("ICMP Code: %d\n",icmpheader->icmp_code);
print("ICMP CheckSum: %d\n",icmpheader->icmp_sum);
}
/*****************************************************************************
函 数 名 : udp_callback
功能描述 : UDP数据包分析
输入参数 : u_char *arg
const struct pcap_pkthdr *pcap_pkt
const u_char *packet
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2018年9月28日
作 者 : Sophisticated
审 核 人 : #
修改内容 : 新生成函数
*****************************************************************************/
void udp_callback(u_char *arg, const struct pcap_pkthdr *pcap_pkt,const u_char *packet)
{
struct udp *udpheader = (struct udp *)(packet + ETHERNET_HEAD_SIZE + IP_HEAD_SIZE(packet));
print("Src Port: %d\n",ntohs(udpheader->udp_sport));
print("Dst Port: %d\n",ntohs(udpheader->udp_dport));
print("UDP Length: %d\n",ntohs(udpheader->udp_len));
print("Checksum: %d\n",ntohs(udpheader->udp_sum));
}
/*****************************************************************************
函 数 名 : arp_callback
功能描述 : arp数据包分析
输入参数 : u_char *arg
const struct pcap_pkthdr *pcap_pkt
const u_char *packet
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2018年9月28日
作 者 : Sophisticated
审 核 人 : #
修改内容 : 新生成函数
*****************************************************************************/
void arp_callback(u_char *arg, const struct pcap_pkthdr *pcap_pkt,const u_char *packet)
{
struct arp *arpheader;
arpheader = (struct arp *)(packet + ETHERNET_HEAD_SIZE);
print("Hardware type: %s\n",(ntohs(arpheader->arp_hrd) == 0x0001) ? "Ethernet" : "Unknow");
print("Protocol type: %s\n",(ntohs(arpheader->arp_pro) == 0x0800) ? "IPv4" : "Unknow");
print("Operation: %s\n",(ntohs(arpheader->arp_op) == ARP_REQUEST) ? "ARP_Request" : "ARP_Reply");
int i = 0;
print("Sender MAC:");
for (i = 0; i < ETHERNET_ADDR_LEN; i++)
{
print("%02x:",arpheader->arp_shost[i]);
}
print("\nSender IP:");
for (i = 0; i < IP_ADDR_LEN; i++)
{
print("%d.",arpheader->arp_sip[i]);
}
print("\nTarget Mac:");
for (i = 0; i < ETHERNET_ADDR_LEN; i++)
{
print("%02x:",arpheader->arp_dhost[i]);
}
print("\nTarget IP:");
for (i = 0; i < IP_ADDR_LEN; i++)
{
print("%d.",arpheader->arp_dip[i]);
}
print("\n\n");
}
在以太网解析中判断协议类型,即3层锁使用的协议,然后根据三层使用的协议使用相应的函数解析,然后在3层解析中判断4层使用协议类型。