#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <string.h>
#include <netdb.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/if_ether.h>
#include <net/ethernet.h>
void die(char *why, int n)
{
perror(why);
exit(n);
}
int do_promisc(char *nif, int sock )
{
struct ifreq ifr;
strncpy(ifr.ifr_name, nif,strlen(nif)+1);
if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) //获得flag
{
die("ioctl", 2);
}
ifr.ifr_flags |= IFF_PROMISC; //重置flag标志
if(ioctl(sock, SIOCSIFFLAGS, &ifr) == -1 ) //改变模式
{
die("ioctl", 3);
}
return 0;
}
//修改网卡成PROMISC(混杂)模式
/* =============================================================================================================下面是实现捕获和分析UDP协议数据包的函数定义
=============================================================================================================*/
void udp_protocol_packet_callback( u_char *packet_content)
{
struct udphdr *udp_protocol;
// UDP协议数据变量
u_short source_port;
// 源端口号
u_short destination_port;
// 目的端口号
udp_protocol = (struct udphdr*)(packet_content + 14+20);
// 获得UDP协议数据内容
source_port = ntohs(udp_protocol->source);
// 获得源端口号
destination_port = ntohs(udp_protocol->dest);
// 获得目的端口号
printf("---------- UDP Protocol (Transport Layer) ----------\n");
printf("Source port:%d\n", source_port);
printf("Destination port:%d\n", destination_port);
switch (destination_port)
//根据端口号判断应用层协议类型
{
case 138:
printf("NETBIOS Datagram Service\n");
break;
// 端口号为138,表示上层协议为NETBIOS 数据报服务
case 137:
printf("NETBIOS Name Service\n");
break;
// 端口号为137,表示上层协议为NETBIOS 名字服务
case 139:
printf("NETBIOS session service\n");
break;
// 端口号为139,表示上层协议为NETBIOS 会话服务
case 53:
printf("name-domain server \n");
break;
// 端口号为53,表示上层协议为域名服务
case 4000:
printf("QQ server \n");
break;
case 1863:
printf("MSN server \n");
break;
case 9001:
printf("OTHERS \n");
break;
default:
printf("NOT WELL-KNOWN PROTOCOL.\n");
break; //其他没有分析
}
} /* =============================================================================================================下面是实现捕获和分析TCP协议数据包的函数定义
=============================================================================================================
*/
void tcp_protocol_packet_callback( u_char *packet_content)
{
struct tcphdr *tcp_protocol;
// TCP协议数据变量
u_short source_port;
// 源端口号
u_short destination_port;
// 目的端口号
tcp_protocol = (struct tcphdr*)(packet_content + 14+20);
// 获得UDP协议数据内容
source_port = ntohs(tcp_protocol->source);
// 获得源端口号
destination_port = ntohs(tcp_protocol->dest);
// 获得目的端口号
printf("---------- TCP Protocol (Transport Layer) ----------\n");
printf("Source port:%d\n", source_port);
printf("Destination port:%d\n", destination_port);
switch (destination_port)
//根据端口号判断应用层协议类型
{
case 7:
printf("ECHO server \n");
break;
case 21:
printf("FTP server \n");
break;
case 23:
printf("TELNET server \n");
break;
case 25:
printf("SMTP server \n");
break;
case 53:
printf("DNS server \n");
break;
case 80:
printf("HTTP server \n");
break;
case 2049:
printf("NFS server \n");
break;
case 6667:
printf("IRCD server \n");
break;
default:
printf("NOT WELL-KNOWN PROTOCOL.\n");
break; //其他没有分析
}
}
/*
=============================================================================================================
下面是分析IP协议的函数的定义
=============================================================================================================
*/
void ip_protocol_packet_callback( u_char *packet_content)
{
struct iphdr *ip_protocol; // IP协议变量
printf("---------- IP Protocol (Network Layer) ----------\n");
ip_protocol = (struct iphdr*)(packet_content + 14); //获得IP协议数据内容
printf("Protocol:%d\n", ip_protocol->protocol); //获得协议类型
switch (ip_protocol->protocol) // 根据协议类型判断
{
case IPPROTO_TCP:
printf("The Transport Layer Protocol is TCP\n");
break;
/* 上层协议为TCP协议 */
case IPPROTO_UDP:
printf("The Transport Layer Protocol is UDP\n");
break;
/* 上层协议为UDP协议 */
case IPPROTO_ICMP:
printf("The Transport Layer Protocol is ICMP\n");
break;
/* 上层协议为ICMP协议 */
case IPPROTO_IGMP:
printf("The Transport Layer Protocol is IGMP\n");
break;
default:
break;
}
printf("TCP pkt :FORM:[%s]\n",inet_ntoa(*(struct in_addr*)&(ip_protocol->saddr)));
printf("TCP pkt :TO: [%s]\n",inet_ntoa(*(struct in_addr*)&(ip_protocol->daddr)));
switch (ip_protocol->protocol)
{
case IPPROTO_TCP:
tcp_protocol_packet_callback(packet_content);
break;
case IPPROTO_UDP:
udp_protocol_packet_callback(packet_content);
break;
default:
break;
}
}
/*
=============================================================================================================
下面是分析以太网协议的回调函数的定义
=============================================================================================================
*/
void ethernet_protocol_packet_callback( 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");
printf("---------- ARP Protocol (Network Layer) ----------\n");
break;
/* 上层协议为ARP协议 */
case 0x8035:
printf("The network layer is RARP protocol\n");
printf("---------- RARP Protocol (Network Layer) ----------\n");
break;
/* 上层协议为RARP协议 */
default:
break;
}
switch (ethernet_type)
{
case 0x0800:
ip_protocol_packet_callback( packet_content);
break;
// 上层协议为IP协议,就调用分析IP 协议的函数,注意参数的传递
default:
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));
// 获得目的以太网地址
break;
}
printf("**************************************************\n");
packet_number++;
}
char buf[40960];
int main()
{
struct sockaddr_in addr;
int sock;
int r = 0;
socklen_t len = 0;
u_char *ptemp;
if((sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) //建立socket ,man socket可以看到上面几个宏的意思
{
die("socket", 1);
}
do_promisc("eth0", sock); //eth0为网卡名称
system("ifconfig");
for(;;)
{
len = sizeof(addr);
if(recvfrom(sock,(char *)buf,sizeof(buf), 0, (struct sockaddr *)&addr,&len) > 0){
}
else{
continue;
}
//成功则返回接收到的字符数,失败返回-1,调试的时候可以增加一个输出r的语句判断是否抓到包
buf[r] = 0;
ptemp = buf;
ethernet_protocol_packet_callback(ptemp);//调用以太网协议的回调函数
usleep(1000);
// perror("dump");
}
return 0;
}
分享到:
相关推荐
### Linux下的抓包程序 #### 知识点概述 本文主要介绍了Linux环境下抓包程序的基本原理及应用。抓包程序通常工作在数据链路层,主要用于捕获网络中传输的数据包,进而对这些数据包进行解析和分析。此外,本文还...
libpcap提供了一个跨平台的API,允许程序员以统一的方式在不同的操作系统上编写抓包程序。它支持多种网络设备,并且能够实时捕获网络上的数据包。通过调用libpcap的函数,开发者可以设置过滤规则,指定捕获特定类型...
在Linux环境下编写一个网卡抓包程序,可以通过原始套接字(raw socket)对本机网卡上的数据包进行捕获。原始套接字允许程序员访问网络层以下的数据包,可以用来开发网络监控工具、协议分析器等应用。网卡抓包程序...
标题中的“pcap在Linux简单实现网络的抓包程序”是指使用libpcap库在Linux操作系统下编写网络数据包捕获程序的过程。libpcap是一个跨平台的库,广泛用于网络监控、数据分析和安全检测等领域。它允许程序员访问底层...
本文将深入探讨Linux环境下的网络抓包工具,特别是标题中提到的基于Qt界面的pcap实现。首先,我们来了解一下`pcap`。 `pcap`是libpcap库的简称,它是一个开源的网络数据包捕获库,广泛应用于各种网络分析软件,如...
Linux(RedHat) 抓包及 Ethereal 抓包工具的使用方法借鉴 Linux 抓包是一种网络协议分析技术,用于捕获和分析网络中的数据包。tcpdump 是 Linux 中最常用的抓包工具之一,能够捕获网络中的数据包并将其存储到文件中...
在提供的"linux 抓包程序libpcap.txt"文件中,可能包含了使用libpcap库在Linux上实现的抓包程序源代码。通过阅读和理解这部分代码,你可以了解到如何使用libpcap API来打开网络接口、设置过滤器、接收数据包和处理...
抓包程序通常是利用操作系统底层接口,如Windows的WinPCAP或Linux的libpcap库,来捕获网络接口卡上的原始网络数据包。这些库提供了访问网络数据包的底层能力,而C++源代码则意味着你可以查看并理解程序的工作原理,...
综上所述,这个名为"M_SS.zip"的压缩包可能包含了一个使用`libpcap`或其他方法实现的Linux网卡抓包程序,以及用于解析和分析数据包的代码。通过学习这些代码,我们可以深入了解Linux环境下的网络监控技术,以及如何...
IPv6网络抓包程序是一种用于监测和分析网络通信的工具,它使用了WpdPack库来捕获和解析IPv6数据包。WpdPack库是一个广泛使用的网络开发资源,特别适用于网络诊断、性能测试和协议分析。在这个程序中,我们重点关注的...
Socket抓包程序是一种用于捕获网络数据包的工具,它可以帮助开发者、网络安全专家以及学习者了解网络通信的细节。在IT行业中,理解网络协议和数据传输过程是非常关键的技能,而socket抓包程序则为此提供了直观的窗口...
【标题】"JAVA网络抓包程序Java源码"所涉及的知识点主要集中在Java编程语言以及网络数据包捕获技术上。网络抓包是网络分析的一种重要手段,它可以帮助开发者、网络安全专家或普通用户查看网络通信的详细信息。在这个...
【简单的抓包程序sniifer】是一个个人编写的用于学习和娱乐的小型网络抓包工具。这个程序的主要目的是帮助用户捕获和分析网络上的数据包,以便更好地理解网络通信过程和数据传输机制。抓包程序在IT领域是网络诊断、...
支持tcp、udp、ARP、icmp等协议并带有协议内容分析
Linux的抓包程序tcpdump是网络诊断和分析的重要工具,它允许系统管理员或开发者捕获网络上的数据包,以便分析网络通信的问题、监控网络活动或者进行安全审计。tcpdump能够解析并显示各种网络协议的数据包详细信息,...
从给定的代码片段来看,这是一段实现了在Windows和Linux两种操作系统环境下运行的抓包程序的源代码。抓包程序通常用于网络监控、故障排查、安全分析等场景,能够捕获并解析网络中的数据包,帮助理解网络通信的具体...
本程序实现的是在两台机器之间抓包的功能,实验环境是linux
Java源码实现的网络抓包程序是一个用于监测和分析网络数据传输的应用,它可以帮助开发者、安全研究人员或网络管理员了解网络中的通信细节。本程序的核心原理是利用Java的套接字编程和网络协议知识,通过捕获网络接口...
网络抓包工具是一种用于监测和分析网络数据传输的软件,它们可以帮助我们查看网络中的数据包流动情况,这对于网络故障排查、网络安全分析以及软件调试等工作至关重要。本文将详细讲解网络抓包工具的功能、工作原理...