当前位置: 首页 > news >正文

长江商学院 网站建设vi设计怎么做

长江商学院 网站建设,vi设计怎么做,乐山网站制作设计公司,怎么将网站权重提上去什么是协议栈呢#xff1f; #xff08;协议栈#xff08;Protocol Stack#xff09;是计算机网络和通信系统中的一个重要概念#xff0c;它指的是一组协议层的层次结构#xff0c;这些协议层一起协同工作#xff0c;以便在不同计算机或设备之间实现数据通信和交换。每… 什么是协议栈呢 协议栈Protocol Stack是计算机网络和通信系统中的一个重要概念它指的是一组协议层的层次结构这些协议层一起协同工作以便在不同计算机或设备之间实现数据通信和交换。每个协议层都有特定的功能和责任从物理层到应用层每一层都在不同的抽象级别上处理数据和通信任务友情提示请阅读代码的注释 通过mmap可以将网卡里的数据映射到内存中去 这里是零拷贝指的是cpu指令没有参与但并不是没有拷贝,这是一种DMA的方式 实现协议栈有几种方式如raw-socket、netmap、dpdk等这里用netmap实现 如果不这样实现的话会多拷贝一次下面看原理图 . 获取原始数据 获取原始数据的三种方法介绍 不经过网络协议栈解析拿到原始数据sk_buff 使用原始套接字raw socket tcpdump和wireshark就是使用这个做的raw socket主要用来抓包。dbdknetmap是用于用户层应用程序收发原始网络数据的高性能框架本文使用netmap进行数据的收发。 1、netmap 原理 网卡即不在物理层也不在数据链路层是在这两层之间做转换。 数据传输的流程 网卡将物理层的光电信号转换为数字信号0101010。给到网卡驱动然后把这个数据(通过sk_buff搬运工)) 拷贝迁移到协议栈。 然后协议栈解析完数据之后将数据拷贝放入recv buffer然后应用程序通过系统调用就能得到这个数据。   netmap 采用 mmap 的方式将网卡驱动的 ring 内存空间映射到用户空间。这样用户态可以直接操作内存获取原始的数据避免了内核和用户态的两次拷贝网卡 - 内核协议栈 - 内存 如果不用netmap走内核协议栈的话我们在驱动和协议栈之间拷贝一次在协议栈和应用层拷贝一次那么就走了两次当大量数据到来的话就会造成 传输速度下降因为我们的IO操作 其实是很费时间的所以我们就拷贝一次大大的缩短了时间 2、netmap 环境搭建 安装 netmap # 安装 netmap git clone https://github.com/luigirizzo/netmap.git cd netmap/LINUX ./configure make make install# 将头文件拷贝到 /usr/include/net cd ./netmap/sys/net/ # netmap 头文件位置 cp * /usr/include/net 启动 netmap # 开启 netmap insmod netmap.ko ls /dev/netmap -l # 关闭 netmap rmmod netmap.ko3、udp 协议栈的实现 3.1.以太网协议头格式 struct ethhdr {unsigned char h_dst[ETH_ALEN];//源mac,6字节unsigned char h_src[ETH_ALEN];//目的mac,6字节unsigned short h_proto;//协议类型2字节 }; 3.2 ip协议头格式 struct iphdr {unsigned char hdrlen:4, //为什么跟报头看着不一样呢那是因为我们的网络字节序是大端的version:4; // 0x45 //我们的协议报头的时候低位是版本号高位是报头长度//那么编程的时候低位的报头长度高位是版本号//那么在转到网络上去之后就是低位是版本号 //字节序问题请去百度一下大小端问题unsigned char tos;//type of serviceunsigned short totlen;//total length//ip包总大小 - 首部大小等于数据大小unsigned short id;//16位标识//标识分片的包因为网络层向下传的时候//会受mtu的大小进行分片//所以要想确保数据是正常的就需要设置一个标识标识完整的数据包//也以便ip上传到传输层后续重组unsigned short flag_offset; //3位标志13位片偏移//3位标识一个是df为1表示数据包不可以分片0表示告知可以分片,//mf标识是否有更多分片为0就表示最后一个分片了//那么我们在收到包的时候可以根据这个标志位和16位标识以及片偏移量重组数据了//unsigned char ttl; //time to live 生存周期(比如每经过一个网关ttl-1)// 0x1234// htonsunsigned char type;//8位协议 用于指明IP的上层协议.传输层的报头没有协议unsigned short check;//16位首部校验和unsigned int sip;//源ip标识发送方主机unsigned int dip;//目的ip标识接收方主机}; // 20字节 3.3 udp协议头 //udp协议头 struct udphdr {unsigned short sport;//源端口unsigned short dport;//目的端口unsigned short length;//udp长度unsigned short check;//校验值}; // 8字节 3.4 arp协议头 struct arphdr {unsigned short h_type;//硬件类型unsigned short h_proto;//协议类型//真正的地址是mac地址//ip地址是逻辑地址mac地址是物理地址唯一标识一台主机的unsigned char h_addrlen;unsigned char h_protolen;unsigned short oper;//操作码在发送arp包的时候会//用到操作码arp响应2和arp请求1//有了这个操作码我们就知道是请求获取我的mac地址还是//我的arp请求已经到了(响应)//因为刚开始发arp包的时候只携带自身的mac地址和arp请求//发送过后再回发arp响应将mac地址填上此时收到的//arp包的源mac地址就是我们之前广播的主机的mac地址//然后做一个映射unsigned char smac[ETH_ADDR_LENGTH];unsigned int sip;unsigned char dmac[ETH_ADDR_LENGTH];unsigned int dip; }; ICMP协议头我就不实现了主要是用来进行ping命令的 3.5 各层数据包格式 我们还得定义一下OSI七层模型的数据包因为网络层的数据包从上到下是解包和封包的过程 越下面的层会封装上面的层的协议头 struct udppkt {struct ethhdr eh;struct iphdr ip;struct udphdr udp;unsigned char data[0];//用户数据//柔性数组这样就可以在结构体末尾动态地分配内存空间。//不会发生越界情况 };//定义完以太网包ip包和udp包之后 //我们还需要定义一个arp包 //为什么呢因为arp缓存 //在我们xshell连接上之后会将 //eh0这张网卡的mac地址和ip地址做一个映射关系 //过一段时间之后这个mac和ip地址的映射关系就会消失 //所以我们需要自己搞一个arp包或者自己设置arp缓存 //或者静态的//没有设置也没有静态arp缓存的话客户端就会发一次arp包 //那么既然我们是用netmap的方式接收的包那么就需要自己接收 //到包封装包struct arppkt {struct ethhdr eh;struct arphdr arp;}; 其他的包就不写了其实就是在上层的包那里添加下当前网络层的协议头 #include stdio.h #include unistd.h #include string.h #include stdlib.h#include sys/poll.h #include arpa/inet.h#define ETH_ADDR_LENGTH 6 #define NETMAP_WITH_LIBS#include net/netmap_user.h #pragma pack(1) //内存对齐设置为1如果不设置为1的话 //会出问题参考我的博客里的内存对齐篇#define ETH_ALEN 6 #define PROTO_IP 0x0800 #define PROTO_ARP 0x0806#define PROTO_UDP 17 #define PROTO_ICMP 1 #define PROTO_IGMP 2struct ethhdr {unsigned char h_dst[ETH_ALEN];//源mac,6字节unsigned char h_src[ETH_ALEN];//目的mac,6字节unsigned short h_proto;//协议类型2字节 };struct iphdr {unsigned char hdrlen:4, //为什么跟报头看着不一样呢那是因为我们的网络字节序是大端的version:4; // 0x45 //我们的协议报头的时候低位是版本号高位是报头长度//那么编程的时候低位的报头长度高位是版本号//那么在转到网络上去之后就是低位是版本号 //字节序问题请去百度一下大小端问题unsigned char tos;//type of serviceunsigned short totlen;//total length//ip包总大小 - 首部大小等于数据大小unsigned short id;//16位标识//标识分片的包因为网络层向下传的时候//会受mtu的大小进行分片//所以要想确保数据是正常的就需要设置一个标识标识完整的数据包//也以便ip上传到传输层后续重组unsigned short flag_offset; //3位标志13位片偏移//3位标识一个是df为1表示数据包不可以分片0表示告知可以分片,//mf标识是否有更多分片为0就表示最后一个分片了//那么我们在收到包的时候可以根据这个标志位和16位标识以及片偏移量重组数据了//unsigned char ttl; //time to live 生存周期(比如每经过一个网关ttl-1)// 0x1234// htonsunsigned char type;//8位协议 用于指明IP的上层协议.传输层的报头没有协议unsigned short check;//16位首部校验和unsigned int sip;//源ip标识发送方主机unsigned int dip;//目的ip标识接收方主机}; // 20字节//udp协议头 struct udphdr {unsigned short sport;//源端口unsigned short dport;//目的端口unsigned short length;//udp长度unsigned short check;//校验值}; // 8字节struct udppkt {struct ethhdr eh;struct iphdr ip;struct udphdr udp;unsigned char data[0];//用户数据//柔性数组这样就可以在结构体末尾动态地分配内存空间。//不会发生越界情况 };//定义完以太网包ip包和udp包之后 //我们还需要定义一个arp包 //为什么呢因为arp缓存 //在我们xshell连接上之后会将 //eh0这张网卡的mac地址和ip地址做一个映射关系 //过一段时间之后这个mac和ip地址的映射关系就会消失 //所以我们需要自己搞一个arp包或者自己设置arp缓存 //或者静态的//没有设置也没有静态arp缓存的话客户端就会发一次arp包 //那么既然我们是用netmap的方式接收的包那么就需要自己接收 //到包封装包struct arphdr {unsigned short h_type;//硬件类型unsigned short h_proto;//协议类型//真正的地址是mac地址//ip地址是逻辑地址mac地址是物理地址唯一标识一台主机的unsigned char h_addrlen;unsigned char h_protolen;unsigned short oper;//操作码在发送arp包的时候会//用到操作码arp响应2和arp请求1//有了这个操作码我们就知道是请求获取我的mac地址还是//我的arp请求已经到了(响应)//因为刚开始发arp包的时候只携带自身的mac地址和arp请求//发送过后再回发arp响应将mac地址填上此时收到的//arp包的源mac地址就是我们之前广播的主机的mac地址//然后做一个映射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;}; //icmp我就不封装了有icmp协议我们才能用ping命令否则用ping命令是 //ping不通的可以用wireshark抓包看一下有没有icmp协议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 *mac) {//把源和目的 的ip换一下就行了然后补个mac地址memcpy(arp_rt, arp, sizeof(struct arppkt));memcpy(arp_rt-eh.h_dst, arp-eh.h_src, ETH_ADDR_LENGTH);str2mac(arp_rt-eh.h_src, mac);arp_rt-eh.h_proto arp-eh.h_proto;arp_rt-arp.h_addrlen 6;arp_rt-arp.h_protolen 4;arp_rt-arp.oper htons(2);str2mac(arp_rt-arp.smac, mac);arp_rt-arp.sip arp-arp.dip;memcpy(arp_rt-arp.dmac, arp-arp.smac, ETH_ADDR_LENGTH);arp_rt-arp.dip arp-arp.sip;} //就是解析完arp包后再发过去目的mac和源mac什么的变一下 // void echo_arp_pkt(struct arppkt *arp, struct arppkt *arp_rt, char *mac) //这是一个函数定义它接受三个参数其中 arp 是指向输入ARP数据包的指针arp_rt //是指向输出ARP数据包的指针mac 是一个字符数组可能用于存储MAC地址。// // memcpy(arp_rt, arp, sizeof(struct arppkt)) // 这行代码将从输入ARP数据包 arp 复制整个数据包的内容到输出ARP数据包 arp_rt 中 // 复制的字节数为 sizeof(struct arppkt)。// // memcpy(arp_rt-eh.h_dst, arp-eh.h_src, ETH_ADDR_LENGTH) // 这行代码将输入ARP数据包中的目标MAC地址eh.h_dst复制到输出ARP数据包的源MAC地址eh.h_src // 以交换它们的值。 ETH_ADDR_LENGTH 可能是一个常量表示MAC地址的长度。// // str2mac(arp_rt-eh.h_src, mac) // 这行代码似乎是将 mac 中的MAC地址数据复制到输出ARP数据包的源MAC地址字段eh.h_src中。// // arp_rt-eh.h_proto arp-eh.h_proto // 这行代码将输出ARP数据包的以太网协议类型字段eh.h_proto设置为与输入ARP数据包相同的值以保持协议类型不变。// // arp_rt-arp.h_addrlen 6 和 arp_rt-arp.h_protolen 4 // 这两行代码设置输出ARP数据包的地址长度字段和协议地址长度字段。// // arp_rt-arp.oper htons(2)这行代码将输出ARP数据包的操作码字段oper设置为2这表示ARP响应。// // str2mac(arp_rt-arp.smac, mac)这行代码将 mac 中的MAC地址数据复制到 // 输出ARP数据包的发送方MAC地址字段smac中。// // arp_rt-arp.sip arp-arp.dip这行代码将输出ARP数据包的发送方IP地址字段sip // 设置为输入ARP数据包的目标IP地址字段dip的值。// // memcpy(arp_rt-arp.dmac, arp-arp.smac, ETH_ADDR_LENGTH)这行代码将输入ARP数据包的源MAC地址smac // 复制到输出ARP数据包的目标MAC地址字段dmac以交换它们的值。// // arp_rt-arp.dip arp-arp.sip这行代码将输出ARP数据包的目标IP地址字段dip // 设置为输入ARP数据包的发送方IP地址字段sip的值。// // 总的来说这个函数接受一个ARP请求数据包将其内容复制到一个ARP响应数据包中 // 同时交换了源和目标的MAC地址和IP地址以制作一个相应的ARP响应数据包用于回应原始ARP请求。 // 这种操作通常用于网络通信中以满足地址解析的需求。函数的实现可能依赖于其他未提供的函数或数据结构 // 如 struct arppkt 和 str2mac。// int main() {struct nm_pkthdr h;//ringbuffer的头struct nm_desc *nmr nm_open(netmap:eth0, NULL, 0, NULL);if (nmr NULL) return -1;//把fd放入pollfd中如果fd可读就去操作数据不可读就不操作struct pollfd pfd {0};pfd.fd nmr-fd;pfd.events POLLIN;while (1) {int ret poll(pfd, 1, -1);//第一个参数pollfd第二个参数fd个数第三个参数-1代表一直阻塞直到数据过来if (ret 0) continue;if (pfd.revents POLLIN) {//有数据来了unsigned char *stream nm_nextpkt(nmr, h);//取数据(因为已经在内存中了不能用读由于是环形ringbuffer因此取数据叫next package)struct ethhdr *eh (struct ethhdr *)stream;//把stream中的第一个部分转换为以太网头if (ntohs(eh-h_proto) PROTO_IP) { //取出来的上层协议是IP协议struct udppkt *udp (struct udppkt *)stream;//转化为udp帧数据格式if (udp-ip.type PROTO_UDP) { //udp包int udplength ntohs(udp-udp.length);udp-data[udplength-8] \0; //udp总长度-8个字节长度的udp头 就是upd数据部分的长度。 末尾加上字符串结尾\0printf(udp -- %s\n, udp-data);} else if (udp-ip.type PROTO_ICMP) {}} else if (ntohs(eh-h_proto) PROTO_ARP) {//ARP包struct arppkt *arp (struct arppkt *)stream;struct arppkt arp_rt;//eth0的ip地址eth0是网卡接口if (arp-arp.dip inet_addr(10.0.4.12)) { //如果接受到的广播arp是本机的就回复 如果不进行判断就是ARP攻击了不管是什么arp请求都回复会导致它们的arp表更新错误的信息//eth0的mac地址echo_arp_pkt(arp, arp_rt, 52:54:00:d5:c3:82);//创建一个arp回复的包源和目的互换补充上mac地址(ifconfig可以查看)nm_inject(nmr, arp_rt, sizeof(arp_rt));//发送arp应答printf(arp ret\n);}}}}}使用nm_open()函数时需要指定的是物理网卡名。eth0是物理显卡名ens33是虚拟网卡名。 修改网卡名字 sudo vim /etc/default/grub//修改GRUB_CMDLINE_LINUX为如下主要是增加 net.ifnames0 biosdevname0 这句 GRUB_CMDLINE_LINUXfind_presend/presend.cfg noprompt net.ifnames0 biosdevname0 default_hugepagesz1G hugepagesz2M hugepages1024 isolcpus0-2启动程序后刚开始可以接收udp包过一段时间后就接受不到了。 1.原因程序把网卡的数据发送到了共享内存不经过协议栈。而局域网内所有机器每隔一段时间会发送arp协议告知局域网内其他机器自己的IP和MAC地址如果一段时间内没有收到对方的arp协议那么本机就会把arp表对应的arp协议信息IP和MAC地址删掉。 因此因为一开始发送udp包对方的时候还知道对方的IP和MAC地址。对方因为没有走协议栈对方就会不发arp协议给我那么过段时间后我的arp表就会把对方的IP和MAC地址信息删掉我就没办法知道对方的IP和MAC地址因此后面就无法发送upd包给到对方了。 没开启进程前可以ping通进程所在的机器过段时间后无法ping通。 2.原因程序把网卡的数据发送到了共享内存不经过协议栈。而ping协议的反馈是走ICMP协议的 因此因为ping对方的时候对方因为没有走协议栈对如果对方处理网卡信息的时候没有实现对ICMP协议的解析和回复那么我ping对方就没办法收到对方的反馈。 解决方法 1.ping命令只需要实现一下icmp包就行2.怎么保存arp缓存呢 2.1 自己添加一下arp设置成静态的那么数据包就知道发到局域网的哪台主机了 因为路由器保存着局域网内的arp缓存表arp缓存表的ip地址是局域网内部的私有ip 地址添加了之后路由器就有一条arp缓存当数据包到来的时候路由器识别到  的是公网ip地址然后路由器收到数据包之后根据arp缓存表找到对应的mac地址 和先去发到mac层判断是否符合数据包的mac地址再发到网络层判断ip是否 是数据包的ip是的话就向传输层传输 2.2 自己写arp包收到arp请求的时候填充我们的eth0的ip地址和mac地址重新发送 过去
http://www.pierceye.com/news/54612/

相关文章:

  • 做网站的出路wordpress狮子歌歌
  • 做网站怎么移动图片杭州品牌网站制作
  • 西樵网站制作电商网站规划论文
  • 个人网站的订单摄影照片投稿网站
  • 网站建设业务介绍刷q币网站建设
  • 做教务网站的需求分析东阿网站建设
  • 专门做拼花网站品牌包装建设网站
  • 用模板建商城购物网站便利的龙岗网站设计
  • 深圳做网站推荐哪家公司好安卓软件下载安装
  • 上海网站制作商东莞关键词优化外包
  • 营销型企业网站建设方案做品牌断码的网站
  • 网站的建设方法包括网站建设与维护招聘条件
  • 太原网站seo服务apache 网站建设
  • 网站标题图片怎么做百度用户服务中心人工电话
  • 小程序定制开发团队长沙网站seo服务
  • 免费做网站的平台windows优化大师好吗
  • 浙江建设干部学校网站首页wordpress 发表评论
  • html设计素材网站淘宝不能发布网站开发了
  • 滨州做企业网站微信怎么搞小程序
  • 口岸地区网站建设内容wordpress本地运行环境
  • 淘客网站免费开源源码中国seo
  • 温州外贸网站建设公司tg cd wordpress
  • 潞城市网站建设公司有哪些做设计交易网站有哪些内容
  • 网站开发费用无形资产wordpress 爱情
  • 网站建设公司成都自助下单网站
  • 国内哪个网站用wordpress苏州有什么好玩的推荐
  • 宁夏微信服务网站扫wordpress漏洞工具
  • 从哪个网站找钢做的微商软件开发外包方案
  • 上海建设局网站首页wordpress自定义登陆页面跳转
  • 如何由网页生成网站网站备案关闭网站