?? get_packet_code.c
字號:
*/
void icmp_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)
{
struct icmp_header *icmp_protocol;
/* ICMP協議變量 */
icmp_protocol = (struct icmp_header*)(packet_content + 14+20);
/* 獲得ICMP協議數據內容,跳過以太網協議和IP協議部分 */
printf("---------- ICMP Protocol (Transport Layer) ----------\n");
printf("ICMP Type:%d\n", icmp_protocol->icmp_type);
/* 獲得ICMP類型 */
switch (icmp_protocol->icmp_type)
/* 根據類型判斷ICMP數據包的種類 */
{
case 8:
/* 類型是8,表示是回顯請求ICMP數據包 */
printf("ICMP Echo Request Protocol \n");
printf("ICMP Code:%d\n", icmp_protocol->icmp_code);
/* 獲得ICMP代碼 */
printf("Identifier:%d\n", icmp_protocol->icmp_id);
/* 獲得標識符 */
printf("Sequence Number:%d\n", icmp_protocol->icmp_sequence);
/* 獲得序列號 */
break;
case 0:
/* 類型為0,表示是回顯應答ICMP數據包 */
printf("ICMP Echo Reply Protocol \n");
printf("ICMP Code:%d\n", icmp_protocol->icmp_code);
/* 獲得ICMP代碼 */
printf("Identifier:%d\n", icmp_protocol->icmp_id);
/* 獲得標識符 */
printf("Sequence Number:%d\n", icmp_protocol->icmp_sequence);
/* 獲得序列號 */
break;
default:
break;
/* 其它類型的ICMP數據包在此沒有分析,讀者可以在此添加其它類型的ICMP數據包的分析 */
}
printf("ICMP Checksum:%d\n", ntohs(icmp_protocol->icmp_checksum));
/* 獲得校驗和 */
}
/*
=======================================================================================================================
下面是實現ARP協議分析的函數定義
=======================================================================================================================
*/
void arp_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)
{
struct arp_header *arp_protocol;
/* ARP協議變量 */
u_short protocol_type;
/* 協議類型 */
u_short hardware_type;
/* 硬件類型 */
u_short operation_code;
/* 操作碼 */
u_char *mac_string;
/* 以太網地址 */
struct in_addr source_ip_address;
/* 源IP地址 */
struct in_addr destination_ip_address;
/* 目的IP地址 */
u_char hardware_length;
/* 硬件地址長度 */
u_char protocol_length;
/* 協議地址長度 */
printf("-------- ARP Protocol (Network Layer) --------\n");
arp_protocol = (struct arp_header*)(packet_content + 14);
/* 獲得ARP協議數據內容,跳過以太網協議部分 */
hardware_type = ntohs(arp_protocol->arp_hardware_type);
/* 獲得硬件類型 */
protocol_type = ntohs(arp_protocol->arp_protocol_type);
/* 獲得協議類型 */
operation_code = ntohs(arp_protocol->arp_operation_code);
/* 獲得操作碼 */
hardware_length = arp_protocol->arp_hardware_length;
/* 獲得硬件地址長度 */
protocol_length = arp_protocol->arp_protocol_length;
/* 獲得協議地址長度 */
printf("ARP Hardware Type:%d\n", hardware_type);
printf("ARP Protocol Type:%d\n", protocol_type);
printf("ARP Hardware Length:%d\n", hardware_length);
printf("ARP Protocol Length:%d\n", protocol_length);
printf("ARP Operation:%d\n", operation_code);
switch (operation_code) /* 根據操作碼判斷ARP協議類型 */
{
case 1:
printf("ARP Request Protocol\n");
break;
/* 操作碼為1,表示是ARP請求協議 */
case 2:
printf("ARP Reply Protocol\n");
break;
/* 操作碼為2,表示是ARP應答協議 */
case 3:
printf("RARP Request Protocol\n");
break;
/* 操作碼為3,表示是RARP請求協議 */
case 4:
printf("RARP Reply Protocol\n");
break;
/* 操作碼為4,表示是RARP應答協議 */
default:
break;
}
printf("Ethernet Source Address is : \n");
mac_string = arp_protocol->arp_source_ethernet_address;
printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));
/* 獲得源以太網地址 */
memcpy((void*) &source_ip_address, (void*) &arp_protocol->arp_source_ip_address, sizeof(struct in_addr));
printf("Source IP Address:%s\n", inet_ntoa(source_ip_address));
/* 獲得源IP地址 */
printf("Ethernet Destination Address is : \n");
mac_string = arp_protocol->arp_destination_ethernet_address;
printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));
/* 獲得目的以太網地址 */
memcpy((void*) &destination_ip_address, (void*) &arp_protocol->arp_destination_ip_address, sizeof(struct in_addr));
printf("Destination IP Address:%s\n", inet_ntoa(destination_ip_address));
/* 獲得目的IP地址 */
}
/*
=======================================================================================================================
下面是實現分析IP協議的函數定義
=======================================================================================================================
*/
void ip_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)
{
struct ip_header *ip_protocol;
/* IP協議變量 */
u_int header_length;
/* 首部長度 */
u_int offset;
/* 偏移 */
u_char tos;
/* 服務質量 */
u_int16_t checksum;
/* 校驗和 */
ip_protocol = (struct ip_header*)(packet_content + 14);
/* 獲得IP協議數據內容,跳過以太網協議部分 */
checksum = ntohs(ip_protocol->ip_checksum);
/* 獲得校驗和 */
header_length = ip_protocol->ip_header_length *4;
/* 獲得IP首部長度 */
tos = ip_protocol->ip_tos;
/* 獲得服務質量 */
offset = ntohs(ip_protocol->ip_off);
/* 活動偏移 */
printf("----------- IP Protocol (Network Layer) -----------\n");
printf("IP Version:%d\n", ip_protocol->ip_version);
/* 獲得版本號 */
printf("Header length:%d\n", header_length);
printf("TOS:%d\n", tos);
printf("Total length:%d\n", ntohs(ip_protocol->ip_length));
/* 獲得總長度 */
printf("Identification:%d\n", ntohs(ip_protocol->ip_id));
/* 獲得標識 */
printf("Offset:%d\n", (offset &0x1fff) *8);
printf("TTL:%d\n", ip_protocol->ip_ttl);
/* 獲得生存時間 */
printf("Protocol:%d\n", ip_protocol->ip_protocol);
/* 獲得協議類型 */
switch (ip_protocol->ip_protocol)
/* 根據協議類型判斷上層協議類型 */
{
case 6:
printf("The Transport Layer Protocol is TCP\n");
break;
/* 上層協議為TCP協議 */
case 17:
printf("The Transport Layer Protocol is UDP\n");
break;
/* 上層協議為UDP協議 */
case 1:
printf("The Transport Layer Protocol is ICMP\n");
break;
/* 上層協議為ICMP協議 */
default:
break;
}
printf("Header checksum:%d\n", checksum);
/* 校驗和 */
printf("Source address:%s\n", inet_ntoa(ip_protocol->ip_souce_address));
/* 獲得源IP地址 */
printf("Destination address:%s\n", inet_ntoa(ip_protocol->ip_destination_address));
/* 獲得目的IP地址 */
switch (ip_protocol->ip_protocol)
/* 判斷上層協議類型,然后調用相應的函數進行分析 */
{
case 6:
/* 上層協議為TCP協議 */
tcp_protocol_packet_callback(argument, packet_header, packet_content);
break;
/* 調用分析TCP協議的函數,注意參數的傳遞,表示分析的是同一個網絡數據包 */
case 17:
/* 上層協議為UDP協議 */
udp_protocol_packet_callback(argument, packet_header, packet_content);
break;
/* 調用分析UDP協議的函數,注意參數的傳遞方式 */
case 1:
/* 上層協議為ICMP協議 */
icmp_protocol_packet_callback(argument, packet_header, packet_content);
break;
/* 調用分析ICMP協議的函數,注意參數的傳遞 */
default:
break;
/* 其他類型的協議在此沒有分析,讀者可以在此進一步分析其它傳輸層協議 */
}
}
/*
=======================================================================================================================
下面是分析以太網協議的函數定義,同時它也是回調函數
=======================================================================================================================
*/
void ethernet_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)
{
u_short ethernet_type;
/* 以太網類型 */
struct ether_header *ethernet_protocol;
/* 以太網協議變量 */
u_char *mac_string;
/* 以太網地址 */
static int packet_number = 1;
printf("**************************************************\n");
printf("The %d packet is captured.\n", packet_number);
printf("-------- Ehternet Protocol (Link Layer) --------\n");
ethernet_protocol = (struct ether_header*)packet_content;
/* 獲得以太網協議數據內容 */
printf("Ethernet type is :\n");
ethernet_type = ntohs(ethernet_protocol->ether_type);
/* 獲得以太網類型 */
printf("%04x\n", ethernet_type);
switch (ethernet_type)
/* 根據以太網類型字段判斷上層協議類型 */
{
case 0x0800:
printf("The network layer is IP protocol\n");
break;
/* 上層協議為IP協議 */
case 0x0806:
printf("The network layer is ARP protocol\n");
break;
/* 上層協議為ARP協議 */
case 0x8035:
printf("The network layer is RARP protocol\n");
break;
/* 上層協議為RARP協議 */
default:
break;
}
printf("Mac Source Address is : \n");
mac_string = ethernet_protocol->ether_shost;
printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));
/* 獲得源以太網地址 */
printf("Mac Destination Address is : \n");
mac_string = ethernet_protocol->ether_dhost;
printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));
/* 獲得目的以太網地址 */
switch (ethernet_type)
/* 根據以太網類型字段判斷上層協議,然后調用相應函數進行分析 */
{
case 0x0806:
/* 上層是ARP協議 */arp_protocol_packet_callback(argument, packet_header, packet_content);
break;
/* 調用分析ARP協議的函數 */
case 0x0800:
/* 上層是IP協議 */ip_protocol_packet_callback(argument, packet_header, packet_content);
break;
/* 調用分析IP協議的函數 */
default:
break; /* 其它的協議在此沒有分析,讀者可以試著進一步分析 */
}
printf("**************************************************\n");
packet_number++;
}
/*
=======================================================================================================================
下面是主函數的定義
=======================================================================================================================
*/
void main()
{
pcap_t *pcap_handle;
/* libpap句柄 */
char error_content[PCAP_ERRBUF_SIZE];
/* 存儲錯誤內容 */
char *net_interface;
/* 網絡接口 */
struct bpf_program bpf_filter;
/* BPF過濾規則 */
char bpf_filter_string[] = "";
/* 過濾規則字符串,此時為空的,表示捕獲所有的網絡數據包,而不是捕獲特定的網絡數據包 */
bpf_u_int32 net_mask;
/* 網絡掩碼 */
bpf_u_int32 net_ip;
/* 網絡地址 */
net_interface = pcap_lookupdev(error_content);
/* 獲得網絡接口 */
pcap_lookupnet(net_interface, &net_ip, &net_mask, error_content);
/* 獲得網絡地址和網絡掩碼 */
pcap_handle = pcap_open_live(net_interface, BUFSIZ, 1, 0, error_content);
/* 打開網絡接口 */
pcap_compile(pcap_handle, &bpf_filter, bpf_filter_string, 0, net_ip);
/* 編譯過濾規則 */
pcap_setfilter(pcap_handle, &bpf_filter);
/* 設置過濾規則 */
if (pcap_datalink(pcap_handle) != DLT_EN10MB)
return ;
pcap_loop(pcap_handle, - 1, ethernet_protocol_packet_callback, NULL);
/* 注冊回調函數,循環捕獲網絡數據包,然后調用回調函數對捕獲的網絡數據包進行分析 */
pcap_close(pcap_handle);
/* 關閉Libpcap操作 */
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -