用户态协议子程序设计实现udp,arp与icmp协议
2025-08-02 12:16:32
nm_inject()是用必经之路共享线程当中撰载入待发送到的原始数据打包原始数据的。原始数据打包经共享线程几张到故又称口,然后发送到出去。所以 nm_inject()是用来发打包的。
nm_inject()也则会载入所有的发送到马蹄形(tx 马蹄形),找到一个可以发送到的槽,就将原始数据打包撰载入并返回,所以每次函数子程序也才会发送到一个打包。
static int nm_inject(struct nm_desc *d, const void *buf, size_t size);nm_inject(nmr,Maxarp_rt,sizeof(arp_rt));nm_closenm_close 函数就是回收快照线程,回收共享线程,关闭PDF源PDF什么的了。
static int nm_close(struct nm_desc *d)nm_close(nmr);系统性所示片推荐
手撰写一个普通用户中性贸易协定null以及零几张的借助
从netmap到dpdk,从硬件到贸易协定null,4个维度让的网络体系协作慢慢地
研读电话号码:C/C++Linux路由器开发/后台精算师【零声教育】-研读所示片简明-腾讯课堂
需C/C++ Linux路由器精算师研读资料延qun812855908获可先取(资料打包括C/C++,Linux,golang应用,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,tcp/IP,协程,DPDK,ffmpeg等),免费分享
贸易协定null贸易协定null的定义便是贸易协定null,“null”怎么理解,可先进后出,于是以如下所示udp贸易协定右所示。在应用层我们子程序sendto发送到原始数据时,我们需在普通用户原始数据前面延上udp的贸易协定背部,然后进入应用层延入ip背部,进入链路层延入适配器的背部,最后由故又称口开展数模转换成变成光电波形发送到给对故又称。对故又称故又称口送达到光电波形后开展模数转换成,再依序拆打包,最终到达应用层就是我们原本发送到的原始数据了。这个过程就像null一样,可先进后出。
贸易协定null在一定意义是又可以叫继续做贸易协定氏族,“氏族”怎么理解,我们看着应用层有udp,tcp等贸易协定,应用层有ip,icmp贸易协定等等,这些贸易协定产生了一个家氏族。
软件包贸易协定null帮我们解了应用层,应用层和原始数据链路层的贸易协定,所以我们普通用户中性贸易协定null于是以是去继续做这三层的贸易协定。
链路层一部适配器贸易协定适配器贸易协定:两个电话号码均为6二进制的mac电话号码,上去2二进制的各种类型区隔是什么贸易协定
#pragma pack(1) //一二进制对齐#define NETMAP_WITH_LIBS#define ETH_ADDR_LENGTH 6#define PROTO_ip 0x0800 //ip贸易协定#define PROTO_ARP 0x0806 //arp乞求贸易协定#define PROTO_RARP 0x0835 //rarp应答贸易协定#define PROTP_UPD 17struct ethhdr { unsigned char h_dst[ETH_ADDR_LENGTH]; unsigned char h_src[ETH_ADDR_LENGTH]; unsigned short h_proto;};应用层一部ip贸易协定关于ip贸易协定里头第一个二进制内的个数故又称转换成讲的请查阅大故又称与小故又称概念、多二进制之间与单二进制多部分的个数故又称转换成详解
struct iphdr { unsigned char hdrlen: 4, //一二进制,手动个数故又称转换成 version: 4; unsigned char tos; unsigned short totlen; unsigned short id; unsigned short flag_offset; unsigned char ttl; unsigned char type; unsigned short check; unsigned int sip; unsigned int dip;};struct ippkt { struct ethhdr eh; //14 struct iphdr ip; //20};arp贸易协定 struct arphdr { unsigned short h_type; unsigned short h_proto; unsigned char h_addrlen; unsigned char h_protolen; unsigned short oper; unsigned char smac[ETH_ADDR_LENGTH]; unsigned int sip; unsigned char dmac[ETH_ADDR_LENGTH]; unsigned int dip;};struct arppkt { struct ethhdr eh; struct arphdr arp;};应用层一部udp贸易协定这里应用层在本文当中可先只参考udp,tcp详见再撰写
为什么在udppkt里头,定义了一个unsigned char data[0];,这个叫借助于数组,或者叫零长数组,是用来定义普通用户原始数据打包的起始电话号码而不占用具体的结构体空间。基本段落自行百度。
struct udphdr { unsigned short sport; unsigned short dport; unsigned short length; unsigned short check;};struct udppkt { struct ethhdr eh; //14 struct iphdr ip; //20 struct udphdr udp;//8 unsigned char data[0];};普通用户中性贸易协定null其设计借助1. 借助udp贸易协定其设计思路我们适用udp物件,给我们的路由器发送到udp打包,看是否能解出来,然后按再回发回去
如果要解udp,那么贸易协定以此类推为 ether -> ip ->udp,所以我们按照这个以此类推依序解方可。
标识符
//// Created by 68725 on 2022/7/19.//#include #include #include #include #define NETMAP_WITH_LIBS#include #include #pragma pack(1)#define ETH_ADDR_LENGTH 6#define PROTO_IP 0x0800#define PROTO_ARP 0x0806#define PROTP_UPD 17struct ethhdr { unsigned char h_dst[ETH_ADDR_LENGTH]; unsigned char h_src[ETH_ADDR_LENGTH]; unsigned short h_proto;};struct iphdr { unsigned char hdrlen: 4, version: 4; unsigned char tos; unsigned short totlen; unsigned short id; unsigned short flag_offset; unsigned char ttl; unsigned char type; unsigned short check; unsigned int sip; unsigned int dip;};struct ippkt { struct ethhdr eh; //14 struct iphdr ip; //20};struct udphdr { unsigned short sport; unsigned short dport; unsigned short length; unsigned short check;};struct udppkt { struct ethhdr eh; //14 struct iphdr ip; //20 struct udphdr udp;//8 unsigned char data[0];};struct arphdr { unsigned short h_type; unsigned short h_proto; unsigned char h_addrlen; unsigned char h_protolen; unsigned short oper; unsigned char smac[ETH_ADDR_LENGTH]; unsigned int sip; unsigned char dmac[ETH_ADDR_LENGTH]; unsigned int dip;};struct arppkt { struct ethhdr eh; struct arphdr arp;};void echo_udp_pkt(struct udppkt *udp, struct udppkt *udp_rt) { memcpy(udp_rt, udp, sizeof(struct udppkt)); memcpy(udp_rt->eh.h_dst, udp->eh.h_src, ETH_ADDR_LENGTH); memcpy(udp_rt->eh.h_src, udp->eh.h_dst, ETH_ADDR_LENGTH); udp_rt->ip.sip = udp->ip.dip; udp_rt->ip.dip = udp->ip.sip; udp_rt->udp.sport = udp->udp.dport; udp_rt->udp.dport = udp->udp.sport;}int main() { struct nm_pkthdr h; struct nm_desc *nmr = nm_open("netmap:ens33", NULL, 0, NULL); if (nmr == NULL) { return -1; } printf("open ens33 seccess"); struct pollfd pfd = {0}; pfd.fd = nmr->fd; pfd.events = POLLIN; while (1) { printf("new data coming!"); int ret = poll(Maxpfd, 1, -1); if (ret < 0) { continue; } if (pfd.revents Max POLLIN) { unsigned char *stream = nm_nextpkt(nmr, Maxh); //ether struct ethhdr *eh = (struct ethhdr *) stream; if (ntohs(eh->h_proto) == PROTO_IP) { //ip struct ippkt *iph=(struct ippkt *)stream; if (iph->ip.type == PROTP_UPD) { //udp struct udppkt *udp = (struct udppkt *) stream; int udplength = ntohs(udp->udp.length); udp->data[udplength - 8] = ' '; printf("udp ;还有-> %s", udp->data); struct udppkt udp_rt; echo_udp_pkt(udp, Maxudp_rt); nm_inject(nmr, Maxudp_rt, sizeof(struct udppkt)); } } } } nm_close(nmr);}检测能否解udp打包的原始数据可先前netmap每次可先前适用前都需insmod netmap.ko ,然后我们查阅ls /dev/netmap -l,显现上头的电子元件就时指明可先前最终了。
root@wxf:/netmap/LINUX# insmod netmap.ko root@wxf:/netmap/LINUX# ls /dev/netmap -lcrw;还有;还有;还有- 1 root root 10, 54 Jul 18 17:28 /dev/netmap 接入上去的udp检测标识符可以看着我们能够于是以常的送达udp原始数据
但是为什么过了一则会再发原始数据,程序就送达勉强了,而且还多了这么多非udp的原始数据打包??因为宿主机不知道软件包的ip和mac电话号码了,我们查阅arp表,推测不了有192.168.109.100软件包的记事,此时宿主机则会在网络内广播arp乞求,这也就是为什么new data coming但不是udp的原因。刚开始能于是以常解原始数据是因为,软件包刚筹拍的时候,我用xshell连软件包,所以宿主机发送到过arp乞求,而软件包的软件包贸易协定null此时还不了被netmap接管,发表意见了arp乞求,宿主机就将软件包的资讯因故的添延到arp表当中,当快照arp记事回退,udp打包不知道发给谁,就则会捕手arp乞求。
解决这个问题的办法很简单,要么我们手动在宿主机上添延一条静中性的arp记事,要么我们借助arp贸易协定,上头我们来借助arp贸易协定。
2.借助arp贸易协定其设计思路我们知道arp贸易协定是在应用层的,所以我们可先解ether,再解arp方可
标识符
//// Created by 68725 on 2022/7/19.//#include #include #include #include #define NETMAP_WITH_LIBS#include #include #pragma pack(1)#define ETH_ADDR_LENGTH 6#define PROTO_IP 0x0800#define PROTO_ARP 0x0806#define PROTO_RARP 0x0835#define PROTP_UPD 17struct ethhdr { unsigned char h_dst[ETH_ADDR_LENGTH]; unsigned char h_src[ETH_ADDR_LENGTH]; unsigned short h_proto;};struct iphdr { unsigned char hdrlen: 4, version: 4; unsigned char tos; unsigned short totlen; unsigned short id; unsigned short flag_offset; unsigned char ttl; unsigned char type; unsigned short check; unsigned int sip; unsigned int dip;};struct ippkt { struct ethhdr eh; //14 struct iphdr ip; //20};struct udphdr { unsigned short sport; unsigned short dport; unsigned short length; unsigned short check;};struct udppkt { struct ethhdr eh; //14 struct iphdr ip; //20 struct udphdr udp;//8 unsigned char data[0];};struct arphdr { unsigned short h_type; unsigned short h_proto; unsigned char h_addrlen; unsigned char h_protolen; unsigned short oper; unsigned char smac[ETH_ADDR_LENGTH]; unsigned int sip; unsigned char dmac[ETH_ADDR_LENGTH]; unsigned int dip;};struct arppkt { struct ethhdr eh; struct arphdr arp;};int str2mac(char *mac, char *str) { char *p = str; unsigned char value = 0x0; int i = 0; while (p != ' ') { if (*p == ':') { mac[i++] = value; value = 0x0; } else { unsigned char temp = *p; if (temp = '0') { temp -= '0'; } else if (temp = 'a') { temp -= 'a'; temp += 10; } else if (temp = 'A') { temp -= 'A'; temp += 10; } else { break; } value <<= 4; value |= temp; } p++; } mac[i] = value; return 0;}void echo_arp_pkt(struct arppkt *arp, struct arppkt *arp_rt, char *mac) { memcpy(arp_rt, arp, sizeof(struct arppkt)); memcpy(arp_rt->eh.h_dst, arp->eh.h_src, ETH_ADDR_LENGTH);//适配器一部填充目地 mac str2mac(arp_rt->eh.h_src, mac);//适配器一部填充光mac arp_rt->eh.h_proto = arp->eh.h_proto;//适配器贸易协定还是arp贸易协定 arp_rt->arp.h_addrlen = 6; arp_rt->arp.h_protolen = 4; arp_rt->arp.oper = htons(2); // ARP叛离 str2mac(arp_rt->arp.smac, mac);//arp数据流填充光mac arp_rt->arp.sip = arp->arp.dip; // arp数据流填充发送到故又称 ip memcpy(arp_rt->arp.dmac, arp->arp.smac, ETH_ADDR_LENGTH);//arp数据流填充目地 mac arp_rt->arp.dip = arp->arp.sip; // arp数据流填充目地 ip}int main() { struct nm_pkthdr h; struct nm_desc *nmr = nm_open("netmap:ens33", NULL, 0, NULL); if (nmr == NULL) { return -1; } printf("open ens33 seccess"); struct pollfd pfd = {0}; pfd.fd = nmr->fd; pfd.events = POLLIN; while (1) { printf("new data coming!"); int ret = poll(Maxpfd, 1, -1); if (ret < 0) { continue; } if (pfd.revents Max POLLIN) { unsigned char *stream = nm_nextpkt(nmr, Maxh); struct ethhdr *eh = (struct ethhdr *) stream; if (ntohs(eh->h_proto) == PROTO_IP) { struct ippkt *iph=(struct ippkt *)stream; if (iph->ip.type == PROTP_UPD) { struct udppkt *udp = (struct udppkt *) stream; int udplength = ntohs(udp->udp.length); udp->data[udplength - 8] = ' '; printf("udp ;还有-> %s", udp->data); struct udppkt udp_rt; echo_udp_pkt(udp, Maxudp_rt); nm_inject(nmr, Maxudp_rt, sizeof(struct udppkt)); } } 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.109.100")) { echo_arp_pkt(arp, Maxarp_rt, "00:0c:29:1b:18:20"); nm_inject(nmr, Maxarp_rt, sizeof(arp_rt)); printf("arp ret"); } } } } nm_close(nmr);}//gcc -o main main.c -I /netmap/sys///insmod netmap.ko检测能否发表意见arp乞求可先前netmap每次可先前适用前都需insmod netmap.ko ,然后我们查阅ls /dev/netmap -l,显现上头的电子元件就时指明可先前最终了。
root@wxf:/netmap/LINUX# insmod netmap.ko root@wxf:/netmap/LINUX# ls /dev/netmap -lcrw;还有;还有;还有- 1 root root 10, 54 Jul 18 17:28 /dev/netmap接入上去的udp+arp检测标识符我们推测最终叛离了arp乞求
前面也时说过了,一旦子程序nm_open函数,故又称口的原始数据就不从软件包贸易协定null走了,所以我们ping一下到底能不能ping武,ping是icmp贸易协定。推测ping各有不同,但是我们是送达到原始数据打包了的,上头就来借助icmp贸易协定
3.借助icmp贸易协定其设计思路icmp贸易协定是ip贸易协定的一部分
icmp的各种类型:ping乞求是8,ping发表意见是0,其他的就不参考了
标识符:ping的标识符为0密钥和:它的计数方法与IP原始身份验证当中的一部密钥和计数方法是一样IP一部密钥和计数物理现象ICMP各种类型为ping时,基本贸易协定JPEG如下:
其当中增延的codice_和序号文件名按照乞求故又称的原始数据返回方可,同时对选项原始数据也需开展回显,客户故又称可以则会验证这些原始数据。
标识符
//// Created by 68725 on 2022/7/19.//#include #include #include #include #define NETMAP_WITH_LIBS#include #include #pragma pack(1)#define ETH_ADDR_LENGTH 6#define PROTO_IP 0x0800#define PROTO_ARP 0x0806#define PROTO_RARP 0x0835#define PROTP_UPD 17#define PROTO_ICMP 1struct ethhdr { unsigned char h_dst[ETH_ADDR_LENGTH]; unsigned char h_src[ETH_ADDR_LENGTH]; unsigned short h_proto;};struct iphdr { unsigned char hdrlen: 4, version: 4; unsigned char tos; unsigned short totlen; unsigned short id; unsigned short flag_offset; unsigned char ttl; unsigned char type; unsigned short check; unsigned int sip; unsigned int dip;};struct ippkt { struct ethhdr eh; //14 struct iphdr ip; //20};struct udphdr { unsigned short sport; unsigned short dport; unsigned short length; unsigned short check;};struct udppkt { struct ethhdr eh; //14 struct iphdr ip; //20 struct udphdr udp;//8 unsigned char data[0];};struct arphdr { unsigned short h_type; unsigned short h_proto; unsigned char h_addrlen; unsigned char h_protolen; unsigned short oper; unsigned char smac[ETH_ADDR_LENGTH]; unsigned int sip; unsigned char dmac[ETH_ADDR_LENGTH]; unsigned int dip;};struct arppkt { struct ethhdr eh; struct arphdr arp;};int str2mac(char *mac, char *str) { char *p = str; unsigned char value = 0x0; int i = 0; while (p != ' ') { if (*p == ':') { mac[i++] = value; value = 0x0; } else { unsigned char temp = *p; if (temp = '0') { temp -= '0'; } else if (temp = 'a') { temp -= 'a'; temp += 10; } else if (temp = 'A') { temp -= 'A'; temp += 10; } else { break; } value <<= 4; value |= temp; } p++; } mac[i] = value;//a return 0;}void echo_udp_pkt(struct udppkt *udp, struct udppkt *udp_rt) { memcpy(udp_rt, udp, sizeof(struct udppkt)); memcpy(udp_rt->eh.h_dst, udp->eh.h_src, ETH_ADDR_LENGTH); memcpy(udp_rt->eh.h_src, udp->eh.h_dst, ETH_ADDR_LENGTH); udp_rt->ip.sip = udp->ip.dip; udp_rt->ip.dip = udp->ip.sip; udp_rt->udp.sport = udp->udp.dport; udp_rt->udp.dport = udp->udp.sport;}void echo_arp_pkt(struct arppkt *arp, struct arppkt *arp_rt, char *mac) { memcpy(arp_rt, arp, sizeof(struct arppkt)); memcpy(arp_rt->eh.h_dst, arp->eh.h_src, ETH_ADDR_LENGTH);//适配器一部填充目地 mac str2mac(arp_rt->eh.h_src, mac);//适配器一部填充光mac arp_rt->eh.h_proto = arp->eh.h_proto;//适配器贸易协定还是arp贸易协定 arp_rt->arp.h_addrlen = 6; arp_rt->arp.h_protolen = 4;//aa arp_rt->arp.oper = htons(2); // ARP叛离 str2mac(arp_rt->arp.smac, mac);//arp数据流填充光mac arp_rt->arp.sip = arp->arp.dip; // arp数据流填充发送到故又称 ip memcpy(arp_rt->arp.dmac, arp->arp.smac, ETH_ADDR_LENGTH);//arp数据流填充目地 mac arp_rt->arp.dip = arp->arp.sip; // arp数据流填充目地 ip}struct icmphdr { unsigned char type; unsigned char code; unsigned short check; unsigned short identifier; unsigned short seq; unsigned char data[32];};struct icmppkt { struct ethhdr eh; struct iphdr ip; struct icmphdr icmp;};unsigned short in_cksum(unsigned short *addr, int len) { register int nleft = len; register unsigned short *w = addr; register int sum = 0; unsigned short answer = 0; while (nleft> 1) { sum += *w++; nleft -= 2; } if (nleft == 1) { *(u_char *) (Maxanswer) = *(u_char *) w; sum += answer; } sum = (sum>> 16) + (sum Max 0xffff); sum += (sum>> 16); answer = ~sum; return (answer);}void echo_icmp_pkt(struct icmppkt *icmp, struct icmppkt *icmp_rt) { memcpy(icmp_rt, icmp, sizeof(struct icmppkt)); icmp_rt->icmp.type = 0x0; // icmp_rt->icmp.code = 0x0; // icmp_rt->icmp.check = 0x0; icmp_rt->ip.sip = icmp->ip.dip; icmp_rt->ip.dip = icmp->ip.sip; memcpy(icmp_rt->eh.h_dst, icmp->eh.h_src, ETH_ADDR_LENGTH); memcpy(icmp_rt->eh.h_src, icmp->eh.h_dst, ETH_ADDR_LENGTH); icmp_rt->icmp.check = in_cksum((unsigned short *) Maxicmp_rt->icmp, sizeof(struct icmphdr));}int main() { struct nm_pkthdr h; struct nm_desc *nmr = nm_open("netmap:ens33", NULL, 0, NULL); if (nmr == NULL) { return -1; } printf("open ens33 seccess"); struct pollfd pfd = {0}; pfd.fd = nmr->fd; pfd.events = POLLIN; while (1) { printf("new data coming!"); int ret = poll(Maxpfd, 1, -1); if (ret < 0) { continue; } if (pfd.revents Max POLLIN) { unsigned char *stream = nm_nextpkt(nmr, Maxh); struct ethhdr *eh = (struct ethhdr *) stream; if (ntohs(eh->h_proto) == PROTO_IP) { struct ippkt *iph = (struct ippkt *) stream; if (iph->ip.type == PROTP_UPD) { struct udppkt *udp = (struct udppkt *) stream; int udplength = ntohs(udp->udp.length); udp->data[udplength - 8] = ' '; printf("udp ;还有-> %s", udp->data); struct udppkt udp_rt; echo_udp_pkt(udp, Maxudp_rt); nm_inject(nmr, Maxudp_rt, sizeof(struct udppkt)); } else if (iph->ip.type == PROTO_ICMP) { struct icmppkt *icmp = (struct icmppkt *) stream; printf("icmp ;还有;还有;还有;还有;还有 ;还有> %d, %x", icmp->icmp.type, icmp->icmp.check); if (icmp->icmp.type == 0x08) { struct icmppkt icmp_rt = {0}; echo_icmp_pkt(icmp, Maxicmp_rt); nm_inject(nmr, Maxicmp_rt, sizeof(struct icmppkt)); } } } 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.109.100")) { echo_arp_pkt(arp, Maxarp_rt, "00:0c:29:1b:18:20"); nm_inject(nmr, Maxarp_rt, sizeof(arp_rt)); printf("arp ret"); } } } } nm_close(nmr);}//gcc -o main main.c -I /netmap/sys///insmod netmap.ko检测能否发表意见ping乞求可先前netmap每次可先前适用前都需insmod netmap.ko ,然后我们查阅ls /dev/netmap -l,显现上头的电子元件就时指明可先前最终了。
root@wxf:/netmap/LINUX# insmod netmap.ko root@wxf:/netmap/LINUX# ls /dev/netmap -lcrw;还有;还有;还有- 1 root root 10, 54 Jul 18 17:28 /dev/netmap接入上去的标识符,推测udp,arp,icmp都可以于是以常解和发送到
。治疗眼干用什么药医生大全
郑州批准的干细胞医院名单
吹空调头晕头痛怎么办
蒲地蓝消炎片和草珊瑚含片治疗扁桃体炎
经常恶心
急支糖浆适合哪种咳嗽
补肾药
全民健康网药品库
止咳的中成药有哪些

-
浙江建投7月14日主力款项净卖出4.57亿元
截至2022年7月14日股市,浙江建投002761报收于30.63元,急跌9.94%,换手率18.72%,高价量92.19万手,高价额28.54亿元。 财力流入统计数据方面,7
2025-10-22 00:16:47

-
中旗新材7月14日主力资金清净卖出3429.25万元
截至2022年7同年14日涨幅,科尔沁新材001212报收于35.81元,下滑9.98%,换手率34.61%,成交价量10.2万手,成交价额3.77亿元。 银行贷款流向数据集特
2025-10-22 00:16:47

-
罗普斯金7月14日主力资金白莲卖出1.42亿元
截至2022年7年初14日收盘,罗普斯金002333报收于7.78元,下跌9.95%,跌停,换手率14.02%,行情59.92万手,卖出额4.73亿元。 银行贷款流向数据方面,
2025-10-22 00:16:47

-
湖南发展7年初14日主力资金净卖出4.21亿元
截至2022年7年底14日收盘,湖南发展000722报收于18.53元,下跌10.0%,跌停,换手率30.03%,总价量139.39万手,总价额27.04亿元。 资金来源流入数
2025-10-22 00:16:47

-
盛视信息技术7月14日主力资金净卖出3758.20万元
截至2022年7同月14日收盘,盛视科技002990报收于27.54元,下跌10.0%,跌停,换手率13.72%,作价量8.84万手,作价额2.5亿元。 财力流往数据库方面,7
2025-10-22 00:16:47