1 /** @file
2   Common definition and functions for IP6 driver.
3 
4   Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
5 
6   SPDX-License-Identifier: BSD-2-Clause-Patent
7 
8 **/
9 
10 #ifndef __EFI_IP6_COMMON_H__
11 #define __EFI_IP6_COMMON_H__
12 
13 #define IP6_LINK_EQUAL(Mac1, Mac2) (CompareMem ((Mac1), (Mac2), sizeof (EFI_MAC_ADDRESS)) == 0)
14 
15 //
16 // Convert the Microsecond to second. IP transmit/receive time is
17 // in the unit of microsecond. IP ticks once per second.
18 //
19 #define IP6_US_TO_SEC(Us)              (((Us) + 999999) / 1000000)
20 
21 #define IP6_ETHER_PROTO                0x86DD
22 
23 #define IP6_MAC_LEN                    6
24 #define IP6_IF_ID_LEN                  8
25 
26 #define IP6_INTERFACE_LOCAL_SCOPE      1
27 #define IP6_LINK_LOCAL_SCOPE           2
28 #define IP6_SITE_LOCAL_SCOPE           5
29 
30 #define IP6_INFINIT_LIFETIME           0xFFFFFFFF
31 
32 #define IP6_HOP_LIMIT                  255
33 //
34 // Make it to 64 since all 54 bits are zero.
35 //
36 #define IP6_LINK_LOCAL_PREFIX_LENGTH   64
37 
38 #define IP6_TIMER_INTERVAL_IN_MS       100
39 #define IP6_ONE_SECOND_IN_MS           1000
40 
41 //
42 // The packet is received as link level broadcast/multicast/promiscuous.
43 //
44 #define IP6_LINK_BROADCAST             0x00000001
45 #define IP6_LINK_MULTICAST             0x00000002
46 #define IP6_LINK_PROMISC               0x00000004
47 
48 #define IP6_U_BIT                      0x02
49 
50 typedef enum {
51   Ip6Promiscuous                     = 1,
52   Ip6Unicast,
53   Ip6Multicast,
54   Ip6AnyCast
55 } IP6_ADDRESS_TYPE;
56 
57 typedef struct {
58   EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
59   EFI_IPv6_ADDRESS              *Address;
60 } IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT;
61 
62 typedef struct _IP6_INTERFACE    IP6_INTERFACE;
63 typedef struct _IP6_PROTOCOL     IP6_PROTOCOL;
64 typedef struct _IP6_SERVICE      IP6_SERVICE;
65 typedef struct _IP6_ADDRESS_INFO IP6_ADDRESS_INFO;
66 
67 /**
68   Build a array of EFI_IP6_ADDRESS_INFO to be returned to the caller. The number
69   of EFI_IP6_ADDRESS_INFO is also returned. If AddressList is NULL,
70   only the address count is returned.
71 
72   @param[in]  IpSb              The IP6 service binding instance.
73   @param[out] AddressCount      The number of returned addresses.
74   @param[out] AddressList       The pointer to the array of EFI_IP6_ADDRESS_INFO.
75                                 This is an optional parameter.
76 
77 
78   @retval EFI_SUCCESS           The address array is successfully build
79   @retval EFI_OUT_OF_RESOURCES  Failed to allocate the memory for the address info.
80   @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
81 
82 **/
83 EFI_STATUS
84 Ip6BuildEfiAddressList (
85   IN IP6_SERVICE            *IpSb,
86   OUT UINT32                *AddressCount,
87   OUT EFI_IP6_ADDRESS_INFO  **AddressList OPTIONAL
88   );
89 
90 /**
91   Generate the multicast addresses identify the group of all IPv6 nodes or IPv6
92   routers defined in RFC4291.
93 
94   All Nodes Addresses: FF01::1, FF02::1.
95   All Router Addresses: FF01::2, FF02::2, FF05::2.
96 
97   @param[in]  Router            If TRUE, generate all routers addresses,
98                                 else generate all node addresses.
99   @param[in]  Scope             interface-local(1), link-local(2), or site-local(5)
100   @param[out] Ip6Addr           The generated multicast address.
101 
102   @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
103   @retval EFI_SUCCESS           The address is generated.
104 
105 **/
106 EFI_STATUS
107 Ip6SetToAllNodeMulticast (
108   IN  BOOLEAN          Router,
109   IN  UINT8            Scope,
110   OUT EFI_IPv6_ADDRESS *Ip6Addr
111   );
112 
113 /**
114   This function converts MAC address to 64 bits interface ID according to RFC4291
115   and returns the interface ID. Currently only 48-bit MAC address is supported by
116   this function.
117 
118   @param[in, out]  IpSb      The IP6 service binding instance.
119 
120   @retval          NULL      The operation fails.
121   @return                    Pointer to the generated interface ID.
122 
123 **/
124 UINT8 *
125 Ip6CreateInterfaceID (
126   IN OUT IP6_SERVICE         *IpSb
127   );
128 
129 /**
130   This function creates link-local address from interface identifier. The
131   interface identifier is normally created from MAC address. It might be manually
132   configured by administrator if the link-local address created from MAC address
133   is a duplicate address.
134 
135   @param[in, out]  IpSb      The IP6 service binding instance.
136 
137   @retval          NULL      If the operation fails.
138   @return                    The generated Link Local address, in network order.
139 
140 **/
141 EFI_IPv6_ADDRESS *
142 Ip6CreateLinkLocalAddr (
143   IN OUT IP6_SERVICE         *IpSb
144   );
145 
146 /**
147   Compute the solicited-node multicast address for an unicast or anycast address,
148   by taking the low-order 24 bits of this address, and appending those bits to
149   the prefix FF02:0:0:0:0:1:FF00::/104.
150 
151   @param  Ip6Addr               The unicast or anycast address, in network order.
152   @param  MulticastAddr         The generated solicited-node multicast address,
153                                 in network order.
154 
155 **/
156 VOID
157 Ip6CreateSNMulticastAddr (
158   IN EFI_IPv6_ADDRESS  *Ip6Addr,
159   OUT EFI_IPv6_ADDRESS *MulticastAddr
160   );
161 
162 /**
163   Check whether the incoming Ipv6 address is a solicited-node multicast address.
164 
165   @param[in]  Ip6               Ip6 address, in network order.
166 
167   @retval TRUE                  Yes, solicited-node multicast address
168   @retval FALSE                 No
169 
170 **/
171 BOOLEAN
172 Ip6IsSNMulticastAddr (
173   IN EFI_IPv6_ADDRESS *Ip6
174   );
175 
176 /**
177   Check whether the incoming IPv6 address is one of the maintained address in
178   the IP6 service binding instance.
179 
180   @param[in]  IpSb              Points to a IP6 service binding instance
181   @param[in]  Address           The IP6 address to be checked.
182   @param[out] Interface         If not NULL, output the IP6 interface which
183                                 maintains the Address.
184   @param[out] AddressInfo       If not NULL, output the IP6 address information
185                                 of the Address.
186 
187   @retval TRUE                  Yes, it is one of the maintained addresses.
188   @retval FALSE                 No, it is not one of the maintained addresses.
189 
190 **/
191 BOOLEAN
192 Ip6IsOneOfSetAddress (
193   IN  IP6_SERVICE           *IpSb,
194   IN  EFI_IPv6_ADDRESS      *Address,
195   OUT IP6_INTERFACE         **Interface   OPTIONAL,
196   OUT IP6_ADDRESS_INFO      **AddressInfo OPTIONAL
197   );
198 
199 /**
200   Check whether the incoming MAC address is valid.
201 
202   @param[in]  IpSb              Points to a IP6 service binding instance.
203   @param[in]  LinkAddress       The MAC address.
204 
205   @retval TRUE                  Yes, it is valid.
206   @retval FALSE                 No, it is not valid.
207 
208 **/
209 BOOLEAN
210 Ip6IsValidLinkAddress (
211   IN  IP6_SERVICE      *IpSb,
212   IN  EFI_MAC_ADDRESS  *LinkAddress
213   );
214 
215 
216 /**
217   Copy the PrefixLength bits from Src to Dest.
218 
219   @param[out] Dest              A pointer to the buffer to copy to.
220   @param[in]  Src               A pointer to the buffer to copy from.
221   @param[in]  PrefixLength      The number of bits to copy.
222 
223 **/
224 VOID
225 Ip6CopyAddressByPrefix (
226   OUT EFI_IPv6_ADDRESS *Dest,
227   IN  EFI_IPv6_ADDRESS *Src,
228   IN  UINT8            PrefixLength
229   );
230 
231 /**
232   Insert a node IP6_ADDRESS_INFO to an IP6 interface.
233 
234   @param[in, out]  IpIf             Points to an IP6 interface.
235   @param[in]       AddrInfo         Points to an IP6_ADDRESS_INFO.
236 
237 **/
238 VOID
239 Ip6AddAddr (
240   IN OUT IP6_INTERFACE *IpIf,
241   IN IP6_ADDRESS_INFO  *AddrInfo
242   );
243 
244 /**
245   Remove the IPv6 address from the address list node points to IP6_ADDRESS_INFO.
246 
247   This function removes the matching IPv6 addresses from the address list and
248   adjusts the address count of the address list. If IpSb is not NULL, this function
249   calls Ip6LeaveGroup to see whether it should call Mnp->Groups() to remove the
250   its solicited-node multicast MAC address from the filter list and sends out
251   a Multicast Listener Done. If Prefix is NULL, all address in the address list
252   will be removed. If Prefix is not NULL, the address that matching the Prefix
253   with PrefixLength in the address list will be removed.
254 
255   @param[in]       IpSb             NULL or points to IP6 service binding instance.
256   @param[in, out]  AddressList      address list array
257   @param[in, out]  AddressCount     the count of addresses in address list array
258   @param[in]       Prefix           NULL or an IPv6 address prefix
259   @param[in]       PrefixLength     the length of Prefix
260 
261   @retval    EFI_SUCCESS            The operation completed successfully.
262   @retval    EFI_NOT_FOUND          The address matching the Prefix with PrefixLength
263                                     cannot be found in address list.
264   @retval    EFI_INVALID_PARAMETER  Any input parameter is invalid.
265 
266 **/
267 EFI_STATUS
268 Ip6RemoveAddr (
269   IN IP6_SERVICE       *IpSb          OPTIONAL,
270   IN OUT LIST_ENTRY    *AddressList,
271   IN OUT UINT32        *AddressCount,
272   IN EFI_IPv6_ADDRESS  *Prefix        OPTIONAL,
273   IN UINT8             PrefixLength
274   );
275 
276 /**
277   Get the MAC address for a multicast IP address. Call
278   Mnp's McastIpToMac to find the MAC address instead of
279   hard-coding the NIC to be Ethernet.
280 
281   @param[in]  Mnp                   The Mnp instance to get the MAC address.
282   @param[in]  Multicast             The multicast IP address to translate.
283   @param[out] Mac                   The buffer to hold the translated address.
284 
285   @retval EFI_SUCCESS               The multicast IP is successfully
286                                     translated to a multicast MAC address.
287   @retval Other                     The address is not converted because an error occurred.
288 
289 **/
290 EFI_STATUS
291 Ip6GetMulticastMac (
292   IN  EFI_MANAGED_NETWORK_PROTOCOL *Mnp,
293   IN  EFI_IPv6_ADDRESS             *Multicast,
294   OUT EFI_MAC_ADDRESS              *Mac
295   );
296 
297 /**
298   Convert the multibyte field in IP header's byter order.
299   In spite of its name, it can also be used to convert from
300   host to network byte order.
301 
302   @param[in, out]  Head                  The IP head to convert.
303 
304   @return Point to the converted IP head.
305 
306 **/
307 EFI_IP6_HEADER *
308 Ip6NtohHead (
309   IN OUT EFI_IP6_HEADER *Head
310   );
311 
312 #endif
313