17

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

 3 years ago
source link: http://yiiyee.cn/blog/2020/04/10/uefi%e5%bc%80%e5%8f%91%e6%8e%a2%e7%b4%a255-uefi%e4%b8%8e%e7%bd%91%e7%bb%9c5/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

708 total views, 1 views today


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK