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