C语言实现抓包工具

举报
C语言C加加学习 发表于 2018/12/21 15:43:17 2018/12/21
【摘要】 本文使用libpcap库在linux下面开发自定义抓包工具,同学们也可以在win下编写同样的代码。抓包的目的:1、分析协议2、伪造数据包3、获取重要信息,例如用户名和密码4、做某些攻击使用抓包的工具(1)Wireshark 可视化的工具(2)Tcpdump是命令行的工具。(3)自定义抓包工具原因1: 只抓取感兴趣的部分,去掉无关紧要的东西,为其他目的服务。原因2:如果有别的目的,例如偷偷安装...

本文使用libpcap库在linux下面开发自定义抓包工具,同学们也可以在win下编写同样的代码。

抓包的目的:

1、分析协议
2、伪造数据包
3、获取重要信息,例如用户名和密码
4、做某些攻击使用

抓包的工具

(1)Wireshark 可视化的工具
在这里插入图片描述
(2)Tcpdump
是命令行的工具。
(3)自定义抓包工具
原因1: 只抓取感兴趣的部分,去掉无关紧要的东西,为其他目的服务。
原因2:如果有别的目的,例如偷偷安装在别的机器上,有必要保持隐身,保持短小。

抓包工具的构造原理

(1)用原始套接字抓取所有的数据包,然后解析。
(2)使用现成的库来抓包。
Libpcap库,是在linux下面的一个库。如果是windows开发的话,可以使用wincap这个库。两个的函数等都是一样。

欢迎加入学习群【892643663】,获取全套免费C/C++企业实战级课程资源(素材+源码+视频)和编译大礼包

自定义抓包工具的编程过程

(1)想要抓到链路层的包,要打开网卡设备。(在linux下面会把所有的设备当成文件,linux的哲学之一)相当于从这个网卡文件里抓取文件内容。

(2)设置好过滤规则,只保留特定的包

(3)开始抓包,然后输出感兴趣的部分

代码

#include <unistd.h>
#include <pcap.h>  //libpcap库的头文件
#include <arpa/inet.h>
#include <netinet/ip.h>  //ip协议定义
#include <netinet/tcp.h>  //tcp协议定义
#include <stdio.h>
#include <string.h>
//用C语言手工写一个抓包工具

int main(void)
{
    //1-1 找出可用的网卡
    pcap_if_t *pcap_if;
    char ErrorBuf[PCAP_ERRBUF_SIZE]={0};
    int r=pcap_findalldevs(&pcap_if,ErrorBuf);//寻找所有网卡设备
    if(r==-1) //异常
    {
        printf("finddev error\n");
        return -1;//直接返回,不要再往下走
    }
    printf("第一个网卡的名字是%s\n",pcap_if[0].name);
    printf("第二个网卡的名字是%s\n",pcap_if[1].name);

    //1-2 打开那个网卡设备
    pcap_t *handler;  //用来描述一个打开的网卡设备对象
    handler=pcap_open_live(pcap_if[0].name,PCAP_BUF_SIZE,1,100,ErrorBuf);
    if(handler==NULL)
    {
        printf("打开失败\n");
        return -1;
    }

    //2 设置好过滤规则,只抓取tcp的包
    unsigned int ip,mask;
    r=pcap_lookupnet(pcap_if[0].name,&ip,&mask,ErrorBuf);
    if(r==-1)
    {
        printf("ip获取失败");
        return -1;
    }
    struct bpf_program prog;
    r=pcap_compile(handler,&prog,"tcp",0,mask);//规则有n种写法,例如port 80表示抓取80端口的包
    if(r==-1)
    {
        printf("编译失败\n");
        return -1;
    }
    pcap_setfilter(handler,&prog);

    //3 抓包
    struct pcap_pkthdr pkhdr;//包的信息
    while(1)
    {
        const unsigned char *packet=pcap_next(handler,&pkhdr);//一行就可以拿到一个包
        if(packet==NULL)
        {
            pcap_close(handler);
            break;
        }
        //将包的信息打出来
        printf("包的长度是%d\n",pkhdr.len);
        // int i;
        // for(i=0;i<pkhdr.len;i++)
        // {
        //     printf("%02x ",packet[i]);
        // }
        // printf("\n");

    //4 输出感兴趣的部分
    //例如,只输出包的源头,目标的ip和端口
    //包由链路层14个字节+ip层20字节+后面的tcp数据组成
    struct ip *ip=(struct ip *)(packet+14);
    struct tcphdr *tcp=(struct tcp *)(packet+14+20);
    char ipsrc[30],ipdst[30];
    //strcpy(ipsrc,inet_ntoa(ip->ip_src));
    inet_ntop(AF_INET,&ip->ip_dst,ipsrc,30);
    strcpy(ipdst,inet_ntoa(ip->ip_dst));
    printf("%s(%d)=====>%s(%d)\n",ipsrc,ntohs(tcp->th_sport),ipdst,ntohs(tcp->th_dport));

    }
}

欢迎加入学习群【892643663】,获取全套免费C/C++企业实战级课程资源(素材+源码+视频)和编译大礼包


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。