1 /** @file
2   This library is only intended to be used by UEFI network stack modules.
3   It provides basic functions for the UEFI network stack.
4 
5 Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7 
8 **/
9 
10 #ifndef _NET_LIB_H_
11 #define _NET_LIB_H_
12 
13 #include <Protocol/Ip6.h>
14 
15 #include <Library/BaseLib.h>
16 #include <Library/BaseMemoryLib.h>
17 
18 typedef UINT32          IP4_ADDR;
19 typedef UINT32          TCP_SEQNO;
20 typedef UINT16          TCP_PORTNO;
21 
22 
23 #define  NET_ETHER_ADDR_LEN    6
24 #define  NET_IFTYPE_ETHERNET   0x01
25 
26 #define  NET_VLAN_TAG_LEN      4
27 #define  ETHER_TYPE_VLAN       0x8100
28 
29 #define  EFI_IP_PROTO_UDP      0x11
30 #define  EFI_IP_PROTO_TCP      0x06
31 #define  EFI_IP_PROTO_ICMP     0x01
32 #define  IP4_PROTO_IGMP        0x02
33 #define  IP6_ICMP              58
34 #define  DNS_MAX_NAME_SIZE     255
35 #define  DNS_MAX_MESSAGE_SIZE  512
36 
37 //
38 // The address classification
39 //
40 #define  IP4_ADDR_CLASSA       1     // Deprecated
41 #define  IP4_ADDR_CLASSB       2     // Deprecated
42 #define  IP4_ADDR_CLASSC       3     // Deprecated
43 #define  IP4_ADDR_CLASSD       4
44 #define  IP4_ADDR_CLASSE       5
45 
46 #define  IP4_MASK_NUM          33
47 #define  IP6_PREFIX_NUM        129
48 
49 #define  IP4_MASK_MAX          32
50 #define  IP6_PREFIX_MAX        128
51 
52 #define  IP6_HOP_BY_HOP        0
53 #define  IP6_DESTINATION       60
54 #define  IP6_ROUTING           43
55 #define  IP6_FRAGMENT          44
56 #define  IP6_AH                51
57 #define  IP6_ESP               50
58 #define  IP6_NO_NEXT_HEADER    59
59 
60 #define  IP_VERSION_4          4
61 #define  IP_VERSION_6          6
62 
63 #define  IP6_PREFIX_LENGTH     64
64 
65 //
66 // DNS QTYPE values
67 //
68 #define  DNS_TYPE_A            1
69 #define  DNS_TYPE_NS           2
70 #define  DNS_TYPE_CNAME        5
71 #define  DNS_TYPE_SOA          6
72 #define  DNS_TYPE_WKS          11
73 #define  DNS_TYPE_PTR          12
74 #define  DNS_TYPE_HINFO        13
75 #define  DNS_TYPE_MINFO        14
76 #define  DNS_TYPE_MX           15
77 #define  DNS_TYPE_TXT          16
78 #define  DNS_TYPE_AAAA         28
79 #define  DNS_TYPE_SRV_RR       33
80 #define  DNS_TYPE_AXFR         252
81 #define  DNS_TYPE_MAILB        253
82 #define  DNS_TYPE_ANY          255
83 
84 //
85 // DNS QCLASS values
86 //
87 #define  DNS_CLASS_INET        1
88 #define  DNS_CLASS_CH          3
89 #define  DNS_CLASS_HS          4
90 #define  DNS_CLASS_ANY         255
91 
92 //
93 // Number of 100ns units time Interval for network media state detect
94 //
95 #define MEDIA_STATE_DETECT_TIME_INTERVAL  1000000U
96 
97 
98 #pragma pack(1)
99 
100 //
101 // Ethernet head definition
102 //
103 typedef struct {
104   UINT8                 DstMac [NET_ETHER_ADDR_LEN];
105   UINT8                 SrcMac [NET_ETHER_ADDR_LEN];
106   UINT16                EtherType;
107 } ETHER_HEAD;
108 
109 //
110 // 802.1Q VLAN Tag Control Information
111 //
112 typedef union {
113   struct {
114     UINT16              Vid      : 12;  // Unique VLAN identifier (0 to 4094)
115     UINT16              Cfi      : 1;   // Canonical Format Indicator
116     UINT16              Priority : 3;   // 802.1Q priority level (0 to 7)
117   } Bits;
118   UINT16                Uint16;
119 } VLAN_TCI;
120 
121 #define VLAN_TCI_CFI_CANONICAL_MAC      0
122 #define VLAN_TCI_CFI_NON_CANONICAL_MAC  1
123 
124 //
125 // The EFI_IP4_HEADER is hard to use because the source and
126 // destination address are defined as EFI_IPv4_ADDRESS, which
127 // is a structure. Two structures can't be compared or masked
128 // directly. This is why there is an internal representation.
129 //
130 typedef struct {
131   UINT8                 HeadLen : 4;
132   UINT8                 Ver     : 4;
133   UINT8                 Tos;
134   UINT16                TotalLen;
135   UINT16                Id;
136   UINT16                Fragment;
137   UINT8                 Ttl;
138   UINT8                 Protocol;
139   UINT16                Checksum;
140   IP4_ADDR              Src;
141   IP4_ADDR              Dst;
142 } IP4_HEAD;
143 
144 
145 //
146 // ICMP head definition. Each ICMP message is categorized as either an error
147 // message or query message. Two message types have their own head format.
148 //
149 typedef struct {
150   UINT8                 Type;
151   UINT8                 Code;
152   UINT16                Checksum;
153 } IP4_ICMP_HEAD;
154 
155 typedef struct {
156   IP4_ICMP_HEAD         Head;
157   UINT32                Fourth; // 4th filed of the head, it depends on Type.
158   IP4_HEAD              IpHead;
159 } IP4_ICMP_ERROR_HEAD;
160 
161 typedef struct {
162   IP4_ICMP_HEAD         Head;
163   UINT16                Id;
164   UINT16                Seq;
165 } IP4_ICMP_QUERY_HEAD;
166 
167 typedef struct {
168   UINT8                 Type;
169   UINT8                 Code;
170   UINT16                Checksum;
171 } IP6_ICMP_HEAD;
172 
173 typedef struct {
174   IP6_ICMP_HEAD         Head;
175   UINT32                Fourth;
176   EFI_IP6_HEADER        IpHead;
177 } IP6_ICMP_ERROR_HEAD;
178 
179 typedef struct {
180   IP6_ICMP_HEAD         Head;
181   UINT32                Fourth;
182 } IP6_ICMP_INFORMATION_HEAD;
183 
184 //
185 // UDP header definition
186 //
187 typedef struct {
188   UINT16                SrcPort;
189   UINT16                DstPort;
190   UINT16                Length;
191   UINT16                Checksum;
192 } EFI_UDP_HEADER;
193 
194 //
195 // TCP header definition
196 //
197 typedef struct {
198   TCP_PORTNO            SrcPort;
199   TCP_PORTNO            DstPort;
200   TCP_SEQNO             Seq;
201   TCP_SEQNO             Ack;
202   UINT8                 Res     : 4;
203   UINT8                 HeadLen : 4;
204   UINT8                 Flag;
205   UINT16                Wnd;
206   UINT16                Checksum;
207   UINT16                Urg;
208 } TCP_HEAD;
209 
210 #pragma pack()
211 
212 #define NET_MAC_EQUAL(pMac1, pMac2, Len)     \
213     (CompareMem ((pMac1), (pMac2), Len) == 0)
214 
215 #define NET_MAC_IS_MULTICAST(Mac, BMac, Len) \
216     (((*((UINT8 *) Mac) & 0x01) == 0x01) && (!NET_MAC_EQUAL (Mac, BMac, Len)))
217 
218 #define NTOHL(x)  SwapBytes32 (x)
219 
220 #define HTONL(x)  NTOHL(x)
221 
222 #define NTOHS(x)  SwapBytes16 (x)
223 
224 #define HTONS(x)   NTOHS(x)
225 #define NTOHLL(x)  SwapBytes64 (x)
226 #define HTONLL(x)  NTOHLL(x)
227 #define NTOHLLL(x) Ip6Swap128 (x)
228 #define HTONLLL(x) NTOHLLL(x)
229 
230 //
231 // Test the IP's attribute, All the IPs are in host byte order.
232 //
233 #define IP4_IS_MULTICAST(Ip)              (((Ip) & 0xF0000000) == 0xE0000000)
234 #define IP4_IS_UNSPECIFIED(Ip)            ((Ip) == 0)
235 #define IP4_IS_LOCAL_BROADCAST(Ip)        ((Ip) == 0xFFFFFFFF)
236 #define IP4_NET_EQUAL(Ip1, Ip2, NetMask)  (((Ip1) & (NetMask)) == ((Ip2) & (NetMask)))
237 #define IP4_IS_VALID_NETMASK(Ip)          (NetGetMaskLength (Ip) != (IP4_MASK_MAX + 1))
238 
239 #define IP6_IS_MULTICAST(Ip6)             (((Ip6)->Addr[0]) == 0xFF)
240 
241 //
242 // Convert the EFI_IP4_ADDRESS to plain UINT32 IP4 address.
243 //
244 #define EFI_IP4(EfiIpAddr)       (*(IP4_ADDR *) ((EfiIpAddr).Addr))
245 #define EFI_NTOHL(EfiIp)         (NTOHL (EFI_IP4 ((EfiIp))))
246 #define EFI_IP4_EQUAL(Ip1, Ip2)  (CompareMem ((Ip1), (Ip2), sizeof (EFI_IPv4_ADDRESS)) == 0)
247 
248 #define EFI_IP6_EQUAL(Ip1, Ip2)  (CompareMem ((Ip1), (Ip2), sizeof (EFI_IPv6_ADDRESS)) == 0)
249 
250 #define IP4_COPY_ADDRESS(Dest, Src) (CopyMem ((Dest), (Src), sizeof (EFI_IPv4_ADDRESS)))
251 #define IP6_COPY_ADDRESS(Dest, Src) (CopyMem ((Dest), (Src), sizeof (EFI_IPv6_ADDRESS)))
252 #define IP6_COPY_LINK_ADDRESS(Mac1, Mac2) (CopyMem ((Mac1), (Mac2), sizeof (EFI_MAC_ADDRESS)))
253 
254 //
255 // The debug level definition. This value is also used as the
256 // syslog's severity level. Don't change it.
257 //
258 #define NETDEBUG_LEVEL_TRACE   5
259 #define NETDEBUG_LEVEL_WARNING 4
260 #define NETDEBUG_LEVEL_ERROR   3
261 
262 //
263 // Network debug message is sent out as syslog packet.
264 //
265 #define NET_SYSLOG_FACILITY    16                 // Syslog local facility local use
266 #define NET_SYSLOG_PACKET_LEN  512
267 #define NET_SYSLOG_TX_TIMEOUT  (500 * 1000 * 10)  // 500ms
268 #define NET_DEBUG_MSG_LEN      470                // 512 - (ether+ip4+udp4 head length)
269 
270 //
271 // The debug output expects the ASCII format string, Use %a to print ASCII
272 // string, and %s to print UNICODE string. PrintArg must be enclosed in ().
273 // For example: NET_DEBUG_TRACE ("Tcp", ("State transit to %a\n", Name));
274 //
275 #define NET_DEBUG_TRACE(Module, PrintArg) \
276   NetDebugOutput ( \
277     NETDEBUG_LEVEL_TRACE, \
278     Module, \
279     __FILE__, \
280     __LINE__, \
281     NetDebugASPrint PrintArg \
282     )
283 
284 #define NET_DEBUG_WARNING(Module, PrintArg) \
285   NetDebugOutput ( \
286     NETDEBUG_LEVEL_WARNING, \
287     Module, \
288     __FILE__, \
289     __LINE__, \
290     NetDebugASPrint PrintArg \
291     )
292 
293 #define NET_DEBUG_ERROR(Module, PrintArg) \
294   NetDebugOutput ( \
295     NETDEBUG_LEVEL_ERROR, \
296     Module, \
297     __FILE__, \
298     __LINE__, \
299     NetDebugASPrint PrintArg \
300     )
301 
302 /**
303   Allocate a buffer, then format the message to it. This is a
304   help function for the NET_DEBUG_XXX macros. The PrintArg of
305   these macros treats the variable length print parameters as a
306   single parameter, and pass it to the NetDebugASPrint. For
307   example, NET_DEBUG_TRACE ("Tcp", ("State transit to %a\n", Name))
308   if extracted to:
309 
310          NetDebugOutput (
311            NETDEBUG_LEVEL_TRACE,
312            "Tcp",
313            __FILE__,
314            __LINE__,
315            NetDebugASPrint ("State transit to %a\n", Name)
316          )
317 
318   @param Format  The ASCII format string.
319   @param ...     The variable length parameter whose format is determined
320                  by the Format string.
321 
322   @return        The buffer containing the formatted message,
323                  or NULL if memory allocation failed.
324 
325 **/
326 CHAR8 *
327 EFIAPI
328 NetDebugASPrint (
329   IN CHAR8                  *Format,
330   ...
331   );
332 
333 /**
334   Builds an UDP4 syslog packet and send it using SNP.
335 
336   This function will locate a instance of SNP then send the message through it.
337   Because it isn't open the SNP BY_DRIVER, apply caution when using it.
338 
339   @param Level    The severity level of the message.
340   @param Module   The Module that generates the log.
341   @param File     The file that contains the log.
342   @param Line     The exact line that contains the log.
343   @param Message  The user message to log.
344 
345   @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
346   @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory for the packet
347   @retval EFI_SUCCESS           The log is discard because that it is more verbose
348                                 than the mNetDebugLevelMax. Or, it has been sent out.
349 **/
350 EFI_STATUS
351 EFIAPI
352 NetDebugOutput (
353   IN UINT32                    Level,
354   IN UINT8                     *Module,
355   IN UINT8                     *File,
356   IN UINT32                    Line,
357   IN UINT8                     *Message
358   );
359 
360 
361 /**
362   Return the length of the mask.
363 
364   Return the length of the mask. Valid values are 0 to 32.
365   If the mask is invalid, return the invalid length 33, which is IP4_MASK_NUM.
366   NetMask is in the host byte order.
367 
368   @param[in]  NetMask              The netmask to get the length from.
369 
370   @return The length of the netmask, or IP4_MASK_NUM (33) if the mask is invalid.
371 
372 **/
373 INTN
374 EFIAPI
375 NetGetMaskLength (
376   IN IP4_ADDR               NetMask
377   );
378 
379 /**
380   Return the class of the IP address, such as class A, B, C.
381   Addr is in host byte order.
382 
383   [ATTENTION]
384   Classful addressing (IP class A/B/C) has been deprecated according to RFC4632.
385   Caller of this function could only check the returned value against
386   IP4_ADDR_CLASSD (multicast) or IP4_ADDR_CLASSE (reserved) now.
387 
388   The address of class A  starts with 0.
389   If the address belong to class A, return IP4_ADDR_CLASSA.
390   The address of class B  starts with 10.
391   If the address belong to class B, return IP4_ADDR_CLASSB.
392   The address of class C  starts with 110.
393   If the address belong to class C, return IP4_ADDR_CLASSC.
394   The address of class D  starts with 1110.
395   If the address belong to class D, return IP4_ADDR_CLASSD.
396   The address of class E  starts with 1111.
397   If the address belong to class E, return IP4_ADDR_CLASSE.
398 
399 
400   @param[in]   Addr                  The address to get the class from.
401 
402   @return IP address class, such as IP4_ADDR_CLASSA.
403 
404 **/
405 INTN
406 EFIAPI
407 NetGetIpClass (
408   IN IP4_ADDR               Addr
409   );
410 
411 /**
412   Check whether the IP is a valid unicast address according to
413   the netmask.
414 
415   ASSERT if NetMask is zero.
416 
417   If all bits of the host address of IP are 0 or 1, IP is also not a valid unicast address,
418   except when the originator is one of the endpoints of a point-to-point link with a 31-bit
419   mask (RFC3021), or a 32bit NetMask (all 0xFF) is used for special network environment (e.g.
420   PPP link).
421 
422   @param[in]  Ip                    The IP to check against.
423   @param[in]  NetMask               The mask of the IP.
424 
425   @return TRUE if IP is a valid unicast address on the network, otherwise FALSE.
426 
427 **/
428 BOOLEAN
429 EFIAPI
430 NetIp4IsUnicast (
431   IN IP4_ADDR               Ip,
432   IN IP4_ADDR               NetMask
433   );
434 
435 /**
436   Check whether the incoming IPv6 address is a valid unicast address.
437 
438   ASSERT if Ip6 is NULL.
439 
440   If the address is a multicast address has binary 0xFF at the start, it is not
441   a valid unicast address. If the address is unspecified ::, it is not a valid
442   unicast address to be assigned to any node. If the address is loopback address
443   ::1, it is also not a valid unicast address to be assigned to any physical
444   interface.
445 
446   @param[in]  Ip6                   The IPv6 address to check against.
447 
448   @return TRUE if Ip6 is a valid unicast address on the network, otherwise FALSE.
449 
450 **/
451 BOOLEAN
452 EFIAPI
453 NetIp6IsValidUnicast (
454   IN EFI_IPv6_ADDRESS       *Ip6
455   );
456 
457 
458 /**
459   Check whether the incoming Ipv6 address is the unspecified address or not.
460 
461   ASSERT if Ip6 is NULL.
462 
463   @param[in] Ip6   - Ip6 address, in network order.
464 
465   @retval TRUE     - Yes, incoming Ipv6 address is the unspecified address.
466   @retval FALSE    - The incoming Ipv6 address is not the unspecified address
467 
468 **/
469 BOOLEAN
470 EFIAPI
471 NetIp6IsUnspecifiedAddr (
472   IN EFI_IPv6_ADDRESS       *Ip6
473   );
474 
475 /**
476   Check whether the incoming Ipv6 address is a link-local address.
477 
478   ASSERT if Ip6 is NULL.
479 
480   @param[in] Ip6   - Ip6 address, in network order.
481 
482   @retval TRUE  - The incoming Ipv6 address is a link-local address.
483   @retval FALSE - The incoming Ipv6 address is not a link-local address.
484 
485 **/
486 BOOLEAN
487 EFIAPI
488 NetIp6IsLinkLocalAddr (
489   IN EFI_IPv6_ADDRESS *Ip6
490   );
491 
492 /**
493   Check whether the Ipv6 address1 and address2 are on the connected network.
494 
495   ASSERT if Ip1 or Ip2 is NULL.
496   ASSERT if PrefixLength exceeds or equals to IP6_PREFIX_MAX.
497 
498   @param[in] Ip1          - Ip6 address1, in network order.
499   @param[in] Ip2          - Ip6 address2, in network order.
500   @param[in] PrefixLength - The prefix length of the checking net.
501 
502   @retval TRUE            - Yes, the Ipv6 address1 and address2 are connected.
503   @retval FALSE           - No the Ipv6 address1 and address2 are not connected.
504 
505 **/
506 BOOLEAN
507 EFIAPI
508 NetIp6IsNetEqual (
509   EFI_IPv6_ADDRESS *Ip1,
510   EFI_IPv6_ADDRESS *Ip2,
511   UINT8            PrefixLength
512   );
513 
514 /**
515   Switches the endianess of an IPv6 address.
516 
517   ASSERT if Ip6 is NULL.
518 
519   This function swaps the bytes in a 128-bit IPv6 address to switch the value
520   from little endian to big endian or vice versa. The byte swapped value is
521   returned.
522 
523   @param  Ip6 Points to an IPv6 address.
524 
525   @return The byte swapped IPv6 address.
526 
527 **/
528 EFI_IPv6_ADDRESS *
529 EFIAPI
530 Ip6Swap128 (
531   EFI_IPv6_ADDRESS *Ip6
532   );
533 
534 extern IP4_ADDR gIp4AllMasks[IP4_MASK_NUM];
535 
536 
537 extern EFI_IPv4_ADDRESS  mZeroIp4Addr;
538 
539 #define NET_IS_DIGIT(Ch)            (('0' <= (Ch)) && ((Ch) <= '9'))
540 #define NET_IS_HEX(Ch)              ((('0' <= (Ch)) && ((Ch) <= '9')) || (('A' <= (Ch)) && ((Ch) <= 'F')) || (('a' <= (Ch)) && ((Ch) <= 'f')))
541 #define NET_ROUNDUP(size, unit)     (((size) + (unit) - 1) & (~((unit) - 1)))
542 #define NET_IS_LOWER_CASE_CHAR(Ch)  (('a' <= (Ch)) && ((Ch) <= 'z'))
543 #define NET_IS_UPPER_CASE_CHAR(Ch)  (('A' <= (Ch)) && ((Ch) <= 'Z'))
544 
545 #define TICKS_PER_MS            10000U
546 #define TICKS_PER_SECOND        10000000U
547 
548 #define NET_RANDOM(Seed)        ((UINT32) ((UINT32) (Seed) * 1103515245UL + 12345) % 4294967295UL)
549 
550 /**
551   Extract a UINT32 from a byte stream.
552 
553   ASSERT if Buf is NULL.
554 
555   This function copies a UINT32 from a byte stream, and then converts it from Network
556   byte order to host byte order. Use this function to avoid alignment error.
557 
558   @param[in]  Buf                 The buffer to extract the UINT32.
559 
560   @return The UINT32 extracted.
561 
562 **/
563 UINT32
564 EFIAPI
565 NetGetUint32 (
566   IN UINT8                  *Buf
567   );
568 
569 /**
570   Puts a UINT32 into the byte stream in network byte order.
571 
572   ASSERT if Buf is NULL.
573 
574   Converts a UINT32 from host byte order to network byte order, then copies it to the
575   byte stream.
576 
577   @param[in, out]  Buf          The buffer in which to put the UINT32.
578   @param[in]       Data         The data to be converted and put into the byte stream.
579 
580 **/
581 VOID
582 EFIAPI
583 NetPutUint32 (
584   IN OUT UINT8                 *Buf,
585   IN     UINT32                Data
586   );
587 
588 /**
589   Initialize a random seed using current time and monotonic count.
590 
591   Get current time and monotonic count first. Then initialize a random seed
592   based on some basic mathematics operation on the hour, day, minute, second,
593   nanosecond and year of the current time and the monotonic count value.
594 
595   @return The random seed initialized with current time.
596 
597 **/
598 UINT32
599 EFIAPI
600 NetRandomInitSeed (
601   VOID
602   );
603 
604 
605 #define NET_LIST_USER_STRUCT(Entry, Type, Field)        \
606           BASE_CR(Entry, Type, Field)
607 
608 #define NET_LIST_USER_STRUCT_S(Entry, Type, Field, Sig)  \
609           CR(Entry, Type, Field, Sig)
610 
611 //
612 // Iterate through the double linked list. It is NOT delete safe
613 //
614 #define NET_LIST_FOR_EACH(Entry, ListHead) \
615   for(Entry = (ListHead)->ForwardLink; Entry != (ListHead); Entry = Entry->ForwardLink)
616 
617 //
618 // Iterate through the double linked list. This is delete-safe.
619 // Don't touch NextEntry. Also, don't use this macro if list
620 // entries other than the Entry may be deleted when processing
621 // the current Entry.
622 //
623 #define NET_LIST_FOR_EACH_SAFE(Entry, NextEntry, ListHead) \
624   for(Entry = (ListHead)->ForwardLink, NextEntry = Entry->ForwardLink; \
625       Entry != (ListHead); \
626       Entry = NextEntry, NextEntry = Entry->ForwardLink \
627      )
628 
629 //
630 // Make sure the list isn't empty before getting the first/last record.
631 //
632 #define NET_LIST_HEAD(ListHead, Type, Field)  \
633           NET_LIST_USER_STRUCT((ListHead)->ForwardLink, Type, Field)
634 
635 #define NET_LIST_TAIL(ListHead, Type, Field)  \
636           NET_LIST_USER_STRUCT((ListHead)->BackLink, Type, Field)
637 
638 
639 /**
640   Remove the first node entry on the list, and return the removed node entry.
641 
642   Removes the first node entry from a doubly linked list. It is up to the caller of
643   this function to release the memory used by the first node, if that is required. On
644   exit, the removed node is returned.
645 
646   If Head is NULL, then ASSERT().
647   If Head was not initialized, then ASSERT().
648   If PcdMaximumLinkedListLength is not zero, and the number of nodes in the
649   linked list including the head node is greater than or equal to PcdMaximumLinkedListLength,
650   then ASSERT().
651 
652   @param[in, out]  Head                  The list header.
653 
654   @return The first node entry that is removed from the list, NULL if the list is empty.
655 
656 **/
657 LIST_ENTRY *
658 EFIAPI
659 NetListRemoveHead (
660   IN OUT LIST_ENTRY            *Head
661   );
662 
663 /**
664   Remove the last node entry on the list and return the removed node entry.
665 
666   Removes the last node entry from a doubly linked list. It is up to the caller of
667   this function to release the memory used by the first node, if that is required. On
668   exit, the removed node is returned.
669 
670   If Head is NULL, then ASSERT().
671   If Head was not initialized, then ASSERT().
672   If PcdMaximumLinkedListLength is not zero, and the number of nodes in the
673   linked list including the head node is greater than or equal to PcdMaximumLinkedListLength,
674   then ASSERT().
675 
676   @param[in, out]  Head                  The list head.
677 
678   @return The last node entry that is removed from the list, NULL if the list is empty.
679 
680 **/
681 LIST_ENTRY *
682 EFIAPI
683 NetListRemoveTail (
684   IN OUT LIST_ENTRY            *Head
685   );
686 
687 /**
688   Insert a new node entry after a designated node entry of a doubly linked list.
689 
690   ASSERT if PrevEntry or NewEntry is NULL.
691 
692   Inserts a new node entry designated by NewEntry after the node entry designated by PrevEntry
693   of the doubly linked list.
694 
695   @param[in, out]  PrevEntry             The entry after which to insert.
696   @param[in, out]  NewEntry              The new entry to insert.
697 
698 **/
699 VOID
700 EFIAPI
701 NetListInsertAfter (
702   IN OUT LIST_ENTRY         *PrevEntry,
703   IN OUT LIST_ENTRY         *NewEntry
704   );
705 
706 /**
707   Insert a new node entry before a designated node entry of a doubly linked list.
708 
709   ASSERT if PostEntry or NewEntry is NULL.
710 
711   Inserts a new node entry designated by NewEntry before the node entry designated by PostEntry
712   of the doubly linked list.
713 
714   @param[in, out]  PostEntry             The entry to insert before.
715   @param[in, out]  NewEntry              The new entry to insert.
716 
717 **/
718 VOID
719 EFIAPI
720 NetListInsertBefore (
721   IN OUT LIST_ENTRY     *PostEntry,
722   IN OUT LIST_ENTRY     *NewEntry
723   );
724 
725 /**
726   Callback function which provided by user to remove one node in NetDestroyLinkList process.
727 
728   @param[in]    Entry           The entry to be removed.
729   @param[in]    Context         Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
730 
731   @retval EFI_SUCCESS           The entry has been removed successfully.
732   @retval Others                Fail to remove the entry.
733 
734 **/
735 typedef
736 EFI_STATUS
737 (EFIAPI *NET_DESTROY_LINK_LIST_CALLBACK) (
738   IN LIST_ENTRY         *Entry,
739   IN VOID               *Context   OPTIONAL
740   );
741 
742 /**
743   Safe destroy nodes in a linked list, and return the length of the list after all possible operations finished.
744 
745   Destroy network children list by list traversals is not safe due to graph dependencies between nodes.
746   This function performs a safe traversal to destroy these nodes by checking to see if the node being destroyed
747   has been removed from the list or not.
748   If it has been removed, then restart the traversal from the head.
749   If it hasn't been removed, then continue with the next node directly.
750   This function will end the iterate and return the CallBack's last return value if error happens,
751   or return EFI_SUCCESS if 2 complete passes are made with no changes in the number of children in the list.
752 
753   @param[in]    List             The head of the list.
754   @param[in]    CallBack         Pointer to the callback function to destroy one node in the list.
755   @param[in]    Context          Pointer to the callback function's context: corresponds to the
756                                  parameter Context in NET_DESTROY_LINK_LIST_CALLBACK.
757   @param[out]   ListLength       The length of the link list if the function returns successfully.
758 
759   @retval EFI_SUCCESS            Two complete passes are made with no changes in the number of children.
760   @retval EFI_INVALID_PARAMETER  The input parameter is invalid.
761   @retval Others                 Return the CallBack's last return value.
762 
763 **/
764 EFI_STATUS
765 EFIAPI
766 NetDestroyLinkList (
767   IN   LIST_ENTRY                       *List,
768   IN   NET_DESTROY_LINK_LIST_CALLBACK   CallBack,
769   IN   VOID                             *Context,    OPTIONAL
770   OUT  UINTN                            *ListLength  OPTIONAL
771   );
772 
773 /**
774   This function checks the input Handle to see if it's one of these handles in ChildHandleBuffer.
775 
776   @param[in]  Handle             Handle to be checked.
777   @param[in]  NumberOfChildren   Number of Handles in ChildHandleBuffer.
778   @param[in]  ChildHandleBuffer  An array of child handles to be freed. May be NULL
779                                  if NumberOfChildren is 0.
780 
781   @retval TRUE                   Found the input Handle in ChildHandleBuffer.
782   @retval FALSE                  Can't find the input Handle in ChildHandleBuffer.
783 
784 **/
785 BOOLEAN
786 EFIAPI
787 NetIsInHandleBuffer (
788   IN  EFI_HANDLE          Handle,
789   IN  UINTN               NumberOfChildren,
790   IN  EFI_HANDLE          *ChildHandleBuffer OPTIONAL
791   );
792 
793 //
794 // Object container: EFI network stack spec defines various kinds of
795 // tokens. The drivers can share code to manage those objects.
796 //
797 typedef struct {
798   LIST_ENTRY                Link;
799   VOID                      *Key;
800   VOID                      *Value;
801 } NET_MAP_ITEM;
802 
803 typedef struct {
804   LIST_ENTRY                Used;
805   LIST_ENTRY                Recycled;
806   UINTN                     Count;
807 } NET_MAP;
808 
809 #define NET_MAP_INCREAMENT  64
810 
811 /**
812   Initialize the netmap. Netmap is a reposity to keep the <Key, Value> pairs.
813 
814   Initialize the forward and backward links of two head nodes donated by Map->Used
815   and Map->Recycled of two doubly linked lists.
816   Initializes the count of the <Key, Value> pairs in the netmap to zero.
817 
818   If Map is NULL, then ASSERT().
819   If the address of Map->Used is NULL, then ASSERT().
820   If the address of Map->Recycled is NULl, then ASSERT().
821 
822   @param[in, out]  Map                   The netmap to initialize.
823 
824 **/
825 VOID
826 EFIAPI
827 NetMapInit (
828   IN OUT NET_MAP                *Map
829   );
830 
831 /**
832   To clean up the netmap, that is, release allocated memories.
833 
834   Removes all nodes of the Used doubly linked list and frees memory of all related netmap items.
835   Removes all nodes of the Recycled doubly linked list and free memory of all related netmap items.
836   The number of the <Key, Value> pairs in the netmap is set to zero.
837 
838   If Map is NULL, then ASSERT().
839 
840   @param[in, out]  Map                   The netmap to clean up.
841 
842 **/
843 VOID
844 EFIAPI
845 NetMapClean (
846   IN OUT NET_MAP            *Map
847   );
848 
849 /**
850   Test whether the netmap is empty and return true if it is.
851 
852   If the number of the <Key, Value> pairs in the netmap is zero, return TRUE.
853 
854   If Map is NULL, then ASSERT().
855 
856   @param[in]  Map                   The net map to test.
857 
858   @return TRUE if the netmap is empty, otherwise FALSE.
859 
860 **/
861 BOOLEAN
862 EFIAPI
863 NetMapIsEmpty (
864   IN NET_MAP                *Map
865   );
866 
867 /**
868   Return the number of the <Key, Value> pairs in the netmap.
869 
870   If Map is NULL, then ASSERT().
871 
872   @param[in]  Map                   The netmap to get the entry number.
873 
874   @return The entry number in the netmap.
875 
876 **/
877 UINTN
878 EFIAPI
879 NetMapGetCount (
880   IN NET_MAP                *Map
881   );
882 
883 /**
884   Allocate an item to save the <Key, Value> pair to the head of the netmap.
885 
886   Allocate an item to save the <Key, Value> pair and add corresponding node entry
887   to the beginning of the Used doubly linked list. The number of the <Key, Value>
888   pairs in the netmap increase by 1.
889 
890   If Map is NULL, then ASSERT().
891   If Key is NULL, then ASSERT().
892 
893   @param[in, out]  Map                   The netmap to insert into.
894   @param[in]       Key                   The user's key.
895   @param[in]       Value                 The user's value for the key.
896 
897   @retval EFI_OUT_OF_RESOURCES  Failed to allocate the memory for the item.
898   @retval EFI_SUCCESS           The item is inserted to the head.
899 
900 **/
901 EFI_STATUS
902 EFIAPI
903 NetMapInsertHead (
904   IN OUT NET_MAP            *Map,
905   IN VOID                   *Key,
906   IN VOID                   *Value    OPTIONAL
907   );
908 
909 /**
910   Allocate an item to save the <Key, Value> pair to the tail of the netmap.
911 
912   Allocate an item to save the <Key, Value> pair and add corresponding node entry
913   to the tail of the Used doubly linked list. The number of the <Key, Value>
914   pairs in the netmap increase by 1.
915 
916   If Map is NULL, then ASSERT().
917   If Key is NULL, then ASSERT().
918 
919   @param[in, out]  Map                   The netmap to insert into.
920   @param[in]       Key                   The user's key.
921   @param[in]       Value                 The user's value for the key.
922 
923   @retval EFI_OUT_OF_RESOURCES  Failed to allocate the memory for the item.
924   @retval EFI_SUCCESS           The item is inserted to the tail.
925 
926 **/
927 EFI_STATUS
928 EFIAPI
929 NetMapInsertTail (
930   IN OUT NET_MAP            *Map,
931   IN VOID                   *Key,
932   IN VOID                   *Value    OPTIONAL
933   );
934 
935 /**
936   Finds the key in the netmap and returns the point to the item containing the Key.
937 
938   Iterate the Used doubly linked list of the netmap to get every item. Compare the key of every
939   item with the key to search. It returns the point to the item contains the Key if found.
940 
941   If Map is NULL, then ASSERT().
942   If Key is NULL, then ASSERT().
943 
944   @param[in]  Map                   The netmap to search within.
945   @param[in]  Key                   The key to search.
946 
947   @return The point to the item contains the Key, or NULL if Key isn't in the map.
948 
949 **/
950 NET_MAP_ITEM *
951 EFIAPI
952 NetMapFindKey (
953   IN  NET_MAP               *Map,
954   IN  VOID                  *Key
955   );
956 
957 /**
958   Remove the node entry of the item from the netmap and return the key of the removed item.
959 
960   Remove the node entry of the item from the Used doubly linked list of the netmap.
961   The number of the <Key, Value> pairs in the netmap decrease by 1. Then add the node
962   entry of the item to the Recycled doubly linked list of the netmap. If Value is not NULL,
963   Value will point to the value of the item. It returns the key of the removed item.
964 
965   If Map is NULL, then ASSERT().
966   If Item is NULL, then ASSERT().
967   if item in not in the netmap, then ASSERT().
968 
969   @param[in, out]  Map                   The netmap to remove the item from.
970   @param[in, out]  Item                  The item to remove.
971   @param[out]      Value                 The variable to receive the value if not NULL.
972 
973   @return                                The key of the removed item.
974 
975 **/
976 VOID *
977 EFIAPI
978 NetMapRemoveItem (
979   IN  OUT NET_MAP             *Map,
980   IN  OUT NET_MAP_ITEM        *Item,
981   OUT VOID                    **Value           OPTIONAL
982   );
983 
984 /**
985   Remove the first node entry on the netmap and return the key of the removed item.
986 
987   Remove the first node entry from the Used doubly linked list of the netmap.
988   The number of the <Key, Value> pairs in the netmap decrease by 1. Then add the node
989   entry to the Recycled doubly linked list of the netmap. If parameter Value is not NULL,
990   parameter Value will point to the value of the item. It returns the key of the removed item.
991 
992   If Map is NULL, then ASSERT().
993   If the Used doubly linked list is empty, then ASSERT().
994 
995   @param[in, out]  Map                   The netmap to remove the head from.
996   @param[out]      Value                 The variable to receive the value if not NULL.
997 
998   @return                                The key of the item removed.
999 
1000 **/
1001 VOID *
1002 EFIAPI
1003 NetMapRemoveHead (
1004   IN OUT NET_MAP            *Map,
1005   OUT VOID                  **Value         OPTIONAL
1006   );
1007 
1008 /**
1009   Remove the last node entry on the netmap and return the key of the removed item.
1010 
1011   Remove the last node entry from the Used doubly linked list of the netmap.
1012   The number of the <Key, Value> pairs in the netmap decrease by 1. Then add the node
1013   entry to the Recycled doubly linked list of the netmap. If parameter Value is not NULL,
1014   parameter Value will point to the value of the item. It returns the key of the removed item.
1015 
1016   If Map is NULL, then ASSERT().
1017   If the Used doubly linked list is empty, then ASSERT().
1018 
1019   @param[in, out]  Map                   The netmap to remove the tail from.
1020   @param[out]      Value                 The variable to receive the value if not NULL.
1021 
1022   @return                                The key of the item removed.
1023 
1024 **/
1025 VOID *
1026 EFIAPI
1027 NetMapRemoveTail (
1028   IN OUT NET_MAP            *Map,
1029   OUT VOID                  **Value       OPTIONAL
1030   );
1031 
1032 typedef
1033 EFI_STATUS
1034 (EFIAPI *NET_MAP_CALLBACK) (
1035   IN NET_MAP                *Map,
1036   IN NET_MAP_ITEM           *Item,
1037   IN VOID                   *Arg
1038   );
1039 
1040 /**
1041   Iterate through the netmap and call CallBack for each item.
1042 
1043   It will continue the traverse if CallBack returns EFI_SUCCESS, otherwise, break
1044   from the loop. It returns the CallBack's last return value. This function is
1045   delete safe for the current item.
1046 
1047   If Map is NULL, then ASSERT().
1048   If CallBack is NULL, then ASSERT().
1049 
1050   @param[in]  Map                   The Map to iterate through.
1051   @param[in]  CallBack              The callback function to call for each item.
1052   @param[in]  Arg                   The opaque parameter to the callback.
1053 
1054   @retval EFI_SUCCESS            There is no item in the netmap, or CallBack for each item
1055                                  returns EFI_SUCCESS.
1056   @retval Others                 It returns the CallBack's last return value.
1057 
1058 **/
1059 EFI_STATUS
1060 EFIAPI
1061 NetMapIterate (
1062   IN NET_MAP                *Map,
1063   IN NET_MAP_CALLBACK       CallBack,
1064   IN VOID                   *Arg      OPTIONAL
1065   );
1066 
1067 
1068 //
1069 // Helper functions to implement driver binding and service binding protocols.
1070 //
1071 /**
1072   Create a child of the service that is identified by ServiceBindingGuid.
1073 
1074   Get the ServiceBinding Protocol first, then use it to create a child.
1075 
1076   If ServiceBindingGuid is NULL, then ASSERT().
1077   If ChildHandle is NULL, then ASSERT().
1078 
1079   @param[in]       Controller            The controller which has the service installed.
1080   @param[in]       Image                 The image handle used to open service.
1081   @param[in]       ServiceBindingGuid    The service's Guid.
1082   @param[in, out]  ChildHandle           The handle to receive the created child.
1083 
1084   @retval EFI_SUCCESS           The child was successfully created.
1085   @retval Others                Failed to create the child.
1086 
1087 **/
1088 EFI_STATUS
1089 EFIAPI
1090 NetLibCreateServiceChild (
1091   IN  EFI_HANDLE            Controller,
1092   IN  EFI_HANDLE            Image,
1093   IN  EFI_GUID              *ServiceBindingGuid,
1094   IN  OUT EFI_HANDLE        *ChildHandle
1095   );
1096 
1097 /**
1098   Destroy a child of the service that is identified by ServiceBindingGuid.
1099 
1100   Get the ServiceBinding Protocol first, then use it to destroy a child.
1101 
1102   If ServiceBindingGuid is NULL, then ASSERT().
1103 
1104   @param[in]   Controller            The controller which has the service installed.
1105   @param[in]   Image                 The image handle used to open service.
1106   @param[in]   ServiceBindingGuid    The service's Guid.
1107   @param[in]   ChildHandle           The child to destroy.
1108 
1109   @retval EFI_SUCCESS           The child was destroyed.
1110   @retval Others                Failed to destroy the child.
1111 
1112 **/
1113 EFI_STATUS
1114 EFIAPI
1115 NetLibDestroyServiceChild (
1116   IN  EFI_HANDLE            Controller,
1117   IN  EFI_HANDLE            Image,
1118   IN  EFI_GUID              *ServiceBindingGuid,
1119   IN  EFI_HANDLE            ChildHandle
1120   );
1121 
1122 /**
1123   Get handle with Simple Network Protocol installed on it.
1124 
1125   There should be MNP Service Binding Protocol installed on the input ServiceHandle.
1126   If Simple Network Protocol is already installed on the ServiceHandle, the
1127   ServiceHandle will be returned. If SNP is not installed on the ServiceHandle,
1128   try to find its parent handle with SNP installed.
1129 
1130   @param[in]   ServiceHandle    The handle where network service binding protocols are
1131                                 installed on.
1132   @param[out]  Snp              The pointer to store the address of the SNP instance.
1133                                 This is an optional parameter that may be NULL.
1134 
1135   @return The SNP handle, or NULL if not found.
1136 
1137 **/
1138 EFI_HANDLE
1139 EFIAPI
1140 NetLibGetSnpHandle (
1141   IN   EFI_HANDLE                  ServiceHandle,
1142   OUT  EFI_SIMPLE_NETWORK_PROTOCOL **Snp  OPTIONAL
1143   );
1144 
1145 /**
1146   Retrieve VLAN ID of a VLAN device handle.
1147 
1148   Search VLAN device path node in Device Path of specified ServiceHandle and
1149   return its VLAN ID. If no VLAN device path node found, then this ServiceHandle
1150   is not a VLAN device handle, and 0 will be returned.
1151 
1152   @param[in]   ServiceHandle    The handle where network service binding protocols are
1153                                 installed on.
1154 
1155   @return VLAN ID of the device handle, or 0 if not a VLAN device.
1156 
1157 **/
1158 UINT16
1159 EFIAPI
1160 NetLibGetVlanId (
1161   IN EFI_HANDLE             ServiceHandle
1162   );
1163 
1164 /**
1165   Find VLAN device handle with specified VLAN ID.
1166 
1167   The VLAN child device handle is created by VLAN Config Protocol on ControllerHandle.
1168   This function will append VLAN device path node to the parent device path,
1169   and then use LocateDevicePath() to find the correct VLAN device handle.
1170 
1171   @param[in]   ControllerHandle The handle where network service binding protocols are
1172                                 installed on.
1173   @param[in]   VlanId           The configured VLAN ID for the VLAN device.
1174 
1175   @return The VLAN device handle, or NULL if not found.
1176 
1177 **/
1178 EFI_HANDLE
1179 EFIAPI
1180 NetLibGetVlanHandle (
1181   IN EFI_HANDLE             ControllerHandle,
1182   IN UINT16                 VlanId
1183   );
1184 
1185 /**
1186   Get MAC address associated with the network service handle.
1187 
1188   If MacAddress is NULL, then ASSERT().
1189   If AddressSize is NULL, then ASSERT().
1190 
1191   There should be MNP Service Binding Protocol installed on the input ServiceHandle.
1192   If SNP is installed on the ServiceHandle or its parent handle, MAC address will
1193   be retrieved from SNP. If no SNP found, try to get SNP mode data use MNP.
1194 
1195   @param[in]   ServiceHandle    The handle where network service binding protocols are
1196                                 installed on.
1197   @param[out]  MacAddress       The pointer to store the returned MAC address.
1198   @param[out]  AddressSize      The length of returned MAC address.
1199 
1200   @retval EFI_SUCCESS           MAC address was returned successfully.
1201   @retval Others                Failed to get SNP mode data.
1202 
1203 **/
1204 EFI_STATUS
1205 EFIAPI
1206 NetLibGetMacAddress (
1207   IN  EFI_HANDLE            ServiceHandle,
1208   OUT EFI_MAC_ADDRESS       *MacAddress,
1209   OUT UINTN                 *AddressSize
1210   );
1211 
1212 /**
1213   Convert MAC address of the NIC associated with specified Service Binding Handle
1214   to a unicode string. Callers are responsible for freeing the string storage.
1215 
1216   If MacString is NULL, then ASSERT().
1217 
1218   Locate simple network protocol associated with the Service Binding Handle and
1219   get the mac address from SNP. Then convert the mac address into a unicode
1220   string. It takes 2 unicode characters to represent a 1 byte binary buffer.
1221   Plus one unicode character for the null-terminator.
1222 
1223   @param[in]   ServiceHandle         The handle where network service binding protocol is
1224                                      installed.
1225   @param[in]   ImageHandle           The image handle used to act as the agent handle to
1226                                      get the simple network protocol. This parameter is
1227                                      optional and may be NULL.
1228   @param[out]  MacString             The pointer to store the address of the string
1229                                      representation of  the mac address.
1230 
1231   @retval EFI_SUCCESS           Converted the mac address a unicode string successfully.
1232   @retval EFI_OUT_OF_RESOURCES  There are not enough memory resources.
1233   @retval Others                Failed to open the simple network protocol.
1234 
1235 **/
1236 EFI_STATUS
1237 EFIAPI
1238 NetLibGetMacString (
1239   IN  EFI_HANDLE            ServiceHandle,
1240   IN  EFI_HANDLE            ImageHandle, OPTIONAL
1241   OUT CHAR16                **MacString
1242   );
1243 
1244 /**
1245   Detect media status for specified network device.
1246 
1247   If MediaPresent is NULL, then ASSERT().
1248 
1249   The underlying UNDI driver may or may not support reporting media status from
1250   GET_STATUS command (PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED). This routine
1251   will try to invoke Snp->GetStatus() to get the media status. If media is already
1252   present, it returns directly. If media is not present, it will stop SNP and then
1253   restart SNP to get the latest media status. This provides an opportunity to get
1254   the correct media status for old UNDI driver, which doesn't support reporting
1255   media status from GET_STATUS command.
1256   Note: there are two limitations for the current algorithm:
1257   1) For UNDI with this capability, when the cable is not attached, there will
1258      be an redundant Stop/Start() process.
1259   2) for UNDI without this capability, in case that network cable is attached when
1260      Snp->Initialize() is invoked while network cable is unattached later,
1261      NetLibDetectMedia() will report MediaPresent as TRUE, causing upper layer
1262      apps to wait for timeout time.
1263 
1264   @param[in]   ServiceHandle    The handle where network service binding protocols are
1265                                 installed.
1266   @param[out]  MediaPresent     The pointer to store the media status.
1267 
1268   @retval EFI_SUCCESS           Media detection success.
1269   @retval EFI_INVALID_PARAMETER ServiceHandle is not a valid network device handle.
1270   @retval EFI_UNSUPPORTED       The network device does not support media detection.
1271   @retval EFI_DEVICE_ERROR      SNP is in an unknown state.
1272 
1273 **/
1274 EFI_STATUS
1275 EFIAPI
1276 NetLibDetectMedia (
1277   IN  EFI_HANDLE            ServiceHandle,
1278   OUT BOOLEAN               *MediaPresent
1279   );
1280 
1281 /**
1282   Detect media state for a network device. This routine will wait for a period of time at
1283   a specified checking interval when a certain network is under connecting until connection
1284   process finishes or timeout. If Aip protocol is supported by low layer drivers, three kinds
1285   of media states can be detected: EFI_SUCCESS, EFI_NOT_READY and EFI_NO_MEDIA, represents
1286   connected state, connecting state and no media state respectively. When function detects
1287   the current state is EFI_NOT_READY, it will loop to wait for next time's check until state
1288   turns to be EFI_SUCCESS or EFI_NO_MEDIA. If Aip protocol is not supported, function will
1289   call NetLibDetectMedia() and return state directly.
1290 
1291   @param[in]   ServiceHandle    The handle where network service binding protocols are
1292                                 installed on.
1293   @param[in]   Timeout          The maximum number of 100ns units to wait when network
1294                                 is connecting. Zero value means detect once and return
1295                                 immediately.
1296   @param[out]  MediaState       The pointer to the detected media state.
1297 
1298   @retval EFI_SUCCESS           Media detection success.
1299   @retval EFI_INVALID_PARAMETER ServiceHandle is not a valid network device handle or
1300                                 MediaState pointer is NULL.
1301   @retval EFI_DEVICE_ERROR      A device error occurred.
1302   @retval EFI_TIMEOUT           Network is connecting but timeout.
1303 
1304 **/
1305 EFI_STATUS
1306 EFIAPI
1307 NetLibDetectMediaWaitTimeout (
1308   IN  EFI_HANDLE            ServiceHandle,
1309   IN  UINT64                Timeout,
1310   OUT EFI_STATUS            *MediaState
1311   );
1312 
1313 
1314 /**
1315   Create an IPv4 device path node.
1316 
1317   If Node is NULL, then ASSERT().
1318 
1319   The header type of IPv4 device path node is MESSAGING_DEVICE_PATH.
1320   The header subtype of IPv4 device path node is MSG_IPv4_DP.
1321   The length of the IPv4 device path node in bytes is 19.
1322   Get other information from parameters to make up the whole IPv4 device path node.
1323 
1324   @param[in, out]  Node                  The pointer to the IPv4 device path node.
1325   @param[in]       Controller            The controller handle.
1326   @param[in]       LocalIp               The local IPv4 address.
1327   @param[in]       LocalPort             The local port.
1328   @param[in]       RemoteIp              The remote IPv4 address.
1329   @param[in]       RemotePort            The remote port.
1330   @param[in]       Protocol              The protocol type in the IP header.
1331   @param[in]       UseDefaultAddress     Whether this instance is using default address or not.
1332 
1333 **/
1334 VOID
1335 EFIAPI
1336 NetLibCreateIPv4DPathNode (
1337   IN OUT IPv4_DEVICE_PATH  *Node,
1338   IN EFI_HANDLE            Controller,
1339   IN IP4_ADDR              LocalIp,
1340   IN UINT16                LocalPort,
1341   IN IP4_ADDR              RemoteIp,
1342   IN UINT16                RemotePort,
1343   IN UINT16                Protocol,
1344   IN BOOLEAN               UseDefaultAddress
1345   );
1346 
1347 /**
1348   Create an IPv6 device path node.
1349 
1350   If Node is NULL, then ASSERT().
1351   If LocalIp is NULL, then ASSERT().
1352   If RemoteIp is NULL, then ASSERT().
1353 
1354   The header type of IPv6 device path node is MESSAGING_DEVICE_PATH.
1355   The header subtype of IPv6 device path node is MSG_IPv6_DP.
1356   The length of the IPv6 device path node in bytes is 43.
1357   Get other information from parameters to make up the whole IPv6 device path node.
1358 
1359   @param[in, out]  Node                  The pointer to the IPv6 device path node.
1360   @param[in]       Controller            The controller handle.
1361   @param[in]       LocalIp               The local IPv6 address.
1362   @param[in]       LocalPort             The local port.
1363   @param[in]       RemoteIp              The remote IPv6 address.
1364   @param[in]       RemotePort            The remote port.
1365   @param[in]       Protocol              The protocol type in the IP header.
1366 
1367 **/
1368 VOID
1369 EFIAPI
1370 NetLibCreateIPv6DPathNode (
1371   IN OUT IPv6_DEVICE_PATH  *Node,
1372   IN EFI_HANDLE            Controller,
1373   IN EFI_IPv6_ADDRESS      *LocalIp,
1374   IN UINT16                LocalPort,
1375   IN EFI_IPv6_ADDRESS      *RemoteIp,
1376   IN UINT16                RemotePort,
1377   IN UINT16                Protocol
1378   );
1379 
1380 
1381 /**
1382   Find the UNDI/SNP handle from controller and protocol GUID.
1383 
1384   If ProtocolGuid is NULL, then ASSERT().
1385 
1386   For example, IP will open an MNP child to transmit/receive
1387   packets. When MNP is stopped, IP should also be stopped. IP
1388   needs to find its own private data that is related the IP's
1389   service binding instance that is installed on the UNDI/SNP handle.
1390   The controller is then either an MNP or an ARP child handle. Note that
1391   IP opens these handles using BY_DRIVER. Use that information to get the
1392   UNDI/SNP handle.
1393 
1394   @param[in]  Controller            The protocol handle to check.
1395   @param[in]  ProtocolGuid          The protocol that is related with the handle.
1396 
1397   @return The UNDI/SNP handle or NULL for errors.
1398 
1399 **/
1400 EFI_HANDLE
1401 EFIAPI
1402 NetLibGetNicHandle (
1403   IN EFI_HANDLE             Controller,
1404   IN EFI_GUID               *ProtocolGuid
1405   );
1406 
1407 /**
1408   This is the default unload handle for all the network drivers.
1409 
1410   Disconnect the driver specified by ImageHandle from all the devices in the handle database.
1411   Uninstall all the protocols installed in the driver entry point.
1412 
1413   @param[in]  ImageHandle       The drivers' driver image.
1414 
1415   @retval EFI_SUCCESS           The image is unloaded.
1416   @retval Others                Failed to unload the image.
1417 
1418 **/
1419 EFI_STATUS
1420 EFIAPI
1421 NetLibDefaultUnload (
1422   IN EFI_HANDLE             ImageHandle
1423   );
1424 
1425 /**
1426   Convert one Null-terminated ASCII string (decimal dotted) to EFI_IPv4_ADDRESS.
1427 
1428   @param[in]      String         The pointer to the Ascii string.
1429   @param[out]     Ip4Address     The pointer to the converted IPv4 address.
1430 
1431   @retval EFI_SUCCESS            Converted to an IPv4 address successfully.
1432   @retval EFI_INVALID_PARAMETER  The string is malformatted, or Ip4Address is NULL.
1433 
1434 **/
1435 EFI_STATUS
1436 EFIAPI
1437 NetLibAsciiStrToIp4 (
1438   IN CONST CHAR8                 *String,
1439   OUT      EFI_IPv4_ADDRESS      *Ip4Address
1440   );
1441 
1442 /**
1443   Convert one Null-terminated ASCII string to EFI_IPv6_ADDRESS. The format of the
1444   string is defined in RFC 4291 - Text Representation of Addresses.
1445 
1446   @param[in]      String         The pointer to the Ascii string.
1447   @param[out]     Ip6Address     The pointer to the converted IPv6 address.
1448 
1449   @retval EFI_SUCCESS            Converted to an IPv6 address successfully.
1450   @retval EFI_INVALID_PARAMETER  The string is malformatted, or Ip6Address is NULL.
1451 
1452 **/
1453 EFI_STATUS
1454 EFIAPI
1455 NetLibAsciiStrToIp6 (
1456   IN CONST CHAR8                 *String,
1457   OUT      EFI_IPv6_ADDRESS      *Ip6Address
1458   );
1459 
1460 /**
1461   Convert one Null-terminated Unicode string (decimal dotted) to EFI_IPv4_ADDRESS.
1462 
1463   @param[in]      String         The pointer to the Ascii string.
1464   @param[out]     Ip4Address     The pointer to the converted IPv4 address.
1465 
1466   @retval EFI_SUCCESS            Converted to an IPv4 address successfully.
1467   @retval EFI_INVALID_PARAMETER  The string is mal-formatted or Ip4Address is NULL.
1468 
1469 **/
1470 EFI_STATUS
1471 EFIAPI
1472 NetLibStrToIp4 (
1473   IN CONST CHAR16                *String,
1474   OUT      EFI_IPv4_ADDRESS      *Ip4Address
1475   );
1476 
1477 /**
1478   Convert one Null-terminated Unicode string to EFI_IPv6_ADDRESS.  The format of
1479   the string is defined in RFC 4291 - Text Representation of Addresses.
1480 
1481   @param[in]      String         The pointer to the Ascii string.
1482   @param[out]     Ip6Address     The pointer to the converted IPv6 address.
1483 
1484   @retval EFI_SUCCESS            Converted to an IPv6 address successfully.
1485   @retval EFI_INVALID_PARAMETER  The string is malformatted or Ip6Address is NULL.
1486 
1487 **/
1488 EFI_STATUS
1489 EFIAPI
1490 NetLibStrToIp6 (
1491   IN CONST CHAR16                *String,
1492   OUT      EFI_IPv6_ADDRESS      *Ip6Address
1493   );
1494 
1495 /**
1496   Convert one Null-terminated Unicode string to EFI_IPv6_ADDRESS and prefix length.
1497   The format of the string is defined in RFC 4291 - Text Representation of Addresses
1498   Prefixes: ipv6-address/prefix-length.
1499 
1500   @param[in]      String         The pointer to the Ascii string.
1501   @param[out]     Ip6Address     The pointer to the converted IPv6 address.
1502   @param[out]     PrefixLength   The pointer to the converted prefix length.
1503 
1504   @retval EFI_SUCCESS            Converted to an  IPv6 address successfully.
1505   @retval EFI_INVALID_PARAMETER  The string is malformatted, or Ip6Address is NULL.
1506 
1507 **/
1508 EFI_STATUS
1509 EFIAPI
1510 NetLibStrToIp6andPrefix (
1511   IN CONST CHAR16                *String,
1512   OUT      EFI_IPv6_ADDRESS      *Ip6Address,
1513   OUT      UINT8                 *PrefixLength
1514   );
1515 
1516 /**
1517 
1518   Convert one EFI_IPv6_ADDRESS to Null-terminated Unicode string.
1519   The text representation of address is defined in RFC 4291.
1520 
1521   @param[in]       Ip6Address     The pointer to the IPv6 address.
1522   @param[out]      String         The buffer to return the converted string.
1523   @param[in]       StringSize     The length in bytes of the input String.
1524 
1525   @retval EFI_SUCCESS             Convert to string successfully.
1526   @retval EFI_INVALID_PARAMETER   The input parameter is invalid.
1527   @retval EFI_BUFFER_TOO_SMALL    The BufferSize is too small for the result. BufferSize has been
1528                                   updated with the size needed to complete the request.
1529 **/
1530 EFI_STATUS
1531 EFIAPI
1532 NetLibIp6ToStr (
1533   IN         EFI_IPv6_ADDRESS      *Ip6Address,
1534   OUT        CHAR16                *String,
1535   IN         UINTN                 StringSize
1536   );
1537 
1538 //
1539 // Various signatures
1540 //
1541 #define  NET_BUF_SIGNATURE    SIGNATURE_32 ('n', 'b', 'u', 'f')
1542 #define  NET_VECTOR_SIGNATURE SIGNATURE_32 ('n', 'v', 'e', 'c')
1543 #define  NET_QUE_SIGNATURE    SIGNATURE_32 ('n', 'b', 'q', 'u')
1544 
1545 
1546 #define  NET_PROTO_DATA       64   // Opaque buffer for protocols
1547 #define  NET_BUF_HEAD         1    // Trim or allocate space from head
1548 #define  NET_BUF_TAIL         0    // Trim or allocate space from tail
1549 #define  NET_VECTOR_OWN_FIRST 0x01  // We allocated the 1st block in the vector
1550 
1551 #define NET_CHECK_SIGNATURE(PData, SIGNATURE) \
1552   ASSERT (((PData) != NULL) && ((PData)->Signature == (SIGNATURE)))
1553 
1554 //
1555 // Single memory block in the vector.
1556 //
1557 typedef struct {
1558   UINT32              Len;        // The block's length
1559   UINT8               *Bulk;      // The block's Data
1560 } NET_BLOCK;
1561 
1562 typedef VOID (EFIAPI *NET_VECTOR_EXT_FREE) (VOID *Arg);
1563 
1564 //
1565 //NET_VECTOR contains several blocks to hold all packet's
1566 //fragments and other house-keeping stuff for sharing. It
1567 //doesn't specify the where actual packet fragment begins.
1568 //
1569 typedef struct {
1570   UINT32              Signature;
1571   INTN                RefCnt;  // Reference count to share NET_VECTOR.
1572   NET_VECTOR_EXT_FREE Free;    // external function to free NET_VECTOR
1573   VOID                *Arg;    // opaque argument to Free
1574   UINT32              Flag;    // Flags, NET_VECTOR_OWN_FIRST
1575   UINT32              Len;     // Total length of the associated BLOCKs
1576 
1577   UINT32              BlockNum;
1578   NET_BLOCK           Block[1];
1579 } NET_VECTOR;
1580 
1581 //
1582 //NET_BLOCK_OP operates on the NET_BLOCK. It specifies
1583 //where the actual fragment begins and ends
1584 //
1585 typedef struct {
1586   UINT8               *BlockHead;   // Block's head, or the smallest valid Head
1587   UINT8               *BlockTail;   // Block's tail. BlockTail-BlockHead=block length
1588   UINT8               *Head;        // 1st byte of the data in the block
1589   UINT8               *Tail;        // Tail of the data in the block, Tail-Head=Size
1590   UINT32              Size;         // The size of the data
1591 } NET_BLOCK_OP;
1592 
1593 typedef union {
1594   IP4_HEAD          *Ip4;
1595   EFI_IP6_HEADER    *Ip6;
1596 } NET_IP_HEAD;
1597 
1598 //
1599 //NET_BUF is the buffer manage structure used by the
1600 //network stack. Every network packet may be fragmented. The Vector points to
1601 //memory blocks used by each fragment, and BlockOp
1602 //specifies where each fragment begins and ends.
1603 //
1604 //It also contains an opaque area for the protocol to store
1605 //per-packet information. Protocol must be careful not
1606 //to overwrite the members after that.
1607 //
1608 typedef struct {
1609   UINT32         Signature;
1610   INTN           RefCnt;
1611   LIST_ENTRY     List;                       // The List this NET_BUF is on
1612 
1613   NET_IP_HEAD    Ip;                         // Network layer header, for fast access
1614   TCP_HEAD       *Tcp;                       // Transport layer header, for fast access
1615   EFI_UDP_HEADER *Udp;                       // User Datagram Protocol header
1616   UINT8          ProtoData [NET_PROTO_DATA]; //Protocol specific data
1617 
1618   NET_VECTOR     *Vector;                    // The vector containing the packet
1619 
1620   UINT32         BlockOpNum;                 // Total number of BlockOp in the buffer
1621   UINT32         TotalSize;                  // Total size of the actual packet
1622   NET_BLOCK_OP   BlockOp[1];                 // Specify the position of actual packet
1623 } NET_BUF;
1624 
1625 //
1626 //A queue of NET_BUFs. It is a thin extension of
1627 //NET_BUF functions.
1628 //
1629 typedef struct {
1630   UINT32              Signature;
1631   INTN                RefCnt;
1632   LIST_ENTRY          List;       // The List this buffer queue is on
1633 
1634   LIST_ENTRY          BufList;    // list of queued buffers
1635   UINT32              BufSize;    // total length of DATA in the buffers
1636   UINT32              BufNum;     // total number of buffers on the chain
1637 } NET_BUF_QUEUE;
1638 
1639 //
1640 // Pseudo header for TCP and UDP checksum
1641 //
1642 #pragma pack(1)
1643 typedef struct {
1644   IP4_ADDR            SrcIp;
1645   IP4_ADDR            DstIp;
1646   UINT8               Reserved;
1647   UINT8               Protocol;
1648   UINT16              Len;
1649 } NET_PSEUDO_HDR;
1650 
1651 typedef struct {
1652   EFI_IPv6_ADDRESS    SrcIp;
1653   EFI_IPv6_ADDRESS    DstIp;
1654   UINT32              Len;
1655   UINT32              Reserved:24;
1656   UINT32              NextHeader:8;
1657 } NET_IP6_PSEUDO_HDR;
1658 #pragma pack()
1659 
1660 //
1661 // The fragment entry table used in network interfaces. This is
1662 // the same as NET_BLOCK now. Use two different to distinguish
1663 // the two in case that NET_BLOCK be enhanced later.
1664 //
1665 typedef struct {
1666   UINT32              Len;
1667   UINT8               *Bulk;
1668 } NET_FRAGMENT;
1669 
1670 #define NET_GET_REF(PData)      ((PData)->RefCnt++)
1671 #define NET_PUT_REF(PData)      ((PData)->RefCnt--)
1672 #define NETBUF_FROM_PROTODATA(Info) BASE_CR((Info), NET_BUF, ProtoData)
1673 
1674 #define NET_BUF_SHARED(Buf) \
1675   (((Buf)->RefCnt > 1) || ((Buf)->Vector->RefCnt > 1))
1676 
1677 #define NET_VECTOR_SIZE(BlockNum) \
1678   (sizeof (NET_VECTOR) + ((BlockNum) - 1) * sizeof (NET_BLOCK))
1679 
1680 #define NET_BUF_SIZE(BlockOpNum)  \
1681   (sizeof (NET_BUF) + ((BlockOpNum) - 1) * sizeof (NET_BLOCK_OP))
1682 
1683 #define NET_HEADSPACE(BlockOp)  \
1684   ((UINTN)((BlockOp)->Head) - (UINTN)((BlockOp)->BlockHead))
1685 
1686 #define NET_TAILSPACE(BlockOp)  \
1687   ((UINTN)((BlockOp)->BlockTail) - (UINTN)((BlockOp)->Tail))
1688 
1689 /**
1690   Allocate a single block NET_BUF. Upon allocation, all the
1691   free space is in the tail room.
1692 
1693   @param[in]  Len              The length of the block.
1694 
1695   @return                      The pointer to the allocated NET_BUF, or NULL if the
1696                                allocation failed due to resource limitations.
1697 
1698 **/
1699 NET_BUF  *
1700 EFIAPI
1701 NetbufAlloc (
1702   IN UINT32                 Len
1703   );
1704 
1705 /**
1706   Free the net buffer and its associated NET_VECTOR.
1707 
1708   Decrease the reference count of the net buffer by one. Free the associated net
1709   vector and itself if the reference count of the net buffer is decreased to 0.
1710   The net vector free operation decreases the reference count of the net
1711   vector by one, and performs the resource free operation when the reference count
1712   of the net vector is 0.
1713 
1714   @param[in]  Nbuf                  The pointer to the NET_BUF to be freed.
1715 
1716 **/
1717 VOID
1718 EFIAPI
1719 NetbufFree (
1720   IN NET_BUF                *Nbuf
1721   );
1722 
1723 /**
1724   Get the index of NET_BLOCK_OP that contains the byte at Offset in the net
1725   buffer.
1726 
1727   For example, this function can be used to retrieve the IP header in the packet. It
1728   also can be used to get the fragment that contains the byte used
1729   mainly by the library implementation itself.
1730 
1731   @param[in]   Nbuf      The pointer to the net buffer.
1732   @param[in]   Offset    The offset of the byte.
1733   @param[out]  Index     Index of the NET_BLOCK_OP that contains the byte at
1734                          Offset.
1735 
1736   @return       The pointer to the Offset'th byte of data in the net buffer, or NULL
1737                 if there is no such data in the net buffer.
1738 
1739 **/
1740 UINT8  *
1741 EFIAPI
1742 NetbufGetByte (
1743   IN  NET_BUF               *Nbuf,
1744   IN  UINT32                Offset,
1745   OUT UINT32                *Index  OPTIONAL
1746   );
1747 
1748 /**
1749   Create a copy of the net buffer that shares the associated net vector.
1750 
1751   The reference count of the newly created net buffer is set to 1. The reference
1752   count of the associated net vector is increased by one.
1753 
1754   @param[in]  Nbuf              The pointer to the net buffer to be cloned.
1755 
1756   @return                       The pointer to the cloned net buffer, or NULL if the
1757                                 allocation failed due to resource limitations.
1758 
1759 **/
1760 NET_BUF *
1761 EFIAPI
1762 NetbufClone (
1763   IN NET_BUF                *Nbuf
1764   );
1765 
1766 /**
1767   Create a duplicated copy of the net buffer with data copied and HeadSpace
1768   bytes of head space reserved.
1769 
1770   The duplicated net buffer will allocate its own memory to hold the data of the
1771   source net buffer.
1772 
1773   @param[in]       Nbuf         The pointer to the net buffer to be duplicated from.
1774   @param[in, out]  Duplicate    The pointer to the net buffer to duplicate to. If
1775                                 NULL, a new net buffer is allocated.
1776   @param[in]      HeadSpace     The length of the head space to reserve.
1777 
1778   @return                       The pointer to the duplicated net buffer, or NULL if
1779                                 the allocation failed due to resource limitations.
1780 
1781 **/
1782 NET_BUF  *
1783 EFIAPI
1784 NetbufDuplicate (
1785   IN NET_BUF                *Nbuf,
1786   IN OUT NET_BUF            *Duplicate        OPTIONAL,
1787   IN UINT32                 HeadSpace
1788   );
1789 
1790 /**
1791   Create a NET_BUF structure which contains Len byte data of Nbuf starting from
1792   Offset.
1793 
1794   A new NET_BUF structure will be created but the associated data in NET_VECTOR
1795   is shared. This function exists to perform IP packet fragmentation.
1796 
1797   @param[in]  Nbuf         The pointer to the net buffer to be extracted.
1798   @param[in]  Offset       Starting point of the data to be included in the new
1799                            net buffer.
1800   @param[in]  Len          The bytes of data to be included in the new net buffer.
1801   @param[in]  HeadSpace    The bytes of the head space to reserve for the protocol header.
1802 
1803   @return                  The pointer to the cloned net buffer, or NULL if the
1804                            allocation failed due to resource limitations.
1805 
1806 **/
1807 NET_BUF  *
1808 EFIAPI
1809 NetbufGetFragment (
1810   IN NET_BUF                *Nbuf,
1811   IN UINT32                 Offset,
1812   IN UINT32                 Len,
1813   IN UINT32                 HeadSpace
1814   );
1815 
1816 /**
1817   Reserve some space in the header room of the net buffer.
1818 
1819   Upon allocation, all the space is in the tail room of the buffer. Call this
1820   function to move space to the header room. This function is quite limited
1821   in that it can only reserve space from the first block of an empty NET_BUF not
1822   built from the external. However, it should be enough for the network stack.
1823 
1824   @param[in, out]  Nbuf     The pointer to the net buffer.
1825   @param[in]       Len      The length of buffer to be reserved from the header.
1826 
1827 **/
1828 VOID
1829 EFIAPI
1830 NetbufReserve (
1831   IN OUT NET_BUF            *Nbuf,
1832   IN UINT32                 Len
1833   );
1834 
1835 /**
1836   Allocate Len bytes of space from the header or tail of the buffer.
1837 
1838   @param[in, out]  Nbuf       The pointer to the net buffer.
1839   @param[in]       Len        The length of the buffer to be allocated.
1840   @param[in]       FromHead   The flag to indicate whether to reserve the data
1841                               from head (TRUE) or tail (FALSE).
1842 
1843   @return                     The pointer to the first byte of the allocated buffer,
1844                               or NULL, if there is no sufficient space.
1845 
1846 **/
1847 UINT8*
1848 EFIAPI
1849 NetbufAllocSpace (
1850   IN OUT NET_BUF            *Nbuf,
1851   IN UINT32                 Len,
1852   IN BOOLEAN                FromHead
1853   );
1854 
1855 /**
1856   Trim Len bytes from the header or the tail of the net buffer.
1857 
1858   @param[in, out]  Nbuf         The pointer to the net buffer.
1859   @param[in]       Len          The length of the data to be trimmed.
1860   @param[in]      FromHead      The flag to indicate whether trim data is from the
1861                                 head (TRUE) or the tail (FALSE).
1862 
1863   @return    The length of the actual trimmed data, which may be less
1864              than Len if the TotalSize of Nbuf is less than Len.
1865 
1866 **/
1867 UINT32
1868 EFIAPI
1869 NetbufTrim (
1870   IN OUT NET_BUF            *Nbuf,
1871   IN UINT32                 Len,
1872   IN BOOLEAN                FromHead
1873   );
1874 
1875 /**
1876   Copy Len bytes of data from the specific offset of the net buffer to the
1877   destination memory.
1878 
1879   The Len bytes of data may cross several fragments of the net buffer.
1880 
1881   @param[in]   Nbuf         The pointer to the net buffer.
1882   @param[in]   Offset       The sequence number of the first byte to copy.
1883   @param[in]   Len          The length of the data to copy.
1884   @param[in]   Dest         The destination of the data to copy to.
1885 
1886   @return           The length of the actual copied data, or 0 if the offset
1887                     specified exceeds the total size of net buffer.
1888 
1889 **/
1890 UINT32
1891 EFIAPI
1892 NetbufCopy (
1893   IN NET_BUF                *Nbuf,
1894   IN UINT32                 Offset,
1895   IN UINT32                 Len,
1896   IN UINT8                  *Dest
1897   );
1898 
1899 /**
1900   Build a NET_BUF from external blocks.
1901 
1902   A new NET_BUF structure will be created from external blocks. An additional block
1903   of memory will be allocated to hold reserved HeadSpace bytes of header room
1904   and existing HeadLen bytes of header, but the external blocks are shared by the
1905   net buffer to avoid data copying.
1906 
1907   @param[in]  ExtFragment           The pointer to the data block.
1908   @param[in]  ExtNum                The number of the data blocks.
1909   @param[in]  HeadSpace             The head space to be reserved.
1910   @param[in]  HeadLen               The length of the protocol header. The function
1911                                     pulls this amount of data into a linear block.
1912   @param[in]  ExtFree               The pointer to the caller-provided free function.
1913   @param[in]  Arg                   The argument passed to ExtFree when ExtFree is
1914                                     called.
1915 
1916   @return                  The pointer to the net buffer built from the data blocks,
1917                            or NULL if the allocation failed due to resource
1918                            limit.
1919 
1920 **/
1921 NET_BUF  *
1922 EFIAPI
1923 NetbufFromExt (
1924   IN NET_FRAGMENT           *ExtFragment,
1925   IN UINT32                 ExtNum,
1926   IN UINT32                 HeadSpace,
1927   IN UINT32                 HeadLen,
1928   IN NET_VECTOR_EXT_FREE    ExtFree,
1929   IN VOID                   *Arg          OPTIONAL
1930   );
1931 
1932 /**
1933   Build a fragment table to contain the fragments in the net buffer. This is the
1934   opposite operation of the NetbufFromExt.
1935 
1936   @param[in]       Nbuf                  Points to the net buffer.
1937   @param[in, out]  ExtFragment           The pointer to the data block.
1938   @param[in, out]  ExtNum                The number of the data blocks.
1939 
1940   @retval EFI_BUFFER_TOO_SMALL  The number of non-empty blocks is bigger than
1941                                 ExtNum.
1942   @retval EFI_SUCCESS           The fragment table was built successfully.
1943 
1944 **/
1945 EFI_STATUS
1946 EFIAPI
1947 NetbufBuildExt (
1948   IN NET_BUF                *Nbuf,
1949   IN OUT NET_FRAGMENT       *ExtFragment,
1950   IN OUT UINT32             *ExtNum
1951   );
1952 
1953 /**
1954   Build a net buffer from a list of net buffers.
1955 
1956   All the fragments will be collected from the list of NEW_BUF, and then a new
1957   net buffer will be created through NetbufFromExt.
1958 
1959   @param[in]   BufList    A List of the net buffer.
1960   @param[in]   HeadSpace  The head space to be reserved.
1961   @param[in]   HeaderLen  The length of the protocol header. The function
1962                           pulls this amount of data into a linear block.
1963   @param[in]   ExtFree    The pointer to the caller provided free function.
1964   @param[in]   Arg        The argument passed to ExtFree when ExtFree is called.
1965 
1966   @return                 The pointer to the net buffer built from the list of net
1967                           buffers.
1968 
1969 **/
1970 NET_BUF  *
1971 EFIAPI
1972 NetbufFromBufList (
1973   IN LIST_ENTRY             *BufList,
1974   IN UINT32                 HeadSpace,
1975   IN UINT32                 HeaderLen,
1976   IN NET_VECTOR_EXT_FREE    ExtFree,
1977   IN VOID                   *Arg              OPTIONAL
1978   );
1979 
1980 /**
1981   Free a list of net buffers.
1982 
1983   @param[in, out]  Head              The pointer to the head of linked net buffers.
1984 
1985 **/
1986 VOID
1987 EFIAPI
1988 NetbufFreeList (
1989   IN OUT LIST_ENTRY         *Head
1990   );
1991 
1992 /**
1993   Initiate the net buffer queue.
1994 
1995   @param[in, out]  NbufQue   The pointer to the net buffer queue to be initialized.
1996 
1997 **/
1998 VOID
1999 EFIAPI
2000 NetbufQueInit (
2001   IN OUT NET_BUF_QUEUE          *NbufQue
2002   );
2003 
2004 /**
2005   Allocate and initialize a net buffer queue.
2006 
2007   @return         The pointer to the allocated net buffer queue, or NULL if the
2008                   allocation failed due to resource limit.
2009 
2010 **/
2011 NET_BUF_QUEUE  *
2012 EFIAPI
2013 NetbufQueAlloc (
2014   VOID
2015   );
2016 
2017 /**
2018   Free a net buffer queue.
2019 
2020   Decrease the reference count of the net buffer queue by one. The real resource
2021   free operation isn't performed until the reference count of the net buffer
2022   queue is decreased to 0.
2023 
2024   @param[in]  NbufQue               The pointer to the net buffer queue to be freed.
2025 
2026 **/
2027 VOID
2028 EFIAPI
2029 NetbufQueFree (
2030   IN NET_BUF_QUEUE          *NbufQue
2031   );
2032 
2033 /**
2034   Remove a net buffer from the head in the specific queue and return it.
2035 
2036   @param[in, out]  NbufQue               The pointer to the net buffer queue.
2037 
2038   @return           The pointer to the net buffer removed from the specific queue,
2039                     or NULL if there is no net buffer in the specific queue.
2040 
2041 **/
2042 NET_BUF  *
2043 EFIAPI
2044 NetbufQueRemove (
2045   IN OUT NET_BUF_QUEUE          *NbufQue
2046   );
2047 
2048 /**
2049   Append a net buffer to the net buffer queue.
2050 
2051   @param[in, out]  NbufQue            The pointer to the net buffer queue.
2052   @param[in, out]  Nbuf               The pointer to the net buffer to be appended.
2053 
2054 **/
2055 VOID
2056 EFIAPI
2057 NetbufQueAppend (
2058   IN OUT NET_BUF_QUEUE          *NbufQue,
2059   IN OUT NET_BUF                *Nbuf
2060   );
2061 
2062 /**
2063   Copy Len bytes of data from the net buffer queue at the specific offset to the
2064   destination memory.
2065 
2066   The copying operation is the same as NetbufCopy, but applies to the net buffer
2067   queue instead of the net buffer.
2068 
2069   @param[in]   NbufQue         The pointer to the net buffer queue.
2070   @param[in]   Offset          The sequence number of the first byte to copy.
2071   @param[in]   Len             The length of the data to copy.
2072   @param[out]  Dest            The destination of the data to copy to.
2073 
2074   @return       The length of the actual copied data, or 0 if the offset
2075                 specified exceeds the total size of net buffer queue.
2076 
2077 **/
2078 UINT32
2079 EFIAPI
2080 NetbufQueCopy (
2081   IN NET_BUF_QUEUE          *NbufQue,
2082   IN UINT32                 Offset,
2083   IN UINT32                 Len,
2084   OUT UINT8                 *Dest
2085   );
2086 
2087 /**
2088   Trim Len bytes of data from the buffer queue and free any net buffer
2089   that is completely trimmed.
2090 
2091   The trimming operation is the same as NetbufTrim but applies to the net buffer
2092   queue instead of the net buffer.
2093 
2094   @param[in, out]  NbufQue               The pointer to the net buffer queue.
2095   @param[in]       Len                   The length of the data to trim.
2096 
2097   @return   The actual length of the data trimmed.
2098 
2099 **/
2100 UINT32
2101 EFIAPI
2102 NetbufQueTrim (
2103   IN OUT NET_BUF_QUEUE      *NbufQue,
2104   IN UINT32                 Len
2105   );
2106 
2107 
2108 /**
2109   Flush the net buffer queue.
2110 
2111   @param[in, out]  NbufQue               The pointer to the queue to be flushed.
2112 
2113 **/
2114 VOID
2115 EFIAPI
2116 NetbufQueFlush (
2117   IN OUT NET_BUF_QUEUE          *NbufQue
2118   );
2119 
2120 /**
2121   Compute the checksum for a bulk of data.
2122 
2123   @param[in]   Bulk                  The pointer to the data.
2124   @param[in]   Len                   The length of the data, in bytes.
2125 
2126   @return    The computed checksum.
2127 
2128 **/
2129 UINT16
2130 EFIAPI
2131 NetblockChecksum (
2132   IN UINT8                  *Bulk,
2133   IN UINT32                 Len
2134   );
2135 
2136 /**
2137   Add two checksums.
2138 
2139   @param[in]   Checksum1             The first checksum to be added.
2140   @param[in]   Checksum2             The second checksum to be added.
2141 
2142   @return         The new checksum.
2143 
2144 **/
2145 UINT16
2146 EFIAPI
2147 NetAddChecksum (
2148   IN UINT16                 Checksum1,
2149   IN UINT16                 Checksum2
2150   );
2151 
2152 /**
2153   Compute the checksum for a NET_BUF.
2154 
2155   @param[in]   Nbuf                  The pointer to the net buffer.
2156 
2157   @return    The computed checksum.
2158 
2159 **/
2160 UINT16
2161 EFIAPI
2162 NetbufChecksum (
2163   IN NET_BUF                *Nbuf
2164   );
2165 
2166 /**
2167   Compute the checksum for TCP/UDP pseudo header.
2168 
2169   Src and Dst are in network byte order, and Len is in host byte order.
2170 
2171   @param[in]   Src                   The source address of the packet.
2172   @param[in]   Dst                   The destination address of the packet.
2173   @param[in]   Proto                 The protocol type of the packet.
2174   @param[in]   Len                   The length of the packet.
2175 
2176   @return   The computed checksum.
2177 
2178 **/
2179 UINT16
2180 EFIAPI
2181 NetPseudoHeadChecksum (
2182   IN IP4_ADDR               Src,
2183   IN IP4_ADDR               Dst,
2184   IN UINT8                  Proto,
2185   IN UINT16                 Len
2186   );
2187 
2188 /**
2189   Compute the checksum for the TCP6/UDP6 pseudo header.
2190 
2191   Src and Dst are in network byte order, and Len is in host byte order.
2192 
2193   @param[in]   Src                   The source address of the packet.
2194   @param[in]   Dst                   The destination address of the packet.
2195   @param[in]   NextHeader            The protocol type of the packet.
2196   @param[in]   Len                   The length of the packet.
2197 
2198   @return   The computed checksum.
2199 
2200 **/
2201 UINT16
2202 EFIAPI
2203 NetIp6PseudoHeadChecksum (
2204   IN EFI_IPv6_ADDRESS       *Src,
2205   IN EFI_IPv6_ADDRESS       *Dst,
2206   IN UINT8                  NextHeader,
2207   IN UINT32                 Len
2208   );
2209 
2210 /**
2211   The function frees the net buffer which allocated by the IP protocol. It releases
2212   only the net buffer and doesn't call the external free function.
2213 
2214   This function should be called after finishing the process of mIpSec->ProcessExt()
2215   for outbound traffic. The (EFI_IPSEC2_PROTOCOL)->ProcessExt() allocates a new
2216   buffer for the ESP, so there needs a function to free the old net buffer.
2217 
2218   @param[in]  Nbuf       The network buffer to be freed.
2219 
2220 **/
2221 VOID
2222 NetIpSecNetbufFree (
2223   NET_BUF   *Nbuf
2224   );
2225 
2226 /**
2227   This function obtains the system guid from the smbios table.
2228 
2229   If SystemGuid is NULL, then ASSERT().
2230 
2231   @param[out]  SystemGuid     The pointer of the returned system guid.
2232 
2233   @retval EFI_SUCCESS         Successfully obtained the system guid.
2234   @retval EFI_NOT_FOUND       Did not find the SMBIOS table.
2235 
2236 **/
2237 EFI_STATUS
2238 EFIAPI
2239 NetLibGetSystemGuid (
2240   OUT EFI_GUID              *SystemGuid
2241   );
2242 
2243 /**
2244   Create Dns QName according the queried domain name.
2245 
2246   If DomainName is NULL, then ASSERT().
2247 
2248   QName is a domain name represented as a sequence of labels,
2249   where each label consists of a length octet followed by that
2250   number of octets. The QName terminates with the zero
2251   length octet for the null label of the root. Caller should
2252   take responsibility to free the buffer in returned pointer.
2253 
2254   @param  DomainName    The pointer to the queried domain name string.
2255 
2256   @retval NULL          Failed to fill QName.
2257   @return               QName filled successfully.
2258 
2259 **/
2260 CHAR8 *
2261 EFIAPI
2262 NetLibCreateDnsQName (
2263   IN  CHAR16              *DomainName
2264   );
2265 
2266 #endif
2267