<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      UDP、IMCP、ARP協(xié)議通過(guò)netmap解析的實(shí)現(xiàn)。

      上一篇文章我們講了一個(gè)異步的線程池大概需要如何去實(shí)現(xiàn),現(xiàn)在的話,我們?nèi)绾蝸?lái)解析一個(gè)UDP的包。

      環(huán)境的搭配

      這個(gè)環(huán)境的問(wèn)題困擾了很久,這個(gè)netmap已經(jīng)不再更新了,支持Ubuntu16.04-Ubuntu18.04的系統(tǒng)內(nèi)核,我們需要按照這樣的步驟去安裝我們的netmap

      建立Ubuntu虛擬機(jī)的過(guò)程,我們就略過(guò)了。
      切換到su用戶下,先去安裝我們的編譯的環(huán)境
      apt-get install build-essential
      安裝完我們的編譯工具之后,就需要看看我們的環(huán)境是否已經(jīng)安裝git工具。
      git --version
      沒(méi)有安裝,就需要安裝一下我們需要的git工具。
      apt-get install git
      安裝成功以后,我們開(kāi)始拉取netmap的代碼
      git clone git://github.com/luigirizzo/netmap.git
      拉取代碼這個(gè)過(guò)程可能會(huì)遇到一個(gè)問(wèn)題,就是443連接失敗的問(wèn)題,這個(gè)問(wèn)題可以通過(guò)魔法上網(wǎng)解決,或者是多嘗試幾次就好了。
      等待拉取代碼成功以后,我們來(lái)進(jìn)行netmap的編譯和安裝。

      cd netmap
      ./configure
      

      這里我們可能會(huì)遇到一個(gè)問(wèn)題

      Cannot find full kernel sources.
      *** 
      *** Please note that most distributions provide separate packages for kernel
      *** headers and sources. Once you know the path to kernel sources, you can
      *** rerun this script with the additional
      *** 
      *** --kernel-sources=/path/to/sources
      

      當(dāng)我們遇到這個(gè)問(wèn)題的時(shí)候,就需要下載一下我們的內(nèi)核頭文件。
      apt-get install -y linux-headers-$(uname -r)
      拉取內(nèi)核頭文件成功以后,就可以進(jìn)行netmap的編譯了。

      ./configure
      make & make install
      insmod netmap.ko
      

      等待運(yùn)行完畢,這樣就完成了netmap的環(huán)境搭配。

      udp協(xié)議解析的代碼編寫(xiě)

      看一下一個(gè)UDP的數(shù)據(jù)幀是什么樣的?

      定義我們需要的結(jié)構(gòu)體

      以太網(wǎng)頭

      #define ETH_ALEN 6
      struct ethhr{
          unsigned char h_dest[ETH_ALEN];
          unsigned char h_source[ETH_ALEN];
          unsigned short h_proto;
      }
      

      ip頭

      struct iphdr {
      	unsigned char version : 4,
      		hdrlen : 4;
      	unsigned char tos;
      	unsigned short tot_len;
      	unsigned short id;
      	unsigned short flag : 3,
      		flag_off : 13;
      	unsigned char ttl;
      	unsigned char protocol;
      	unsigned short check;
      	unsigned int saddr;
      	unsigned int daddr;
      };
      

      UDP協(xié)議

      struct udphdr {
      	unsigned short source;
      	unsigned short dest;
      	unsigned short len;
      	unsigned short check;
      };
      

      最后拼接成UDP協(xié)議

      struct udppkt {
      	struct ethhdr eh;
      	struct iphdr ip;
      	struct udphdr udp;
      	unsigned char body[0];
      };
      
      

      arp協(xié)議

      
      struct arphdr {
      	unsigned short h_type;
      	unsigned short h_proto;
      	unsigned char h_addrlen;
      	unsigned char protolen;
      	unsigned short oper;
      	unsigned char smac[ETH_ALEN];
      	unsigned int sip;
      	unsigned char dmac[ETH_ALEN];
      	unsigned int dip;
      };
      
      

      arp包

      struct arppkt {
      	struct ethhdr eh;
      	struct arphdr arp;
      };
      

      icmp協(xié)議

      
      struct icmphdr {
      	unsigned char type;
      	unsigned char code;
      	unsigned short check;
      	unsigned short identifier;
      	unsigned short seq;
      	unsigned char data[32];
      };
      

      icmp協(xié)議包

      struct icmppkt {
      	struct ethhdr eh;
      	struct iphdr ip;
      	struct icmphdr icmp;
      };
      
      

      編寫(xiě)我們解析包的代碼

      這樣定義完我們需要的結(jié)構(gòu)體,就可以編寫(xiě)我們的代碼了
      最終代碼如下:

      
      
      #include <stdio.h>
      #include <unistd.h>
      #include <string.h>
      #include <stdlib.h>
      
      #include <sys/poll.h>
      #include <arpa/inet.h>
      
      
      #define NETMAP_WITH_LIBS
      
      #include <net/netmap_user.h> 
      #pragma pack(1)
      
      
      
      #define ETH_ALEN	6
      #define PROTO_IP	0x0800
      #define PROTO_ARP	0x0806
      
      #define PROTO_UDP	17
      #define PROTO_ICMP	1
      #define PROTO_IGMP	2
      
      struct ethhdr {
      	unsigned char h_dest[ETH_ALEN];
      	unsigned char h_source[ETH_ALEN];
      	unsigned short h_proto;
      };
      
      
      
      struct iphdr {
      	unsigned char version:4,
      			  hdrlen:4;
      	unsigned char tos;
      	unsigned short tot_len;
      	unsigned short id;
      	unsigned short flag:3,
      			   flag_off:13;
      	unsigned char ttl;
      	unsigned char protocol;
      	unsigned short check;
      	unsigned int saddr;
      	unsigned int daddr;
      };
      
      
      struct udphdr {
      	unsigned short source;
      	unsigned short dest;
      	unsigned short len;
      	unsigned short check;
      };
      
      
      struct udppkt {
      	struct ethhdr eh;
      	struct iphdr ip;
      	struct udphdr udp;
      	unsigned char body[0];
      };
      
      
      
      struct arphdr {
      	unsigned short h_type;
      	unsigned short h_proto;
      	unsigned char h_addrlen;
      	unsigned char protolen;
      	unsigned short oper;
      	unsigned char smac[ETH_ALEN];
      	unsigned int sip;
      	unsigned char dmac[ETH_ALEN];
      	unsigned int dip;
      };
      
      struct arppkt {
      	struct ethhdr eh;
      	struct arphdr arp;
      };
      
      
      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;
      };
      
      void print_mac(unsigned char *mac) {
      	int i = 0;
      	for (i = 0;i < ETH_ALEN-1;i ++) {
      		printf("%02x:", mac[i]);
      	}
      	printf("%02x", mac[i]);
      }
      
      void print_ip(unsigned char *ip) {
      	int i = 0;
      
      	for (i = 0;i < 3;i ++) {
      		printf("%d.", ip[i]);
      	}
      	printf("%d", ip[i]);
      }
      
      
      void print_arp(struct arppkt *arp) {
      	print_mac(arp->eh.h_dest);
      	printf(" ");
      
      	print_mac(arp->eh.h_source);
      	printf(" ");
      
      	printf("0x%04x ", ntohs(arp->eh.h_proto));
      	printf("  ");
      	
      }
      
      int str2mac(char *mac, char *str) {
      
      	char *p = str;
      	unsigned char value = 0x0;
      	int i = 0;
      
      	while (p != '\0') {
      		
      		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;
      
      	return 0;
      }
      
      void echo_arp_pkt(struct arppkt *arp, struct arppkt *arp_rt, char *hmac) {
      
      	memcpy(arp_rt, arp, sizeof(struct arppkt));
      
      	memcpy(arp_rt->eh.h_dest, arp->eh.h_source, ETH_ALEN);
      	str2mac(arp_rt->eh.h_source, hmac);
      	arp_rt->eh.h_proto = arp->eh.h_proto;
      
      	arp_rt->arp.h_addrlen = 6;
      	arp_rt->arp.protolen = 4;
      	arp_rt->arp.oper = htons(2);
      	
      	str2mac(arp_rt->arp.smac, hmac);
      	arp_rt->arp.sip = arp->arp.dip;
      	
      	memcpy(arp_rt->arp.dmac, arp->arp.smac, ETH_ALEN);
      	arp_rt->arp.dip = arp->arp.sip;
      
      }
      
      
      void echo_udp_pkt(struct udppkt *udp, struct udppkt *udp_rt) {
      
      	memcpy(udp_rt, udp, sizeof(struct udppkt));
      
      	memcpy(udp_rt->eh.h_dest, udp->eh.h_source, ETH_ALEN);
      	memcpy(udp_rt->eh.h_source, udp->eh.h_dest, ETH_ALEN);
      
      	udp_rt->ip.saddr = udp->ip.daddr;
      	udp_rt->ip.daddr = udp->ip.saddr;
      
      	udp_rt->udp.source = udp->udp.dest;
      	udp_rt->udp.dest = udp->udp.source;
      
      }
      
      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.saddr = icmp->ip.daddr;
      	icmp_rt->ip.daddr = icmp->ip.saddr;
      
      	memcpy(icmp_rt->eh.h_dest, icmp->eh.h_source, ETH_ALEN);
      	memcpy(icmp_rt->eh.h_source, icmp->eh.h_dest, ETH_ALEN);
      
      	icmp_rt->icmp.check = in_cksum((unsigned short*)&icmp_rt->icmp, sizeof(struct icmphdr));
      	
      }
      
      
      int main() {
      	
      	struct ethhdr *eh;
      	struct pollfd pfd = {0};
      	struct nm_pkthdr h;
      	unsigned char *stream = NULL;
      
      	struct nm_desc *nmr = nm_open("netmap:eth0", NULL, 0, NULL);
      	if (nmr == NULL) {
      		return -1;
      	}
      
      	pfd.fd = nmr->fd;
      	pfd.events = POLLIN;
      
      	while (1) {
      		int ret = poll(&pfd, 1, -1);
      		if (ret < 0) continue;
      		
      		if (pfd.revents & POLLIN) {
      			//獲取收到的包
      			stream = nm_nextpkt(nmr, &h);
      			//強(qiáng)轉(zhuǎn)為以太網(wǎng)頭
      			eh = (struct ethhdr*)stream;
      			//如果是IP協(xié)議
      			if (ntohs(eh->h_proto) == PROTO_IP) {
      				//強(qiáng)轉(zhuǎn)為udp的包
      				struct udppkt *udp = (struct udppkt*)stream;
      				//判斷是否為UDP協(xié)議
      				if (udp->ip.protocol == PROTO_UDP) {
      						
      					struct in_addr addr;
      					addr.s_addr = udp->ip.saddr;
      
      					int udp_length = ntohs(udp->udp.len);
      					printf("%s:%d:length:%d, ip_len:%d --> ", inet_ntoa(addr), udp->udp.source, 
      						udp_length, ntohs(udp->ip.tot_len));
      
      					udp->body[udp_length-8] = '\0';
      					printf("udp --> %s\n", udp->body);
      #if 1
      					struct udppkt udp_rt;
      					echo_udp_pkt(udp, &udp_rt);
      					nm_inject(nmr, &udp_rt, sizeof(struct udppkt));
      #endif			//判斷是否為ICMP的包
      				} else if (udp->ip.protocol == PROTO_ICMP) {
      					//強(qiáng)轉(zhuǎn)為 imcp的包
      					struct icmppkt *icmp = (struct icmppkt*)stream;
      
      					printf("icmp ---------- --> %d, %x\n", icmp->icmp.type, icmp->icmp.check);
      					if (icmp->icmp.type == 0x08) {
      						struct icmppkt icmp_rt = {0};
      						echo_icmp_pkt(icmp, &icmp_rt);
      
      						//printf("icmp check %x\n", icmp_rt.icmp.check);
      						nm_inject(nmr, &icmp_rt, sizeof(struct icmppkt));
      					}
      					//如果是IGMP協(xié)議的話
      				} else if (udp->ip.protocol == PROTO_IGMP) {
      
      				} else {
      					printf("other ip packet");
      				}
      				
      			}  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.26")) {
      					echo_arp_pkt(arp, &arp_rt, "00:50:56:33:1c:ca");
      					nm_inject(nmr, &arp_rt, sizeof(struct arppkt));
      				}
      			}
      		} 
      	}
      }
      

      這樣就通過(guò)使用netmap完成了icmp和arp,以及UDP包的解析。

      posted @ 2023-03-13 13:26  飄雨的河  閱讀(111)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 日本一区不卡高清更新二区| 亚洲欧美中文日韩V日本| 日韩精品一区二区三区视频| 欧美成人黄在线观看| 亚洲日本精品国产第一区| 伦伦影院精品一区| 固始县| 性色a码一区二区三区天美传媒| 偷拍精品一区二区三区| 蜜桃一区二区三区在线看| 精品日韩精品国产另类专区| 另类 专区 欧美 制服| 777奇米四色成人影视色区| 国产mv在线天堂mv免费观看| 国产中文成人精品久久久| 国模冰莲自慰肥美胞极品人体图| 色天使亚洲综合一区二区| 精品亚洲精品日韩精品| 波多野结衣久久一区二区| 久久青草国产精品一区| 亚洲国产一成人久久精品| 精品人妻伦九区久久aaa片| 日韩av综合免费在线| jlzz大jlzz大全免费| 亚洲精品漫画一二三区| 红桃视频成人传媒| 国内精品自在拍精选| 18禁成人免费无码网站| 推油少妇久久99久久99久久| 国产成人精品亚洲日本片| 激情国产一区二区三区四| 扒开粉嫩的小缝隙喷白浆视频| 强奷白丝美女在线观看| 亚洲熟女国产熟女二区三区| 欧美国产日韩久久mv| 日本亚洲一区二区精品久久| 四虎精品国产精品亚洲精| 毛片免费观看视频| 99久久婷婷国产综合精品青草漫画| 天啦噜国产精品亚洲精品| 亚洲欧美成人a∨观看|