1/** @file
2    Display the DHCP options
3
4    Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
5    This program and the accompanying materials
6    are licensed and made available under the terms and conditions of the BSD License
7    which accompanies this distribution. The full text of the license may be found at
8    http://opensource.org/licenses/bsd-license.
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#include <WebServer.h>
14#include <Guid/DxeServices.h>
15#include <Pi/PiDxeCis.h>
16
17#include <Protocol/Dhcp4.h>
18#include <Protocol/ServiceBinding.h>
19
20/**
21  Respond with the DHCP options
22
23  @param[in]  SocketFD      The socket's file descriptor to add to the list.
24  @param[in]  pPort         The WSDT_PORT structure address
25  @param[out] pbDone        Address to receive the request completion status
26
27  @retval EFI_SUCCESS       The request was successfully processed
28
29**/
30EFI_STATUS
31DhcpOptionsPage (
32  IN int SocketFD,
33  IN WSDT_PORT * pPort,
34  OUT BOOLEAN * pbDone
35  )
36{
37//  EFI_HANDLE Dhcp4Handle;
38  EFI_DHCP4_MODE_DATA Dhcp4Mode;
39  UINTN HandleCount;
40  EFI_DHCP4_PROTOCOL * pDhcp4;
41  EFI_DHCP4_PACKET * pDhcp4Packet;
42  EFI_HANDLE * pEnd;
43  EFI_HANDLE * pHandle;
44//  EFI_SERVICE_BINDING_PROTOCOL * pService;
45  EFI_STATUS Status;
46
47  DBG_ENTER ( );
48
49  //
50  //  Send the DHCP options
51  //
52  for ( ; ; ) {
53    //
54    //  Send the page header
55    //
56    Status = HttpPageHeader ( SocketFD, pPort, L"DHCP Options" );
57    if ( EFI_ERROR ( Status )) {
58      break;
59    }
60
61    //
62    //  Build the header
63    //
64    Status = HttpSendAnsiString ( SocketFD,
65                                  pPort,
66                                  "<h1>" );
67    if ( EFI_ERROR ( Status )) {
68      break;
69    }
70    Status = HttpSendUnicodeString ( SocketFD,
71                                     pPort,
72                                     L"DHCP Options" );
73    if ( EFI_ERROR ( Status )) {
74      break;
75    }
76    Status = HttpSendAnsiString ( SocketFD,
77                                  pPort,
78                                  "</h1>\r\n" );
79    if ( EFI_ERROR ( Status )) {
80      break;
81    }
82
83    //
84    //  Attempt to locate DHCP clients
85    //
86    Status = gBS->LocateHandleBuffer ( ByProtocol,
87//                                       &gEfiDhcp4ServiceBindingProtocolGuid,
88                                       &gEfiDhcp4ProtocolGuid,
89                                       NULL,
90                                       &HandleCount,
91                                       &pHandle );
92    if ( EFI_ERROR ( Status )) {
93      Status = HttpSendAnsiString ( SocketFD,
94                                    pPort,
95                                    "DHCP not in use" );
96      if ( EFI_ERROR ( Status )) {
97        break;
98      }
99    }
100    else {
101      //
102      //  Walk the list of handles
103      //
104      pEnd = &pHandle [ HandleCount ];
105      while ( pEnd > pHandle ) {
106/*
107        //
108        //  Get the DHCP service binding
109        //
110        Status = gBS->OpenProtocol ( *pHandle,
111                                      &gEfiDhcp4ServiceBindingProtocolGuid,
112                                      &pService,
113                                      NULL,
114                                      gImageHandle,
115                                      EFI_OPEN_PROTOCOL_GET_PROTOCOL );
116        if ( EFI_ERROR ( Status )) {
117          Status = HttpSendAnsiString ( SocketFD,
118                                        pPort,
119                                        "Failed to open gEfiDhcp4ServiceBindingProtocolGuid" );
120          break;
121        }
122
123        //
124        //  Get the DHCP handle
125        //
126        Status = pService->CreateChild ( pService,
127                                         &Dhcp4Handle );
128        if ( EFI_ERROR ( Status )) {
129          Status = HttpSendAnsiString ( SocketFD,
130                                        pPort,
131                                        "Failed to create DHCP4 child" );
132        }
133        else {
134*/
135          //
136          //  Get the DHCP protocol
137          //
138          Status = gBS->OpenProtocol ( *pHandle,
139//                                       Dhcp4Handle,
140                                       &gEfiDhcp4ProtocolGuid,
141                                       (VOID **)&pDhcp4,
142                                       NULL,
143                                       gImageHandle,
144                                       EFI_OPEN_PROTOCOL_GET_PROTOCOL );
145          if ( EFI_ERROR ( Status )) {
146            Status = HttpSendAnsiString ( SocketFD,
147                                          pPort,
148                                          "Failed to open gEfiDhcp4ProtocolGuid" );
149          }
150          else {
151            //
152            //  Get the DHCP packet
153            //
154            Status = pDhcp4->GetModeData ( pDhcp4,
155                                           &Dhcp4Mode );
156            if ( EFI_ERROR ( Status )) {
157              Status = HttpSendAnsiString ( SocketFD,
158                                            pPort,
159                                            "Failed to get DHCP4 mode" );
160            }
161            else {
162              //
163              //  Get the last packet
164              //
165              pDhcp4Packet = Dhcp4Mode.ReplyPacket;
166              if ( NULL == pDhcp4Packet ) {
167                Status = HttpSendAnsiString ( SocketFD,
168                                              pPort,
169                                              "No DHCP reply received!<br/>DHCP Mode:<br/>" );
170                if ( EFI_ERROR ( Status )) {
171                  break;
172                }
173
174                //
175                //  Display the DHCP mode data
176                //
177                Status = HttpSendDump ( SocketFD,
178                                        pPort,
179                                        sizeof ( Dhcp4Mode ),
180                                        (UINT8 *)&Dhcp4Mode );
181              }
182              else {
183                //
184                //  Display the DHCP packet
185                //
186                Status = HttpSendDump ( SocketFD,
187                                        pPort,
188                                        pDhcp4Packet->Length,
189                                        (UINT8 *)&pDhcp4Packet->Dhcp4 );
190              }
191            }
192/*
193          }
194
195          //
196          //  Done with the DHCP protocol
197          //
198          pService->DestroyChild ( pService,
199                                   Dhcp4Handle );
200*/
201        }
202
203        //
204        //  Set the next service binding
205        //
206        pHandle += 1;
207      }
208    }
209
210    //
211    //  Send the page trailer
212    //
213    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
214    break;
215  }
216
217  //
218  //  Return the operation status
219  //
220  DBG_EXIT_STATUS ( Status );
221  return Status;
222}
223