3 Copyright (c) 2005 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Library for the UEFI network stack.
27 #include <Protocol/DriverBinding.h>
28 #include <Protocol/ComponentName.h>
29 #include <Protocol/DriverConfiguration.h>
30 #include <Protocol/DriverDiagnostics.h>
32 #define EFI_NET_LITTLE_ENDIAN
34 typedef UINT32 IP4_ADDR
;
35 typedef UINT32 TCP_SEQNO
;
36 typedef UINT16 TCP_PORTNO
;
39 NET_ETHER_ADDR_LEN
= 6,
40 NET_IFTYPE_ETHERNET
= 0x01,
42 EFI_IP_PROTO_UDP
= 0x11,
43 EFI_IP_PROTO_TCP
= 0x06,
44 EFI_IP_PROTO_ICMP
= 0x01,
47 // The address classfication
61 // Ethernet head definition
64 UINT8 DstMac
[NET_ETHER_ADDR_LEN
];
65 UINT8 SrcMac
[NET_ETHER_ADDR_LEN
];
71 // The EFI_IP4_HEADER is hard to use because the source and
72 // destination address are defined as EFI_IPv4_ADDRESS, which
73 // is a structure. Two structures can't be compared or masked
74 // directly. This is why there is an internal representation.
77 #ifdef EFI_NET_LITTLE_ENDIAN
97 // ICMP head definition. ICMP message is categoried as either an error
98 // message or query message. Two message types have their own head format.
108 UINT32 Fourth
; // 4th filed of the head, it depends on Type.
110 } IP4_ICMP_ERROR_HEAD
;
116 } IP4_ICMP_QUERY_HEAD
;
120 // UDP header definition
131 // TCP header definition
138 #ifdef EFI_NET_LITTLE_ENDIAN
153 #define NET_MAC_EQUAL(pMac1, pMac2, Len) \
154 (NetCompareMem ((pMac1), (pMac2), Len) == 0)
156 #define NET_MAC_IS_MULTICAST(Mac, BMac, Len) \
157 (((*((UINT8 *) Mac) & 0x01) == 0x01) && (!NET_MAC_EQUAL (Mac, BMac, Len)))
159 #ifdef EFI_NET_LITTLE_ENDIAN
160 #define NTOHL(x) (UINT32)((((UINT32) (x) & 0xff) << 24) | \
161 (((UINT32) (x) & 0xff00) << 8) | \
162 (((UINT32) (x) & 0xff0000) >> 8) | \
163 (((UINT32) (x) & 0xff000000) >> 24))
165 #define HTONL(x) NTOHL(x)
167 #define NTOHS(x) (UINT16)((((UINT16) (x) & 0xff) << 8) | \
168 (((UINT16) (x) & 0xff00) >> 8))
170 #define HTONS(x) NTOHS(x)
172 #define NTOHL(x) (UINT32)(x)
173 #define HTONL(x) (UINT32)(x)
174 #define NTOHS(x) (UINT16)(x)
175 #define HTONS(x) (UINT16)(x)
179 // Test the IP's attribute, All the IPs are in host byte order.
181 #define IP4_IS_MULTICAST(Ip) (((Ip) & 0xF0000000) == 0xE0000000)
182 #define IP4_IS_LOCAL_BROADCAST(Ip) ((Ip) == 0xFFFFFFFF)
183 #define IP4_NET_EQUAL(Ip1, Ip2, NetMask) (((Ip1) & (NetMask)) == ((Ip2) & (NetMask)))
184 #define IP4_IS_VALID_NETMASK(Ip) (NetGetMaskLength (Ip) != IP4_MASK_NUM)
187 // Convert the EFI_IP4_ADDRESS to plain UINT32 IP4 address.
189 #define EFI_IP4(EfiIpAddr) (*(IP4_ADDR *) ((EfiIpAddr).Addr))
190 #define EFI_NTOHL(EfiIp) (NTOHL (EFI_IP4 ((EfiIp))))
191 #define EFI_IP4_EQUAL(Ip1, Ip2) (NetCompareMem ((Ip1), (Ip2), sizeof (EFI_IPv4_ADDRESS)) == 0)
209 extern IP4_ADDR mIp4AllMasks
[IP4_MASK_NUM
];
212 extern EFI_IPv4_ADDRESS mZeroIp4Addr
;
214 #define NET_IS_DIGIT(Ch) (('0' <= (Ch)) && ((Ch) <= '9'))
216 // Wrap functions to ease the impact of EFI library changes.
218 #define NetAllocateZeroPool AllocateZeroPool
219 #define NetAllocatePool AllocatePool
220 #define NetFreePool gBS->FreePool
221 #define NetCopyMem CopyMem
222 #define NetSetMem SetMem
223 #define NetZeroMem(Dest, Len) SetMem ((Dest), (Len), 0)
224 #define NetCompareMem CompareMem
227 // Lock primitives: the stack implements its lock primitives according
228 // to the standard EFI enviornment. It will NOT consider multiprocessor.
230 #define NET_TPL_LOCK TPL_CALLBACK
231 #define NET_TPL_RECYCLE_LOCK (NET_TPL_LOCK + 1)
232 #define NET_TPL_EVENT TPL_CALLBACK
233 #define NET_TPL_RECYCLE (NET_TPL_LOCK + 1)
234 #define NET_TPL_SLOW_TIMER (TPL_CALLBACK - 1)
235 #define NET_TPL_FAST_TIMER NET_TPL_RECYCLE
236 #define NET_TPL_TIMER TPL_CALLBACK
238 #define NET_LOCK EFI_LOCK
239 #define NET_LOCK_INIT(x) EfiInitializeLock (x, NET_TPL_LOCK)
240 #define NET_RECYCLE_LOCK_INIT(x) EfiInitializeLock (x, NET_TPL_RECYCLE_LOCK)
241 #define NET_TRYLOCK(x) EfiAcquireLockOrFail (x)
242 #define NET_UNLOCK(x) EfiReleaseLock (x)
244 #define NET_RAISE_TPL(x) (gBS->RaiseTPL (x))
245 #define NET_RESTORE_TPL(x) (gBS->RestoreTPL (x))
247 #define TICKS_PER_MS 10000U
248 #define TICKS_PER_SECOND 10000000U
250 #define NET_MIN(a, b) ((a) < (b) ? (a) : (b))
251 #define NET_MAX(a, b) ((a) > (b) ? (a) : (b))
252 #define NET_RANDOM(Seed) ((UINT32) ((UINT32) (Seed) * 1103515245UL + 12345) % 4294967295UL)
273 // Double linked list entry functions, this extends the
274 // EFI list functions.
276 typedef LIST_ENTRY NET_LIST_ENTRY
;
278 #define NetListInit(Head) InitializeListHead(Head)
279 #define NetListInsertHead(Head, Entry) InsertHeadList((Head), (Entry))
280 #define NetListInsertTail(Head, Entry) InsertTailList((Head), (Entry))
281 #define NetListIsEmpty(List) IsListEmpty(List)
283 #define NET_LIST_USER_STRUCT(Entry, Type, Field) \
284 _CR(Entry, Type, Field)
286 #define NET_LIST_USER_STRUCT_S(Entry, Type, Field, Sig) \
287 CR(Entry, Type, Field, Sig)
290 // Iterate through the doule linked list. It is NOT delete safe
292 #define NET_LIST_FOR_EACH(Entry, ListHead) \
293 for(Entry = (ListHead)->ForwardLink; Entry != (ListHead); Entry = Entry->ForwardLink)
296 // Iterate through the doule linked list. This is delete-safe.
297 // Don't touch NextEntry. Also, don't use this macro if list
298 // entries other than the Entry may be deleted when processing
299 // the current Entry.
301 #define NET_LIST_FOR_EACH_SAFE(Entry, NextEntry, ListHead) \
302 for(Entry = (ListHead)->ForwardLink, NextEntry = Entry->ForwardLink; \
303 Entry != (ListHead); \
304 Entry = NextEntry, NextEntry = Entry->ForwardLink \
308 // Make sure the list isn't empty before get the frist/last record.
310 #define NET_LIST_HEAD(ListHead, Type, Field) \
311 NET_LIST_USER_STRUCT((ListHead)->ForwardLink, Type, Field)
313 #define NET_LIST_TAIL(ListHead, Type, Field) \
314 NET_LIST_USER_STRUCT((ListHead)->BackLink, Type, Field)
316 #define NetListRemoveEntry(Entry) RemoveEntryList (Entry)
330 IN NET_LIST_ENTRY
*PrevEntry
,
331 IN NET_LIST_ENTRY
*NewEntry
335 NetListInsertBefore (
336 IN NET_LIST_ENTRY
*PostEntry
,
337 IN NET_LIST_ENTRY
*NewEntry
342 // Object container: EFI network stack spec defines various kinds of
343 // tokens. The drivers can share code to manage those objects.
353 NET_LIST_ENTRY Recycled
;
357 #define NET_MAP_INCREAMENT 64
383 IN VOID
*Value OPTIONAL
390 IN VOID
*Value OPTIONAL
402 IN NET_MAP_ITEM
*Item
,
403 OUT VOID
**Value OPTIONAL
409 OUT VOID
**Value OPTIONAL
415 OUT VOID
**Value OPTIONAL
420 (*NET_MAP_CALLBACK
) (
422 IN NET_MAP_ITEM
*Item
,
429 IN NET_MAP_CALLBACK CallBack
,
430 IN VOID
*Arg OPTIONAL
435 // Helper functions to implement driver binding and service binding protocols.
438 NetLibCreateServiceChild (
439 IN EFI_HANDLE ControllerHandle
,
440 IN EFI_HANDLE ImageHandle
,
441 IN EFI_GUID
*ServiceBindingGuid
,
442 OUT EFI_HANDLE
*ChildHandle
446 NetLibDestroyServiceChild (
447 IN EFI_HANDLE ControllerHandle
,
448 IN EFI_HANDLE ImageHandle
,
449 IN EFI_GUID
*ServiceBindingGuid
,
450 IN EFI_HANDLE ChildHandle
455 IN EFI_HANDLE SnpHandle
,
456 IN EFI_HANDLE ImageHandle
,
457 IN OUT CHAR16
**MacString
461 NetLibCreateIPv4DPathNode (
462 IN OUT IPv4_DEVICE_PATH
*Node
,
463 IN EFI_HANDLE Controller
,
466 IN IP4_ADDR RemoteIp
,
467 IN UINT16 RemotePort
,
469 IN BOOLEAN UseDefaultAddress
474 IN EFI_HANDLE Controller
,
475 IN EFI_GUID
*ProtocolGuid
480 (EFIAPI
*NET_LIB_DRIVER_UNLOAD
) (
481 IN EFI_HANDLE ImageHandle
486 NetLibDefaultUnload (
487 IN EFI_HANDLE ImageHandle
491 NetLibInstallAllDriverProtocolsWithUnload (
492 IN EFI_HANDLE ImageHandle
,
493 IN EFI_SYSTEM_TABLE
*SystemTable
,
494 IN EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
,
495 IN EFI_HANDLE DriverBindingHandle
,
496 IN EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
, OPTIONAL
497 IN EFI_DRIVER_CONFIGURATION_PROTOCOL
*DriverConfiguration
, OPTIONAL
498 IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL
*DriverDiagnostics
, OPTIONAL
499 IN NET_LIB_DRIVER_UNLOAD CustomizedUnload
503 NetLibInstallAllDriverProtocols (
504 IN EFI_HANDLE ImageHandle
,
505 IN EFI_SYSTEM_TABLE
*SystemTable
,
506 IN EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
,
507 IN EFI_HANDLE DriverBindingHandle
,
508 IN EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
, OPTIONAL
509 IN EFI_DRIVER_CONFIGURATION_PROTOCOL
*DriverConfiguration
, OPTIONAL
510 IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL
*DriverDiagnostics OPTIONAL
517 NET_BUF_SIGNATURE
= EFI_SIGNATURE_32 ('n', 'b', 'u', 'f'),
518 NET_VECTOR_SIGNATURE
= EFI_SIGNATURE_32 ('n', 'v', 'e', 'c'),
519 NET_QUE_SIGNATURE
= EFI_SIGNATURE_32 ('n', 'b', 'q', 'u'),
522 NET_PROTO_DATA
= 64, // Opaque buffer for protocols
523 NET_BUF_HEAD
= 1, // Trim or allocate space from head
524 NET_BUF_TAIL
= 0, // Trim or allocate space from tail
525 NET_VECTOR_OWN_FIRST
= 0x01, // We allocated the 1st block in the vector
528 #define NET_CHECK_SIGNATURE(PData, SIGNATURE) \
529 ASSERT (((PData) != NULL) && ((PData)->Signature == (SIGNATURE)))
531 #define NET_SWAP_SHORT(Value) \
532 ((((Value) & 0xff) << 8) | (((Value) >> 8) & 0xff))
535 // Single memory block in the vector.
538 UINT32 Len
; // The block's length
539 UINT8
*Bulk
; // The block's Data
542 typedef VOID (*NET_VECTOR_EXT_FREE
) (VOID
*Arg
);
545 //NET_VECTOR contains several blocks to hold all packet's
546 //fragments and other house-keeping stuff for sharing. It
547 //doesn't specify the where actual packet fragment begins.
551 INTN RefCnt
; // Reference count to share NET_VECTOR.
552 NET_VECTOR_EXT_FREE Free
; // external function to free NET_VECTOR
553 VOID
*Arg
; // opeque argument to Free
554 UINT32 Flag
; // Flags, NET_VECTOR_OWN_FIRST
555 UINT32 Len
; // Total length of the assocated BLOCKs
562 //NET_BLOCK_OP operate on the NET_BLOCK, It specifies
563 //where the actual fragment begins and where it ends
566 UINT8
*BlockHead
; // Block's head, or the smallest valid Head
567 UINT8
*BlockTail
; // Block's tail. BlockTail-BlockHead=block length
568 UINT8
*Head
; // 1st byte of the data in the block
569 UINT8
*Tail
; // Tail of the data in the block, Tail-Head=Size
570 UINT32 Size
; // The size of the data
575 //NET_BUF is the buffer manage structure used by the
576 //network stack. Every network packet may be fragmented,
577 //and contains multiple fragments. The Vector points to
578 //memory blocks used by the each fragment, and BlockOp
579 //specifies where each fragment begins and ends.
581 //It also contains a opaque area for protocol to store
582 //per-packet informations. Protocol must be caution not
583 //to overwrite the members after that.
588 NET_LIST_ENTRY List
; // The List this NET_BUF is on
590 IP4_HEAD
*Ip
; // Network layer header, for fast access
591 TCP_HEAD
*Tcp
; // Transport layer header, for fast access
592 UINT8 ProtoData
[NET_PROTO_DATA
]; //Protocol specific data
594 NET_VECTOR
*Vector
; // The vector containing the packet
596 UINT32 BlockOpNum
; // Total number of BlockOp in the buffer
597 UINT32 TotalSize
; // Total size of the actual packet
598 NET_BLOCK_OP BlockOp
[1]; // Specify the position of actual packet
603 //A queue of NET_BUFs, It is just a thin extension of
609 NET_LIST_ENTRY List
; // The List this buffer queue is on
611 NET_LIST_ENTRY BufList
; // list of queued buffers
612 UINT32 BufSize
; // total length of DATA in the buffers
613 UINT32 BufNum
; // total number of buffers on the chain
617 // Pseudo header for TCP and UDP checksum
630 // The fragment entry table used in network interfaces. This is
631 // the same as NET_BLOCK now. Use two different to distinguish
632 // the two in case that NET_BLOCK be enhanced later.
639 #define NET_GET_REF(PData) ((PData)->RefCnt++)
640 #define NET_PUT_REF(PData) ((PData)->RefCnt--)
641 #define NETBUF_FROM_PROTODATA(Info) _CR((Info), NET_BUF, ProtoData)
643 #define NET_BUF_SHARED(Buf) \
644 (((Buf)->RefCnt > 1) || ((Buf)->Vector->RefCnt > 1))
646 #define NET_VECTOR_SIZE(BlockNum) \
647 (sizeof (NET_VECTOR) + ((BlockNum) - 1) * sizeof (NET_BLOCK))
649 #define NET_BUF_SIZE(BlockOpNum) \
650 (sizeof (NET_BUF) + ((BlockOpNum) - 1) * sizeof (NET_BLOCK_OP))
652 #define NET_HEADSPACE(BlockOp) \
653 (UINTN)((BlockOp)->Head - (BlockOp)->BlockHead)
655 #define NET_TAILSPACE(BlockOp) \
656 (UINTN)((BlockOp)->BlockTail - (BlockOp)->Tail)
673 OUT UINT32
*Index OPTIONAL
684 IN NET_BUF
*Duplicate OPTIONAL
,
726 IN NET_FRAGMENT
*ExtFragment
,
730 IN NET_VECTOR_EXT_FREE ExtFree
,
731 IN VOID
*Arg OPTIONAL
737 IN NET_FRAGMENT
*ExtFragment
,
743 IN NET_LIST_ENTRY
*BufList
,
746 IN NET_VECTOR_EXT_FREE ExtFree
,
747 IN VOID
*Arg OPTIONAL
752 IN NET_LIST_ENTRY
*Head
757 IN NET_BUF_QUEUE
*NbufQue
767 IN NET_BUF_QUEUE
*NbufQue
772 IN NET_BUF_QUEUE
*NbufQue
777 IN NET_BUF_QUEUE
*NbufQue
,
783 IN NET_BUF_QUEUE
*NbufQue
,
791 IN NET_BUF_QUEUE
*NbufQue
,
797 IN NET_BUF_QUEUE
*NbufQue
818 NetPseudoHeadChecksum (
826 // The debug level definition. This value is also used as the
827 // syslog's servity level. Don't change it.
830 NETDEBUG_LEVEL_TRACE
= 5,
831 NETDEBUG_LEVEL_WARNING
= 4,
832 NETDEBUG_LEVEL_ERROR
= 3,
835 #ifdef EFI_NETWORK_STACK_DEBUG
838 // The debug output expects the ASCII format string, Use %a to print ASCII
839 // string, and %s to print UNICODE string. PrintArg must be enclosed in ().
840 // For example: NET_DEBUG_TRACE ("Tcp", ("State transit to %a\n", Name));
842 #define NET_DEBUG_TRACE(Module, PrintArg) \
844 NETDEBUG_LEVEL_TRACE, \
848 NetDebugASPrint PrintArg \
851 #define NET_DEBUG_WARNING(Module, PrintArg) \
853 NETDEBUG_LEVEL_WARNING, \
857 NetDebugASPrint PrintArg \
860 #define NET_DEBUG_ERROR(Module, PrintArg) \
862 NETDEBUG_LEVEL_ERROR, \
866 NetDebugASPrint PrintArg \
870 #define NET_DEBUG_TRACE(Module, PrintString)
871 #define NET_DEBUG_WARNING(Module, PrintString)
872 #define NET_DEBUG_ERROR(Module, PrintString)
891 // Network debug message is sent out as syslog.
894 NET_SYSLOG_FACILITY
= 16, // Syslog local facility local use
895 NET_SYSLOG_PACKET_LEN
= 512,
896 NET_DEBUG_MSG_LEN
= 470, // 512 - (ether+ip+udp head length)
897 NET_SYSLOG_TX_TIMEOUT
= 500 *1000 *10, // 500ms