请保留-> 【原文: https://blog.csdn.net/luobing4365 和 http://yiiyee.cn/blog/author/luobing/】
本篇开始编写IPV6的代码。因为一直使用的网络调试助手不支持IPV6的通信,只好花了点时间,自己把相关的IPV6的代码(windows和linux下)实现了一遍。
1 搭建IPV6的通信环境
由于现在基本上还在使用IPV4的网络,特别是家庭中,很少使用支持IPV6的路由器。所以,如果需要在双机间调试IPV6的代码,最好买个支持IPV6的路由器,按照路由器手册设置一下就可以了。
当然,我们也可以虚拟机来搭建通信环境。我所使用的虚拟机,都是使用NAT模式的。在打开IPV6支持选项前,虚拟机操作系统上的网卡,没有分配对外的IPV6的地址,导致无法与宿主机通信。
做个类比,开启虚拟机的IPV6支持选项,相当于为虚拟机添加了IPV6的路由器。虚拟机操作系统上的网卡设备会分配IPV6地址,虚拟机之间、虚拟机和宿主机之间可以通过IPV6通信。
记录下Vmware和VirtualBox打开IPV6的方法。
1) Vmware: 打开菜单栏-编辑-虚拟机网络编辑器-更改设备,在弹出的菜单中,选择Vmnet8,这是NAT模式的虚拟网卡。打开“NAT设置”,将“启用IPv6”选项勾选,确定即可。如图:
2) VirtualBox: 打开菜单栏的 File-Prefence,选择Network,添加NAT network,如图:
将支持IPv6的所有选项勾选上。选择需要支持IPV6的虚拟机,打开其Setting选项,选择Network,并将网卡设备改为NatNetwork,如图:
修改完毕,虚拟机可以支持IPv6了。
2 在Nt32模拟器中支持IPv6
其设置的基本步骤和之前博客中,让Nt32模拟器支持IPv4的步骤差不多。注意看图4中的网络协议栈,IPv6与Ipv4很类似,只不过配置工具从ping和Ifconfig变为了ping6和Ifconfig6。
通过之前的博客,我们已经知道,IPv6的协议驱动,是在NetworkPkg中的。因此,需要先编译出这些驱动,编译命令如下:
C:\MyWorkspace>build -p NetworkPkg\NetworkPkg.dsc -a IA32
将相应的驱动拷贝到Nt32的目录中,启动模拟环境(网卡在之前配置IPv4时已经完成),加载IPv6网卡驱动,命令如下:
FS0:\>load Mtftp6Dxe.efi Ip6Dxe.efi VlanConfigDxe.efi Udp6Dxe.efi Dhcp6Dxe.efi Mtftp6Dxe.efi TcpDxe.efi
配置网卡设备的IPv6地址自动获取,命令为:
FS0:\>ifconfig6 -s eth0 auto
可通过命令ifconfig6 -l eth0查看地址是否分配成功。配置完成后,测试其与主机间的通信:
3 编写TCP6代码
上一篇中,介绍过编写TCP4代码的过程,TCP6的代码编写流程是一样的。只不过,我没找到现成的TCP6测试工具,只能自己写一个了。
我们将设计一个“回声”的程序,服务端作为回声壁,对客户端发过来的消息,全部原样返回。由于我的UEFI程序大部分是在windows上编译的,所以编写个windows的服务端就可以了。
3.1 Windows服务端代码编写
打开Vs2015,新建 Win32 Console Application类型的工程。添加以下头文件:
#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
#include <Ws2tcpip.h> //InetPton() 头文件
并引入微软的socket库:
#pragma comment(lib,”ws2_32″)//引入库函数
与TCP4不同,地址类型改为SOCKADDR_IN6,其余的代码与TCP4编写差不多。
由于这是服务端代码,对IPv6的地址不需要处理。但在需要获取服务端地址的客户端中,与TCP4的编写不一样,和Linux下的编写也不大一样。
为了演示这部分的区别,我也编写了windows平台的客户端。(后面干脆连IPv6的UDP服务端、客户端都编号了)
具体可以参考微软网站上的文档:https://docs.microsoft.com/en-us/windows/win32/winsock/ipv6-enabled-client-code-2?redirectedfrom=MSDN
微软提供的getaddrinfo()函数,可以对机器名、IPv4、IPv6地址进行解析,配合getnaminfo(),可以得到服务端IPv6的地址。然后使用connect()连接服务端,进行通信。
只有这块与TCP4的编写稍微不同,其他都是一样的。
3.2 UEFI客户端编写
编写TCP6的UEFI客户端,编程方式与Linux下的TCP6很相似。实际上,我的代码也是从以前的Linux代码中移植过来的,只是稍微修改了下变量的类型。
先是建立TCP6的socket,代码如下:
socketID = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
然后对命令行传入的IPv6地址进行转换,并通过IP地址连接服务端:
inet_pton(AF_INET6, Argv[1], &ServerIp.sin6_addr);
connect(sockfd, (struct sockaddr *) &ServerIp, sizeof(ServerIp));
最后构建收发数据的循环,向服务端发送数据,并接受从服务端发过来的数据。
4 编译测试
编译命令如下:
C:\MyWorkspace> build -p RobinPkg\RobinPkg.dsc -a IA32 -m RobinPkg\Applications\stdEchoTcp6\stdEchoTcp6.inf
编译后,将执行文件拷贝到Nt32模拟环境所在的目录。按照第2节所描述的方法,搭建IPv6的测试环境,进行测试:
到本篇为止,所有与网络相关的博客就完成了。至于应用层的协议,包括pxe、ftp等,目前在项目上还没怎么用到,待未来如果遇到类似项目,到时再深入总结吧。下篇开始研究UEFI对USB的支持。
TCP6 uefi客户端代码:
百度云链接:https://pan.baidu.com/s/1gccSosw8_UAGTI5gZPnLCA
提取码:dx23
文件在 FF RobinPkg/ RobinPkg /Applications/stdEchoTCP6
Windows端IPv6的代码,包括TCP的服务端和客户端、UDP的服务端和客户端(VS2015编译):
百度云链接:https://pan.baidu.com/s/1gccSosw8_UAGTI5gZPnLCA
提取码:dx23
文件在 55blog-WindowsIPv6
3,371 total views, 1 views today
博主你的百度云ID有点亮眼
这个……试图改过几次,没法改。本以为没人会注意到…