需要清楚以太网帧头结构,tcp报头结构、udp报头结构
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/ether.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
int main()
{
int sockfd;
//SOCK_RAW提供原始网络协议访问
if((sockfd = socket(AF_PACKET,SOCK_RAW,ntohs(ETH_P_ALL))) < 0){
perror("socket error");
exit(1);
}
//接收数据并分析
unsigned char msg[1600] = "";
while (1) {
if(recvfrom(sockfd,msg,sizeof (msg),0,NULL,NULL) < 0){
perror("recvfrom error");
exit(1);
}
unsigned char src_mac[18] = "";
unsigned char dst_mac[18] = "";
unsigned short type;
sprintf(dst_mac,"%x:%x:%x:%x:%x:%x",msg[0],msg[1],msg[2],msg[3],msg[4],msg[5]);
sprintf(src_mac,"%x:%x:%x:%x:%x:%x",msg[6],msg[7],msg[8],msg[9],msg[10],msg[11]);
type = ntohs(*(unsigned short*)(msg+12));
printf("源mac地址:%s --> 目标mac地址:%s\n",src_mac,dst_mac);
printf("类型type:%#x\n",type);
if(type == 0x800){
printf("IP数据报\n");
//ip数据报头部长度、总长度
unsigned char ip_head_len;
unsigned short ip_len;
ip_head_len = (*(unsigned char *)(msg+14)&0x0f)*4;
ip_len = ntohs(*(unsigned short*)(msg+16));
printf("ip数据报头部长度:%d;ip数据报总长度:%d\n",ip_head_len,ip_len);
//获取源ip地址和目标ip地址
unsigned char dst_ip[16] = "";
unsigned char src_ip[16] = "";
sprintf(src_ip,"%u.%u.%u.%u",msg[26],msg[27],msg[28],msg[29]);
sprintf(dst_ip,"%u.%u.%u.%u",msg[30],msg[31],msg[32],msg[33]);
printf("源ip地址:%s --> 目标ip地址:%s\n",src_ip,dst_ip);
//得到协议号
unsigned char ip_types;
ip_types = *(msg+23);
printf("ip协议类型为:%d\n",ip_types);
if(ip_types == 1){
printf("ICMP报文\n");
}else if(ip_types == 2){
printf("IGMP报文\n");
}else if(ip_types == 6){
printf("TCP报文\n");
//获得目标端口号和源端口号
unsigned short dst_port;
unsigned short src_port;
src_port = ntohs(*(unsigned short*)(msg+34));
dst_port = ntohs(*(unsigned short*)(msg+36));
printf("源端口号为:%d --> 目标端口号为:%d\n",src_port,dst_port);
}else if(ip_types == 17){
printf("UDP报文\n");
//获得目标端口号和源端口号
unsigned short dst_port;
unsigned short src_port;
src_port = ntohs(*(unsigned short*)(msg+34));
dst_port = ntohs(*(unsigned short*)(msg+36));
printf("源端口号为:%d --> 目标端口号为:%d\n",src_port,dst_port);
}
}else if(type == 0x0806){
printf("ARP数据报\n");
//获取源ip地址和目标ip地址
unsigned char dst_ip[16] = "";
unsigned char src_ip[16] = "";
sprintf(src_ip,"%u.%u.%u.%u",msg[28],msg[29],msg[30],msg[31]);
sprintf(dst_ip,"%u.%u.%u.%u",msg[38],msg[39],msg[40],msg[41]);
printf("源ip地址:%s --> 目标ip地址:%s\n",src_ip,dst_ip);
}else if(type == 0x8035){
printf("RARP数据报\n");
}
printf("\n******************\n\n");
}
close(sockfd);
return 0;
}