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 <Library/BaseMemoryLib.h>
28 #include <Library/MemoryAllocationLib.h>
29 #include <Protocol/DriverBinding.h>
30 #include <Protocol/ComponentName.h>
31 #include <Protocol/DriverConfiguration.h>
32 #include <Protocol/DriverDiagnostics.h>
33 #include <Protocol/Dpc.h>
35 #define EFI_NET_LITTLE_ENDIAN
37 typedef UINT32 IP4_ADDR
;
38 typedef UINT32 TCP_SEQNO
;
39 typedef UINT16 TCP_PORTNO
;
42 NET_ETHER_ADDR_LEN
= 6,
43 NET_IFTYPE_ETHERNET
= 0x01,
45 EFI_IP_PROTO_UDP
= 0x11,
46 EFI_IP_PROTO_TCP
= 0x06,
47 EFI_IP_PROTO_ICMP
= 0x01,
50 // The address classfication
64 // Ethernet head definition
67 UINT8 DstMac
[NET_ETHER_ADDR_LEN
];
68 UINT8 SrcMac
[NET_ETHER_ADDR_LEN
];
74 // The EFI_IP4_HEADER is hard to use because the source and
75 // destination address are defined as EFI_IPv4_ADDRESS, which
76 // is a structure. Two structures can't be compared or masked
77 // directly. This is why there is an internal representation.
80 #ifdef EFI_NET_LITTLE_ENDIAN
100 // ICMP head definition. ICMP message is categoried as either an error
101 // message or query message. Two message types have their own head format.
111 UINT32 Fourth
; // 4th filed of the head, it depends on Type.
113 } IP4_ICMP_ERROR_HEAD
;
119 } IP4_ICMP_QUERY_HEAD
;
123 // UDP header definition
134 // TCP header definition
141 #ifdef EFI_NET_LITTLE_ENDIAN
156 #define NET_MAC_EQUAL(pMac1, pMac2, Len) \
157 (NetCompareMem ((pMac1), (pMac2), Len) == 0)
159 #define NET_MAC_IS_MULTICAST(Mac, BMac, Len) \
160 (((*((UINT8 *) Mac) & 0x01) == 0x01) && (!NET_MAC_EQUAL (Mac, BMac, Len)))
162 #ifdef EFI_NET_LITTLE_ENDIAN
163 #define NTOHL(x) (UINT32)((((UINT32) (x) & 0xff) << 24) | \
164 (((UINT32) (x) & 0xff00) << 8) | \
165 (((UINT32) (x) & 0xff0000) >> 8) | \
166 (((UINT32) (x) & 0xff000000) >> 24))
168 #define HTONL(x) NTOHL(x)
170 #define NTOHS(x) (UINT16)((((UINT16) (x) & 0xff) << 8) | \
171 (((UINT16) (x) & 0xff00) >> 8))
173 #define HTONS(x) NTOHS(x)
175 #define NTOHL(x) (UINT32)(x)
176 #define HTONL(x) (UINT32)(x)
177 #define NTOHS(x) (UINT16)(x)
178 #define HTONS(x) (UINT16)(x)
182 // Test the IP's attribute, All the IPs are in host byte order.
184 #define IP4_IS_MULTICAST(Ip) (((Ip) & 0xF0000000) == 0xE0000000)
185 #define IP4_IS_LOCAL_BROADCAST(Ip) ((Ip) == 0xFFFFFFFF)
186 #define IP4_NET_EQUAL(Ip1, Ip2, NetMask) (((Ip1) & (NetMask)) == ((Ip2) & (NetMask)))
187 #define IP4_IS_VALID_NETMASK(Ip) (NetGetMaskLength (Ip) != IP4_MASK_NUM)
190 // Convert the EFI_IP4_ADDRESS to plain UINT32 IP4 address.
192 #define EFI_IP4(EfiIpAddr) (*(IP4_ADDR *) ((EfiIpAddr).Addr))
193 #define EFI_NTOHL(EfiIp) (NTOHL (EFI_IP4 ((EfiIp))))
194 #define EFI_IP4_EQUAL(Ip1, Ip2) (NetCompareMem ((Ip1), (Ip2), sizeof (EFI_IPv4_ADDRESS)) == 0)
212 extern IP4_ADDR mIp4AllMasks
[IP4_MASK_NUM
];
215 extern EFI_IPv4_ADDRESS mZeroIp4Addr
;
217 #define NET_IS_DIGIT(Ch) (('0' <= (Ch)) && ((Ch) <= '9'))
218 #define NET_ROUNDUP(size, unit) (((size) + (unit) - 1) & (~((unit) - 1)))
219 #define NET_IS_LOWER_CASE_CHAR(Ch) (('a' <= (Ch)) && ((Ch) <= 'z'))
220 #define NET_IS_UPPER_CASE_CHAR(Ch) (('A' <= (Ch)) && ((Ch) <= 'Z'))
223 // Wrap functions to ease the impact of EFI library changes.
225 #define NetAllocateZeroPool AllocateZeroPool
226 #define NetAllocatePool AllocatePool
227 #define NetFreePool gBS->FreePool
228 #define NetCopyMem CopyMem
229 #define NetSetMem SetMem
230 #define NetZeroMem(Dest, Len) SetMem ((Dest), (Len), 0)
231 #define NetCompareMem CompareMem
234 // Lock primitives: the stack implements its lock primitives according
235 // to the standard EFI enviornment. It will NOT consider multiprocessor.
237 #define NET_TPL_LOCK TPL_CALLBACK
238 #define NET_TPL_EVENT TPL_NOTIFY
239 #define NET_TPL_RECYCLE TPL_NOTIFY
240 #define NET_TPL_TIMER NET_TPL_LOCK
242 #define NET_LOCK EFI_LOCK
243 #define NET_LOCK_INIT(x) EfiInitializeLock (x, NET_TPL_LOCK)
244 #define NET_RECYCLE_LOCK_INIT(x) EfiInitializeLock (x, NET_TPL_RECYCLE)
245 #define NET_TRYLOCK(x) EfiAcquireLockOrFail (x)
246 #define NET_UNLOCK(x) EfiReleaseLock (x)
248 #define NET_RAISE_TPL(x) (gBS->RaiseTPL (x))
249 #define NET_RESTORE_TPL(x) (gBS->RestoreTPL (x))
251 #define TICKS_PER_MS 10000U
252 #define TICKS_PER_SECOND 10000000U
254 #define NET_RANDOM(Seed) ((UINT32) ((UINT32) (Seed) * 1103515245UL + 12345) % 4294967295UL)
275 // Double linked list entry functions, this extends the
276 // EFI list functions.
278 typedef LIST_ENTRY NET_LIST_ENTRY
;
280 #define NetListInit(Head) InitializeListHead(Head)
281 #define NetListInsertHead(Head, Entry) InsertHeadList((Head), (Entry))
282 #define NetListInsertTail(Head, Entry) InsertTailList((Head), (Entry))
283 #define NetListIsEmpty(List) IsListEmpty(List)
285 #define NET_LIST_USER_STRUCT(Entry, Type, Field) \
286 _CR(Entry, Type, Field)
288 #define NET_LIST_USER_STRUCT_S(Entry, Type, Field, Sig) \
289 CR(Entry, Type, Field, Sig)
292 // Iterate through the doule linked list. It is NOT delete safe
294 #define NET_LIST_FOR_EACH(Entry, ListHead) \
295 for(Entry = (ListHead)->ForwardLink; Entry != (ListHead); Entry = Entry->ForwardLink)
298 // Iterate through the doule linked list. This is delete-safe.
299 // Don't touch NextEntry. Also, don't use this macro if list
300 // entries other than the Entry may be deleted when processing
301 // the current Entry.
303 #define NET_LIST_FOR_EACH_SAFE(Entry, NextEntry, ListHead) \
304 for(Entry = (ListHead)->ForwardLink, NextEntry = Entry->ForwardLink; \
305 Entry != (ListHead); \
306 Entry = NextEntry, NextEntry = Entry->ForwardLink \
310 // Make sure the list isn't empty before get the frist/last record.
312 #define NET_LIST_HEAD(ListHead, Type, Field) \
313 NET_LIST_USER_STRUCT((ListHead)->ForwardLink, Type, Field)
315 #define NET_LIST_TAIL(ListHead, Type, Field) \
316 NET_LIST_USER_STRUCT((ListHead)->BackLink, Type, Field)
318 #define NetListRemoveEntry(Entry) RemoveEntryList (Entry)
332 IN NET_LIST_ENTRY
*PrevEntry
,
333 IN NET_LIST_ENTRY
*NewEntry
337 NetListInsertBefore (
338 IN NET_LIST_ENTRY
*PostEntry
,
339 IN NET_LIST_ENTRY
*NewEntry
344 // Object container: EFI network stack spec defines various kinds of
345 // tokens. The drivers can share code to manage those objects.
355 NET_LIST_ENTRY Recycled
;
359 #define NET_MAP_INCREAMENT 64
385 IN VOID
*Value OPTIONAL
392 IN VOID
*Value OPTIONAL
404 IN NET_MAP_ITEM
*Item
,
405 OUT VOID
**Value OPTIONAL
411 OUT VOID
**Value OPTIONAL
417 OUT VOID
**Value OPTIONAL
422 (*NET_MAP_CALLBACK
) (
424 IN NET_MAP_ITEM
*Item
,
431 IN NET_MAP_CALLBACK CallBack
,
432 IN VOID
*Arg OPTIONAL
437 // Helper functions to implement driver binding and service binding protocols.
440 NetLibCreateServiceChild (
441 IN EFI_HANDLE ControllerHandle
,
442 IN EFI_HANDLE ImageHandle
,
443 IN EFI_GUID
*ServiceBindingGuid
,
444 OUT EFI_HANDLE
*ChildHandle
448 NetLibDestroyServiceChild (
449 IN EFI_HANDLE ControllerHandle
,
450 IN EFI_HANDLE ImageHandle
,
451 IN EFI_GUID
*ServiceBindingGuid
,
452 IN EFI_HANDLE ChildHandle
457 IN EFI_HANDLE SnpHandle
,
458 IN EFI_HANDLE ImageHandle
,
459 IN OUT CHAR16
**MacString
463 NetLibCreateIPv4DPathNode (
464 IN OUT IPv4_DEVICE_PATH
*Node
,
465 IN EFI_HANDLE Controller
,
468 IN IP4_ADDR RemoteIp
,
469 IN UINT16 RemotePort
,
471 IN BOOLEAN UseDefaultAddress
476 IN EFI_HANDLE Controller
,
477 IN EFI_GUID
*ProtocolGuid
483 IN EFI_DPC_PROCEDURE DpcProcedure
,
484 IN VOID
*DpcContext OPTIONAL
494 NetLibDefaultUnload (
495 IN EFI_HANDLE ImageHandle
502 NET_BUF_SIGNATURE
= EFI_SIGNATURE_32 ('n', 'b', 'u', 'f'),
503 NET_VECTOR_SIGNATURE
= EFI_SIGNATURE_32 ('n', 'v', 'e', 'c'),
504 NET_QUE_SIGNATURE
= EFI_SIGNATURE_32 ('n', 'b', 'q', 'u'),
507 NET_PROTO_DATA
= 64, // Opaque buffer for protocols
508 NET_BUF_HEAD
= 1, // Trim or allocate space from head
509 NET_BUF_TAIL
= 0, // Trim or allocate space from tail
510 NET_VECTOR_OWN_FIRST
= 0x01, // We allocated the 1st block in the vector
513 #define NET_CHECK_SIGNATURE(PData, SIGNATURE) \
514 ASSERT (((PData) != NULL) && ((PData)->Signature == (SIGNATURE)))
516 #define NET_SWAP_SHORT(Value) \
517 ((((Value) & 0xff) << 8) | (((Value) >> 8) & 0xff))
520 // Single memory block in the vector.
523 UINT32 Len
; // The block's length
524 UINT8
*Bulk
; // The block's Data
527 typedef VOID (*NET_VECTOR_EXT_FREE
) (VOID
*Arg
);
530 //NET_VECTOR contains several blocks to hold all packet's
531 //fragments and other house-keeping stuff for sharing. It
532 //doesn't specify the where actual packet fragment begins.
536 INTN RefCnt
; // Reference count to share NET_VECTOR.
537 NET_VECTOR_EXT_FREE Free
; // external function to free NET_VECTOR
538 VOID
*Arg
; // opeque argument to Free
539 UINT32 Flag
; // Flags, NET_VECTOR_OWN_FIRST
540 UINT32 Len
; // Total length of the assocated BLOCKs
547 //NET_BLOCK_OP operate on the NET_BLOCK, It specifies
548 //where the actual fragment begins and where it ends
551 UINT8
*BlockHead
; // Block's head, or the smallest valid Head
552 UINT8
*BlockTail
; // Block's tail. BlockTail-BlockHead=block length
553 UINT8
*Head
; // 1st byte of the data in the block
554 UINT8
*Tail
; // Tail of the data in the block, Tail-Head=Size
555 UINT32 Size
; // The size of the data
560 //NET_BUF is the buffer manage structure used by the
561 //network stack. Every network packet may be fragmented,
562 //and contains multiple fragments. The Vector points to
563 //memory blocks used by the each fragment, and BlockOp
564 //specifies where each fragment begins and ends.
566 //It also contains a opaque area for protocol to store
567 //per-packet informations. Protocol must be caution not
568 //to overwrite the members after that.
573 NET_LIST_ENTRY List
; // The List this NET_BUF is on
575 IP4_HEAD
*Ip
; // Network layer header, for fast access
576 TCP_HEAD
*Tcp
; // Transport layer header, for fast access
577 UINT8 ProtoData
[NET_PROTO_DATA
]; //Protocol specific data
579 NET_VECTOR
*Vector
; // The vector containing the packet
581 UINT32 BlockOpNum
; // Total number of BlockOp in the buffer
582 UINT32 TotalSize
; // Total size of the actual packet
583 NET_BLOCK_OP BlockOp
[1]; // Specify the position of actual packet
588 //A queue of NET_BUFs, It is just a thin extension of
594 NET_LIST_ENTRY List
; // The List this buffer queue is on
596 NET_LIST_ENTRY BufList
; // list of queued buffers
597 UINT32 BufSize
; // total length of DATA in the buffers
598 UINT32 BufNum
; // total number of buffers on the chain
602 // Pseudo header for TCP and UDP checksum
615 // The fragment entry table used in network interfaces. This is
616 // the same as NET_BLOCK now. Use two different to distinguish
617 // the two in case that NET_BLOCK be enhanced later.
624 #define NET_GET_REF(PData) ((PData)->RefCnt++)
625 #define NET_PUT_REF(PData) ((PData)->RefCnt--)
626 #define NETBUF_FROM_PROTODATA(Info) _CR((Info), NET_BUF, ProtoData)
628 #define NET_BUF_SHARED(Buf) \
629 (((Buf)->RefCnt > 1) || ((Buf)->Vector->RefCnt > 1))
631 #define NET_VECTOR_SIZE(BlockNum) \
632 (sizeof (NET_VECTOR) + ((BlockNum) - 1) * sizeof (NET_BLOCK))
634 #define NET_BUF_SIZE(BlockOpNum) \
635 (sizeof (NET_BUF) + ((BlockOpNum) - 1) * sizeof (NET_BLOCK_OP))
637 #define NET_HEADSPACE(BlockOp) \
638 (UINTN)((BlockOp)->Head - (BlockOp)->BlockHead)
640 #define NET_TAILSPACE(BlockOp) \
641 (UINTN)((BlockOp)->BlockTail - (BlockOp)->Tail)
658 OUT UINT32
*Index OPTIONAL
669 IN NET_BUF
*Duplicate OPTIONAL
,
711 IN NET_FRAGMENT
*ExtFragment
,
715 IN NET_VECTOR_EXT_FREE ExtFree
,
716 IN VOID
*Arg OPTIONAL
722 IN NET_FRAGMENT
*ExtFragment
,
728 IN NET_LIST_ENTRY
*BufList
,
731 IN NET_VECTOR_EXT_FREE ExtFree
,
732 IN VOID
*Arg OPTIONAL
737 IN NET_LIST_ENTRY
*Head
742 IN NET_BUF_QUEUE
*NbufQue
752 IN NET_BUF_QUEUE
*NbufQue
757 IN NET_BUF_QUEUE
*NbufQue
762 IN NET_BUF_QUEUE
*NbufQue
,
768 IN NET_BUF_QUEUE
*NbufQue
,
776 IN NET_BUF_QUEUE
*NbufQue
,
782 IN NET_BUF_QUEUE
*NbufQue
803 NetPseudoHeadChecksum (
811 // The debug level definition. This value is also used as the
812 // syslog's servity level. Don't change it.
815 NETDEBUG_LEVEL_TRACE
= 5,
816 NETDEBUG_LEVEL_WARNING
= 4,
817 NETDEBUG_LEVEL_ERROR
= 3,
820 #ifdef EFI_NETWORK_STACK_DEBUG
823 // The debug output expects the ASCII format string, Use %a to print ASCII
824 // string, and %s to print UNICODE string. PrintArg must be enclosed in ().
825 // For example: NET_DEBUG_TRACE ("Tcp", ("State transit to %a\n", Name));
827 #define NET_DEBUG_TRACE(Module, PrintArg) \
829 NETDEBUG_LEVEL_TRACE, \
833 NetDebugASPrint PrintArg \
836 #define NET_DEBUG_WARNING(Module, PrintArg) \
838 NETDEBUG_LEVEL_WARNING, \
842 NetDebugASPrint PrintArg \
845 #define NET_DEBUG_ERROR(Module, PrintArg) \
847 NETDEBUG_LEVEL_ERROR, \
851 NetDebugASPrint PrintArg \
855 #define NET_DEBUG_TRACE(Module, PrintString)
856 #define NET_DEBUG_WARNING(Module, PrintString)
857 #define NET_DEBUG_ERROR(Module, PrintString)
876 // Network debug message is sent out as syslog.
879 NET_SYSLOG_FACILITY
= 16, // Syslog local facility local use
880 NET_SYSLOG_PACKET_LEN
= 512,
881 NET_DEBUG_MSG_LEN
= 470, // 512 - (ether+ip+udp head length)
882 NET_SYSLOG_TX_TIMEOUT
= 500 *1000 *10, // 500ms