首页 > 其他分享 >网络开发工具

网络开发工具

时间:2023-10-16 14:00:10浏览次数:32  
标签:libnet int 数据包 捕获 网络 char 开发工具 pcap

网络开发工具

1. libpcap库

1.1 libpcap库

  • 是一个网络数据捕获开发包
  • 平台独立具有强大功能
  • 是一套高层的编程接口的集合;其隐藏了操作系统的细节,可以捕获网上的所有,包括到达其他主机的数据包
  • 使用非常广泛,几乎只要涉及到网络数据包的捕获的功能,都可以用它开发
  • 开发语言为C语言

1.2 libpcap主要的作用

  • 捕获各种数据包
  • 过滤网络数据包
  • 分析网络数据包
  • 存储网络数据包

1.3 libpcap的安装

Ubantu:

sudo apt-get install libpcap-dev

注意:

1、gcc 编译时需要加上 -lpcap

2、运行时需要使用超级权限

1.4 libpcap开发流程

1、打开网络设备

2、设置过滤规则

1)先编译过滤规则 2)设置过滤规则

3、捕获数据 【重要】

4、关闭网络设备

1.5 libpcap函数

头文件:#include <pcap/pcap.h>

常用函数:

1. pcap_lookupdev()
2. pcap_open_live()
3. pcap_lookupnet()
4. pcap_compile()、pcap_setfilter()
5. pcap_next()、pcap_loop()
6. pcap_close()

1. pcap_lookupdev

获取可用的网络设备名指针

char *pcap_lookupdev(char *errbuf);

参数:errbuf:存放相关的错误信息

返回值:成功返回设备名指针,失败返回NULL

2. pcap_lookupnet

获得指定网络设备的网络号和掩码

int pcap_lookupnet(char *device,bpf_u_int32 *netp,bpf_u_int32 *maskp,char *errbuf);

参数:

  • device:网络设备名
  • netp:存放网络号的指针
  • maskp:存放掩码的指针
  • errbuf:存放出错信息

返回值:成功0,失败-1

3. pcap_open_live

打开一个用于捕获数据的网络接口

pcap_t *pcap_open_live(const char*device,int snaplen,int promise,int to_ms,char *ebuf);

参数:

  • device:网络接口的名字

  • snaplen:捕获数据包的长度

  • promise:1代表混杂模式,其他非混杂模式

  • to_ms:等待时间,单位毫秒

    • 0,表示不等待
    • 正数,表示等待的毫秒时间
    • -1,表示无限等待
  • ebuf:存储错误信息

返回值:返回libpcap句柄

4. pcap_next

捕获一个网络数据

const u_char *pcap_next(pcap_t *p,struct pcap_pkthdr *h);

参数:

  • p:libpcap句柄
  • h:数据包头

struct pcap_pkthdr结构体:

struct pcap_pkthdr
{
    struct timeval ts; // 抓到包的时间
    bpf_u_int32 caplen; // 表示抓到的数据长度
    bpf_u_int32 len; // 表示数据包的实际长度
}

返回值:捕获的数据包的地址

5. pcap_loop

循环捕获网络数据包,每收到一个数据,就会触发callback函数

int pcap_loop(pcap_t *p,int cnt,pcap_handler callback,u_char *user);

参数:

  • p:libpcap句柄

  • cnt:指定捕获数据包的个数,如果是1,就会永无休止的捕获

  • callback:回调函数

    void callback(u_char *userarg,const struct pcap_pkthdr *pkthdr,const u_char *packet);
    
    • userarg:用户传递过来的数据
    • pkthdr:帧数据的头信息(帧数据的长度)
    • packet:帧数据
  • user:向回调函数中传递的参数,通常采用NULL

6. pcap_close

关闭libpcap的句柄

void pcap_close(pcap_t *p);

7. pcap_compile

编译BPF(Berkeley Packet Filter)过滤规则的函数,BPF规则主要用于如tcpdump和wireshark等网络抓包工具中

int pcap_compile(pcap_t *p,struct bpf_program *program,char *buf,int optimize,bpf_u_int32 mask);

参数:

  • p:libpcap句柄
  • program:存放编译号的bpf过滤规则
  • buf:过滤规则字符串
  • optmize:优化 默认为0表示不优化
  • mask:网络掩码

返回值:成功0,失败-1

过滤字符串的格式(接收数据的格式):

1.mac地址过滤
ether host 11:22:33:44:55:66 表示捕获源/目的mac地址为11:22:33:44:55:66的数据包

ether src 11:22:33:44:55:66 表示捕获源mac地址为11:22:33:44:55:66的数据包
ether dst 11:22:33:44:55:66 表示捕获目的mac地址为11:22:33:44:55:66的数据包

2.IP地址过滤
host 192.168.0.2 表示捕获源/目的地址为192.168.0.2的数据报文
src host 192.168.0.2 表示捕获源地址为192.168.0.2的数据报文
dst host 192.168.0.2 表示捕获目的地址为192.168.0.2的数据报文

ip src host 192.168.0.2表示捕获源地址为192.168.0.2的IP协议数据报。
ip dst host 192.168.0.2表示捕获目的地址为192.168.0.2的IP协议数据报。

3.端口过滤
port 8000 表示捕获源/目的端口为8000的数据报文
src port 8000 表示捕获源端口为8000的数据报文
dst port 8000 表示捕获目的端口为8000的数据报文

tcp src port 8000 表示捕获源端口为8000的TCP数据报文
tcp dst port 8000 表示捕获目的端口为8000的TCP数据报文

udp src port 8000 表示捕获源端口为8000的udp数据报文
udp dst port 8000 表示捕获目的端口为8000的udp数据报文

4. 协议过滤
tcp udp tftp http icmp...
5. 多条语句关系
and表示同时成立,or表示任意一个条件为真则成立

8. pcap_setfilter

设置BPF过滤规则对象

int pcap_setfilter(pcap *p,struct bpt_program *fp);

参数:

  • p:libpcap句柄
  • fp:编译成功的BPF过滤规则指针对象

返回值:成功0,失败-1

如:

#include <pcap.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <netinet/ip.h>

void  recv_data_handle(u_char *userarg,const struct pcap_pkthdr *cap_hdr,const u_char *data)
{
    if(cap_hdr->caplen > 0)
    {
        printf("捕获的数据长度:%d,实际长度:%d\n",cap_hdr->caplen,cap_hdr->len);
        //分析UDP报文,输出src ip,数据
        printf("data:%s\n",data+14+20+8);
    }
    sleep(1);
}

int main(int argc,char const *argc[])
{
    //1.获取可用的网络设备名称
    char *dev = pcap_lookupdev(NULL);
    if(dev!=NULL)
    {
        printf("网络设备名称:%s\n",dev);
    }
    
    //2.打开网络设备,开始捕获数据
    pcap_t *cap = pcap_open_live(dev,128,0,0,NULL);
    if(cap == NULL)
    {
        printf("open pcap fail!")
            return -1;
    }
    
    //编译过滤规则,成功则设置过滤规则
    char filter[]="udp dst port 8001";
    struct bpf_program program;
    if(pcap_compile(cap,&program,filter,0,0xffffff00)==0)
    {
        pcap_setfilter(cap,&program);
    }
    
    //循环捕获数据
    pcap_loop(cap,-1,recv_data_handle,NULL);
    
    //关闭网络设备
    pcap_close(cap);
    return 0;
}

2. libnet库

2.1 libnet的概述

专业的构造和发送网络数据包的开发工具包

隐藏了很多底层细节,省去了很多麻烦;如缓冲区管理、字节留顺序、校验和计算等问题,使开发者把重心放到程序的开发中

2.2 libnet安装

sudo apt-get install libnet-dev

开发时引用头文件: #include <libnet.h>

编译时加: -lnet

2.3 libnet开发流程

1、数据包内存初始化

2、构造数据包, 由UDP或TCP层到MAC层的顺序构造

3、发送数据

4、释放资源

2.4 libnet的函数

2.4.1 libnet_init

数据包内存初始化及环境建立

libnet_t *libnet_init(int injection_type,char *device,char *err_buf);

参数:

  • injection_type:构造的类型
    • LIBNET_LINK 链路层注入方式,可以直接操作链路层帧
    • LIBNET_RAW4 原始IPV4注入方式,可以构造和发送原始的IPV4数据包,但不能直接操作链路层帧
    • LIBNET_RAW6 原始IPV6注入方式
    • LIBNET_RAW 原始注入方式,这是个通用的选项,可以根据需要自动选择IPV4或IPV6注入方式
    • LIBNET_LINK_ADV 高级链路层注入方式,提供了更高级的链路层控制,可以进行更灵活的链路层操作
  • device:网络接口,如"etc0",或IP地址,亦可为NULL(自动查询搜索)
  • err_buf:存放出错的信息

返回值:成功返回一个libnet句柄,失败返回NULL

2.4.2 libnet_destroy

释放资源

void libnet_destroy(libnet_t *l);

2.4.3 libnet_build_udp

构造udp数据包

【注】libnet提供的函数,不需要将小端字节转化为大端字节

libnet_ptag_t libnet_build_udp(u_int16_t sp,
                              u_int16_t dp,
                              u_int16_t len,
                              u_int16_t sum,
                              u_int8_t *payload,
                              u_int32_t payload_s,
                              libnet_t *l,
                              libnet_ptag_t ptag);

参数:

  • sp:源端口号,不需要通过htons()函数进行转换
  • dp:目的端口号
  • len:udp包总长度
  • sum:校验和,设为0,libnet自动填充
  • payload:负载(即数据),可设置为NULL
  • payload_s:负载长度,或为0
  • l:libnet句柄
  • ptag:协议部分标记,一般给定0即可

返回值:成功返回协议标记,失败返回-1

2.4.4 libnet_build_ipv4

构造一个IPV4数据包

libnet_ptag_t libnet_build_ipv4(u_int16_t,ip_len,u_int8_t tos,
                               u_int16_t id,u_int16_t frag,
                               u_int8_t ttl,u_int8_t prot,
                               u_int16 sum,u_int32_t src,
                               u_int32_t dst,u_int8_t *payload,
                               u_int32_t payload_s,
                               libnet_t *l,libnet_ptag_t ptag);

参数:

  • ip_len:ip包总长
  • tos:服务类型
  • id:ip数据包的标识,由发送方设置
  • frag:分段偏移
  • ttl:生存时间
  • prot:上层协议
  • sum:校验和,设为0,libnet自动填充
  • src:源ip地址
  • dst:目的ip地址
  • payload:负载,可设置为NULL
  • payload_s:负载长度,或为0
  • l:libnet句柄
  • ptag:协议的部分标记,一般为0,表示新建报文

返回值:成功返回协议标记;失败返回-1

2.4.5 libnet_build_ethernet

构造一个以太网数据包,即MAC报文

libnet_ptag_t libnet_build_ethernet(u_int8_t *dst,
                                   u_int8_t *src,
                                   u_int16_t type,
                                   u_int8_t *payload,
                                   u_int32_t payload_s,
                                   libnet_t *l,
                                   libnet_ptag_t ptag); 

参数:

  • dst:目的mac
  • src:源mac
  • type:上层协议类型,可以为0x0800
  • payload:负载,即附带的数据
  • payload_s:负载长度
  • l:libnet句柄
  • ptag:协议标记

返回值:成功返回协议标记,失败返回-1

2.4.6 libnet_write

发送报文数据

int libnet_write(libnet_t * l);

返回值:失败返回-1,成功返回其他

2.4.7 案例

#include <stdio.h>
#include <libnet.h>

int main(int argc,char const *argv[])
{
    if(argc<2)
    {
        printf("format:%s 网卡名\n",argc[0]);
        return -1;
    }
    //初始化libnet
    libnet_t *net = libnet_init(LIBNET_LINK_ADV,argv[1],NULL);
    if(net == NULL)
    {
        printf("libnet_init fail");
        return -1;
    }
    printf("libnet初始化成功\n");
    
    //构建数据
    //1.udp
    u_char data_buf[64]="";
    fgets(data_buf,64,stdin);
    data_buf[strlen(data_buf)-1]=0;
    int data_len=strlen(data_buf)+strlen(data_buf)%2;
    libnet_ptag_t udp_tag=libnet_build_udp(8001,8000,
                                           8+data_len,
                                          0,data_buf,
                                          data_len,net,0);
    if(udp_tag != -1)
    {
        printf("udp tag:%d\n",udp_tag);
    }
    //2.ip
    libnet_ptag_t ip_tag=libnet_build_ipv4(20+8+data_len,
                                          0,
                                           0,
                                           0,
                                           32,
                                           17,
                                           0,
                                    inet_addr("10.12.156.xxx"),                                     inet_addr("10.12.156.xxx"),
                                           NULL,
                                           0,
                                           net,
                                           0);
    if(ip_tag!=-1)
    {
        printf("ip tag:%d\n",ip_tag);
    }
    //3.mac报文
    u_char src_mac[6]={0xxx,0xxx,0xxx,0xxx,0xxx,0xxx};
    u_char dst_mac[6]={0xxx,0xxx,0xxx,0xxx,0xxx,0xxx};
    libnet_ptag_t mac_tag=libnet_build_ethernet(dst_mac,
                                               src_mac,
                                               0x800,
                                               NULL,
                                               0,
                                               net,
                                               0);
    if(mac_tag!=-1)
    {
        printf("mac tag %d\n",mac_tag);
    }
    
    //发送数据
    int ret=libnet_write(net);
    if(ret!=-1)
    {
        printf("数据发送成功\n");
    }
    //释放空间
    libnet_destroy(net);
    return 0;
}

标签:libnet,int,数据包,捕获,网络,char,开发工具,pcap
From: https://www.cnblogs.com/dijun666/p/17767193.html

相关文章

  • 360等Chrome浏览器查看不了网络下的请求头信息【解决办法】
    在使用360等浏览器的时候,点击网络有时候会查看不到网络信息,例如这样:解决方法点击【Filter】按钮,就是哪个小漏斗的按钮即可:打完收工! ......
  • 【Linux 网络编程】为什么 IP 地址通常以192.168开头?——私有 IP 地址段
    首先,192.168并不是设置局域网IP地址的唯一选择。很多企业都选择10.或者172.16开头规划局域网。三个私有IP地址段网络中的主机需要通信,需要使用一个IP地址,目前我们普遍使用的IPv4的地址,分为A、B、C、D、E五类,其中A、B、C类是我们常见的IP地址段。在这三类地址中,大多数为公有地......
  • 手机爬虫用Scrapy详细教程:构建高效的网络爬虫
    如果你正在进行手机爬虫的工作,并且希望通过一个高效而灵活的框架来进行数据抓取,那么Scrapy将会是你的理想选择。Scrapy是一个强大的Python框架,专门用于构建网络爬虫。今天,我将与大家分享一份关于使用Scrapy进行手机爬虫的详细教程,让我们一起来探索Scrapy的功能和操作,为手机爬虫增添......
  • 开发工具
    低代码平台:JEECG,文档中心企业级低代码平台:JeecgBoot企业级报表系统:JimuReport积木报表文档......
  • 网络穿透/视频拉转推服务系统EasyNTS的详细介绍以及下载地址
    ​EasyNTS是一款开源的IPCamera解决方案,它为海康威视、大华等主流厂商的IPC(网络摄像机)提供了便捷的接入方式。通过使用RTSP/RTP/RTCP协议,EasyNTS能够将IPC的视频流安全传输到客户端,确保用户能够实时观看和控制摄像机的画面。此外,EasyNTS还兼容多种平台和操作系统,包括Windows、Li......
  • Linux服务器网络配置
    Linux服务器网络配置记录材料准备材料数量服务器1显示器1网线2(千兆*1)千兆交换机1插线板1网线连接从路由器LAN口引出网线到交换机任一口,再从交换机剩余任一口引出千兆网线到服务器网线插口1服务器网线插口1插入后有有灯闪烁代表网线连接正常网......
  • 各神经网络模型全称
    博客地址:https://www.cnblogs.com/zylyehuo/人工神经网络--ANN--ArtificialNeuralNetworks卷积神经网络--CNN--RecurrentNeConvolutionalNeuralNetworks递归(循环)神经网络--RNN--RecurrentNeuralNetworks长短期记忆递归网络--LSTM(特殊的RNN)--LongSho......
  • 网络安全知识导航
    <spanstyle="color:red"></span><spanstyle="color:yellow"></span><spanstyle="color:green"></span>网络基础网络通信IP地址OSI七层模型客户端与服务端协议和端口网站构成WEB安全SQL注入课前导论自学部分市场上主流的数据库,及常搭配后端语言;......
  • Kubernetes 网络简单介绍
    后续会详细展示其原理并验证下,这里先汇总下,水平比较有限。Kubernetes网络模型Kubernetes使用一个称为CNI(ContainerNetworkInterface)的接口标准,使其网络实现与具体的网络插件解耦。Kubernetes网络模型有以下几个重要的原则:所有Pod都在一个扁平的共享网络中:每个Pod都有一个......
  • 2023中山市第三届香山杯网络安全大赛线上初赛
    序被带飞了PWNmove先往变量sskd写入0x20字节,往第二个输入点输入0x12345678即可进入到第三个输入点,存在0x8字节的溢出。思路是在第一个输入点布置rop链,然后利用第三个输入点的溢出,打栈迁移然后泄libc后重新返回到main函数,这里要注意的是移了栈之后,栈顶指针就指......