测试能否回应arp请求
- 开启netmap
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测试代码
文章插图
?前面也说过了,一旦调用nm_open函数,网卡的数据就不从内核协议栈走了,所以我们ping一下看看能不能ping通,ping是icmp协议 。发现ping不同,但是我们是接收到数据包了的,下面就来实现icmp协议
文章插图
3.实现icmp协议设计思路icmp协议是ip协议的一部分
文章插图
文章插图
?icmp的类型:ping请求是8,ping回应是0,其他的就不介绍了
- 代码:ping的代码为0
- 校验和:它的计算方法与IP数据报中的首部校验和计算方式是一样IP首部校验和计算原理
文章插图
?其中增加的标识符和序号字段按照请求端的数据返回即可,同时对选项数据也必须进行回显,客户端可以会验证这些数据 。
代码
//// Created by 68725 on 2022/7/19.//#include <stdio.h>#include <sys/poll.h>#include <netinet/in.h>#include <arpa/inet.h>#define NETMAP_WITH_LIBS#include <net/netmap_user.h>#include <string.h>#pragma pack(1)#define ETH_ADDR_LENGTH 6#define PROTO_IP 0x0800#define PROTO_ARP 0x0806#define PROTO_RARP0x0835#define PROTP_UPD 17#define PROTO_ICMP1struct 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; //14struct iphdr ip; //20};struct udphdr {unsigned short sport;unsigned short dport;unsigned short length;unsigned short check;};struct udppkt {struct ethhdr eh; //14struct iphdr ip; //20struct udphdr udp;//8unsigned 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 = https://www.isolves.com/it/wl/zs/2022-07-21/0x0;int i = 0;while (p != '') {if (*p == ':') {mac[i++] = value;value = 0x0;}else {unsigned char temp = *p;if (temp <= '9' && temp >= '0') {temp -= '0';}else if (temp <= 'f' && temp >= 'a') {temp -= 'a';temp += 10;}else if (temp <= 'F' && temp >= 'A') {temp -= 'A';temp += 10;}else {break;}value <<= 4;value |= temp;}p++;}mac[i] = value;//areturn 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);//以太网首部填入目的 macstr2mac(arp_rt->eh.h_src, mac);//以太网首部填入源macarp_rt->eh.h_proto = arp->eh.h_proto;//以太网协议还是arp协议arp_rt->arp.h_addrlen = 6;arp_rt->arp.h_protolen = 4;//aaarp_rt->arp.oper = htons(2); // ARP响应str2mac(arp_rt->arp.smac, mac);//arp报文填入源macarp_rt->arp.sip = arp->arp.dip; // arp报文填入发送端 ipmemcpy(arp_rt->arp.dmac, arp->arp.smac, ETH_ADDR_LENGTH);//arp报文填入目的 macarp_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 *) (&answer) = *(u_char *) w;sum += answer;}sum = (sum >> 16) + (sum & 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 *) &icmp_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 seccessn");struct pollfd pfd = {0};pfd.fd = nmr->fd;pfd.events = POLLIN;while (1) {printf("new data coming!n");int ret = poll(&pfd, 1, -1);if (ret
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 基于阿里云实现WEB访问故障转移静态提示页面
- hdr模式是什么?
- 饵料|男子钓鱼遇见孩子落水,急忙将其救起后,家长的态度让人无奈
- 职业教育|不愿向上,让自己永远处在一个低层的状态,那是毫无实力的表现
- 苹果|iPhone用户快升级!苹果发布iOS 15.6更新:修复存储已满等烦人问题
- 如何恢复连接? 打印机提示脱机状态
- 拜登特朗普谁对中国友好一些-拜登大胜对中国的态度
- 公积金封存状态怎么解封?
- 露华浓达成避免破产协议-露华浓为申请破产作准备
- 阳光心态的正能量句子有哪些?