【前言】通过对数据包的分析,我们可以判断通信双方的操作系统、网络信息流量、经过的路由、数据包的大小,以及数据包的内容等等。尤其对于喜欢网络安全的人来说,掌握这方面的知识是相当重要的。本文介绍一个基于Linux平台实现的网络抓包工具。

0.基础知识

在Linux环境下,可以使用raw

socket,即原始套接字,接收本机网卡上的数据帧或者数据包,实现对与监听网络的流量和分析是很有作用的。一共可以有3种方式创建这种socket:

1.socket(AF_INET,

SOCK_RAW, IPPROTO_TCP|IPPROTO_UDP|IPPROTO_ICMP)发送接收ip数据包

2.socket(PF_PACKET,

SOCK_RAW, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL))发送接收以太网数据帧

3.socket(AF_INET,

SOCK_PACKET, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL))过时了,不要用啊 1.程序代码

/********************************************************

*

功能:网络抓包工具

* 环境: GCC-4.2.4

* 作者:YSQ-NJUST,yushengqiangyu@163.com

*

备注:自由软件,主要用于学习、交流、共享。

*******************************************************/

#include

#include #include

#include #include

#include #include

#include #include

#include #include

#include #include

#include #include

/* 接收缓冲区大小 */

#define RCV_BUF_SIZE     1024 * 5

/* 接收缓冲区 */

static int g_iRecvBufSize = RCV_BUF_SIZE;

static char

g_acRecvBuf[RCV_BUF_SIZE] = {0};

/* 物理网卡接口,需要根据具体情况修改 */

static const char *g_szIfName = "eth1";

/*

以太网帧封装的协议类型 */

static const int      g_iEthProId[] = {

ETHERTYPE_PUP,

ETHERTYPE_SPRITE,

ETHERTYPE_IP,

ETHERTYPE_ARP,

ETHERTYPE_REVARP,

ETHERTYPE_AT,

ETHERTYPE_AARP,

ETHERTYPE_VLAN,

ETHERTYPE_IPX,

ETHERTYPE_IPV6,

ETHERTYPE_LOOPBACK

};

static const

char g_szProName[][24] = { "none", "xerox pup", "sprite", "ip",

"arp",

"rarp", "apple-protocol",

"apple-arp",

"802.1q", "ipx",

"ipv6", "loopback"

};

/* 输出MAC地址 */

static void ethdump_showMac(const int iType, const char

acHWAddr[])

{

int i = 0;

if (0 == iType)

{

printf("SMAC=[");

}

else

{

printf("DMAC=[");

}

for(i = 0; i < ETHER_ADDR_LEN - 1; i++)

{

printf("%02x:", *((unsigned char *)&(acHWAddr[i])));

}

printf("%02x] ", *((unsigned char *)&(acHWAddr[i])));

}

/* 物理网卡混杂模式属性操作 */

static int ethdump_setPromisc(const char *pcIfName, int

fd, int iFlags)

{

int iRet = -1;

struct ifreq stIfr;

/* 获取接口属性标志位 */

strcpy(stIfr.ifr_name, pcIfName);

iRet =

ioctl(fd, SIOCGIFFLAGS, &stIfr);

if (0 > iRet)

{

perror("[Error]Get Interface Flags");

return -1;

}

if (0 == iFlags)

{

/* 取消混杂模式 */

stIfr.ifr_flags &= ~IFF_PROMISC;

}

else

{

/*

设置为混杂模式 */

stIfr.ifr_flags |= IFF_PROMISC;

}

iRet = ioctl(fd, SIOCSIFFLAGS, &stIfr);

if (0 >

iRet)

{

perror("[Error]Set Interface Flags");

return -1;

}

return 0;

}

/* 获取L2帧封装的协议类型 */

static char *ethdump_getProName(const int

iProNum)

{

int iIndex = 0;

for(iIndex = 0; iIndex <

sizeof(g_iEthProId) / sizeof(g_iEthProId[0]); iIndex++)

{

if

(iProNum == g_iEthProId[iIndex])

{

break;

}

}

return (char *)(g_szProName[iIndex + 1]);

}

/* Init L2 Socket */

static int ethdump_initSocket()

{

int iRet

= -1;

int fd = -1;

struct ifreq stIf;

struct sockaddr_ll

stLocal = {0};

/* 创建SOCKET */

fd = socket(PF_PACKET,

SOCK_RAW, htons(ETH_P_ALL));

if (0 > fd)

{

perror("[Error]Initinate L2 raw socket");

return -1;

}

/* 网卡混杂模式设置 */

ethdump_setPromisc(g_szIfName, fd,

1);

/* 设置SOCKET选项 */

iRet = setsockopt(fd, SOL_SOCKET, SO_RCVBUF,

&g_iRecvBufSize,sizeof(int));

if (0 > iRet)

{

perror("[Error]Set socket option");

close(fd);

return

-1;

}

/* 获取物理网卡接口索引 */

strcpy(stIf.ifr_name,

g_szIfName);

iRet = ioctl(fd, SIOCGIFINDEX, &stIf);

if (0 >

iRet)

{

perror("[Error]Ioctl operation");

close(fd);

return -1;

}

/* 绑定物理网卡 */

stLocal.sll_family = PF_PACKET;

stLocal.sll_ifindex = stIf.ifr_ifindex;

stLocal.sll_protocol =

htons(ETH_P_ALL);

iRet = bind(fd, (struct sockaddr *)&stLocal,

sizeof(stLocal));

if (0 > iRet)

{

perror("[Error]Bind the interface");

close(fd);

return

-1;

}

return fd;

}

/* 解析Ethernet帧首部 */

static int ethdump_parseEthHead(const struct

ether_header *pstEthHead)

{

unsigned short usEthPktType;

if (NULL == pstEthHead)

{

return -1;

}

/* 协议类型、源MAC、目的MAC */

usEthPktType =

ntohs(pstEthHead->ether_type);

printf(">>>\nEth-Pkt-Type:0x%04x(%s) ", usEthPktType,

ethdump_getProName(usEthPktType));

ethdump_showMac(0,

pstEthHead->ether_shost);

ethdump_showMac(1,

pstEthHead->ether_dhost);

return 0;

}

/* 解析IP数据包头 */

static int ethdump_parseIpHead(const struct ip

*pstIpHead)

{

struct protoent *pstIpProto = NULL;

if (NULL == pstIpHead)

{

return -1;

}

/* 协议类型、源IP地址、目的IP地址 */

pstIpProto =

getprotobynumber(pstIpHead->ip_p);

if(NULL != pstIpProto)

{

printf("\nIP-Pkt-Type:%d(%s) ", pstIpHead->ip_p,

pstIpProto->p_name);

}

else

{

printf("\nIP-Pkt-Type:%d(%s) ", pstIpHead->ip_p, "None");

}

printf("SAddr=[%s] ", inet_ntoa(pstIpHead->ip_src));

printf("DAddr=[%s]\n", inet_ntoa(pstIpHead->ip_dst));

return 0;

}

/* 数据帧解析函数 */

static int ethdump_parseFrame(const char

*pcFrameData)

{

int iRet = -1;

struct ether_header *pstEthHead = NULL;

struct ip *pstIpHead =

NULL;

/* Ethnet帧头解析 */

pstEthHead = (struct

ether_header*)g_acRecvBuf;

iRet =

ethdump_parseEthHead(pstEthHead);

if (0 > iRet)

{

return iRet;

}

/* IP数据包类型 */

pstIpHead  = (struct ip *)(pstEthHead + 1);

iRet = ethdump_parseIpHead(pstIpHead);

return iRet;

}

/* 捕获网卡数据帧 */

static void ethdump_startCapture(const int fd)

{

int iRet = -1;

socklen_t stFromLen = 0;

/* 循环监听 */

while(1)

{

/* 清空接收缓冲区 */

memset(g_acRecvBuf, 0,

RCV_BUF_SIZE);

/* 接收数据帧 */

iRet = recvfrom(fd, g_acRecvBuf,

g_iRecvBufSize, 0, NULL, &stFromLen);

if (0 > iRet)

{

continue;

}

/* 解析数据帧

*/

ethdump_parseFrame(g_acRecvBuf);

}

}

/* Main */

int main(int argc, char *argv[])

{

int iRet =

-1;

int fd   = -1;

/* 初始化SOCKET */

fd =

ethdump_initSocket();

if(0 > fd)

{

return -1;

}

/* 捕获数据包 */

ethdump_startCapture(fd);

/*

关闭SOCKET */

close(fd);

return 0;

}

2.编译命令

sudo gcc -g -o dump dump.c

sudo ./dump

3.运行效果

...

>>>Eth-Pkt-Type:0x0800(ip) SMAC=[00:1a:92:ef:b6:dd]

DMAC=[00:24:7e:dc:99:18] IP-Pkt-Type:6(tcp) SAddr=[192.168.0.111]

DAddr=[192.168.0.100]

>>> Eth-Pkt-Type:0x0800(ip) SMAC=[00:24:7e:dc:99:18]

DMAC=[00:1a:92:ef:b6:dd] IP-Pkt-Type:6(tcp) SAddr=[192.168.0.100]

DAddr=[192.168.0.111]

>>> Eth-Pkt-Type:0x0800(ip) SMAC=[00:24:7e:dc:99:18]

DMAC=[00:1a:92:ef:b6:dd] IP-Pkt-Type:1(icmp) SAddr=[192.168.0.100]

DAddr=[192.168.0.111]

>>> Eth-Pkt-Type:0x0800(ip) SMAC=[00:1a:92:ef:b6:dd]

DMAC=[00:24:7e:dc:99:18] IP-Pkt-Type:1(icmp) SAddr=[192.168.0.111]

DAddr=[192.168.0.100]

>>> Eth-Pkt-Type:0x0800(ip) SMAC=[00:1a:92:ef:b6:dd]

DMAC=[00:24:7e:dc:99:18] IP-Pkt-Type:6(tcp) SAddr=[192.168.0.111]

DAddr=[192.168.0.100]

...

linux网卡抓包命令,基于Linux Socket实现的网卡抓包程序相关推荐

  1. linux查看网卡的驱动命令行,Linux下查看网卡驱动和版本信息

    Linux下查看网卡驱动和版本信息 查看网卡生产厂商和信号 查看基本信息:lspci 查看详细信息:lspci -vvv # 3个小写的v 查看网卡信息:lspci | grep Ethernet 查 ...

  2. linux查找数据包contr,基于Linux防火墙的P2P报文识别研究-计算机技术专业论文.docx...

    基于Linux防火墙的P2P报文识别研究-计算机技术专业论文 掣哪炒I掣j!:|l哕必磐 掣哪炒I掣j!:|l哕必磐Y1 9 1 7709 原创性声明 本人声明,所呈交的学位论文是本人在导师指导下进行 ...

  3. linux服务器性能查看命令,查看Linux服务器性能的日常命令和工具大全

    通过使用以下命令和工具,可以在1分钟内对系统资源使用情况有个大致的了解uptime dmesg | tail vmstat 1 mpstat -P ALL 1 pidstat 1 iostat -xz ...

  4. Linux拉取代码启动镜像,基于Linux源代码及Busybox源代码制作精简可启动内核镜像技术实验方法...

    基于Linux源代码及Busybox源代码制作精简可启动内核镜像技术实验方法总结 熊海泉 内核源代码 下载地址 这里下载的是linux-2.6.38.tar.bz源代码 下载地址 这里下载的是busy ...

  5. linux定时执行任务命令,crontab(linux下定时执行任务命令)

    在linux在可以通过在脚本里(列如sh)写如日常需要进行的操作,然后通过crontab定时运行脚本. Linux下的任务调度分为两类,系统任务调度和用户任务调度. 系统任务调度:系统周期性所要执行的 ...

  6. linux测试自动化,一种基于Linux系统下自动化测试RoCE性能的方法及系统与流程

    本发明涉及自动化测试的技术领域,特别涉及一种基于Linux系统下自动化测试roce性能的方法及其系统. 背景技术: 现在迅速发展的服务器行业,对网络服务性能提出了越来越高的要求.特别是在互联网行业以及 ...

  7. linux远程执行shell命令行,linux shell 远程执行命令--ftp

    linux shell 远程执行命令--ftp 2018-12-07 ftp有很多命令,熟悉这些命令你能大大的提高工作效率: FTP命令行格式为: ftp -v -d -i -n -g [主机名] , ...

  8. linux下添加apt-get命令,Ubuntu Linux系统下apt-get命令整理

    Ubuntu Linux系统下apt-get命令整理 首次接触ubuntu,很多命令都需要sudo.尤其是安装命令都需要apt . 这里做个apt命令的简单汇总,方便一来了解下加深印象,二来以便以后使 ...

  9. linux 认证 转发,一种基于Linux系统实现路由器的portal认证报文转发方法和装置

    主权项: 1.一种基于Linux系统实现路由器的portal认证报文转发方法,其特征在于,在Linux系统上创建虚拟网卡,为虚拟网卡配置环回口IP地址,配置portal进程监听环回口的TCP协议预设端 ...

最新文章

  1. python在内存中生成Zip文件!
  2. Linq查询datatable的记录集合
  3. ecshop彻底去版权把信息修改成自己的全教程
  4. PAT乙级 1004 成绩排名
  5. 【ES】es 冻结的索引如何查询
  6. python十大必备知识_python学习必备知识汇总
  7. 电池供电的电容麦_板儿砖变电池?!是的,科学家已成功实现这一功能
  8. Eureka/Zookeeper/Consul三种注册中心的区别
  9. 【转】numpy.random.randn()与rand()的区别
  10. Android游戏编程之从零开始pdf
  11. 单片机原理及接口技术
  12. Linux中命令行中EOF的用法
  13. 计算机如何删除程序,win7电脑怎么卸载软件
  14. 上海基诺墙绘 中荷学生共同创作涂鸦 “We are伐木累”示好
  15. qlabel 详解
  16. 2021-07-28 产品开发过程纪实-家用洗菜-智商税收割
  17. vcs使用一分钟速通
  18. grafana+graphit安装笔记
  19. 牛掰!100行Python,自动动手打造一款多国语言翻译软件,酷啊!
  20. postgresql根据周和年计算周对应的时间段

热门文章

  1. 参观了他的中式别墅,才懂何为诗意,里面的红木装修,太壕了!
  2. 心理咨询师考试 笔记[4]
  3. VC个性化窗口界面设计
  4. Linux操作系统基础知识
  5. 西部数码域名注册Python版本
  6. rest和soapui
  7. 爆肝2W字梳理50道计算机网络必问面试题
  8. word2016高级替换功能
  9. 原生js javascript 实现进度条拖动---移动端
  10. R语言数据表三元组(长数据)格式与宽数据格式转换