3 Copyright (c) 2006, 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.
25 This function is used to assign a station address to the ARP cache for this instance
26 of the ARP driver. A call to this function with the ConfigData field set to NULL
27 will reset this ARP instance.
29 @param This Pointer to the EFI_ARP_PROTOCOL instance.
30 @param ConfigData Pointer to the EFI_ARP_CONFIG_DATA structure.
32 @retval EFI_SUCCESS The new station address was successfully
34 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
35 This is NULL. SwAddressLength is zero when
36 ConfigData is not NULL. StationAddress is NULL
37 when ConfigData is not NULL.
38 @retval EFI_ACCESS_DENIED The SwAddressType, SwAddressLength, or
39 StationAddress is different from the one that is
41 @retval EFI_OUT_OF_RESOURCES Storage for the new StationAddress could not be
48 IN EFI_ARP_PROTOCOL
*This
,
49 IN EFI_ARP_CONFIG_DATA
*ConfigData OPTIONAL
53 ARP_INSTANCE_DATA
*Instance
;
56 return EFI_INVALID_PARAMETER
;
59 if ((ConfigData
!= NULL
) &&
60 ((ConfigData
->SwAddressLength
== 0) ||
61 (ConfigData
->StationAddress
== NULL
) ||
62 (ConfigData
->SwAddressType
<= 1500))) {
63 return EFI_INVALID_PARAMETER
;
66 Instance
= ARP_INSTANCE_DATA_FROM_THIS (This
);
68 if (EFI_ERROR (NET_TRYLOCK (&Instance
->ArpService
->Lock
))) {
69 return EFI_ACCESS_DENIED
;
73 // Configure this instance, the ConfigData has already passed the basic checks.
75 Status
= ArpConfigureInstance (Instance
, ConfigData
);
77 NET_UNLOCK (&Instance
->ArpService
->Lock
);
84 This function is used to insert entries into the ARP cache.
86 @param This Pointer to the EFI_ARP_PROTOCOL instance.
87 @param DenyFlag Set to TRUE if this entry is a deny entry. Set to
88 FALSE if this entry is a normal entry.
89 @param TargetSwAddress Pointer to a protocol address to add (or deny).
90 May be set to NULL if DenyFlag is TRUE.
91 @param TargetHwAddress Pointer to a hardware address to add (or deny).
92 May be set to NULL if DenyFlag is TRUE.
93 @param TimeoutValue Time in 100-ns units that this entry will remain
94 in the ARP cache. A value of zero means that the
95 entry is permanent. A nonzero value will override
96 the one given by Configure() if the entry to be
97 added is a dynamic entry.
98 @param Overwrite If TRUE, the matching cache entry will be
99 overwritten with the supplied parameters. If
100 FALSE, EFI_ACCESS_DENIED is returned if the
101 corresponding cache entry already exists.
103 @retval EFI_SUCCESS The entry has been added or updated.
104 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
105 This is NULL. DenyFlag is FALSE and
106 TargetHwAddress is NULL. DenyFlag is FALSE and
107 TargetSwAddress is NULL. TargetHwAddress is NULL
108 and TargetSwAddress is NULL. Both TargetSwAddress
109 and TargetHwAddress are not NULL when DenyFlag is
111 @retval EFI_OUT_OF_RESOURCES The new ARP cache entry could not be allocated.
112 @retval EFI_ACCESS_DENIED The ARP cache entry already exists and Overwrite
114 @retval EFI_NOT_STARTED The ARP driver instance has not been configured.
120 IN EFI_ARP_PROTOCOL
*This
,
122 IN VOID
*TargetSwAddress OPTIONAL
,
123 IN VOID
*TargetHwAddress OPTIONAL
,
124 IN UINT32 TimeoutValue
,
129 ARP_INSTANCE_DATA
*Instance
;
130 ARP_SERVICE_DATA
*ArpService
;
131 ARP_CACHE_ENTRY
*CacheEntry
;
132 EFI_SIMPLE_NETWORK_MODE
*SnpMode
;
133 NET_ARP_ADDRESS MatchAddress
[2];
136 return EFI_INVALID_PARAMETER
;
139 if (((!DenyFlag
) && ((TargetHwAddress
== NULL
) || (TargetSwAddress
== NULL
))) ||
140 (DenyFlag
&& (TargetHwAddress
!= NULL
) && (TargetSwAddress
!= NULL
)) ||
141 ((TargetHwAddress
== NULL
) && (TargetSwAddress
== NULL
))) {
142 return EFI_INVALID_PARAMETER
;
145 Instance
= ARP_INSTANCE_DATA_FROM_THIS (This
);
147 if (!Instance
->Configured
) {
148 return EFI_NOT_STARTED
;
151 Status
= EFI_SUCCESS
;
152 ArpService
= Instance
->ArpService
;
153 SnpMode
= &Instance
->ArpService
->SnpMode
;
156 // Fill the hardware address part in the MatchAddress.
158 MatchAddress
[Hardware
].Type
= SnpMode
->IfType
;
159 MatchAddress
[Hardware
].Length
= (UINT8
) SnpMode
->HwAddressSize
;
160 MatchAddress
[Hardware
].AddressPtr
= TargetHwAddress
;
163 // Fill the software address part in the MatchAddress.
165 MatchAddress
[Protocol
].Type
= Instance
->ConfigData
.SwAddressType
;
166 MatchAddress
[Protocol
].Length
= Instance
->ConfigData
.SwAddressLength
;
167 MatchAddress
[Protocol
].AddressPtr
= TargetSwAddress
;
169 if (EFI_ERROR (NET_TRYLOCK (&ArpService
->Lock
))) {
170 return EFI_ACCESS_DENIED
;
174 // See whether the entry to add exists. Check the DeinedCacheTable first.
176 CacheEntry
= ArpFindDeniedCacheEntry (
178 &MatchAddress
[Protocol
],
179 &MatchAddress
[Hardware
]
182 if (CacheEntry
== NULL
) {
184 // Check the ResolvedCacheTable
186 CacheEntry
= ArpFindNextCacheEntryInTable (
187 &ArpService
->ResolvedCacheTable
,
190 &MatchAddress
[Protocol
],
191 &MatchAddress
[Hardware
]
195 if ((CacheEntry
!= NULL
) && !Overwrite
) {
197 // The entry to add exists, if not Overwirte, deny this add request.
199 Status
= EFI_ACCESS_DENIED
;
203 if ((CacheEntry
== NULL
) && (TargetSwAddress
!= NULL
)) {
205 // Check whether there are pending requests matching the entry to be added.
207 CacheEntry
= ArpFindNextCacheEntryInTable (
208 &ArpService
->PendingRequestTable
,
211 &MatchAddress
[Protocol
],
216 if (CacheEntry
!= NULL
) {
218 // Remove it from the Table.
220 NetListRemoveEntry (&CacheEntry
->List
);
223 // It's a new entry, allocate memory for the entry.
225 CacheEntry
= ArpAllocCacheEntry (Instance
);
227 if (CacheEntry
== NULL
) {
228 ARP_DEBUG_ERROR (("ArpAdd: Failed to allocate pool for CacheEntry.\n"));
229 Status
= EFI_OUT_OF_RESOURCES
;
235 // Overwrite these parameters.
237 CacheEntry
->DefaultDecayTime
= TimeoutValue
;
238 CacheEntry
->DecayTime
= TimeoutValue
;
241 // Fill in the addresses.
243 ArpFillAddressInCacheEntry (
245 &MatchAddress
[Hardware
],
246 &MatchAddress
[Protocol
]
250 // Inform the user if there is any.
252 ArpAddressResolved (CacheEntry
, NULL
, NULL
);
255 // Add this CacheEntry to the corresponding CacheTable.
258 NetListInsertHead (&ArpService
->DeniedCacheTable
, &CacheEntry
->List
);
260 NetListInsertHead (&ArpService
->ResolvedCacheTable
, &CacheEntry
->List
);
265 NET_UNLOCK (&ArpService
->Lock
);
272 This function searches the ARP cache for matching entries and allocates a buffer into
273 which those entries are copied.
275 @param This Pointer to the EFI_ARP_PROTOCOL instance.
276 @param BySwAddress Set to TRUE to look for matching software protocol
277 addresses. Set to FALSE to look for matching
278 hardware protocol addresses.
279 @param AddressBuffer Pointer to address buffer. Set to NULL to match
281 @param EntryLength The size of an entry in the entries buffer.
282 @param EntryCount The number of ARP cache entries that are found by
283 the specified criteria.
284 @param Entries Pointer to the buffer that will receive the ARP
286 @param Refresh Set to TRUE to refresh the timeout value of the
287 matching ARP cache entry.
289 @retval EFI_SUCCESS The requested ARP cache entries were copied into
291 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
292 This is NULL. Both EntryCount and EntryLength are
293 NULL, when Refresh is FALSE.
294 @retval EFI_NOT_FOUND No matching entries were found.
295 @retval EFI_NOT_STARTED The ARP driver instance has not been configured.
301 IN EFI_ARP_PROTOCOL
*This
,
302 IN BOOLEAN BySwAddress
,
303 IN VOID
*AddressBuffer OPTIONAL
,
304 OUT UINT32
*EntryLength OPTIONAL
,
305 OUT UINT32
*EntryCount OPTIONAL
,
306 OUT EFI_ARP_FIND_DATA
**Entries OPTIONAL
,
311 ARP_INSTANCE_DATA
*Instance
;
312 ARP_SERVICE_DATA
*ArpService
;
314 if ((This
== NULL
) ||
315 (!Refresh
&& (EntryCount
== NULL
) && (EntryLength
== NULL
)) ||
316 ((Entries
!= NULL
) && ((EntryLength
== NULL
) || (EntryCount
== NULL
)))) {
317 return EFI_INVALID_PARAMETER
;
320 Instance
= ARP_INSTANCE_DATA_FROM_THIS (This
);
321 ArpService
= Instance
->ArpService
;
323 if (!Instance
->Configured
) {
324 return EFI_NOT_STARTED
;
327 if (EFI_ERROR (NET_TRYLOCK (&ArpService
->Lock
))) {
328 return EFI_ACCESS_DENIED
;
332 // All the check passed, find the cache entries now.
334 Status
= ArpFindCacheEntry (
344 NET_UNLOCK (&ArpService
->Lock
);
351 This function removes specified ARP cache entries.
353 @param This Pointer to the EFI_ARP_PROTOCOL instance.
354 @param BySwAddress Set to TRUE to delete matching protocol addresses.
355 Set to FALSE to delete matching hardware
357 @param AddressBuffer Pointer to the address buffer that is used as a
358 key to look for the cache entry. Set to NULL to
361 @retval EFI_SUCCESS The entry was removed from the ARP cache.
362 @retval EFI_INVALID_PARAMETER This is NULL.
363 @retval EFI_NOT_FOUND The specified deletion key was not found.
364 @retval EFI_NOT_STARTED The ARP driver instance has not been configured.
370 IN EFI_ARP_PROTOCOL
*This
,
371 IN BOOLEAN BySwAddress
,
372 IN VOID
*AddressBuffer OPTIONAL
375 ARP_INSTANCE_DATA
*Instance
;
376 ARP_SERVICE_DATA
*ArpService
;
380 return EFI_INVALID_PARAMETER
;
383 Instance
= ARP_INSTANCE_DATA_FROM_THIS (This
);
385 if (!Instance
->Configured
) {
386 return EFI_NOT_STARTED
;
389 ArpService
= Instance
->ArpService
;
391 if (EFI_ERROR (NET_TRYLOCK (&ArpService
->Lock
))) {
392 return EFI_ACCESS_DENIED
;
396 // Delete the specified cache entries.
398 Count
= ArpDeleteCacheEntry (Instance
, BySwAddress
, AddressBuffer
, TRUE
);
400 NET_UNLOCK (&ArpService
->Lock
);
402 return (Count
== 0) ? EFI_NOT_FOUND
: EFI_SUCCESS
;
407 This function delete all dynamic entries from the ARP cache that match the specified
408 software protocol type.
410 @param This Pointer to the EFI_ARP_PROTOCOL instance.
412 @retval EFI_SUCCESS The cache has been flushed.
413 @retval EFI_INVALID_PARAMETER This is NULL.
414 @retval EFI_NOT_FOUND There are no matching dynamic cache entries.
415 @retval EFI_NOT_STARTED The ARP driver instance has not been configured.
421 IN EFI_ARP_PROTOCOL
*This
424 ARP_INSTANCE_DATA
*Instance
;
425 ARP_SERVICE_DATA
*ArpService
;
429 return EFI_INVALID_PARAMETER
;
432 Instance
= ARP_INSTANCE_DATA_FROM_THIS (This
);
434 if (!Instance
->Configured
) {
435 return EFI_NOT_STARTED
;
438 ArpService
= Instance
->ArpService
;
440 if (EFI_ERROR (NET_TRYLOCK (&ArpService
->Lock
))) {
441 return EFI_ACCESS_DENIED
;
445 // Delete the dynamic entries from the cache table.
447 Count
= ArpDeleteCacheEntry (Instance
, FALSE
, NULL
, FALSE
);
449 NET_UNLOCK (&ArpService
->Lock
);
451 return (Count
== 0) ? EFI_NOT_FOUND
: EFI_SUCCESS
;
456 This function tries to resolve the TargetSwAddress and optionally returns a
457 TargetHwAddress if it already exists in the ARP cache.
459 @param This Pointer to the EFI_ARP_PROTOCOL instance.
460 @param TargetSwAddress Pointer to the protocol address to resolve.
461 @param ResolvedEvent Pointer to the event that will be signaled when
462 the address is resolved or some error occurs.
463 @param TargetHwAddress Pointer to the buffer for the resolved hardware
464 address in network byte order.
466 @retval EFI_SUCCESS The data is copied from the ARP cache into the
467 TargetHwAddress buffer.
468 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
469 This is NULL. TargetHwAddress is NULL.
470 @retval EFI_ACCESS_DENIED The requested address is not present in the normal
471 ARP cache but is present in the deny address list.
472 Outgoing traffic to that address is forbidden.
473 @retval EFI_NOT_STARTED The ARP driver instance has not been configured.
474 @retval EFI_NOT_READY The request has been started and is not finished.
480 IN EFI_ARP_PROTOCOL
*This
,
481 IN VOID
*TargetSwAddress OPTIONAL
,
482 IN EFI_EVENT ResolvedEvent OPTIONAL
,
483 OUT VOID
*TargetHwAddress
487 ARP_INSTANCE_DATA
*Instance
;
488 ARP_SERVICE_DATA
*ArpService
;
489 EFI_SIMPLE_NETWORK_MODE
*SnpMode
;
490 ARP_CACHE_ENTRY
*CacheEntry
;
491 NET_ARP_ADDRESS HardwareAddress
;
492 NET_ARP_ADDRESS ProtocolAddress
;
493 USER_REQUEST_CONTEXT
*RequestContext
;
495 if ((This
== NULL
) || (TargetHwAddress
== NULL
)) {
496 return EFI_INVALID_PARAMETER
;
499 Instance
= ARP_INSTANCE_DATA_FROM_THIS (This
);
501 if (!Instance
->Configured
) {
502 return EFI_NOT_STARTED
;
505 Status
= EFI_SUCCESS
;
506 ArpService
= Instance
->ArpService
;
507 SnpMode
= &ArpService
->SnpMode
;
509 if ((TargetSwAddress
== NULL
) ||
510 ((Instance
->ConfigData
.SwAddressType
== IPv4_ETHER_PROTO_TYPE
) &&
511 IP4_IS_LOCAL_BROADCAST (*((UINT32
*)TargetSwAddress
)))) {
513 // Return the hardware broadcast address.
515 NetCopyMem (TargetHwAddress
, &SnpMode
->BroadcastAddress
, SnpMode
->HwAddressSize
);
520 if ((Instance
->ConfigData
.SwAddressType
== IPv4_ETHER_PROTO_TYPE
) &&
521 IP4_IS_MULTICAST (NTOHL (*((UINT32
*)TargetSwAddress
)))) {
523 // If the software address is an IPv4 multicast address, invoke Mnp to
524 // resolve the address.
526 Status
= ArpService
->Mnp
->McastIpToMac (
535 HardwareAddress
.Type
= SnpMode
->IfType
;
536 HardwareAddress
.Length
= (UINT8
)SnpMode
->HwAddressSize
;
537 HardwareAddress
.AddressPtr
= NULL
;
539 ProtocolAddress
.Type
= Instance
->ConfigData
.SwAddressType
;
540 ProtocolAddress
.Length
= Instance
->ConfigData
.SwAddressLength
;
541 ProtocolAddress
.AddressPtr
= TargetSwAddress
;
544 // Initialize the TargetHwAddrss to a zero address.
546 NetZeroMem (TargetHwAddress
, SnpMode
->HwAddressSize
);
548 if (EFI_ERROR (NET_TRYLOCK (&ArpService
->Lock
))) {
549 return EFI_ACCESS_DENIED
;
553 // Check whether the software address is in the denied table.
555 CacheEntry
= ArpFindDeniedCacheEntry (ArpService
, &ProtocolAddress
, NULL
);
556 if (CacheEntry
!= NULL
) {
557 Status
= EFI_ACCESS_DENIED
;
562 // Check whether the software address is already resolved.
564 CacheEntry
= ArpFindNextCacheEntryInTable (
565 &ArpService
->ResolvedCacheTable
,
571 if (CacheEntry
!= NULL
) {
573 // Resolved, copy the address into the user buffer.
577 CacheEntry
->Addresses
[Hardware
].AddressPtr
,
578 CacheEntry
->Addresses
[Hardware
].Length
584 if (ResolvedEvent
== NULL
) {
585 Status
= EFI_NOT_READY
;
590 // Create a request context for this arp request.
592 RequestContext
= NetAllocatePool (sizeof(USER_REQUEST_CONTEXT
));
593 if (RequestContext
== NULL
) {
594 ARP_DEBUG_ERROR (("ArpRequest: Allocate memory for RequestContext failed.\n"));
596 Status
= EFI_OUT_OF_RESOURCES
;
600 RequestContext
->Instance
= Instance
;
601 RequestContext
->UserRequestEvent
= ResolvedEvent
;
602 RequestContext
->UserHwAddrBuffer
= TargetHwAddress
;
603 NetListInit (&RequestContext
->List
);
606 // Check whether there is a same request.
608 CacheEntry
= ArpFindNextCacheEntryInTable (
609 &ArpService
->PendingRequestTable
,
615 if (CacheEntry
!= NULL
) {
617 CacheEntry
->NextRetryTime
= Instance
->ConfigData
.RetryTimeOut
;
618 CacheEntry
->RetryCount
= Instance
->ConfigData
.RetryCount
;
621 // Allocate a cache entry for this request.
623 CacheEntry
= ArpAllocCacheEntry (Instance
);
624 if (CacheEntry
== NULL
) {
625 ARP_DEBUG_ERROR (("ArpRequest: Allocate memory for CacheEntry failed.\n"));
626 NetFreePool (RequestContext
);
628 Status
= EFI_OUT_OF_RESOURCES
;
633 // Fill the software address.
635 ArpFillAddressInCacheEntry (CacheEntry
, &HardwareAddress
, &ProtocolAddress
);
638 // Add this entry into the PendingRequestTable.
640 NetListInsertTail (&ArpService
->PendingRequestTable
, &CacheEntry
->List
);
644 // Link this request context into the cache entry.
646 NetListInsertHead (&CacheEntry
->UserRequestList
, &RequestContext
->List
);
649 // Send out the ARP Request frame.
651 ArpSendFrame (Instance
, CacheEntry
, ARP_OPCODE_REQUEST
);
652 Status
= EFI_NOT_READY
;
656 NET_UNLOCK (&ArpService
->Lock
);
660 if ((ResolvedEvent
!= NULL
) && (Status
== EFI_SUCCESS
)) {
661 gBS
->SignalEvent (ResolvedEvent
);
669 This function aborts the previous ARP request (identified by This, TargetSwAddress
670 and ResolvedEvent) that is issued by EFI_ARP_PROTOCOL.Request().
672 @param This Pointer to the EFI_ARP_PROTOCOL instance.
673 @param TargetSwAddress Pointer to the protocol address in previous
675 @param ResolvedEvent Pointer to the event that is used as the
676 notification event in previous request session.
678 @retval EFI_SUCCESS The pending request session(s) is/are aborted and
679 corresponding event(s) is/are signaled.
680 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
681 This is NULL. TargetSwAddress is not NULL and
682 ResolvedEvent is NULL. TargetSwAddress is NULL and
683 ResolvedEvent is not NULL.
684 @retval EFI_NOT_STARTED The ARP driver instance has not been configured.
685 @retval EFI_NOT_FOUND The request is not issued by
686 EFI_ARP_PROTOCOL.Request().
692 IN EFI_ARP_PROTOCOL
*This
,
693 IN VOID
*TargetSwAddress OPTIONAL
,
694 IN EFI_EVENT ResolvedEvent OPTIONAL
697 ARP_INSTANCE_DATA
*Instance
;
698 ARP_SERVICE_DATA
*ArpService
;
701 if ((This
== NULL
) ||
702 ((TargetSwAddress
!= NULL
) && (ResolvedEvent
== NULL
)) ||
703 ((TargetSwAddress
== NULL
) && (ResolvedEvent
!= NULL
))) {
704 return EFI_INVALID_PARAMETER
;
707 Instance
= ARP_INSTANCE_DATA_FROM_THIS (This
);
709 if (!Instance
->Configured
) {
710 return EFI_NOT_STARTED
;
713 ArpService
= Instance
->ArpService
;
715 if (EFI_ERROR (NET_TRYLOCK (&ArpService
->Lock
))) {
716 return EFI_ACCESS_DENIED
;
720 // Cancel the specified request.
722 Count
= ArpCancelRequest (Instance
, TargetSwAddress
, ResolvedEvent
);
724 NET_UNLOCK (&ArpService
->Lock
);
726 return (Count
== 0) ? EFI_NOT_FOUND
: EFI_SUCCESS
;