博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用libpcap抓包(三)----------数据包解析函数的实现
阅读量:4126 次
发布时间:2019-05-25

本文共 11091 字,大约阅读时间需要 36 分钟。

下面是对抓取到的数据包进行解析,分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层使用协议类型。

转载地址:http://fuhpi.baihongyu.com/

你可能感兴趣的文章
Container With Most Water --装最多水的容器(重)
查看>>
Longest Common Prefix -最长公共前缀
查看>>
Letter Combinations of a Phone Number
查看>>
Single Number II --出现一次的数(重)
查看>>
Valid Parentheses --括号匹配
查看>>
Remove Element--原地移除重复元素
查看>>
Remove Duplicates from Sorted Array--从有序数组中移除重复元素
查看>>
Count and Say
查看>>
Gas Station
查看>>
Palindrome Partitioning --回文切割 深搜(重重)
查看>>
Valid Palindrome 简单的回文判断
查看>>
Pascal's Triangle -- 生成杨辉三角
查看>>
Pascal's Triangle II 生成杨辉三角中的某行
查看>>
Minimum Depth of Binary Tree -- 二叉树的最小深度 DFS 加剪枝
查看>>
Climbing Stairs 爬楼梯方法 动态规划
查看>>
Merge Two Sorted Lists 合并两个有序链表
查看>>
pow(x,n) 为什么错这么多次
查看>>
Jump Game 动态规划
查看>>
Subsets 深搜
查看>>
Subsets II
查看>>