文章目录
- 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=60unsigned 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 -lint 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;
}