源代码:
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/in.h>
#include <linux/if_ether.h>
#include <net/if.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
int sock, n;
char buffer[2048];
unsigned char *iphead, ethhead;
struct ifreq ethreq;
int no=0;
//设置原始套接字方式为接受所有的数据包
if ( (sock=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)))<0) {
perror("\n原始套接字建立失败\n");
exit(1);
}
//设置网卡工作方式为混杂模式,SIOCGIFFLAGS请求表示需要获取接口标志
strncpy(ethreq.ifr_name,“ens33”,IFNAMSIZ);
if (ioctl(sock,SIOCGIFFLAGS,ðreq)-1) {
perror("\n设置混杂工作模式失败\n");
close(sock);
exit(1);
}
//开始捕获数据并进行简单分析
while (1) {
n = recvfrom(sock,buffer,2048,0,NULL,NULL);
no++;
printf("\n\n ******************************\n\n");
//检查包是否包含了至少完整的以太帧(14),IP(20)和TCP/UDP(8)包头
if (n<42) {
perror(“recvfrom():”);
exit(0);
}
ethhead = buffer;
printf(“Dest MAC address:%02x:%02x:%02x:%02x:%02x:%02x\n”,
ethhead[0],ethhead[1],ethhead[2],ethhead[3],ethhead[4],ethhead[5]);
printf(“Source MAC address:%02x:%02x:%02x:%02x:%02x:%02x\n”,
ethhead[6],ethhead[7],ethhead[8],ethhead[9],ethhead[10],ethhead[11]);
iphead = buffer+14; /*跳过Ethernet header */
if (*iphead0x45) {
/ Double check for IPv4 and no options present */
printf(“Source host: %d.%d.%d.%d\n”,
iphead[12],iphead[13],iphead[14],iphead[15]);
printf(“Dest host: %d.%d.%d.%d\n”,
iphead[16],iphead[17],iphead[18],iphead[19]);
printf(“Source port:%d,Dest port:%d\n”,
(iphead[20]<<8)+iphead[21],(iphead[22]<<8)+iphead[23]);//端口号为int:左移八位
if(iphead[9]==6)
printf(“protocol TCP\n”);
else if(iphead[9]==17)
printf(“protocol UDP\n”);
else
printf(“Not TCP or UDP,protocol id %d\n”,iphead[9]);
}
}
}
运行结果如图:
(1)输入ifconfig:查看本机配置
输入route -n:查看网关IP
(2)Ping网关(192.168.18.2):
运行程序抓包分析:
由上图可知,源MAC地址:00:50:56:f6:0a:ff;目的MAC地址:00:0c:29:97:aa:01;
源IP:192.168.18.2;目的IP:192.168.18.129;
源端口号:0;目的端口号是动态变化的;
可知ping命令发送的包既不是TCP也不是UDP,但是其协议id为1.