Home | History | Annotate | Download | only in Dhcp6Dxe
      1 /** @file
      2   Dhcp6 internal data structure and definition declaration.
      3 
      4   Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
      5 
      6   This program and the accompanying materials
      7   are licensed and made available under the terms and conditions of the BSD License
      8   which accompanies this distribution.  The full text of the license may be found at
      9   http://opensource.org/licenses/bsd-license.php.
     10 
     11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #ifndef __EFI_DHCP6_IMPL_H__
     17 #define __EFI_DHCP6_IMPL_H__
     18 
     19 
     20 #include <Uefi.h>
     21 
     22 #include <IndustryStandard/Dhcp.h>
     23 
     24 #include <Protocol/Dhcp6.h>
     25 #include <Protocol/Udp6.h>
     26 #include <Protocol/Ip6Config.h>
     27 #include <Protocol/ServiceBinding.h>
     28 #include <Protocol/DriverBinding.h>
     29 
     30 #include <Library/UdpIoLib.h>
     31 #include <Library/DebugLib.h>
     32 #include <Library/BaseMemoryLib.h>
     33 #include <Library/MemoryAllocationLib.h>
     34 #include <Library/UefiBootServicesTableLib.h>
     35 #include <Library/UefiRuntimeServicesTableLib.h>
     36 #include <Library/UefiLib.h>
     37 #include <Library/BaseLib.h>
     38 #include <Library/NetLib.h>
     39 #include <Library/PrintLib.h>
     40 
     41 
     42 typedef struct _DHCP6_IA_CB    DHCP6_IA_CB;
     43 typedef struct _DHCP6_INF_CB   DHCP6_INF_CB;
     44 typedef struct _DHCP6_TX_CB    DHCP6_TX_CB;
     45 typedef struct _DHCP6_SERVICE  DHCP6_SERVICE;
     46 typedef struct _DHCP6_INSTANCE DHCP6_INSTANCE;
     47 
     48 #include "Dhcp6Utility.h"
     49 #include "Dhcp6Io.h"
     50 #include "Dhcp6Driver.h"
     51 
     52 #define DHCP6_SERVICE_SIGNATURE   SIGNATURE_32 ('D', 'H', '6', 'S')
     53 #define DHCP6_INSTANCE_SIGNATURE  SIGNATURE_32 ('D', 'H', '6', 'I')
     54 
     55 #define DHCP6_PACKET_ALL          0
     56 #define DHCP6_PACKET_STATEFUL     1
     57 #define DHCP6_PACKET_STATELESS    2
     58 
     59 #define DHCP6_BASE_PACKET_SIZE    1024
     60 
     61 #define DHCP6_PORT_CLIENT         546
     62 #define DHCP6_PORT_SERVER         547
     63 
     64 #define DHCP6_INSTANCE_FROM_THIS(Instance) CR ((Instance), DHCP6_INSTANCE, Dhcp6, DHCP6_INSTANCE_SIGNATURE)
     65 #define DHCP6_SERVICE_FROM_THIS(Service)   CR ((Service), DHCP6_SERVICE, ServiceBinding, DHCP6_SERVICE_SIGNATURE)
     66 
     67 extern EFI_IPv6_ADDRESS           mAllDhcpRelayAndServersAddress;
     68 extern EFI_IPv6_ADDRESS           mAllDhcpServersAddress;
     69 extern EFI_DHCP6_PROTOCOL         gDhcp6ProtocolTemplate;
     70 
     71 //
     72 // Control block for each IA.
     73 //
     74 struct _DHCP6_IA_CB {
     75   EFI_DHCP6_IA                  *Ia;
     76   UINT32                        T1;
     77   UINT32                        T2;
     78   UINT32                        AllExpireTime;
     79   UINT32                        LeaseTime;
     80 };
     81 
     82 //
     83 // Control block for each transmitted message.
     84 //
     85 struct _DHCP6_TX_CB {
     86   LIST_ENTRY                    Link;
     87   UINT32                        Xid;
     88   EFI_DHCP6_PACKET              *TxPacket;
     89   EFI_DHCP6_RETRANSMISSION      RetryCtl;
     90   UINT32                        RetryCnt;
     91   UINT32                        RetryExp;
     92   UINT32                        RetryLos;
     93   UINT32                        TickTime;
     94   UINT16                        *Elapsed;
     95   BOOLEAN                       SolicitRetry;
     96 };
     97 
     98 //
     99 // Control block for each info-request message.
    100 //
    101 struct _DHCP6_INF_CB {
    102   LIST_ENTRY                    Link;
    103   UINT32                        Xid;
    104   EFI_DHCP6_INFO_CALLBACK       ReplyCallback;
    105   VOID                          *CallbackContext;
    106   EFI_EVENT                     TimeoutEvent;
    107 };
    108 
    109 //
    110 // Control block for Dhcp6 instance, it's per configuration data.
    111 //
    112 struct _DHCP6_INSTANCE {
    113   UINT32                        Signature;
    114   EFI_HANDLE                    Handle;
    115   DHCP6_SERVICE                 *Service;
    116   LIST_ENTRY                    Link;
    117   EFI_DHCP6_PROTOCOL            Dhcp6;
    118   EFI_EVENT                     Timer;
    119   EFI_DHCP6_CONFIG_DATA         *Config;
    120   EFI_DHCP6_IA                  *CacheIa;
    121   DHCP6_IA_CB                   IaCb;
    122   LIST_ENTRY                    TxList;
    123   LIST_ENTRY                    InfList;
    124   EFI_DHCP6_PACKET              *AdSelect;
    125   UINT8                         AdPref;
    126   EFI_IPv6_ADDRESS              *Unicast;
    127   volatile EFI_STATUS           UdpSts;
    128   BOOLEAN                       InDestroy;
    129   BOOLEAN                       MediaPresent;
    130   //
    131   // StartTime is used to calculate the 'elapsed-time' option. Refer to RFC3315,
    132   // the elapsed-time is amount of time since the client began its current DHCP transaction.
    133   //
    134   UINT64                        StartTime;
    135 };
    136 
    137 //
    138 // Control block for Dhcp6 service, it's per Nic handle.
    139 //
    140 struct _DHCP6_SERVICE {
    141   UINT32                        Signature;
    142   EFI_HANDLE                    Controller;
    143   EFI_HANDLE                    Image;
    144   EFI_SERVICE_BINDING_PROTOCOL  ServiceBinding;
    145   EFI_SIMPLE_NETWORK_PROTOCOL   *Snp;
    146   EFI_IP6_CONFIG_PROTOCOL       *Ip6Cfg;
    147   EFI_DHCP6_DUID                *ClientId;
    148   UDP_IO                        *UdpIo;
    149   UINT32                        Xid;
    150   LIST_ENTRY                    Child;
    151   UINTN                         NumOfChild;
    152 };
    153 
    154 /**
    155   Starts the DHCPv6 standard S.A.R.R. process.
    156 
    157   The Start() function starts the DHCPv6 standard process. This function can
    158   be called only when the state of Dhcp6 instance is in the Dhcp6Init state.
    159   If the DHCP process completes successfully, the state of the Dhcp6 instance
    160   will be transferred through Dhcp6Selecting and Dhcp6Requesting to the
    161   Dhcp6Bound state.
    162   Refer to rfc-3315 for precise state transitions during this process. At the
    163   time when each event occurs in this process, the callback function that was set
    164   by EFI_DHCP6_PROTOCOL.Configure() will be called and the user can take this
    165   opportunity to control the process.
    166 
    167   @param[in]  This              The pointer to Dhcp6 protocol.
    168 
    169   @retval EFI_SUCCESS           The DHCPv6 standard process has started, or it
    170                                 completed when CompletionEvent was NULL.
    171   @retval EFI_ACCESS_DENIED     The EFI DHCPv6 Child instance hasn't been configured.
    172   @retval EFI_INVALID_PARAMETER This is NULL.
    173   @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
    174   @retval EFI_TIMEOUT           The DHCPv6 configuration process failed because no
    175                                 response was received from the server within the
    176                                 specified timeout value.
    177   @retval EFI_ABORTED           The user aborted the DHCPv6 process.
    178   @retval EFI_ALREADY_STARTED   Some other Dhcp6 instance already started the DHCPv6
    179                                 standard process.
    180   @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.
    181 
    182 **/
    183 EFI_STATUS
    184 EFIAPI
    185 EfiDhcp6Start (
    186   IN EFI_DHCP6_PROTOCOL        *This
    187   );
    188 
    189 /**
    190   Stops the DHCPv6 standard S.A.R.R. process.
    191 
    192   The Stop() function is used to stop the DHCPv6 standard process. After this
    193   function is called successfully, the state of Dhcp6 instance is transferred
    194   into the Dhcp6Init. EFI_DHCP6_PROTOCOL.Configure() needs to be called
    195   before DHCPv6 standard process can be started again. This function can be
    196   called when the Dhcp6 instance is in any state.
    197 
    198   @param[in]  This              The pointer to the Dhcp6 protocol.
    199 
    200   @retval EFI_SUCCESS           The Dhcp6 instance is now in the Dhcp6Init state.
    201   @retval EFI_INVALID_PARAMETER This is NULL.
    202 
    203 **/
    204 EFI_STATUS
    205 EFIAPI
    206 EfiDhcp6Stop (
    207   IN EFI_DHCP6_PROTOCOL        *This
    208   );
    209 
    210 /**
    211   Returns the current operating mode data for the Dhcp6 instance.
    212 
    213   The GetModeData() function returns the current operating mode and
    214   cached data packet for the Dhcp6 instance.
    215 
    216   @param[in]  This              The pointer to the Dhcp6 protocol.
    217   @param[out] Dhcp6ModeData     The pointer to the Dhcp6 mode data.
    218   @param[out] Dhcp6ConfigData   The pointer to the Dhcp6 configure data.
    219 
    220   @retval EFI_SUCCESS           The mode data was returned.
    221   @retval EFI_INVALID_PARAMETER This is NULL.
    222   @retval EFI_ACCESS_DENIED     The EFI DHCPv6 Protocol instance has not
    223                                 been configured when Dhcp6ConfigData is
    224                                 not NULL.
    225 **/
    226 EFI_STATUS
    227 EFIAPI
    228 EfiDhcp6GetModeData (
    229   IN  EFI_DHCP6_PROTOCOL       *This,
    230   OUT EFI_DHCP6_MODE_DATA      *Dhcp6ModeData      OPTIONAL,
    231   OUT EFI_DHCP6_CONFIG_DATA    *Dhcp6ConfigData    OPTIONAL
    232   );
    233 
    234 /**
    235   Initializes, changes, or resets the operational settings for the Dhcp6 instance.
    236 
    237   The Configure() function is used to initialize or clean up the configuration
    238   data of the Dhcp6 instance:
    239   - When Dhcp6CfgData is not NULL and Configure() is called successfully, the
    240     configuration data will be initialized in the Dhcp6 instance and the state
    241     of the configured IA will be transferred into Dhcp6Init.
    242   - When Dhcp6CfgData is NULL and Configure() is called successfully, the
    243     configuration data will be cleaned up and no IA will be associated with
    244     the Dhcp6 instance.
    245   To update the configuration data for an Dhcp6 instance, the original data
    246   must be cleaned up before setting the new configuration data.
    247 
    248   @param[in]  This                   The pointer to the Dhcp6 protocol
    249   @param[in]  Dhcp6CfgData           The pointer to the EFI_DHCP6_CONFIG_DATA.
    250 
    251   @retval EFI_SUCCESS           The Dhcp6 is configured successfully with the
    252                                 Dhcp6Init state, or cleaned up the original
    253                                 configuration setting.
    254   @retval EFI_ACCESS_DENIED     The Dhcp6 instance has been already configured
    255                                 when Dhcp6CfgData is not NULL.
    256                                 The Dhcp6 instance has already started the
    257                                 DHCPv6 S.A.R.R when Dhcp6CfgData is NULL.
    258   @retval EFI_INVALID_PARAMETER Some of the parameter is invalid.
    259   @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
    260   @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.
    261 
    262 **/
    263 EFI_STATUS
    264 EFIAPI
    265 EfiDhcp6Configure (
    266   IN EFI_DHCP6_PROTOCOL        *This,
    267   IN EFI_DHCP6_CONFIG_DATA     *Dhcp6CfgData    OPTIONAL
    268   );
    269 
    270 /**
    271   Request configuration information without the assignment of any
    272   Ia addresses of the client.
    273 
    274   The InfoRequest() function is used to request configuration information
    275   without the assignment of any IPv6 address of the client. Client sends
    276   out Information Request packet to obtain the required configuration
    277   information, and DHCPv6 server responds with Reply packet containing
    278   the information for the client. The received Reply packet will be passed
    279   to the user by ReplyCallback function. If user returns EFI_NOT_READY from
    280   ReplyCallback, the Dhcp6 instance will continue to receive other Reply
    281   packets unless timeout according to the Retransmission parameter.
    282   Otherwise, the Information Request exchange process will be finished
    283   successfully if user returns EFI_SUCCESS from ReplyCallback.
    284 
    285   @param[in]  This              The pointer to the Dhcp6 protocol.
    286   @param[in]  SendClientId      If TRUE, the DHCPv6 protocol instance will build Client
    287                                 Identifier option and include it into Information Request
    288                                 packet. Otherwise, Client Identifier option will not be included.
    289   @param[in]  OptionRequest     The pointer to the buffer of option request options.
    290   @param[in]  OptionCount       The option number in the OptionList.
    291   @param[in]  OptionList        The list of appended options.
    292   @param[in]  Retransmission    The pointer to the retransmission of the message.
    293   @param[in]  TimeoutEvent      The event of timeout.
    294   @param[in]  ReplyCallback     The callback function when a reply was received.
    295   @param[in]  CallbackContext   The pointer to the parameter passed to the callback.
    296 
    297   @retval EFI_SUCCESS           The DHCPv6 information request exchange process
    298                                 completed when TimeoutEvent is NULL. Information
    299                                 Request packet has been sent to DHCPv6 server when
    300                                 TimeoutEvent is not NULL.
    301   @retval EFI_NO_RESPONSE       The DHCPv6 information request exchange process failed
    302                                 because of no response, or not all requested-options
    303                                 are responded to by DHCPv6 servers when Timeout happened.
    304   @retval EFI_ABORTED           The DHCPv6 information request exchange process was aborted
    305                                 by the user.
    306   @retval EFI_INVALID_PARAMETER Some parameter is NULL.
    307   @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
    308   @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.
    309 
    310 **/
    311 EFI_STATUS
    312 EFIAPI
    313 EfiDhcp6InfoRequest (
    314   IN EFI_DHCP6_PROTOCOL        *This,
    315   IN BOOLEAN                   SendClientId,
    316   IN EFI_DHCP6_PACKET_OPTION   *OptionRequest,
    317   IN UINT32                    OptionCount,
    318   IN EFI_DHCP6_PACKET_OPTION   *OptionList[]    OPTIONAL,
    319   IN EFI_DHCP6_RETRANSMISSION  *Retransmission,
    320   IN EFI_EVENT                 TimeoutEvent     OPTIONAL,
    321   IN EFI_DHCP6_INFO_CALLBACK   ReplyCallback,
    322   IN VOID                      *CallbackContext OPTIONAL
    323   );
    324 
    325 /**
    326   Manually extend the valid and preferred lifetimes for the IPv6 addresses
    327   of the configured IA and update other configuration parameters by sending
    328   Renew or Rebind packet.
    329 
    330   The RenewRebind() function is used to manually extend the valid and preferred
    331   lifetimes for the IPv6 addresses of the configured IA and update other
    332   configuration parameters by sending a Renew or Rebind packet.
    333   - When RebindRequest is FALSE and the state of the configured IA is Dhcp6Bound,
    334     it will send Renew packet to the previously DHCPv6 server and transfer the
    335     state of the configured IA to Dhcp6Renewing. If valid Reply packet received,
    336     the state transfers to Dhcp6Bound and the valid and preferred timer restarts.
    337     If fails, the state transfers to Dhcp6Bound but the timer continues.
    338   - When RebindRequest is TRUE and the state of the configured IA is Dhcp6Bound,
    339     it will send a Rebind packet. If a valid Reply packet is received, the state transfers
    340     to Dhcp6Bound, and the valid and preferred timer restarts. If it fails, the state
    341     transfers to Dhcp6Init, and the IA can't be used.
    342 
    343   @param[in]  This              The pointer to the Dhcp6 protocol.
    344   @param[in]  RebindRequest     If TRUE, Rebind packet will be sent and enter Dhcp6Rebinding state.
    345                                 Otherwise, Renew packet will be sent and enter Dhcp6Renewing state.
    346 
    347   @retval EFI_SUCCESS           The DHCPv6 renew/rebind exchange process
    348                                 completed and at least one IPv6 address of the
    349                                 configured IA was bound again when
    350                                 EFI_DHCP6_CONFIG_DATA.IaInfoEvent was NULL.
    351                                 The EFI DHCPv6 Protocol instance has sent Renew
    352                                 or Rebind packet when
    353                                 EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL.
    354   @retval EFI_ACCESS_DENIED     The Dhcp6 instance hasn't been configured, or the
    355                                 state of the configured IA is not in Dhcp6Bound.
    356   @retval EFI_ALREADY_STARTED   The state of the configured IA has already entered
    357                                 Dhcp6Renewing when RebindRequest is FALSE.
    358                                 The state of the configured IA has already entered
    359                                 Dhcp6Rebinding when RebindRequest is TRUE.
    360   @retval EFI_ABORTED           The DHCPv6 renew/rebind exchange process aborted
    361                                 by user.
    362   @retval EFI_NO_RESPONSE       The DHCPv6 renew/rebind exchange process failed
    363                                 because of no response.
    364   @retval EFI_NO_MAPPING        No IPv6 address has been bound to the configured
    365                                 IA after the DHCPv6 renew/rebind exchange process.
    366   @retval EFI_INVALID_PARAMETER Some parameter is NULL.
    367   @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.
    368 
    369 **/
    370 EFI_STATUS
    371 EFIAPI
    372 EfiDhcp6RenewRebind (
    373   IN EFI_DHCP6_PROTOCOL        *This,
    374   IN BOOLEAN                   RebindRequest
    375   );
    376 
    377 /**
    378   Inform that one or more addresses assigned by a server are already
    379   in use by another node.
    380 
    381   The Decline() function is used to manually decline the assignment of
    382   IPv6 addresses, which have been already used by another node. If all
    383   IPv6 addresses of the configured IA are declined through this function,
    384   the state of the IA will switch through Dhcp6Declining to Dhcp6Init.
    385   Otherwise, the state of the IA will restore to Dhcp6Bound after the
    386   declining process. The Decline() can only be called when the IA is in
    387   Dhcp6Bound state. If the EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL,
    388   this function is a blocking operation. It will return after the
    389   declining process finishes, or aborted by user.
    390 
    391   @param[in]  This              The pointer to the Dhcp6 protocol.
    392   @param[in]  AddressCount      The number of declining addresses.
    393   @param[in]  Addresses         The pointer to the buffer stored the declining
    394                                 addresses.
    395 
    396   @retval EFI_SUCCESS           The DHCPv6 decline exchange process completed
    397                                 when EFI_DHCP6_CONFIG_DATA.IaInfoEvent was NULL.
    398                                 The Dhcp6 instance has sent Decline packet when
    399                                 EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL.
    400   @retval EFI_ACCESS_DENIED     The Dhcp6 instance hasn't been configured, or the
    401                                 state of the configured IA is not in Dhcp6Bound.
    402   @retval EFI_ABORTED           The DHCPv6 decline exchange process was aborted by the user.
    403   @retval EFI_NOT_FOUND         Any specified IPv6 address is not correlated with
    404                                 the configured IA for this instance.
    405   @retval EFI_INVALID_PARAMETER Some parameter is NULL.
    406   @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.
    407 
    408 **/
    409 EFI_STATUS
    410 EFIAPI
    411 EfiDhcp6Decline (
    412   IN EFI_DHCP6_PROTOCOL        *This,
    413   IN UINT32                    AddressCount,
    414   IN EFI_IPv6_ADDRESS          *Addresses
    415   );
    416 
    417 /**
    418   Release one or more addresses associated with the configured Ia
    419   for the current instance.
    420 
    421   The Release() function is used to manually release the one or more
    422   IPv6 address. If AddressCount is zero, it will release all IPv6
    423   addresses of the configured IA. If all IPv6 addresses of the IA are
    424   released through this function, the state of the IA will switch
    425   through Dhcp6Releasing to Dhcp6Init, otherwise, the state of the
    426   IA will restore to Dhcp6Bound after the releasing process.
    427   The Release() can only be called when the IA is in a Dhcp6Bound state.
    428   If the EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL, the function is
    429   a blocking operation. It will return after the releasing process
    430   finishes, or aborted by user.
    431 
    432   @param[in]  This              The pointer to the Dhcp6 protocol.
    433   @param[in]  AddressCount      The number of releasing addresses.
    434   @param[in]  Addresses         The pointer to the buffer stored the releasing
    435                                 addresses.
    436   @retval EFI_SUCCESS           The DHCPv6 release exchange process has
    437                                 completed when EFI_DHCP6_CONFIG_DATA.IaInfoEvent
    438                                 is NULL. The Dhcp6 instance has sent Release
    439                                 packet when EFI_DHCP6_CONFIG_DATA.IaInfoEvent
    440                                 is not NULL.
    441   @retval EFI_ACCESS_DENIED     The Dhcp6 instance hasn't been configured, or the
    442                                 state of the configured IA is not in Dhcp6Bound.
    443   @retval EFI_ABORTED           The DHCPv6 release exchange process was aborted by the user.
    444   @retval EFI_NOT_FOUND         Any specified IPv6 address is not correlated with
    445                                 the configured IA for this instance.
    446   @retval EFI_INVALID_PARAMETER Some parameter is NULL.
    447   @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.
    448 
    449 **/
    450 EFI_STATUS
    451 EFIAPI
    452 EfiDhcp6Release (
    453   IN EFI_DHCP6_PROTOCOL        *This,
    454   IN UINT32                    AddressCount,
    455   IN EFI_IPv6_ADDRESS          *Addresses
    456   );
    457 
    458 /**
    459   Parse the option data in the Dhcp6 packet.
    460 
    461   The Parse() function is used to retrieve the option list in the DHCPv6 packet.
    462 
    463   @param[in]      This              The pointer to the Dhcp6 protocol.
    464   @param[in]      Packet            The pointer to the Dhcp6 packet.
    465   @param[in, out] OptionCount       The number of option in the packet.
    466   @param[out]     PacketOptionList  The array of pointers to the each option in the packet.
    467 
    468   @retval EFI_SUCCESS           The packet was successfully parsed.
    469   @retval EFI_INVALID_PARAMETER Some parameter is NULL.
    470   @retval EFI_BUFFER_TOO_SMALL  *OptionCount is smaller than the number of options
    471                                 that were found in the Packet.
    472 
    473 **/
    474 EFI_STATUS
    475 EFIAPI
    476 EfiDhcp6Parse (
    477   IN EFI_DHCP6_PROTOCOL        *This,
    478   IN EFI_DHCP6_PACKET          *Packet,
    479   IN OUT UINT32                *OptionCount,
    480   OUT EFI_DHCP6_PACKET_OPTION  *PacketOptionList[]  OPTIONAL
    481   );
    482 
    483 #endif
    484