UEFI开发探索55 – UEFI与网络5(IPv6)

请保留-> 【原文:  https://blog.csdn.net/luobing4365http://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”选项勾选,确定即可。如图:

图1 VMware 启用IPv6

2) VirtualBox: 打开菜单栏的 File-Prefence,选择Network,添加NAT network,如图:

图2 VirtualBox添加NatNetwork

将支持IPv6的所有选项勾选上。选择需要支持IPV6的虚拟机,打开其Setting选项,选择Network,并将网卡设备改为NatNetwork,如图:

图3 修改网卡类型

修改完毕,虚拟机可以支持IPv6了。

2 在Nt32模拟器中支持IPv6

其设置的基本步骤和之前博客中,让Nt32模拟器支持IPv4的步骤差不多。注意看图4中的网络协议栈,IPv6与Ipv4很类似,只不过配置工具从ping和Ifconfig变为了ping6和Ifconfig6。

图4 UEFI网络协议栈(摘自Harnessing the uefi shell p107)

通过之前的博客,我们已经知道,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查看地址是否分配成功。配置完成后,测试其与主机间的通信:

图5 ping6连接主机

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的测试环境,进行测试:

图6 测试程序

到本篇为止,所有与网络相关的博客就完成了。至于应用层的协议,包括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,333 total views, 1 views today

《UEFI开发探索55 – UEFI与网络5(IPv6)》有2个想法

发表评论

电子邮件地址不会被公开。