作者:lijunlin66_8460dd | 来源:互联网 | 2024-09-24 17:49
Linux数据链路层的包解析仅以此文作为学习笔记,初学者,如有错误欢迎批评指正,但求轻喷。一般而言,Linux系统截获数据包后,会通过协议栈,按照TCPIP层次进行解析,那我们如何
Linux数据链路层的包解析
仅以此文作为学习笔记,初学者,如有错误欢迎批评指正,但求轻喷。
一般而言,Linux系统截获数据包后,会通过协议栈,按照TCP/IP层次进行解析,那我们如何直接获得更为底层的数据报文呢,这里用到一个类型SOCK_PACKET类型。
int sockfd = socket(AF_INET,SOCK_PACKET,htons(0x0003));
通过上面这个函数可以获得一个特殊的套接字,其中:
- AF_INET: 表示因特网协议族
- SOCK_PACKET: 表示数据包截取在物理层
- 0x0003: 表示数据帧类型不确定
修改网络接口结构:
struct ifreq ifr;
strcpy(ifr.ifr_name,"eth0");
ioctl(sockfd,SIOCGIFFLAGS,&ifr);
设置混杂模式
ifr.ifr_flags| = IFR_PROMISC;
ioctl(sockfd,SIOCSIFFLAGS,&ifr);
注意:进行标志位设定时,遵循以下步骤:
- 取出原标识位;
- 与待设定标志位进行位或运算(“|”);
- 重新写入;
一个小小的抓包程序
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
char ethernet_frame[ETH_FRAME_LEN];//定义一个数据帧的长度
struct iphdr *ipheader;//定义ip头部指针
int socketcreate()
{
int sockfd = socket(AF_INET,SOCK_PACKET,htons(0x0003));
//构建了一个数据链路层的数据包;
if(sockfd == -1)
{
cout<<"Socket init error!"< return -1;
}
/*
下面设置接口结构
*/
char *ifname = "eth0";
struct ifreq ifr;
strcpy(ifr.ifr_name,ifname);
int result = ioctl(sockfd,SIOCGIFFLAGS,&ifr);
if(result == -1)
{
cout<<"Can't get flags!"< close(sockfd);
return -2;
}
ifr.ifr_flags|= IFF_PROMISC;
/*
一般而言,Linux系统截获数据包后,会通过协议栈,按照TCP/IP层次进行解析,那我们如何直接获得更为底层的数据报文呢,这里用到一个类型SOCK_PACKET类型。
int sockfd = socket(AF_INET,SOCK_PACKET,htons(0x0003));
通过上面这个函数可以获得一个特殊的套接字,其中:
AF_INET: 表示因特网协议族
SOCK_PACKET: 表示数据包截取在物理层
0x0003: 表示数据帧类型不确定
修改网络接口结构:
struct ifreq ifr;
strcpy(ifr.ifr_name,"eth0");
ioctl(sockfd,SIOCGIFFLAGS,&ifr);
设置混杂模式
ifr.ifr_flags| = IFR_PROMISC;
ioctl(sockfd,SIOCSIFFLAGS,&ifr);
注意:
进行标志位设定时,遵循以下步骤:
(1)取出原标识位;
(2)与待设定标志位进行位或运算(“|”);
(3)重新写入;
*/
result = ioctl(sockfd,SIOCSIFFLAGS,&ifr);
if(result == -1)
{
cout<<"Can't set flags!"< close(sockfd);
return -3;
} return sockfd;
}
int getframe(int sockfd,int num)
{
struct ethhdr* fheader;
fheader = (struct ethhdr*)ethernet_frame;
memset(ethernet_frame,0,ETH_FRAME_LEN);
int size = read(sockfd,ethernet_frame,ETH_FRAME_LEN);
if(size <= 0)
{
cout<<"No packet or packet error!"< return -1;
}
cout<<"************************Packet"< printf("DST MAC: ");
for(int i=0;i {
printf("%2x-",fheader->h_dest[i]);
}
printf("%2x\n",fheader->h_dest[ETH_ALEN-1]);
printf("SRC MAC: ");
for(int i=0;i {
printf("%2x-",fheader->h_source[i]);
}
printf("%2x\n",fheader->h_source[ETH_ALEN-1]);
if(ntohs(fheader->h_proto) == 0x0800)
{
cout<<"Protocol: IP"< }
if(ntohs(fheader->h_proto) == 0x0806)
{
cout<<"Protocol: RAP"< }
if(ntohs(fheader->h_proto) == 0x8035)
{
cout<<"Protocol: RARP"< }
int ret = ntohs(fheader->h_proto);
return ret;
}
int getip(int protocol,int num)
{
if(protocol != 0x0800)
{
cout<<"NO IP Packet!"< cout<<"************************Packet"< return 0;
}
ipheader = (struct iphdr*)(ethernet_frame+ETH_HLEN);
printf("Version: 4");
cout< in_addr *p,*q;
p = (struct in_addr*)&ipheader->saddr;
printf("SRC IP: %s",inet_ntoa(*p));
cout< q = (struct in_addr*)&ipheader->daddr;
printf("DST IP: %s",inet_ntoa(*q));
cout< if(ipheader->protocol == 1)
{
cout<<"PROTOCOL: ICMP"< }
if(ipheader->protocol == 6)
{
cout<<"PROTOCOL: TCP"< }
if(ipheader->protocol == 17)
{
cout<<"PROTOCOL: UDP"< }
return ipheader->protocol;
}
int gettcp(int protocol)
{
if(protocol != 6)
{
return -1;
}
struct tcphdr* tcph;
tcph = (struct tcphdr*)(ipheader+((ipheader->ihl)*4));
printf("SRC PORT: %d",ntohs(tcph->source));
cout< printf("DST PORT: %d",ntohs(tcph->dest));
cout< return 0;
}
int getudp(int protocol)
{
if(protocol != 17)
{
return -1;
}
struct udphdr* udph;
udph = (struct udphdr*)(ipheader+((ipheader->ihl)*4));
printf("SRC PORT: %d",ntohs(udph->source));
cout< printf("DST PORT: %d",ntohs(udph->dest));
cout< return 0;
}
int main(int argc,char *argv[])
{
if(argc <2)
{
cout<<"Please input the nummber of packet that you want to catch!"< return 0;
}
int num = (int)argv[1][0];
int sock = socketcreate();
for(int i=1;i {
int ip_protocol = getframe(sock,i);
int trasnport_protocol = getip(ip_protocol,i);
gettcp(trasnport_protocol);
getudp(trasnport_protocol);
cout<<"************************Packet"< cout< cout< cout< cout< }
return 0;
}