linux下使用libcpcap的简单代码
来源:互联网 发布:js获取当前设备 编辑:程序博客网 时间:2024/05/17 00:52
#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>#include <arpa/inet.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <string.h>
struct arp_header
{
u_int16_t arp_hardware_type; /*硬件类型 */
u_int16_t arp_protocol_type; /*协议类型 */
u_int8_t arp_hardware_length; /*硬件地址长度 */
u_int8_t arp_protocol_length; /*协议地址长度 */
u_int16_t arp_operation_code; /*ARP操作码 */
u_int8_t arp_source_ethernet_address[6]; /*源以太网地址 */
u_int8_t arp_source_ip_address[4]; /*源IP地址 */
u_int8_t arp_destination_ethernet_address[6]; /*目的以太网地址 */
u_int8_t arp_destination_ip_address[4]; /*目的IP地址 */
};
/*ip协议格式的定义*/
struct ip_header
{
#ifdef WORDS_BIGENDIAN
u_int8_t ip_version:4, ip_header_length:4;
#else
u_int8_t ip_header_length:4, ip_version:4;
#endif
u_int8_t ip_tos; //服务质量
u_int16_t ip_length; //总长度
u_int16_t ip_id; //标识
u_int16_t ip_off; //偏移
u_int8_t ip_ttl; //生存时间
u_int8_t ip_protocol; //协议类型
u_int16_t ip_checksum; //校验和
struct in_addr ip_souce_address; //源ip地址
struct in_addr ip_destination_address; //目的ip地址
};
/*tcp协议格式的定义*/
struct tcp_header
{
#ifdef WORDS_BIGENDIAN
u_int8_t tcp_offset:4, tcp_reserved:4;
#else
u_int8_t tcp_reserved:4, tcp_offset:4;
#endif
u_int16_t tcp_source_port; //源端口号
u_int16_t tcp_destination_port; //目的端口号
u_int32_t tcp_acknowledgement; //序列号
u_int32_t tcp_ack; //确认号
u_int8_t tcp_flags; //标记
u_int16_t tcp_windows; //窗口大小
u_int16_t tcp_checksum; //校验和
u_int16_t tcp_urgent_pointer; //紧急指针
};
/*udp些一个是的定义*/
struct udp_header
{
u_int16_t udp_source_port; /*源端口号 */
u_int16_t udp_destination_port; /*目的端口号 */
u_int16_t udp_length; /*长度 */
u_int16_t udp_checksum; /*校验和 */
};
/*icmp协议格式的定义*/
struct icmp_header
{
u_int8_t icmp_type; /*ICMP类型 */
u_int8_t icmp_code; /*ICMP代码 */
u_int16_t icmp_checksum; /*校验和 */
u_int16_t icmp_id; /*标识 */
u_int16_t icmp_sequence; /*序列号 */
};
/*分析tcp协议的回调函数*/
void
tcp_protocol_callback (u_char * argument,
const struct pcap_pkthdr *packet_header,
const u_char * packet_content)
{
struct tcp_header *tcp_protocol;
u_char flags;
u_int header_len;
u_short source_port;
u_short destination_port;
u_short windows;
u_short urgent_pointer;
u_int sequence;
u_int acknowledgement;
u_int16_t checksum;
tcp_protocol = (struct tcp_header *) (packet_content + 14 + 20);
source_port = ntohs (tcp_protocol->tcp_source_port);
destination_port = ntohs (tcp_protocol->tcp_destination_port);
header_len = tcp_protocol->tcp_offset * 4;
sequence = ntohl (tcp_protocol->tcp_acknowledgement);
windows = ntohs (tcp_protocol->tcp_windows);
urgent_pointer = ntohs (tcp_protocol->tcp_urgent_pointer);
flags = tcp_protocol->tcp_flags;
checksum = ntohs (tcp_protocol->tcp_checksum);
printf ("-------------------TCP Protocol--------------/n");
printf ("Source Port:%d/n", source_port);
printf ("Destination port:%d/n", destination_port);
switch (destination_port)
{
case 80:
printf ("HTTP protocol/n");
break; //端口80,表示上层协议是HTTP
case 21:
printf ("FTP protocol/n");
break; //端口21,表示上层协议是FTP
case 23:
printf ("TELNET protocol/n");
break; //端口23,表示上层协议是TELNET
case 25:
printf ("SMTP protocol/n");
break; //端口25,表示上层协议是SMTP
case 110:
printf ("POP3 protocol/n");
break; //端口110,表示上层协议是POP3
default:
break;
}
printf ("Sequence Number:%u/n", sequence);
printf ("Acknowledgement Number:%u/n", acknowledgement);
printf ("Header Length:%d/n", header_len);
printf ("Reserved:%d/n", tcp_protocol->tcp_reserved);
printf ("flags:");
if (flags & 0x80)
printf ("PSH");
if (flags & 0x10)
printf ("ACK");
if (flags & 0x02)
printf ("SYN");
if (flags & 0x20)
printf ("URG");
if (flags & 0x01)
printf ("FIN");
if (flags & 0x04)
printf ("RST");
printf ("/n");
printf ("Window size:%d/n", windows);
printf ("Checksum:%d/n", checksum);
printf ("Urgent pointer:%d/n", urgent_pointer);
}
/*分析udp协议的回调函数*/
void
udp_protocol_callback (u_char * argument,
const struct pcap_pkthdr *packet_header,
const u_char * packet_content)
{
struct udp_header *udp_protocol;
u_short source_port;
u_short destination_port;
u_short length;
udp_protocol = (struct udp_header *) (packet_content + 14 + 20);
source_port = ntohs (udp_protocol->udp_source_port);
destination_port = ntohs (udp_protocol->udp_destination_port);
length = ntohs (udp_protocol->udp_length);
printf ("---------------------UDP PROTOCOL---------------------/n");
printf ("Source port is:%d/n", source_port);
printf ("Destination port is:%d/n", destination_port);
switch (destination_port)
{
case 138:
printf ("NETBIOS Datagram Service./n");
break;
case 137:
printf ("NETBIOS Name Service./n");
break;
case 139:
printf ("NETBIOS Session Service./n");
break;
case 53:
printf ("name-domain server./n");
break;
default:
break;
}
printf ("Length is:%d/n", length);
printf ("checksum is:%d/n", ntohs (udp_protocol->udp_checksum));
}
/*分析ICMP协议的回调函数*/
void
icmp_protocol_callback (u_char * argument,
const struct pcap_pkthdr *packet_header,
const u_char * packet_content)
{
struct icmp_header *icmp_protocol;
icmp_protocol = (struct icmp_header *) (packet_content + 14 + 20);
printf ("---------------------ICMP PROTOCOL-------------------------/n");
printf ("ICMP type is:%d/n", icmp_protocol->icmp_type);
switch (icmp_protocol->icmp_type)
{
case 8:
printf ("ICMP Echo Request Protocol/n");
printf ("ICMP Code:%d/n", icmp_protocol->icmp_code);
printf ("Idetifier:%d/n", icmp_protocol->icmp_id);
printf ("Sequence Number:%d/n", icmp_protocol->icmp_sequence);
break;
case 0:
printf ("ICMP Echo Reply Protocol/n");
printf ("ICMP Code:%d/n", icmp_protocol->icmp_code);
printf ("Idetifier:%d/n", icmp_protocol->icmp_id);
printf ("Sequence Number:%d/n", icmp_protocol->icmp_sequence);
break;
default:
break;
}
printf ("ICMP Checksum is:%d/n", ntohs (icmp_protocol->icmp_checksum));
}
/*分析ARP协议的回调函数*/
void
arp_protocol_callback (u_char * argument,
const struct pcap_pkthdr *packet_header,
const u_char * packet_content)
{
struct arp_header *arp_protocol;
u_short protocol_type;
u_short hardware_type;
u_short operation_code;
u_char *mac_string;
struct in_addr addr;
u_char hardware_len;
u_char protocol_len;
printf ("--------------------ARP Protocol --------------------------/n");
arp_protocol = (struct arp_header *) (packet_content + 14);
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_len = arp_protocol->arp_hardware_length;
protocol_len = 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_len);
printf ("ARP Protocol Length:%d/n", protocol_len);
switch (operation_code)
{
case 1:
printf ("ARP Request Protocol/n");
break;
case 2:
printf ("ARP Reply Protocol/n");
break;
case 3:
printf ("RARP Request Protocol/n");
break;
case 4:
printf ("RARP Reply Protocol/n");
break;
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 *) &addr, (void *) &arp_protocol->arp_source_ip_address,
sizeof (struct in_addr));
printf ("Source IP Address is:%s/n", inet_ntoa (addr));
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 *) &addr, (void *) &arp_protocol->arp_destination_ip_address,
sizeof (struct in_addr));
printf ("Source IP Address is:%s/n", inet_ntoa (addr));
}
/*分析ip协议的回调函数*/
void
ip_protocol_callback (u_char * argument,
const struct pcap_pkthdr *packet_header,
const u_char * packet_content)
{
struct ip_header *ip_protocol;
//struct iphdr *ip_protocol;
u_int header_len;
u_int offset;
u_char tos;
u_int16_t checksum;
ip_protocol = (struct ip_header *) (packet_content + 14);
checksum = ntohs (ip_protocol->ip_checksum);
header_len = (ip_protocol->ip_header_length) * 4;
tos = ip_protocol->ip_tos;
offset = ntohs (ip_protocol->ip_off);
printf ("------------IP Protocol --------------------/n");
printf ("IP Version:%d/n", ip_protocol->ip_version);
printf ("Header length:%d/n", header_len);
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);
printf ("Header checksum:%d/n", checksum);
printf ("Source address:%s/n", inet_ntoa (ip_protocol->ip_souce_address));
printf ("Destination address:%s/n",
inet_ntoa (ip_protocol->ip_destination_address));
switch (ip_protocol->ip_protocol)
{
case 6://上层是TCP协议
printf ("The Transport Layer Protocol is TCP/n");
tcp_protocol_callback (argument, packet_header, packet_content);
break;
case 17://上层是UDP协议
printf ("The Transport Layer Protocol is UDP/n");
udp_protocol_callback (argument, packet_header, packet_content);
break;
case 1://上层是ICMP协议
printf ("The Transport Layer Protocol is ICMP/n");
icmp_protocol_callback (argument, packet_header, packet_content);
break;
default:
break;
}
}
/*分析以太网协议的回调函数*/
void
ether_protocol_callback (u_char * argument,
const struct pcap_pkthdr *packet_header,
const u_char * packet_content)
{
static int number = 0;
struct ether_header *ethernet_protocol;
u_short ethernet_type;
u_char *mac_string;
printf
("---------------------------------------------------------------------/n");
printf ("The %d packet is captured./n", ++number);
printf ("---------------------ETHER PROTOCOL----------------------/n");
ethernet_protocol = (struct ether_header *) packet_content;
printf ("Ether type is:/n");
ethernet_type = ntohs (ethernet_protocol->ether_type);
printf ("%04x/n", ethernet_type);
printf ("MAC Source Address is:/n");
int i = ETHER_ADDR_LEN;
mac_string = ethernet_protocol->ether_shost;
do
{
printf ("%s%02x", (i == ETHER_ADDR_LEN) ? "" : ":", *mac_string++);
}
while (--i > 0);
printf ("/nMac Destination Address is:/n");
i = ETHER_ADDR_LEN;
mac_string = ethernet_protocol->ether_dhost;
do
{
printf ("%s%02x", (i == ETHER_ADDR_LEN) ? "" : ":", *mac_string++);
}
while (--i > 0);
printf("/n");
switch (ethernet_type)
{
case 0x0800://上层是IP协议
printf ("the network layer is IP protocol/n");
ip_protocol_callback (argument, packet_header, packet_content);//调用分析ip协议函数
break;
case 0x0806://上层是ARP协议
printf ("the network layer is ARP protocol/n");
arp_protocol_callback (argument, packet_header, packet_content);//调用分析ARP协议函数
break;
case 0x8035://上层是RARP协议
printf ("the network layer is RARP protocol/n");
break;
default:
break;
}
printf
("-------------------------------------------------------------------------------/n");
}
int
main (char *argv, char *argc[])
{
char *dev;//网络接口
char errbuf[PCAP_ERRBUF_SIZE];
u_int32_t net_ip;
u_int32_t net_mask;
char bpf_filter_string[] = "";//过滤规则字符串
pcap_t *packet_handle;//libpcap句柄
struct bpf_program bpf_filter;//BPF过滤规则
dev = pcap_lookupdev (errbuf);//获得网络接口
if (dev == NULL)
exit (1);
int ret = pcap_lookupnet (dev, &net_ip, &net_mask, errbuf);//获得网络地址和网络掩码
if (ret == -1)
exit (1);
packet_handle = pcap_open_live (dev, 1000, 1, 0, errbuf);//打开网络接口
pcap_compile (packet_handle, &bpf_filter, bpf_filter_string, 0, net_ip);//编译过滤规则
pcap_setfilter (packet_handle, &bpf_filter);//设置过滤规则
if (pcap_datalink (packet_handle) != DLT_EN10MB)
return;
pcap_loop (packet_handle, -1, ether_protocol_callback, NULL);//进行抓包,然后用回掉函数进行数据包的分析
pcap_close (packet_handle);
}
- linux下使用libcpcap的简单代码
- linux下使用libcpcap的简单代码
- Linux下的tree的简单使用
- linux下vi命令的简单使用
- linux下NDK的简单使用
- Linux Mint下Nanopb的简单使用
- Linux下tar命令的简单使用
- linux下supervisord的简单使用
- Linux下getopt()函数的简单使用
- Linux下getopt()函数的简单使用
- Linux下MySQL的简单使用(1)
- Linux下MySQL的简单使用(3)
- linux下简单的mail使用
- linux下JBoss的简单使用
- Linux下getopt()函数的简单使用
- Linux下的简单C代码的运行
- linux下的最简单的线程应用代码
- linux下用C++代码实现简单的进度条
- 无法显示隐藏的文件或文件夹
- Java内部类模拟实现多继承
- Mac平台retina高分屏开发技术分享
- 【iphone游戏开发】iphone-Cocos2d游戏开发之三:精灵表的详细讲解(二)小鸟眨眼睛
- Linux 下socket超时(connect超时/recv超时)
- linux下使用libcpcap的简单代码
- QQ整人使人一分钟内关机(附破解方法)
- USB-HDD/ZIP/HDD+/ZIP+/CDROM(量产) U盘启动模式简介
- android开机默认中文的方法
- 简单高级搜索页面的简单实现,包括数据控件循环嵌套,DataTable动态生成数据添加等
- 奇怪的错误!
- 异步post例子(Meal4me登陆)
- 怎么解除任务管理器锁?
- 关门变量