IP4
IP全称Internet Protocol。
它算是整个网络协议中最重要的一部分,它的主要作用是在复杂的网络环境中,将数据包发送给最终的目的地址。
本文以IP4作为介绍对象。
需要注意,在网络协议中有Protocol这个词,而对应UEFI也有一个Protocol的概念,后者其实表示的是UEFI可调用的接口。
IP4的初始化驱动是Ip4Driver.c,它做的事情主要是以下的几个部分:
1. 通过Ip4CreateService()函数初始化IP4_SERVICE结构体;
2. 安装gEfiIp4ServiceBindingProtocolGuid对应的Protocol;
3. 参数配置;
4. 启动收发数据并处理的程序;
这一步是通过Ip4ReceiveFrame()函数来启动的,它注册了MNP接收到数据之后的回调函数,而在这个回调函数中又执行了Ip4ReceiveFrame(),形成了循环收发数据并处理的过程。
5. 启动定时器处理各种其它需要IP4来处理的情形,具体的就是下面的函数:
/**
There are two steps for this the heart beat timer of IP4 service instance.
First, it times out all of its IP4 children's received-but-not-delivered
and transmitted-but-not-recycle packets, and provides time input for its
IGMP protocol.
Second, a dedicated timer is used to poll underlying media status. In case
of cable swap, a new round auto configuration will be initiated. The timer
will signal the IP4 to run DHCP configuration again. IP4 driver will free
old IP address related resource, such as route table and Interface, then
initiate a DHCP process to acquire new IP, eventually create route table
for new IP address.
@param[in] Event The IP4 service instance's heart beat timer.
@param[in] Context The IP4 service instance.
**/
VOID
EFIAPI
Ip4TimerTicking (
IN EFI_EVENT Event,
IN VOID *Context
)
下面首先介绍Ip4CreateService()函数创建的IP4_SERVICE结构体,然后是两个另外的重要的结构体:IP4_INTERFACE和IP4_PROTOCOL;
它们之间的区别大致是:
1. IP4_SERVICE描述的是一个网络设备的特征,它包括了其下的所有IP4_INTERFACE和IP4_PROTOCOL;
2. IP4_INTERFACE用于描述网络层的信息,比如IP地址等;
3. IP4_PROTOCOL主要用作底层的数据收发;
IP4_SERVICE和IP4_PROTOCOL在之前讲过的MNP和SNP中都有,算是UEFI实现的一部分;而IP4_INTERFACE更像是网络协议架构中的网络层的表现。
IP4_SERVICE structure
IP4_SERVICE位于Ip4Impl.h文件中,如下所示:
struct _IP4_SERVICE {
UINT32 Signature;
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
INTN State;
//
// List of all the IP instances and interfaces, and default
// interface and route table and caches.
//
UINTN NumChildren;
LIST_ENTRY Children;
LIST_ENTRY Interfaces;
IP4_INTERFACE *DefaultInterface;
IP4_ROUTE_TABLE *DefaultRouteTable;
//
// Ip reassemble utilities, and IGMP data
//
IP4_ASSEMBLE_TABLE Assemble;
IGMP_SERVICE_DATA IgmpCtrl;
//
// Low level protocol used by this service instance
//
EFI_HANDLE Image;
EFI_HANDLE Controller;
EFI_HANDLE MnpChildHandle;
EFI_MANAGED_NETWORK_PROTOCOL *Mnp;
EFI_MANAGED_NETWORK_CONFIG_DATA MnpConfigData;
EFI_SIMPLE_NETWORK_MODE SnpMode;
EFI_EVENT Timer;
EFI_EVENT ReconfigEvent;
BOOLEAN Reconfig;
//
// Underlying media present status.
//
BOOLEAN MediaPresent;
//
// IPv4 Configuration II Protocol instance
//
IP4_CONFIG2_INSTANCE Ip4Config2Instance;
CHAR16 *MacString;
UINT32 MaxPacketSize;
UINT32 OldMaxPacketSize; ///< The MTU before IPsec enable.
};
这些值的介绍如下:
1. Signature:它的值是SIGNATURE_32 ('I', 'P', '4', 'S');
2. ServiceBinding:对应的就是IP4的ServiceBindingProtocol,下面有CreateChild()和DestroyChild()两个接口;
3. State:它有如下的值:
//
// The state of IP4 service. It starts from UNSTARTED. It transits
// to STARTED if autoconfigure is started. If default address is
// configured, it becomes CONFIGED. and if partly destroyed, it goes
// to DESTROY.
//
#define IP4_SERVICE_UNSTARTED 0
#define IP4_SERVICE_STARTED 1
#define IP4_SERVICE_CONFIGED 2
#define IP4_SERVICE_DESTROY 3
注释中已经说明白了各个状态的变换;
4. NumChildren,Children:表示通过ServiceBindingProtocol的CreateChild()创建的子例,这个子例才是真正的IP4实例,类型是IP4_PROTOCOL;
5. Interfaces:跟上面说的Children类似,不过这里的子例类型是IP4_INTERFACE,它在EFI_IP4_PROTOCOL的Configure()接口中会被初始化,后续还会进一步介绍这个结构体;
6. DefaultInterface:跟上面类似,不过上面的Interfaces是一个IP4_INTERFACE的链表,而这个是一个单独的IP4_INTERFACE,它在Ip4CreateService()的时候初始化,所以在创建好的IP4_SERVICE结构体中都有一个默认的IP4_INTERFACE;
7. DefaultRouteTable:默认的路由表,关于路由表的说明如下:
///
/// Each IP4 instance has its own route table. Each ServiceBinding
/// instance has a default route table and default address.
///
/// All the route table entries with the same mask are linked
/// together in one route area. For example, RouteArea[0] contains
/// the default routes. A route table also contains a route cache.
///
typedef struct _IP4_ROUTE_TABLE IP4_ROUTE_TABLE;
struct _IP4_ROUTE_TABLE {
INTN RefCnt;
UINT32 TotalNum;
LIST_ENTRY RouteArea[IP4_MASK_NUM];
IP4_ROUTE_TABLE *Next;
IP4_ROUTE_CACHE Cache;
};
8. Assemble:关于它的介绍如下:
///
/// Each Ip service instance has an assemble table to reassemble
/// the packets before delivery to its children. It is organized
/// as hash table.
///
typedef struct {
LIST_ENTRY Bucket[IP4_ASSEMLE_HASH_SIZE];
} IP4_ASSEMBLE_TABLE;
9. IgmpCtrl:关于IgmpCtrl的介绍如下:
///
/// The IGMP status. Each IP4 service instance has a IGMP_SERVICE_DATA
/// attached. The Igmpv1QuerySeen remember whether the server on this
/// connected network is v1 or v2.
///
typedef struct {
INTN Igmpv1QuerySeen;
LIST_ENTRY Groups;
} IGMP_SERVICE_DATA;
10. Image,Controller:对应的就是EFI_DRIVER_BINDING_PROTOCOL中的ImageHandle和DriverBindingHandle;
11. MnpChildHandle,Mnp,MnpConfigData,SnpMode:都是当前Handle上挂载的MNP和SNP的信息,其中MnpConfigData在Ip4CreateService()中会做配置,并且还会在该函数中做好MNP的配置:
Status = Ip4ServiceConfigMnp (IpSb, TRUE);
在MNP的介绍中已经说过,MNP被Config之后该网络就真正开始运行了;
12. Timer:对应的处理函数是Ip4TimerTicking(),具体这个函数做了什么就不说了;
13. ReconfigEvent:对应的处理函数是Ip4AutoReconfigCallBack(),用于DHCP;
14. Reconfig:这个跟前面说的ReconfigEvent不是一回事儿,这里的Reconfig只是的是对应MNP是否重新配置;
15. MediaPresent:表示的是物理连接是否OK,也是从UNDI-SNP-MNP一层层传上来的;
16. Ip4Config2Instance:用于配置IP4的一个实例;
17. MacString:表示MAC地址的字符串;
18. MaxPacketSize,OldMaxPacketSize:直接列出它的计算方式:
IpSb->MaxPacketSize = IpSb->SnpMode.MaxPacketSize - sizeof (IP4_HEAD);
if (NetLibGetVlanId (IpSb->Controller) != 0) {
//
// This is a VLAN device, reduce MTU by VLAN tag length
//
IpSb->MaxPacketSize -= NET_VLAN_TAG_LEN;
}
IpSb->OldMaxPacketSize = IpSb->MaxPacketSize;
IP4_INTERFACE structure
IP4_INTERFACE位于Ip4If.h文件中,如下所示(注释中所说的IP4 instance指的是IP4_PROTOCOL):
//
// Each IP4 instance has its own station address. All the instances
// with the same station address share a single interface structure.
// Each interface has its own ARP child, and shares one MNP child.
// Notice the special cases that DHCP can configure the interface
// with 0.0.0.0/0.0.0.0.
//
struct _IP4_INTERFACE {
UINT32 Signature;
LIST_ENTRY Link;
INTN RefCnt;
//
// IP address and subnet mask of the interface. It also contains
// the subnet/net broadcast address for quick access. The fields
// are invalid if (Configured == FALSE)
//
IP4_ADDR Ip;
IP4_ADDR SubnetMask;
IP4_ADDR SubnetBrdcast;
IP4_ADDR NetBrdcast;
BOOLEAN Configured;
//
// Handle used to create/destroy ARP child. All the IP children
// share one MNP which is owned by IP service binding.
//
EFI_HANDLE Controller;
EFI_HANDLE Image;
EFI_MANAGED_NETWORK_PROTOCOL *Mnp;
EFI_ARP_PROTOCOL *Arp;
EFI_HANDLE ArpHandle;
//
// Queues to keep the frames sent and waiting ARP request.
//
LIST_ENTRY ArpQues;
LIST_ENTRY SentFrames;
IP4_LINK_RX_TOKEN *RecvRequest;
//
// The interface's MAC and broadcast MAC address.
//
EFI_MAC_ADDRESS Mac;
EFI_MAC_ADDRESS BroadcastMac;
UINT32 HwaddrLen;
//
// All the IP instances that have the same IP/SubnetMask are linked
// together through IpInstances. If any of the instance enables
// promiscuous receive, PromiscRecv is true.
//
LIST_ENTRY IpInstances;
BOOLEAN PromiscRecv;
};
IP4_PROTOCOL structure
IP4_PROTOCOL位于Ip4Impl.h中,如下所示:
struct _IP4_PROTOCOL {
UINT32 Signature;
EFI_IP4_PROTOCOL Ip4Proto;
EFI_HANDLE Handle;
INTN State;
IP4_SERVICE *Service;
LIST_ENTRY Link; // Link to all the IP protocol from the service
//
// User's transmit/receive tokens, and received/deliverd packets
//
NET_MAP RxTokens;
NET_MAP TxTokens; // map between (User's Token, IP4_TXTOKE_WRAP)
LIST_ENTRY Received; // Received but not delivered packet
LIST_ENTRY Delivered; // Delivered and to be recycled packets
EFI_LOCK RecycleLock;
//
// Instance's address and route tables. There are two route tables.
// RouteTable is used by the IP4 driver to route packet. EfiRouteTable
// is used to communicate the current route info to the upper layer.
//
IP4_INTERFACE *Interface;
LIST_ENTRY AddrLink; // Ip instances with the same IP address.
IP4_ROUTE_TABLE *RouteTable;
EFI_IP4_ROUTE_TABLE *EfiRouteTable;
UINT32 EfiRouteCount;
//
// IGMP data for this instance
//
IP4_ADDR *Groups; // stored in network byte order
UINT32 GroupCount;
EFI_IP4_CONFIG_DATA ConfigData;
};
IP4 Interface
这个的IP4 Interface就是指UEFI下的Protocol接口了:
///
/// The EFI IPv4 Protocol implements a simple packet-oriented interface that can be
/// used by drivers, daemons, and applications to transmit and receive network packets.
///
struct _EFI_IP4_PROTOCOL {
EFI_IP4_GET_MODE_DATA GetModeData;
EFI_IP4_CONFIGURE Configure;
EFI_IP4_GROUPS Groups;
EFI_IP4_ROUTES Routes;
EFI_IP4_TRANSMIT Transmit;
EFI_IP4_RECEIVE Receive;
EFI_IP4_CANCEL Cancel;
EFI_IP4_POLL Poll;
};
to be continued......