]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/ArpDxe/ArpMain.c
eb1b082a21c0b2b9f39eb5976f0e1c83a348bd40
[mirror_edk2.git] / MdeModulePkg / Universal / Network / ArpDxe / ArpMain.c
1 /** @file
2
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
8
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.
11
12 Module Name:
13
14 ArpMain.c
15
16 Abstract:
17
18
19 **/
20
21 #include "ArpImpl.h"
22
23
24 /**
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.
28
29 @param This Pointer to the EFI_ARP_PROTOCOL instance.
30 @param ConfigData Pointer to the EFI_ARP_CONFIG_DATA structure.
31
32 @retval EFI_SUCCESS The new station address was successfully
33 registered.
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
40 already registered.
41 @retval EFI_OUT_OF_RESOURCES Storage for the new StationAddress could not be
42 allocated.
43
44 **/
45 EFI_STATUS
46 EFIAPI
47 ArpConfigure (
48 IN EFI_ARP_PROTOCOL *This,
49 IN EFI_ARP_CONFIG_DATA *ConfigData OPTIONAL
50 )
51 {
52 EFI_STATUS Status;
53 ARP_INSTANCE_DATA *Instance;
54
55 if (This == NULL) {
56 return EFI_INVALID_PARAMETER;
57 }
58
59 if ((ConfigData != NULL) &&
60 ((ConfigData->SwAddressLength == 0) ||
61 (ConfigData->StationAddress == NULL) ||
62 (ConfigData->SwAddressType <= 1500))) {
63 return EFI_INVALID_PARAMETER;
64 }
65
66 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
67
68 if (EFI_ERROR (NET_TRYLOCK (&Instance->ArpService->Lock))) {
69 return EFI_ACCESS_DENIED;
70 }
71
72 //
73 // Configure this instance, the ConfigData has already passed the basic checks.
74 //
75 Status = ArpConfigureInstance (Instance, ConfigData);
76
77 NET_UNLOCK (&Instance->ArpService->Lock);
78
79 return Status;
80 }
81
82
83 /**
84 This function is used to insert entries into the ARP cache.
85
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.
102
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
110 TRUE.
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
113 is not true.
114 @retval EFI_NOT_STARTED The ARP driver instance has not been configured.
115
116 **/
117 EFI_STATUS
118 EFIAPI
119 ArpAdd (
120 IN EFI_ARP_PROTOCOL *This,
121 IN BOOLEAN DenyFlag,
122 IN VOID *TargetSwAddress OPTIONAL,
123 IN VOID *TargetHwAddress OPTIONAL,
124 IN UINT32 TimeoutValue,
125 IN BOOLEAN Overwrite
126 )
127 {
128 EFI_STATUS Status;
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];
134
135 if (This == NULL) {
136 return EFI_INVALID_PARAMETER;
137 }
138
139 if (((!DenyFlag) && ((TargetHwAddress == NULL) || (TargetSwAddress == NULL))) ||
140 (DenyFlag && (TargetHwAddress != NULL) && (TargetSwAddress != NULL)) ||
141 ((TargetHwAddress == NULL) && (TargetSwAddress == NULL))) {
142 return EFI_INVALID_PARAMETER;
143 }
144
145 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
146
147 if (!Instance->Configured) {
148 return EFI_NOT_STARTED;
149 }
150
151 Status = EFI_SUCCESS;
152 ArpService = Instance->ArpService;
153 SnpMode = &Instance->ArpService->SnpMode;
154
155 //
156 // Fill the hardware address part in the MatchAddress.
157 //
158 MatchAddress[Hardware].Type = SnpMode->IfType;
159 MatchAddress[Hardware].Length = (UINT8) SnpMode->HwAddressSize;
160 MatchAddress[Hardware].AddressPtr = TargetHwAddress;
161
162 //
163 // Fill the software address part in the MatchAddress.
164 //
165 MatchAddress[Protocol].Type = Instance->ConfigData.SwAddressType;
166 MatchAddress[Protocol].Length = Instance->ConfigData.SwAddressLength;
167 MatchAddress[Protocol].AddressPtr = TargetSwAddress;
168
169 if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {
170 return EFI_ACCESS_DENIED;
171 }
172
173 //
174 // See whether the entry to add exists. Check the DeinedCacheTable first.
175 //
176 CacheEntry = ArpFindDeniedCacheEntry (
177 ArpService,
178 &MatchAddress[Protocol],
179 &MatchAddress[Hardware]
180 );
181
182 if (CacheEntry == NULL) {
183 //
184 // Check the ResolvedCacheTable
185 //
186 CacheEntry = ArpFindNextCacheEntryInTable (
187 &ArpService->ResolvedCacheTable,
188 NULL,
189 ByBoth,
190 &MatchAddress[Protocol],
191 &MatchAddress[Hardware]
192 );
193 }
194
195 if ((CacheEntry != NULL) && !Overwrite) {
196 //
197 // The entry to add exists, if not Overwirte, deny this add request.
198 //
199 Status = EFI_ACCESS_DENIED;
200 goto UNLOCK_EXIT;
201 }
202
203 if ((CacheEntry == NULL) && (TargetSwAddress != NULL)) {
204 //
205 // Check whether there are pending requests matching the entry to be added.
206 //
207 CacheEntry = ArpFindNextCacheEntryInTable (
208 &ArpService->PendingRequestTable,
209 NULL,
210 ByProtoAddress,
211 &MatchAddress[Protocol],
212 NULL
213 );
214 }
215
216 if (CacheEntry != NULL) {
217 //
218 // Remove it from the Table.
219 //
220 NetListRemoveEntry (&CacheEntry->List);
221 } else {
222 //
223 // It's a new entry, allocate memory for the entry.
224 //
225 CacheEntry = ArpAllocCacheEntry (Instance);
226
227 if (CacheEntry == NULL) {
228 ARP_DEBUG_ERROR (("ArpAdd: Failed to allocate pool for CacheEntry.\n"));
229 Status = EFI_OUT_OF_RESOURCES;
230 goto UNLOCK_EXIT;
231 }
232 }
233
234 //
235 // Overwrite these parameters.
236 //
237 CacheEntry->DefaultDecayTime = TimeoutValue;
238 CacheEntry->DecayTime = TimeoutValue;
239
240 //
241 // Fill in the addresses.
242 //
243 ArpFillAddressInCacheEntry (
244 CacheEntry,
245 &MatchAddress[Hardware],
246 &MatchAddress[Protocol]
247 );
248
249 //
250 // Inform the user if there is any.
251 //
252 ArpAddressResolved (CacheEntry, NULL, NULL);
253
254 //
255 // Add this CacheEntry to the corresponding CacheTable.
256 //
257 if (DenyFlag) {
258 NetListInsertHead (&ArpService->DeniedCacheTable, &CacheEntry->List);
259 } else {
260 NetListInsertHead (&ArpService->ResolvedCacheTable, &CacheEntry->List);
261 }
262
263 UNLOCK_EXIT:
264
265 NET_UNLOCK (&ArpService->Lock);
266
267 return Status;
268 }
269
270
271 /**
272 This function searches the ARP cache for matching entries and allocates a buffer into
273 which those entries are copied.
274
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
280 all addresses.
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
285 cache entries.
286 @param Refresh Set to TRUE to refresh the timeout value of the
287 matching ARP cache entry.
288
289 @retval EFI_SUCCESS The requested ARP cache entries were copied into
290 the buffer.
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.
296
297 **/
298 EFI_STATUS
299 EFIAPI
300 ArpFind (
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,
307 IN BOOLEAN Refresh
308 )
309 {
310 EFI_STATUS Status;
311 ARP_INSTANCE_DATA *Instance;
312 ARP_SERVICE_DATA *ArpService;
313
314 if ((This == NULL) ||
315 (!Refresh && (EntryCount == NULL) && (EntryLength == NULL)) ||
316 ((Entries != NULL) && ((EntryLength == NULL) || (EntryCount == NULL)))) {
317 return EFI_INVALID_PARAMETER;
318 }
319
320 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
321 ArpService = Instance->ArpService;
322
323 if (!Instance->Configured) {
324 return EFI_NOT_STARTED;
325 }
326
327 if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {
328 return EFI_ACCESS_DENIED;
329 }
330
331 //
332 // All the check passed, find the cache entries now.
333 //
334 Status = ArpFindCacheEntry (
335 Instance,
336 BySwAddress,
337 AddressBuffer,
338 EntryLength,
339 EntryCount,
340 Entries,
341 Refresh
342 );
343
344 NET_UNLOCK (&ArpService->Lock);
345
346 return Status;
347 }
348
349
350 /**
351 This function removes specified ARP cache entries.
352
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
356 addresses.
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
359 delete all entries.
360
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.
365
366 **/
367 EFI_STATUS
368 EFIAPI
369 ArpDelete (
370 IN EFI_ARP_PROTOCOL *This,
371 IN BOOLEAN BySwAddress,
372 IN VOID *AddressBuffer OPTIONAL
373 )
374 {
375 ARP_INSTANCE_DATA *Instance;
376 ARP_SERVICE_DATA *ArpService;
377 UINTN Count;
378
379 if (This == NULL) {
380 return EFI_INVALID_PARAMETER;
381 }
382
383 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
384
385 if (!Instance->Configured) {
386 return EFI_NOT_STARTED;
387 }
388
389 ArpService = Instance->ArpService;
390
391 if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {
392 return EFI_ACCESS_DENIED;
393 }
394
395 //
396 // Delete the specified cache entries.
397 //
398 Count = ArpDeleteCacheEntry (Instance, BySwAddress, AddressBuffer, TRUE);
399
400 NET_UNLOCK (&ArpService->Lock);
401
402 return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
403 }
404
405
406 /**
407 This function delete all dynamic entries from the ARP cache that match the specified
408 software protocol type.
409
410 @param This Pointer to the EFI_ARP_PROTOCOL instance.
411
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.
416
417 **/
418 EFI_STATUS
419 EFIAPI
420 ArpFlush (
421 IN EFI_ARP_PROTOCOL *This
422 )
423 {
424 ARP_INSTANCE_DATA *Instance;
425 ARP_SERVICE_DATA *ArpService;
426 UINTN Count;
427
428 if (This == NULL) {
429 return EFI_INVALID_PARAMETER;
430 }
431
432 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
433
434 if (!Instance->Configured) {
435 return EFI_NOT_STARTED;
436 }
437
438 ArpService = Instance->ArpService;
439
440 if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {
441 return EFI_ACCESS_DENIED;
442 }
443
444 //
445 // Delete the dynamic entries from the cache table.
446 //
447 Count = ArpDeleteCacheEntry (Instance, FALSE, NULL, FALSE);
448
449 NET_UNLOCK (&ArpService->Lock);
450
451 return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
452 }
453
454
455 /**
456 This function tries to resolve the TargetSwAddress and optionally returns a
457 TargetHwAddress if it already exists in the ARP cache.
458
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.
465
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.
475
476 **/
477 EFI_STATUS
478 EFIAPI
479 ArpRequest (
480 IN EFI_ARP_PROTOCOL *This,
481 IN VOID *TargetSwAddress OPTIONAL,
482 IN EFI_EVENT ResolvedEvent OPTIONAL,
483 OUT VOID *TargetHwAddress
484 )
485 {
486 EFI_STATUS Status;
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;
494
495 if ((This == NULL) || (TargetHwAddress == NULL)) {
496 return EFI_INVALID_PARAMETER;
497 }
498
499 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
500
501 if (!Instance->Configured) {
502 return EFI_NOT_STARTED;
503 }
504
505 Status = EFI_SUCCESS;
506 ArpService = Instance->ArpService;
507 SnpMode = &ArpService->SnpMode;
508
509 if ((TargetSwAddress == NULL) ||
510 ((Instance->ConfigData.SwAddressType == IPv4_ETHER_PROTO_TYPE) &&
511 IP4_IS_LOCAL_BROADCAST (*((UINT32 *)TargetSwAddress)))) {
512 //
513 // Return the hardware broadcast address.
514 //
515 NetCopyMem (TargetHwAddress, &SnpMode->BroadcastAddress, SnpMode->HwAddressSize);
516
517 goto SIGNAL_USER;
518 }
519
520 if ((Instance->ConfigData.SwAddressType == IPv4_ETHER_PROTO_TYPE) &&
521 IP4_IS_MULTICAST (NTOHL (*((UINT32 *)TargetSwAddress)))) {
522 //
523 // If the software address is an IPv4 multicast address, invoke Mnp to
524 // resolve the address.
525 //
526 Status = ArpService->Mnp->McastIpToMac (
527 ArpService->Mnp,
528 FALSE,
529 TargetSwAddress,
530 TargetHwAddress
531 );
532 goto SIGNAL_USER;
533 }
534
535 HardwareAddress.Type = SnpMode->IfType;
536 HardwareAddress.Length = (UINT8)SnpMode->HwAddressSize;
537 HardwareAddress.AddressPtr = NULL;
538
539 ProtocolAddress.Type = Instance->ConfigData.SwAddressType;
540 ProtocolAddress.Length = Instance->ConfigData.SwAddressLength;
541 ProtocolAddress.AddressPtr = TargetSwAddress;
542
543 //
544 // Initialize the TargetHwAddrss to a zero address.
545 //
546 NetZeroMem (TargetHwAddress, SnpMode->HwAddressSize);
547
548 if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {
549 return EFI_ACCESS_DENIED;
550 }
551
552 //
553 // Check whether the software address is in the denied table.
554 //
555 CacheEntry = ArpFindDeniedCacheEntry (ArpService, &ProtocolAddress, NULL);
556 if (CacheEntry != NULL) {
557 Status = EFI_ACCESS_DENIED;
558 goto UNLOCK_EXIT;
559 }
560
561 //
562 // Check whether the software address is already resolved.
563 //
564 CacheEntry = ArpFindNextCacheEntryInTable (
565 &ArpService->ResolvedCacheTable,
566 NULL,
567 ByProtoAddress,
568 &ProtocolAddress,
569 NULL
570 );
571 if (CacheEntry != NULL) {
572 //
573 // Resolved, copy the address into the user buffer.
574 //
575 NetCopyMem (
576 TargetHwAddress,
577 CacheEntry->Addresses[Hardware].AddressPtr,
578 CacheEntry->Addresses[Hardware].Length
579 );
580
581 goto UNLOCK_EXIT;
582 }
583
584 if (ResolvedEvent == NULL) {
585 Status = EFI_NOT_READY;
586 goto UNLOCK_EXIT;
587 }
588
589 //
590 // Create a request context for this arp request.
591 //
592 RequestContext = NetAllocatePool (sizeof(USER_REQUEST_CONTEXT));
593 if (RequestContext == NULL) {
594 ARP_DEBUG_ERROR (("ArpRequest: Allocate memory for RequestContext failed.\n"));
595
596 Status = EFI_OUT_OF_RESOURCES;
597 goto UNLOCK_EXIT;
598 }
599
600 RequestContext->Instance = Instance;
601 RequestContext->UserRequestEvent = ResolvedEvent;
602 RequestContext->UserHwAddrBuffer = TargetHwAddress;
603 NetListInit (&RequestContext->List);
604
605 //
606 // Check whether there is a same request.
607 //
608 CacheEntry = ArpFindNextCacheEntryInTable (
609 &ArpService->PendingRequestTable,
610 NULL,
611 ByProtoAddress,
612 &ProtocolAddress,
613 NULL
614 );
615 if (CacheEntry != NULL) {
616
617 CacheEntry->NextRetryTime = Instance->ConfigData.RetryTimeOut;
618 CacheEntry->RetryCount = Instance->ConfigData.RetryCount;
619 } else {
620 //
621 // Allocate a cache entry for this request.
622 //
623 CacheEntry = ArpAllocCacheEntry (Instance);
624 if (CacheEntry == NULL) {
625 ARP_DEBUG_ERROR (("ArpRequest: Allocate memory for CacheEntry failed.\n"));
626 NetFreePool (RequestContext);
627
628 Status = EFI_OUT_OF_RESOURCES;
629 goto UNLOCK_EXIT;
630 }
631
632 //
633 // Fill the software address.
634 //
635 ArpFillAddressInCacheEntry (CacheEntry, &HardwareAddress, &ProtocolAddress);
636
637 //
638 // Add this entry into the PendingRequestTable.
639 //
640 NetListInsertTail (&ArpService->PendingRequestTable, &CacheEntry->List);
641 }
642
643 //
644 // Link this request context into the cache entry.
645 //
646 NetListInsertHead (&CacheEntry->UserRequestList, &RequestContext->List);
647
648 //
649 // Send out the ARP Request frame.
650 //
651 ArpSendFrame (Instance, CacheEntry, ARP_OPCODE_REQUEST);
652 Status = EFI_NOT_READY;
653
654 UNLOCK_EXIT:
655
656 NET_UNLOCK (&ArpService->Lock);
657
658 SIGNAL_USER:
659
660 if ((ResolvedEvent != NULL) && (Status == EFI_SUCCESS)) {
661 gBS->SignalEvent (ResolvedEvent);
662 }
663
664 return Status;
665 }
666
667
668 /**
669 This function aborts the previous ARP request (identified by This, TargetSwAddress
670 and ResolvedEvent) that is issued by EFI_ARP_PROTOCOL.Request().
671
672 @param This Pointer to the EFI_ARP_PROTOCOL instance.
673 @param TargetSwAddress Pointer to the protocol address in previous
674 request session.
675 @param ResolvedEvent Pointer to the event that is used as the
676 notification event in previous request session.
677
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().
687
688 **/
689 EFI_STATUS
690 EFIAPI
691 ArpCancel (
692 IN EFI_ARP_PROTOCOL *This,
693 IN VOID *TargetSwAddress OPTIONAL,
694 IN EFI_EVENT ResolvedEvent OPTIONAL
695 )
696 {
697 ARP_INSTANCE_DATA *Instance;
698 ARP_SERVICE_DATA *ArpService;
699 UINTN Count;
700
701 if ((This == NULL) ||
702 ((TargetSwAddress != NULL) && (ResolvedEvent == NULL)) ||
703 ((TargetSwAddress == NULL) && (ResolvedEvent != NULL))) {
704 return EFI_INVALID_PARAMETER;
705 }
706
707 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
708
709 if (!Instance->Configured) {
710 return EFI_NOT_STARTED;
711 }
712
713 ArpService = Instance->ArpService;
714
715 if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {
716 return EFI_ACCESS_DENIED;
717 }
718
719 //
720 // Cancel the specified request.
721 //
722 Count = ArpCancelRequest (Instance, TargetSwAddress, ResolvedEvent);
723
724 NET_UNLOCK (&ArpService->Lock);
725
726 return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
727 }