]> git.proxmox.com Git - mirror_edk2.git/blob - StdLib/EfiSocketLib/Ip4.c
StdLib: Fix GCC warnings/errors caused by variables being set but not used.
[mirror_edk2.git] / StdLib / EfiSocketLib / Ip4.c
1 /** @file
2 Implement the IP4 driver support for the socket layer.
3
4 Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are licensed and made available
6 under the terms and conditions of the BSD License which accompanies this
7 distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "Socket.h"
16
17
18 /**
19 Get the local socket address
20
21 This routine returns the IPv4 address associated with the local
22 socket.
23
24 This routine is called by ::EslSocketGetLocalAddress to determine the
25 network address for the SOCK_RAW socket.
26
27 @param [in] pPort Address of an ::ESL_PORT structure.
28
29 @param [out] pAddress Network address to receive the local system address
30
31 **/
32 VOID
33 EslIp4LocalAddressGet (
34 IN ESL_PORT * pPort,
35 OUT struct sockaddr * pAddress
36 )
37 {
38 struct sockaddr_in * pLocalAddress;
39 ESL_IP4_CONTEXT * pIp4;
40
41 DBG_ENTER ( );
42
43 //
44 // Return the local address
45 //
46 pIp4 = &pPort->Context.Ip4;
47 pLocalAddress = (struct sockaddr_in *)pAddress;
48 pLocalAddress->sin_family = AF_INET;
49 CopyMem ( &pLocalAddress->sin_addr,
50 &pIp4->ModeData.ConfigData.StationAddress.Addr[0],
51 sizeof ( pLocalAddress->sin_addr ));
52
53 DBG_EXIT ( );
54 }
55
56
57 /**
58 Set the local port address.
59
60 This routine sets the local port address.
61
62 This support routine is called by ::EslSocketPortAllocate.
63
64 @param [in] pPort Address of an ESL_PORT structure
65 @param [in] pSockAddr Address of a sockaddr structure that contains the
66 connection point on the local machine. An IPv4 address
67 of INADDR_ANY specifies that the connection is made to
68 all of the network stacks on the platform. Specifying a
69 specific IPv4 address restricts the connection to the
70 network stack supporting that address. Specifying zero
71 for the port causes the network layer to assign a port
72 number from the dynamic range. Specifying a specific
73 port number causes the network layer to use that port.
74
75 @param [in] bBindTest TRUE = run bind testing
76
77 @retval EFI_SUCCESS The operation was successful
78
79 **/
80 EFI_STATUS
81 EslIp4LocalAddressSet (
82 IN ESL_PORT * pPort,
83 IN CONST struct sockaddr * pSockAddr,
84 IN BOOLEAN bBindTest
85 )
86 {
87 EFI_IP4_CONFIG_DATA * pConfig;
88 CONST struct sockaddr_in * pIpAddress;
89 CONST UINT8 * pIpv4Address;
90 EFI_STATUS Status;
91
92 DBG_ENTER ( );
93
94 //
95 // Validate the address
96 //
97 pIpAddress = (struct sockaddr_in *)pSockAddr;
98 if ( INADDR_BROADCAST == pIpAddress->sin_addr.s_addr ) {
99 //
100 // The local address must not be the broadcast address
101 //
102 Status = EFI_INVALID_PARAMETER;
103 pPort->pSocket->errno = EADDRNOTAVAIL;
104 }
105 else {
106 Status = EFI_SUCCESS;
107
108 //
109 // Set the local address
110 //
111 pIpAddress = (struct sockaddr_in *)pSockAddr;
112 pIpv4Address = (UINT8 *)&pIpAddress->sin_addr.s_addr;
113 pConfig = &pPort->Context.Ip4.ModeData.ConfigData;
114 pConfig->StationAddress.Addr[0] = pIpv4Address[0];
115 pConfig->StationAddress.Addr[1] = pIpv4Address[1];
116 pConfig->StationAddress.Addr[2] = pIpv4Address[2];
117 pConfig->StationAddress.Addr[3] = pIpv4Address[3];
118
119 //
120 // Determine if the default address is used
121 //
122 pConfig->UseDefaultAddress = (BOOLEAN)( 0 == pIpAddress->sin_addr.s_addr );
123
124 //
125 // Display the local address
126 //
127 DEBUG (( DEBUG_BIND,
128 "0x%08x: Port, Local IP4 Address: %d.%d.%d.%d\r\n",
129 pPort,
130 pConfig->StationAddress.Addr[0],
131 pConfig->StationAddress.Addr[1],
132 pConfig->StationAddress.Addr[2],
133 pConfig->StationAddress.Addr[3]));
134
135 //
136 // Set the subnet mask
137 //
138 if ( pConfig->UseDefaultAddress ) {
139 pConfig->SubnetMask.Addr[0] = 0;
140 pConfig->SubnetMask.Addr[1] = 0;
141 pConfig->SubnetMask.Addr[2] = 0;
142 pConfig->SubnetMask.Addr[3] = 0;
143 }
144 else {
145 pConfig->SubnetMask.Addr[0] = 0xff;
146 pConfig->SubnetMask.Addr[1] = ( 128 <= pConfig->StationAddress.Addr[0]) ? 0xff : 0;
147 pConfig->SubnetMask.Addr[2] = ( 192 <= pConfig->StationAddress.Addr[0]) ? 0xff : 0;
148 pConfig->SubnetMask.Addr[3] = ( 224 <= pConfig->StationAddress.Addr[0]) ? 0xff : 0;
149 }
150 }
151
152 //
153 // Return the operation status
154 //
155 DBG_EXIT_STATUS ( Status );
156 return Status;
157 }
158
159
160 /**
161 Get the option value
162
163 This routine handles the IPv4 level options.
164
165 The ::EslSocketOptionGet routine calls this routine to retrieve
166 the IPv4 options one at a time by name.
167
168 @param [in] pSocket Address of an ::ESL_SOCKET structure
169 @param [in] OptionName Name of the option
170 @param [out] ppOptionData Buffer to receive address of option value
171 @param [out] pOptionLength Buffer to receive the option length
172
173 @retval EFI_SUCCESS - Socket data successfully received
174
175 **/
176 EFI_STATUS
177 EslIp4OptionGet (
178 IN ESL_SOCKET * pSocket,
179 IN int OptionName,
180 OUT CONST void ** __restrict ppOptionData,
181 OUT socklen_t * __restrict pOptionLength
182 )
183 {
184 EFI_STATUS Status;
185
186 DBG_ENTER ( );
187
188 //
189 // Assume success
190 //
191 pSocket->errno = 0;
192 Status = EFI_SUCCESS;
193
194 //
195 // Attempt to get the option
196 //
197 switch ( OptionName ) {
198 default:
199 //
200 // Option not supported
201 //
202 pSocket->errno = ENOPROTOOPT;
203 Status = EFI_INVALID_PARAMETER;
204 break;
205
206 case IP_HDRINCL:
207 *ppOptionData = (void *)&pSocket->bIncludeHeader;
208 *pOptionLength = sizeof ( pSocket->bIncludeHeader );
209 break;
210 }
211
212 //
213 // Return the operation status
214 //
215 DBG_EXIT_STATUS ( Status );
216 return Status;
217 }
218
219
220 /**
221 Set the option value
222
223 This routine handles the IPv4 level options.
224
225 The ::EslSocketOptionSet routine calls this routine to adjust
226 the IPv4 options one at a time by name.
227
228 @param [in] pSocket Address of an ::ESL_SOCKET structure
229 @param [in] OptionName Name of the option
230 @param [in] pOptionValue Buffer containing the option value
231 @param [in] OptionLength Length of the buffer in bytes
232
233 @retval EFI_SUCCESS - Option successfully set
234
235 **/
236 EFI_STATUS
237 EslIp4OptionSet (
238 IN ESL_SOCKET * pSocket,
239 IN int OptionName,
240 IN CONST void * pOptionValue,
241 IN socklen_t OptionLength
242 )
243 {
244 BOOLEAN bTrueFalse;
245 socklen_t LengthInBytes;
246 UINT8 * pOptionData;
247 EFI_STATUS Status;
248
249 DBG_ENTER ( );
250
251 //
252 // Assume success
253 //
254 pSocket->errno = 0;
255 Status = EFI_SUCCESS;
256
257 //
258 // Determine if the option protocol matches
259 //
260 LengthInBytes = 0;
261 pOptionData = NULL;
262 switch ( OptionName ) {
263 default:
264 //
265 // Protocol level not supported
266 //
267 DEBUG (( DEBUG_INFO | DEBUG_OPTION, "ERROR - Invalid protocol option\r\n" ));
268 pSocket->errno = ENOTSUP;
269 Status = EFI_UNSUPPORTED;
270 break;
271
272 case IP_HDRINCL:
273
274 //
275 // Validate the option length
276 //
277 if ( sizeof ( UINT32 ) == OptionLength ) {
278 //
279 // Restrict the input to TRUE or FALSE
280 //
281 bTrueFalse = TRUE;
282 if ( 0 == *(UINT32 *)pOptionValue ) {
283 bTrueFalse = FALSE;
284 }
285 pOptionValue = &bTrueFalse;
286
287 //
288 // Set the option value
289 //
290 pOptionData = (UINT8 *)&pSocket->bIncludeHeader;
291 LengthInBytes = sizeof ( pSocket->bIncludeHeader );
292 }
293 break;
294 }
295
296 //
297 // Return the operation status
298 //
299 DBG_EXIT_STATUS ( Status );
300 return Status;
301 }
302
303
304 /**
305 Free a receive packet
306
307 This routine performs the network specific operations necessary
308 to free a receive packet.
309
310 This routine is called by ::EslSocketPortCloseTxDone to free a
311 receive packet.
312
313 @param [in] pPacket Address of an ::ESL_PACKET structure.
314 @param [in, out] pRxBytes Address of the count of RX bytes
315
316 **/
317 VOID
318 EslIp4PacketFree (
319 IN ESL_PACKET * pPacket,
320 IN OUT size_t * pRxBytes
321 )
322 {
323 EFI_IP4_RECEIVE_DATA * pRxData;
324 DBG_ENTER ( );
325
326 //
327 // Account for the receive bytes
328 //
329 pRxData = pPacket->Op.Ip4Rx.pRxData;
330 *pRxBytes -= pRxData->HeaderLength + pRxData->DataLength;
331
332 //
333 // Disconnect the buffer from the packet
334 //
335 pPacket->Op.Ip4Rx.pRxData = NULL;
336
337 //
338 // Return the buffer to the IP4 driver
339 //
340 gBS->SignalEvent ( pRxData->RecycleSignal );
341 DBG_EXIT ( );
342 }
343
344
345 /**
346 Initialize the network specific portions of an ::ESL_PORT structure.
347
348 This routine initializes the network specific portions of an
349 ::ESL_PORT structure for use by the socket.
350
351 This support routine is called by ::EslSocketPortAllocate
352 to connect the socket with the underlying network adapter
353 running the IPv4 protocol.
354
355 @param [in] pPort Address of an ESL_PORT structure
356 @param [in] DebugFlags Flags for debug messages
357
358 @retval EFI_SUCCESS - Socket successfully created
359
360 **/
361 EFI_STATUS
362 EslIp4PortAllocate (
363 IN ESL_PORT * pPort,
364 IN UINTN DebugFlags
365 )
366 {
367 EFI_IP4_CONFIG_DATA * pConfig;
368 ESL_SOCKET * pSocket;
369 EFI_STATUS Status;
370
371 DBG_ENTER ( );
372
373 //
374 // Initialize the port
375 //
376 pSocket = pPort->pSocket;
377 pSocket->TxPacketOffset = OFFSET_OF ( ESL_PACKET, Op.Ip4Tx.TxData );
378 pSocket->TxTokenEventOffset = OFFSET_OF ( ESL_IO_MGMT, Token.Ip4Tx.Event );
379 pSocket->TxTokenOffset = OFFSET_OF ( EFI_IP4_COMPLETION_TOKEN, Packet.TxData );
380
381 //
382 // Save the cancel, receive and transmit addresses
383 //
384 pPort->pfnConfigure = (PFN_NET_CONFIGURE)pPort->pProtocol.IPv4->Configure;
385 pPort->pfnRxCancel = (PFN_NET_IO_START)pPort->pProtocol.IPv4->Cancel;
386 pPort->pfnRxPoll = (PFN_NET_POLL)pPort->pProtocol.IPv4->Poll;
387 pPort->pfnRxStart = (PFN_NET_IO_START)pPort->pProtocol.IPv4->Receive;
388 pPort->pfnTxStart = (PFN_NET_IO_START)pPort->pProtocol.IPv4->Transmit;
389
390 //
391 // Set the configuration flags
392 //
393 pConfig = &pPort->Context.Ip4.ModeData.ConfigData;
394 pConfig->AcceptIcmpErrors = FALSE;
395 pConfig->AcceptBroadcast = FALSE;
396 pConfig->AcceptPromiscuous = FALSE;
397 pConfig->TypeOfService = 0;
398 pConfig->TimeToLive = 255;
399 pConfig->DoNotFragment = FALSE;
400 pConfig->RawData = FALSE;
401 pConfig->ReceiveTimeout = 0;
402 pConfig->TransmitTimeout = 0;
403
404 //
405 // Set the default protocol
406 //
407 pConfig->DefaultProtocol = (UINT8)pSocket->Protocol;
408 pConfig->AcceptAnyProtocol = (BOOLEAN)( 0 == pConfig->DefaultProtocol );
409 Status = EFI_SUCCESS;
410
411 //
412 // Return the operation status
413 //
414 DBG_EXIT_STATUS ( Status );
415 return Status;
416 }
417
418
419 /**
420 Receive data from a network connection.
421
422 This routine attempts to return buffered data to the caller. The
423 data is removed from the urgent queue if the message flag MSG_OOB
424 is specified, otherwise data is removed from the normal queue.
425 See the \ref ReceiveEngine section.
426
427 This routine is called by ::EslSocketReceive to handle the network
428 specific receive operation to support SOCK_RAW sockets.
429
430 @param [in] pPort Address of an ::ESL_PORT structure.
431
432 @param [in] pPacket Address of an ::ESL_PACKET structure.
433
434 @param [in] pbConsumePacket Address of a BOOLEAN indicating if the packet is to be consumed
435
436 @param [in] BufferLength Length of the the buffer
437
438 @param [in] pBuffer Address of a buffer to receive the data.
439
440 @param [in] pDataLength Number of received data bytes in the buffer.
441
442 @param [out] pAddress Network address to receive the remote system address
443
444 @param [out] pSkipBytes Address to receive the number of bytes skipped
445
446 @return Returns the address of the next free byte in the buffer.
447
448 **/
449 UINT8 *
450 EslIp4Receive (
451 IN ESL_PORT * pPort,
452 IN ESL_PACKET * pPacket,
453 IN BOOLEAN * pbConsumePacket,
454 IN size_t BufferLength,
455 IN UINT8 * pBuffer,
456 OUT size_t * pDataLength,
457 OUT struct sockaddr * pAddress,
458 OUT size_t * pSkipBytes
459 )
460 {
461 size_t DataBytes;
462 size_t HeaderBytes;
463 size_t LengthInBytes;
464 struct sockaddr_in * pRemoteAddress;
465 EFI_IP4_RECEIVE_DATA * pRxData;
466
467 DBG_ENTER ( );
468
469 //
470 // Return the remote system address if requested
471 //
472 pRxData = pPacket->Op.Ip4Rx.pRxData;
473 if ( NULL != pAddress ) {
474 //
475 // Build the remote address
476 //
477 DEBUG (( DEBUG_RX,
478 "Getting packet remote address: %d.%d.%d.%d\r\n",
479 pRxData->Header->SourceAddress.Addr[0],
480 pRxData->Header->SourceAddress.Addr[1],
481 pRxData->Header->SourceAddress.Addr[2],
482 pRxData->Header->SourceAddress.Addr[3]));
483 pRemoteAddress = (struct sockaddr_in *)pAddress;
484 CopyMem ( &pRemoteAddress->sin_addr,
485 &pRxData->Header->SourceAddress.Addr[0],
486 sizeof ( pRemoteAddress->sin_addr ));
487 }
488
489 //
490 // Copy the IP header
491 //
492 HeaderBytes = pRxData->HeaderLength;
493 if ( HeaderBytes > BufferLength ) {
494 HeaderBytes = BufferLength;
495 }
496 DEBUG (( DEBUG_RX,
497 "0x%08x --> 0x%08x: Copy header 0x%08x bytes\r\n",
498 pRxData->Header,
499 pBuffer,
500 HeaderBytes ));
501 CopyMem ( pBuffer, pRxData->Header, HeaderBytes );
502 pBuffer += HeaderBytes;
503 LengthInBytes = HeaderBytes;
504
505 //
506 // Copy the received data
507 //
508 if ( 0 < ( BufferLength - LengthInBytes )) {
509 pBuffer = EslSocketCopyFragmentedBuffer ( pRxData->FragmentCount,
510 &pRxData->FragmentTable[0],
511 BufferLength - LengthInBytes,
512 pBuffer,
513 &DataBytes );
514 LengthInBytes += DataBytes;
515 }
516
517 //
518 // Determine if the data is being read
519 //
520 if ( *pbConsumePacket ) {
521 //
522 // Display for the bytes consumed
523 //
524 DEBUG (( DEBUG_RX,
525 "0x%08x: Port account for 0x%08x bytes\r\n",
526 pPort,
527 LengthInBytes ));
528
529 //
530 // Account for any discarded data
531 //
532 *pSkipBytes = pRxData->HeaderLength + pRxData->DataLength - LengthInBytes;
533 }
534
535 //
536 // Return the data length and the buffer address
537 //
538 *pDataLength = LengthInBytes;
539 DBG_EXIT_HEX ( pBuffer );
540 return pBuffer;
541 }
542
543
544 /**
545 Get the remote socket address
546
547 This routine returns the address of the remote connection point
548 associated with the SOCK_RAW socket.
549
550 This routine is called by ::EslSocketGetPeerAddress to detemine
551 the IPv4 address associated with the network adapter.
552
553 @param [in] pPort Address of an ::ESL_PORT structure.
554
555 @param [out] pAddress Network address to receive the remote system address
556
557 **/
558 VOID
559 EslIp4RemoteAddressGet (
560 IN ESL_PORT * pPort,
561 OUT struct sockaddr * pAddress
562 )
563 {
564 struct sockaddr_in * pRemoteAddress;
565 ESL_IP4_CONTEXT * pIp4;
566
567 DBG_ENTER ( );
568
569 //
570 // Return the remote address
571 //
572 pIp4 = &pPort->Context.Ip4;
573 pRemoteAddress = (struct sockaddr_in *)pAddress;
574 pRemoteAddress->sin_family = AF_INET;
575 CopyMem ( &pRemoteAddress->sin_addr,
576 &pIp4->DestinationAddress.Addr[0],
577 sizeof ( pRemoteAddress->sin_addr ));
578
579 DBG_EXIT ( );
580 }
581
582
583 /**
584 Set the remote address
585
586 This routine sets the remote address in the port.
587
588 This routine is called by ::EslSocketConnect to specify the
589 remote network address.
590
591 @param [in] pPort Address of an ::ESL_PORT structure.
592
593 @param [in] pSockAddr Network address of the remote system.
594
595 @param [in] SockAddrLength Length in bytes of the network address.
596
597 @retval EFI_SUCCESS The operation was successful
598
599 **/
600 EFI_STATUS
601 EslIp4RemoteAddressSet (
602 IN ESL_PORT * pPort,
603 IN CONST struct sockaddr * pSockAddr,
604 IN socklen_t SockAddrLength
605 )
606 {
607 ESL_IP4_CONTEXT * pIp4;
608 CONST struct sockaddr_in * pRemoteAddress;
609 EFI_STATUS Status;
610
611 DBG_ENTER ( );
612
613 //
614 // Set the remote address
615 //
616 pIp4 = &pPort->Context.Ip4;
617 pRemoteAddress = (struct sockaddr_in *)pSockAddr;
618 pIp4->DestinationAddress.Addr[0] = (UINT8)( pRemoteAddress->sin_addr.s_addr );
619 pIp4->DestinationAddress.Addr[1] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 8 );
620 pIp4->DestinationAddress.Addr[2] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 16 );
621 pIp4->DestinationAddress.Addr[3] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 24 );
622 pPort->pSocket->bAddressSet = TRUE;
623 Status = EFI_SUCCESS;
624
625 //
626 // Return the operation status
627 //
628 DBG_EXIT_STATUS ( Status );
629 return Status;
630 }
631
632
633 /**
634 Process the receive completion
635
636 This routine keeps the IPv4 driver's buffer and queues it in
637 in FIFO order to the data queue. The IP4 driver's buffer will
638 be returned by either ::EslIp4Receive or ::EslSocketPortCloseTxDone.
639 See the \ref ReceiveEngine section.
640
641 This routine is called by the IPv4 driver when data is
642 received.
643
644 @param [in] Event The receive completion event
645
646 @param [in] pIo The address of an ::ESL_IO_MGMT structure
647
648 **/
649 VOID
650 EslIp4RxComplete (
651 IN EFI_EVENT Event,
652 IN ESL_IO_MGMT * pIo
653 )
654 {
655 size_t LengthInBytes;
656 ESL_PACKET * pPacket;
657 EFI_IP4_RECEIVE_DATA * pRxData;
658 EFI_STATUS Status;
659
660 DBG_ENTER ( );
661
662 //
663 // Get the operation status.
664 //
665 Status = pIo->Token.Ip4Rx.Status;
666
667 //
668 // Get the packet length
669 //
670 pRxData = pIo->Token.Ip4Rx.Packet.RxData;
671 LengthInBytes = pRxData->HeaderLength + pRxData->DataLength;
672
673 //{{
674 // +--------------------+ +----------------------+
675 // | ESL_IO_MGMT | | Data Buffer |
676 // | | | (Driver owned) |
677 // | +---------------+ +----------------------+
678 // | | Token | ^
679 // | | Rx Event | |
680 // | | | +----------------------+
681 // | | RxData --> | EFI_IP4_RECEIVE_DATA |
682 // +----+---------------+ | (Driver owned) |
683 // +----------------------+
684 // +--------------------+ ^
685 // | ESL_PACKET | .
686 // | | .
687 // | +---------------+ .
688 // | | pRxData --> NULL .......
689 // +----+---------------+
690 //
691 //
692 // Save the data in the packet
693 //}}
694 pPacket = pIo->pPacket;
695 pPacket->Op.Ip4Rx.pRxData = pRxData;
696
697 //
698 // Complete this request
699 //
700 EslSocketRxComplete ( pIo, Status, LengthInBytes, FALSE );
701 DBG_EXIT ( );
702 }
703
704
705 /**
706 Determine if the socket is configured.
707
708 This routine uses the flag ESL_SOCKET::bConfigured to determine
709 if the network layer's configuration routine has been called.
710 This routine calls the ::EslSocketBind and configuration routines
711 if they were not already called. After the port is configured,
712 the \ref ReceiveEngine is started.
713
714 This routine is called by EslSocketIsConfigured to verify
715 that the socket is configured.
716
717 @param [in] pSocket Address of an ::ESL_SOCKET structure
718
719 @retval EFI_SUCCESS - The port is connected
720 @retval EFI_NOT_STARTED - The port is not connected
721
722 **/
723 EFI_STATUS
724 EslIp4SocketIsConfigured (
725 IN ESL_SOCKET * pSocket
726 )
727 {
728 UINTN Index;
729 ESL_PORT * pPort;
730 ESL_PORT * pNextPort;
731 ESL_IP4_CONTEXT * pIp4;
732 EFI_IP4_PROTOCOL * pIp4Protocol;
733 EFI_STATUS Status;
734 struct sockaddr_in LocalAddress;
735
736 DBG_ENTER ( );
737
738 //
739 // Assume success
740 //
741 Status = EFI_SUCCESS;
742
743 //
744 // Configure the port if necessary
745 //
746 if ( !pSocket->bConfigured ) {
747 //
748 // Fill in the port list if necessary
749 //
750 pSocket->errno = ENETDOWN;
751 if ( NULL == pSocket->pPortList ) {
752 LocalAddress.sin_len = sizeof ( LocalAddress );
753 LocalAddress.sin_family = AF_INET;
754 LocalAddress.sin_addr.s_addr = 0;
755 LocalAddress.sin_port = 0;
756 Status = EslSocketBind ( &pSocket->SocketProtocol,
757 (struct sockaddr *)&LocalAddress,
758 LocalAddress.sin_len,
759 &pSocket->errno );
760 }
761
762 //
763 // Walk the port list
764 //
765 pPort = pSocket->pPortList;
766 while ( NULL != pPort ) {
767 //
768 // Update the raw setting
769 //
770 pIp4 = &pPort->Context.Ip4;
771 if ( pSocket->bIncludeHeader ) {
772 //
773 // IP header will be included with the data on transmit
774 //
775 pIp4->ModeData.ConfigData.RawData = TRUE;
776 }
777
778 //
779 // Attempt to configure the port
780 //
781 pNextPort = pPort->pLinkSocket;
782 pIp4Protocol = pPort->pProtocol.IPv4;
783 DEBUG (( DEBUG_TX,
784 "0x%08x: pPort Configuring for %d.%d.%d.%d --> %d.%d.%d.%d\r\n",
785 pPort,
786 pIp4->ModeData.ConfigData.StationAddress.Addr[0],
787 pIp4->ModeData.ConfigData.StationAddress.Addr[1],
788 pIp4->ModeData.ConfigData.StationAddress.Addr[2],
789 pIp4->ModeData.ConfigData.StationAddress.Addr[3],
790 pIp4->DestinationAddress.Addr[0],
791 pIp4->DestinationAddress.Addr[1],
792 pIp4->DestinationAddress.Addr[2],
793 pIp4->DestinationAddress.Addr[3]));
794 Status = pIp4Protocol->Configure ( pIp4Protocol,
795 &pIp4->ModeData.ConfigData );
796 if ( !EFI_ERROR ( Status )) {
797 //
798 // Update the configuration data
799 //
800 Status = pIp4Protocol->GetModeData ( pIp4Protocol,
801 &pIp4->ModeData,
802 NULL,
803 NULL );
804 }
805 if ( EFI_ERROR ( Status )) {
806 if ( !pSocket->bConfigured ) {
807 DEBUG (( DEBUG_LISTEN,
808 "ERROR - Failed to configure the Ip4 port, Status: %r\r\n",
809 Status ));
810 switch ( Status ) {
811 case EFI_ACCESS_DENIED:
812 pSocket->errno = EACCES;
813 break;
814
815 default:
816 case EFI_DEVICE_ERROR:
817 pSocket->errno = EIO;
818 break;
819
820 case EFI_INVALID_PARAMETER:
821 pSocket->errno = EADDRNOTAVAIL;
822 break;
823
824 case EFI_NO_MAPPING:
825 pSocket->errno = EAFNOSUPPORT;
826 break;
827
828 case EFI_OUT_OF_RESOURCES:
829 pSocket->errno = ENOBUFS;
830 break;
831
832 case EFI_UNSUPPORTED:
833 pSocket->errno = EOPNOTSUPP;
834 break;
835 }
836 }
837 }
838 else {
839 DEBUG (( DEBUG_TX,
840 "0x%08x: pPort Configured for %d.%d.%d.%d --> %d.%d.%d.%d\r\n",
841 pPort,
842 pIp4->ModeData.ConfigData.StationAddress.Addr[0],
843 pIp4->ModeData.ConfigData.StationAddress.Addr[1],
844 pIp4->ModeData.ConfigData.StationAddress.Addr[2],
845 pIp4->ModeData.ConfigData.StationAddress.Addr[3],
846 pIp4->DestinationAddress.Addr[0],
847 pIp4->DestinationAddress.Addr[1],
848 pIp4->DestinationAddress.Addr[2],
849 pIp4->DestinationAddress.Addr[3]));
850 DEBUG (( DEBUG_TX,
851 "Subnet Mask: %d.%d.%d.%d\r\n",
852 pIp4->ModeData.ConfigData.SubnetMask.Addr[0],
853 pIp4->ModeData.ConfigData.SubnetMask.Addr[1],
854 pIp4->ModeData.ConfigData.SubnetMask.Addr[2],
855 pIp4->ModeData.ConfigData.SubnetMask.Addr[3]));
856 DEBUG (( DEBUG_TX,
857 "Route Count: %d\r\n",
858 pIp4->ModeData.RouteCount ));
859 for ( Index = 0; pIp4->ModeData.RouteCount > Index; Index++ ) {
860 if ( 0 == Index ) {
861 DEBUG (( DEBUG_TX, "Route Table:\r\n" ));
862 }
863 DEBUG (( DEBUG_TX,
864 "%5d: %d.%d.%d.%d, %d.%d.%d.%d ==> %d.%d.%d.%d\r\n",
865 Index,
866 pIp4->ModeData.RouteTable[Index].SubnetAddress.Addr[0],
867 pIp4->ModeData.RouteTable[Index].SubnetAddress.Addr[1],
868 pIp4->ModeData.RouteTable[Index].SubnetAddress.Addr[2],
869 pIp4->ModeData.RouteTable[Index].SubnetAddress.Addr[3],
870 pIp4->ModeData.RouteTable[Index].SubnetMask.Addr[0],
871 pIp4->ModeData.RouteTable[Index].SubnetMask.Addr[1],
872 pIp4->ModeData.RouteTable[Index].SubnetMask.Addr[2],
873 pIp4->ModeData.RouteTable[Index].SubnetMask.Addr[3],
874 pIp4->ModeData.RouteTable[Index].GatewayAddress.Addr[0],
875 pIp4->ModeData.RouteTable[Index].GatewayAddress.Addr[1],
876 pIp4->ModeData.RouteTable[Index].GatewayAddress.Addr[2],
877 pIp4->ModeData.RouteTable[Index].GatewayAddress.Addr[3]));
878 }
879 pPort->bConfigured = TRUE;
880 pSocket->bConfigured = TRUE;
881
882 //
883 // Start the first read on the port
884 //
885 EslSocketRxStart ( pPort );
886
887 //
888 // The socket is connected
889 //
890 pSocket->State = SOCKET_STATE_CONNECTED;
891 pSocket->errno = 0;
892 }
893
894 //
895 // Set the next port
896 //
897 pPort = pNextPort;
898 }
899 }
900
901 //
902 // Determine the socket configuration status
903 //
904 Status = pSocket->bConfigured ? EFI_SUCCESS : EFI_NOT_STARTED;
905
906 //
907 // Return the port connected state.
908 //
909 DBG_EXIT_STATUS ( Status );
910 return Status;
911 }
912
913
914 /**
915 Buffer data for transmission over a network connection.
916
917 This routine buffers data for the transmit engine in the normal
918 data queue. When the \ref TransmitEngine has resources, this
919 routine will start the transmission of the next buffer on the
920 network connection.
921
922 This routine is called by ::EslSocketTransmit to buffer
923 data for transmission. The data is copied into a local buffer
924 freeing the application buffer for reuse upon return. When
925 necessary, this routine starts the transmit engine that
926 performs the data transmission on the network connection. The
927 transmit engine transmits the data a packet at a time over the
928 network connection.
929
930 Transmission errors are returned during the next transmission or
931 during the close operation. Only buffering errors are returned
932 during the current transmission attempt.
933
934 @param [in] pSocket Address of an ::ESL_SOCKET structure
935
936 @param [in] Flags Message control flags
937
938 @param [in] BufferLength Length of the the buffer
939
940 @param [in] pBuffer Address of a buffer to receive the data.
941
942 @param [in] pDataLength Number of received data bytes in the buffer.
943
944 @param [in] pAddress Network address of the remote system address
945
946 @param [in] AddressLength Length of the remote network address structure
947
948 @retval EFI_SUCCESS - Socket data successfully buffered
949
950 **/
951 EFI_STATUS
952 EslIp4TxBuffer (
953 IN ESL_SOCKET * pSocket,
954 IN int Flags,
955 IN size_t BufferLength,
956 IN CONST UINT8 * pBuffer,
957 OUT size_t * pDataLength,
958 IN const struct sockaddr * pAddress,
959 IN socklen_t AddressLength
960 )
961 {
962 ESL_PACKET * pPacket;
963 ESL_PACKET * pPreviousPacket;
964 ESL_PORT * pPort;
965 const struct sockaddr_in * pRemoteAddress;
966 ESL_IP4_CONTEXT * pIp4;
967 size_t * pTxBytes;
968 ESL_IP4_TX_DATA * pTxData;
969 EFI_STATUS Status;
970 EFI_TPL TplPrevious;
971
972 DBG_ENTER ( );
973
974 //
975 // Assume failure
976 //
977 Status = EFI_UNSUPPORTED;
978 pSocket->errno = ENOTCONN;
979 *pDataLength = 0;
980
981 //
982 // Verify that the socket is connected
983 //
984 if ( SOCKET_STATE_CONNECTED == pSocket->State ) {
985 //
986 // Verify that there is enough room to buffer another
987 // transmit operation
988 //
989 pTxBytes = &pSocket->TxBytes;
990 if ( pSocket->MaxTxBuf > *pTxBytes ) {
991 //
992 // Locate the port
993 //
994 pPort = pSocket->pPortList;
995 while ( NULL != pPort ) {
996 //
997 // Determine the queue head
998 //
999 pIp4 = &pPort->Context.Ip4;
1000
1001 //
1002 // Attempt to allocate the packet
1003 //
1004 Status = EslSocketPacketAllocate ( &pPacket,
1005 sizeof ( pPacket->Op.Ip4Tx )
1006 - sizeof ( pPacket->Op.Ip4Tx.Buffer )
1007 + BufferLength,
1008 0,
1009 DEBUG_TX );
1010 if ( !EFI_ERROR ( Status )) {
1011 //
1012 // Initialize the transmit operation
1013 //
1014 pTxData = &pPacket->Op.Ip4Tx;
1015 pTxData->TxData.DestinationAddress.Addr[0] = pIp4->DestinationAddress.Addr[0];
1016 pTxData->TxData.DestinationAddress.Addr[1] = pIp4->DestinationAddress.Addr[1];
1017 pTxData->TxData.DestinationAddress.Addr[2] = pIp4->DestinationAddress.Addr[2];
1018 pTxData->TxData.DestinationAddress.Addr[3] = pIp4->DestinationAddress.Addr[3];
1019 pTxData->TxData.OverrideData = NULL;
1020 pTxData->TxData.OptionsLength = 0;
1021 pTxData->TxData.OptionsBuffer = NULL;
1022 pTxData->TxData.TotalDataLength = (UINT32) BufferLength;
1023 pTxData->TxData.FragmentCount = 1;
1024 pTxData->TxData.FragmentTable[0].FragmentLength = (UINT32) BufferLength;
1025 pTxData->TxData.FragmentTable[0].FragmentBuffer = &pPacket->Op.Ip4Tx.Buffer[0];
1026
1027 //
1028 // Set the remote system address if necessary
1029 //
1030 if ( NULL != pAddress ) {
1031 pRemoteAddress = (const struct sockaddr_in *)pAddress;
1032 pTxData->Override.SourceAddress.Addr[0] = pIp4->ModeData.ConfigData.StationAddress.Addr[0];
1033 pTxData->Override.SourceAddress.Addr[1] = pIp4->ModeData.ConfigData.StationAddress.Addr[1];
1034 pTxData->Override.SourceAddress.Addr[2] = pIp4->ModeData.ConfigData.StationAddress.Addr[2];
1035 pTxData->Override.SourceAddress.Addr[3] = pIp4->ModeData.ConfigData.StationAddress.Addr[3];
1036 pTxData->TxData.DestinationAddress.Addr[0] = (UINT8)pRemoteAddress->sin_addr.s_addr;
1037 pTxData->TxData.DestinationAddress.Addr[1] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 8 );
1038 pTxData->TxData.DestinationAddress.Addr[2] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 16 );
1039 pTxData->TxData.DestinationAddress.Addr[3] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 24 );
1040 pTxData->Override.GatewayAddress.Addr[0] = 0;
1041 pTxData->Override.GatewayAddress.Addr[1] = 0;
1042 pTxData->Override.GatewayAddress.Addr[2] = 0;
1043 pTxData->Override.GatewayAddress.Addr[3] = 0;
1044 pTxData->Override.Protocol = (UINT8)pSocket->Protocol;
1045 pTxData->Override.TypeOfService = 0;
1046 pTxData->Override.TimeToLive = 255;
1047 pTxData->Override.DoNotFragment = FALSE;
1048
1049 //
1050 // Use the remote system address when sending this packet
1051 //
1052 pTxData->TxData.OverrideData = &pTxData->Override;
1053 }
1054
1055 //
1056 // Copy the data into the buffer
1057 //
1058 CopyMem ( &pPacket->Op.Ip4Tx.Buffer[0],
1059 pBuffer,
1060 BufferLength );
1061
1062 //
1063 // Synchronize with the socket layer
1064 //
1065 RAISE_TPL ( TplPrevious, TPL_SOCKETS );
1066
1067 //
1068 // Display the request
1069 //
1070 DEBUG (( DEBUG_TX,
1071 "Send %d bytes from 0x%08x, %d.%d.%d.%d --> %d.%d.%d.%d\r\n",
1072 BufferLength,
1073 pBuffer,
1074 pIp4->ModeData.ConfigData.StationAddress.Addr[0],
1075 pIp4->ModeData.ConfigData.StationAddress.Addr[1],
1076 pIp4->ModeData.ConfigData.StationAddress.Addr[2],
1077 pIp4->ModeData.ConfigData.StationAddress.Addr[3],
1078 pTxData->TxData.DestinationAddress.Addr[0],
1079 pTxData->TxData.DestinationAddress.Addr[1],
1080 pTxData->TxData.DestinationAddress.Addr[2],
1081 pTxData->TxData.DestinationAddress.Addr[3]));
1082
1083 //
1084 // Queue the data for transmission
1085 //
1086 pPacket->pNext = NULL;
1087 pPreviousPacket = pSocket->pTxPacketListTail;
1088 if ( NULL == pPreviousPacket ) {
1089 pSocket->pTxPacketListHead = pPacket;
1090 }
1091 else {
1092 pPreviousPacket->pNext = pPacket;
1093 }
1094 pSocket->pTxPacketListTail = pPacket;
1095 DEBUG (( DEBUG_TX,
1096 "0x%08x: Packet on transmit list\r\n",
1097 pPacket ));
1098
1099 //
1100 // Account for the buffered data
1101 //
1102 *pTxBytes += BufferLength;
1103 *pDataLength = BufferLength;
1104
1105 //
1106 // Start the transmit engine if it is idle
1107 //
1108 if ( NULL != pPort->pTxFree ) {
1109 EslSocketTxStart ( pPort,
1110 &pSocket->pTxPacketListHead,
1111 &pSocket->pTxPacketListTail,
1112 &pPort->pTxActive,
1113 &pPort->pTxFree );
1114
1115 //
1116 // Ignore any transmit error
1117 //
1118 if ( EFI_ERROR ( pSocket->TxError )) {
1119 DEBUG (( DEBUG_TX,
1120 "0x%08x: Transmit error, Packet: 0x%08x, Status: %r\r\n",
1121 pPort,
1122 pPacket,
1123 pSocket->TxError ));
1124 }
1125 pSocket->TxError = EFI_SUCCESS;
1126 }
1127
1128 //
1129 // Release the socket layer synchronization
1130 //
1131 RESTORE_TPL ( TplPrevious );
1132 }
1133 else {
1134 //
1135 // Packet allocation failed
1136 //
1137 pSocket->errno = ENOMEM;
1138 break;
1139 }
1140
1141 //
1142 // Set the next port
1143 //
1144 pPort = pPort->pLinkSocket;
1145 }
1146 }
1147 else {
1148 //
1149 // Not enough buffer space available
1150 //
1151 pSocket->errno = EAGAIN;
1152 Status = EFI_NOT_READY;
1153 }
1154 }
1155
1156 //
1157 // Return the operation status
1158 //
1159 DBG_EXIT_STATUS ( Status );
1160 return Status;
1161 }
1162
1163
1164 /**
1165 Process the transmit completion
1166
1167 This routine use ::EslSocketTxComplete to perform the transmit
1168 completion processing for data packets.
1169
1170 This routine is called by the IPv4 network layer when a data
1171 transmit request completes.
1172
1173 @param [in] Event The normal transmit completion event
1174
1175 @param [in] pIo The address of an ::ESL_IO_MGMT structure
1176
1177 **/
1178 VOID
1179 EslIp4TxComplete (
1180 IN EFI_EVENT Event,
1181 IN ESL_IO_MGMT * pIo
1182 )
1183 {
1184 UINT32 LengthInBytes;
1185 ESL_PORT * pPort;
1186 ESL_PACKET * pPacket;
1187 ESL_SOCKET * pSocket;
1188 EFI_STATUS Status;
1189
1190 DBG_ENTER ( );
1191
1192 //
1193 // Locate the active transmit packet
1194 //
1195 pPacket = pIo->pPacket;
1196 pPort = pIo->pPort;
1197 pSocket = pPort->pSocket;
1198
1199 //
1200 // Get the transmit length and status
1201 //
1202 LengthInBytes = pPacket->Op.Ip4Tx.TxData.TotalDataLength;
1203 pSocket->TxBytes -= LengthInBytes;
1204 Status = pIo->Token.Ip4Tx.Status;
1205
1206 //
1207 // Ignore the transmit error
1208 //
1209 if ( EFI_ERROR ( Status )) {
1210 DEBUG (( DEBUG_TX,
1211 "0x%08x: Transmit completion error, Packet: 0x%08x, Status: %r\r\n",
1212 pPort,
1213 pPacket,
1214 Status ));
1215 Status = EFI_SUCCESS;
1216 }
1217
1218 //
1219 // Complete the transmit operation
1220 //
1221 EslSocketTxComplete ( pIo,
1222 LengthInBytes,
1223 Status,
1224 "Raw ",
1225 &pSocket->pTxPacketListHead,
1226 &pSocket->pTxPacketListTail,
1227 &pPort->pTxActive,
1228 &pPort->pTxFree );
1229 DBG_EXIT ( );
1230 }
1231
1232
1233 /**
1234 Verify the adapter's IP address
1235
1236 This support routine is called by EslSocketBindTest.
1237
1238 @param [in] pPort Address of an ::ESL_PORT structure.
1239 @param [in] pConfigData Address of the configuration data
1240
1241 @retval EFI_SUCCESS - The IP address is valid
1242 @retval EFI_NOT_STARTED - The IP address is invalid
1243
1244 **/
1245 EFI_STATUS
1246 EslIp4VerifyLocalIpAddress (
1247 IN ESL_PORT * pPort,
1248 IN EFI_IP4_CONFIG_DATA * pConfigData
1249 )
1250 {
1251 UINTN DataSize;
1252 EFI_IP4_IPCONFIG_DATA * pIpConfigData;
1253 EFI_IP4_CONFIG_PROTOCOL * pIpConfigProtocol;
1254 ESL_SERVICE * pService;
1255 EFI_STATUS Status;
1256
1257 DBG_ENTER ( );
1258
1259 //
1260 // Use break instead of goto
1261 //
1262 pIpConfigData = NULL;
1263 for ( ; ; ) {
1264 //
1265 // Determine if the IP address is specified
1266 //
1267 DEBUG (( DEBUG_BIND,
1268 "UseDefaultAddress: %s\r\n",
1269 pConfigData->UseDefaultAddress ? L"TRUE" : L"FALSE" ));
1270 DEBUG (( DEBUG_BIND,
1271 "Requested IP address: %d.%d.%d.%d\r\n",
1272 pConfigData->StationAddress.Addr [ 0 ],
1273 pConfigData->StationAddress.Addr [ 1 ],
1274 pConfigData->StationAddress.Addr [ 2 ],
1275 pConfigData->StationAddress.Addr [ 3 ]));
1276 if ( pConfigData->UseDefaultAddress
1277 || (( 0 == pConfigData->StationAddress.Addr [ 0 ])
1278 && ( 0 == pConfigData->StationAddress.Addr [ 1 ])
1279 && ( 0 == pConfigData->StationAddress.Addr [ 2 ])
1280 && ( 0 == pConfigData->StationAddress.Addr [ 3 ])))
1281 {
1282 Status = EFI_SUCCESS;
1283 break;
1284 }
1285
1286 //
1287 // Open the configuration protocol
1288 //
1289 pService = pPort->pService;
1290 Status = gBS->OpenProtocol ( pService->Controller,
1291 &gEfiIp4ConfigProtocolGuid,
1292 (VOID **)&pIpConfigProtocol,
1293 NULL,
1294 NULL,
1295 EFI_OPEN_PROTOCOL_GET_PROTOCOL );
1296 if ( EFI_ERROR ( Status )) {
1297 DEBUG (( DEBUG_ERROR,
1298 "ERROR - IP Configuration Protocol not available, Status: %r\r\n",
1299 Status ));
1300 break;
1301 }
1302
1303 //
1304 // Get the IP configuration data size
1305 //
1306 DataSize = 0;
1307 Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
1308 &DataSize,
1309 NULL );
1310 if ( EFI_BUFFER_TOO_SMALL != Status ) {
1311 DEBUG (( DEBUG_ERROR,
1312 "ERROR - Failed to get IP Configuration data size, Status: %r\r\n",
1313 Status ));
1314 break;
1315 }
1316
1317 //
1318 // Allocate the configuration data buffer
1319 //
1320 pIpConfigData = AllocatePool ( DataSize );
1321 if ( NULL == pIpConfigData ) {
1322 DEBUG (( DEBUG_ERROR,
1323 "ERROR - Not enough memory to allocate IP Configuration data!\r\n" ));
1324 Status = EFI_OUT_OF_RESOURCES;
1325 break;
1326 }
1327
1328 //
1329 // Get the IP configuration
1330 //
1331 Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
1332 &DataSize,
1333 pIpConfigData );
1334 if ( EFI_ERROR ( Status )) {
1335 DEBUG (( DEBUG_ERROR,
1336 "ERROR - Failed to return IP Configuration data, Status: %r\r\n",
1337 Status ));
1338 break;
1339 }
1340
1341 //
1342 // Display the current configuration
1343 //
1344 DEBUG (( DEBUG_BIND,
1345 "Actual adapter IP address: %d.%d.%d.%d\r\n",
1346 pIpConfigData->StationAddress.Addr [ 0 ],
1347 pIpConfigData->StationAddress.Addr [ 1 ],
1348 pIpConfigData->StationAddress.Addr [ 2 ],
1349 pIpConfigData->StationAddress.Addr [ 3 ]));
1350
1351 //
1352 // Assume the port is not configured
1353 //
1354 Status = EFI_SUCCESS;
1355 if (( pConfigData->StationAddress.Addr [ 0 ] == pIpConfigData->StationAddress.Addr [ 0 ])
1356 && ( pConfigData->StationAddress.Addr [ 1 ] == pIpConfigData->StationAddress.Addr [ 1 ])
1357 && ( pConfigData->StationAddress.Addr [ 2 ] == pIpConfigData->StationAddress.Addr [ 2 ])
1358 && ( pConfigData->StationAddress.Addr [ 3 ] == pIpConfigData->StationAddress.Addr [ 3 ])) {
1359 break;
1360 }
1361
1362 //
1363 // The IP address did not match
1364 //
1365 Status = EFI_NOT_STARTED;
1366 break;
1367 }
1368
1369 //
1370 // Free the buffer if necessary
1371 //
1372 if ( NULL != pIpConfigData ) {
1373 FreePool ( pIpConfigData );
1374 }
1375
1376 //
1377 // Return the IP address status
1378 //
1379 DBG_EXIT_STATUS ( Status );
1380 return Status;
1381 }
1382
1383
1384 /**
1385 Interface between the socket layer and the network specific
1386 code that supports SOCK_RAW sockets over IPv4.
1387 **/
1388 CONST ESL_PROTOCOL_API cEslIp4Api = {
1389 "IPv4",
1390 IPPROTO_IP,
1391 OFFSET_OF ( ESL_PORT, Context.Ip4.ModeData.ConfigData ),
1392 OFFSET_OF ( ESL_LAYER, pIp4List ),
1393 OFFSET_OF ( struct sockaddr_in, sin_zero ),
1394 sizeof ( struct sockaddr_in ),
1395 AF_INET,
1396 sizeof (((ESL_PACKET *)0 )->Op.Ip4Rx ),
1397 sizeof (((ESL_PACKET *)0 )->Op.Ip4Rx ),
1398 OFFSET_OF ( ESL_IO_MGMT, Token.Ip4Rx.Packet.RxData ),
1399 FALSE,
1400 EADDRNOTAVAIL,
1401 NULL, // Accept
1402 NULL, // ConnectPoll
1403 NULL, // ConnectStart
1404 EslIp4SocketIsConfigured,
1405 EslIp4LocalAddressGet,
1406 EslIp4LocalAddressSet,
1407 NULL, // Listen
1408 EslIp4OptionGet,
1409 EslIp4OptionSet,
1410 EslIp4PacketFree,
1411 EslIp4PortAllocate,
1412 NULL, // PortClose
1413 NULL, // PortCloseOp
1414 TRUE,
1415 EslIp4Receive,
1416 EslIp4RemoteAddressGet,
1417 EslIp4RemoteAddressSet,
1418 EslIp4RxComplete,
1419 NULL, // RxStart
1420 EslIp4TxBuffer,
1421 EslIp4TxComplete,
1422 NULL, // TxOobComplete
1423 (PFN_API_VERIFY_LOCAL_IP_ADDRESS)EslIp4VerifyLocalIpAddress
1424 };