文章目录
- 1、安装编译netmap
- 2、使用netmap
- 3、运行编写自己的代码
1、安装编译netmap
github地址
git clone https://github.com/luigirizzo/netmap
1、进入目录
cd netmap-master/LINUX
2、安装编译环境
apt-get install build-essential
3、初始化配置环境
./configure
出现这个界面不是卡住了,需要长时间等待完成,这个过程可能比较长,运行到下面表示成功

 
 4、编译和安装
make && make install
2、使用netmap
每次使用前都需要insmod netmap.ko ,然后我们查看ls /dev/netmap -l,出现下面的设备就说明开启成功了。
# 在netmap-master/LINUX执行
insmod netmap.ko 
ls /dev/netmap -l
取消加载
rmmod netmap
3、运行编写自己的代码
# 头文件 #include<net/netmap_user.h> 在 /netmap/sys/目录下
gcc -o nty_udp nty_udp.c -I /netmap/sys/
#include <stdio.h>
#include <sys/epoll.h>
#include <arpa/inet.h>
#define NETMAP_WITH_LIBS
#include <net/netmap_user.h>
#define ETH_ADDR_LENGTH 6
#define PROTO_IP 0x0800
#define PROTO_ARP 0x0806
#define PROTO_UDP 17
#pragma pack(1)
// 以太网帧头 14字节
struct ethhdr{
    unsigned char h_dst[ETH_ADDR_LENGTH];
    unsigned char h_stc[ETH_ADDR_LENGTH];
    unsigned short h_proto;
};
// ip头 20字节
struct iphdr{
    // 位域 版本表示:使用的是ipv4还是ipv6
    // 首部长度表示:最大长度可以是 15*4=60
    unsigned char hdrlen:4,
                  version:4;
    
    unsigned char tos;
    unsigned short tolen;
    unsigned short flag_offset;
    unsigned char ttl;
    unsigned char type;
    unsigned long check;
    unsigned int sip;
    unsigned int dip;
};
struct updhdr{
    unsigned short sport;
    unsigned short dport;
    unsigned short length;
    unsigned short check;
};
struct arphdr{
    unsigned short h_type;
    unsigned short h_proto;
    unsigned char h_addr;
    unsigned char h_protolen;
    unsigned char oper;
    unsigned char smac[ETH_ADDR_LENGTH];
    unsigned int sip;
    unsigned char dmac[ETH_ADDR_LENGTH];
    unsigned int dip;
};
struct udppkt{
    struct ethhdr eh;
    struct iphdr ip;
    struct udphdr upd;
    // 数据长度不确定,所以使用柔性数组
    unsigned char data[0];
};
struct arppkt{
    struct ethhdr eh;
    struct arphdr arp;
};
// 在netmap目录下
// insmod netmap.ko
// ls /dev/netmap -l
int main()
{
    // 
    struct nm_pkthdr head;
    struct nm_desc *nmr = nm_open("netmap:eth0",NULL,0,NULL);
    if(nmr == NULL) return -1;
    // 通过poll检测是否有事件读事件来了
    struct pollfd pfd = {0};
    pfd.fd = nmr->fd;
    while(1){
        int ret = poll(&pfd,1,-1);
        if(ret < 0) continue;
        if(pfd.revents & POLLIN){
            // 从ringbuffer环形队列中取出一帧数据
            unsigned char *stream = nm_nextpkt(nmr,&h);
            // 解包 
            struct ethhdr *eh = (struct ethhdr*)stream;
            if(ntohs(eh->h_proto) == PROTO_IP){
                struct udppkt *udp = (struct udppkt*)stream;
                if(upd->ip.type == PROTO_UDP){
                    int udplength = ntohs(udp->udp.length);
                    udp->data[udplength-8] = '\0';
                    printf("%s\n",udp->data);
                }
            }else if (ntohs(eh->h_proto) == PROTO_ARP){
                // 先判断
                struct arppkt *arp = (struct arppkt*)stream;
                struct arppkt arp_rt;
                
                if(arp->arp.dip == inet_addr("192.168.0.123")){
                }
            }
        }
    }
    return 0;
}















![[机器学习]分类算法系列①:初识概念](https://img-blog.csdnimg.cn/img_convert/423a7bf5233cf98171a8b0dd6024c403.png)



