1 /** @file
2   Support routines for PxeBc.
3 
4 Copyright (c) 2007 - 2015, 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.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 
16 #include "PxeBcImpl.h"
17 
18 
19 /**
20   The common notify function associated with various PxeBc events.
21 
22   @param  Event     The event signaled.
23   @param  Context   The context.
24 
25 **/
26 VOID
27 EFIAPI
PxeBcCommonNotify(IN EFI_EVENT Event,IN VOID * Context)28 PxeBcCommonNotify (
29   IN EFI_EVENT           Event,
30   IN VOID                *Context
31   )
32 {
33   *((BOOLEAN *) Context) = TRUE;
34 }
35 
36 
37 /**
38   This function initialize(or configure) the Udp4Write instance.
39 
40   @param  Udp4       Pointer to the EFI_UDP4_PROTOCOL instance.
41   @param  StationIp  Pointer to the station ip address.
42   @param  SubnetMask Pointer to the subnetmask of the station ip address.
43   @param  Gateway    Pointer to the gateway ip address.
44   @param  SrcPort    Pointer to the srouce port of the station.
45 
46   @retval EFI_SUCCESS           The configuration settings were set, changed, or reset successfully.
47   @retval EFI_NO_MAPPING        When using a default address, configuration (DHCP, BOOTP,
48                                 RARP, etc.) is not finished yet.
49   @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE:
50   @retval EFI_ALREADY_STARTED   The EFI UDPv4 Protocol instance is already started/configured
51                                 and must be stopped/reset before it can be reconfigured.
52   @retval EFI_ACCESS_DENIED     UdpConfigData. AllowDuplicatePort is FALSE
53                                 and UdpConfigData.StationPort is already used by
54                                 other instance.
55   @retval EFI_OUT_OF_RESOURCES  The EFI UDPv4 Protocol driver cannot allocate memory for this
56                                 EFI UDPv4 Protocol instance.
57   @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred and this instance
58                                 was not opened.
59   @retval Others                Please examine the function Udp4->Routes(Udp4, FALSE, &mZeroIp4Addr, &mZeroIp4Addr, Gateway) returns.
60 
61 **/
62 EFI_STATUS
PxeBcConfigureUdpWriteInstance(IN EFI_UDP4_PROTOCOL * Udp4,IN EFI_IPv4_ADDRESS * StationIp,IN EFI_IPv4_ADDRESS * SubnetMask,IN EFI_IPv4_ADDRESS * Gateway,IN OUT UINT16 * SrcPort)63 PxeBcConfigureUdpWriteInstance (
64   IN EFI_UDP4_PROTOCOL  *Udp4,
65   IN EFI_IPv4_ADDRESS   *StationIp,
66   IN EFI_IPv4_ADDRESS   *SubnetMask,
67   IN EFI_IPv4_ADDRESS   *Gateway,
68   IN OUT UINT16         *SrcPort
69   )
70 {
71   EFI_UDP4_CONFIG_DATA  Udp4CfgData;
72   EFI_STATUS            Status;
73 
74   ZeroMem (&Udp4CfgData, sizeof (Udp4CfgData));
75 
76   Udp4CfgData.ReceiveTimeout = PXEBC_DEFAULT_LIFETIME;
77   Udp4CfgData.TypeOfService  = DEFAULT_ToS;
78   Udp4CfgData.TimeToLive     = DEFAULT_TTL;
79   Udp4CfgData.AllowDuplicatePort = TRUE;
80 
81   CopyMem (&Udp4CfgData.StationAddress, StationIp, sizeof (*StationIp));
82   CopyMem (&Udp4CfgData.SubnetMask, SubnetMask, sizeof (*SubnetMask));
83 
84   Udp4CfgData.StationPort    = *SrcPort;
85 
86   //
87   // Reset the instance.
88   //
89   Udp4->Configure (Udp4, NULL);
90 
91   Status = Udp4->Configure (Udp4, &Udp4CfgData);
92   if (!EFI_ERROR (Status) && (Gateway->Addr[0] != 0)) {
93     //
94     // basic configuration OK, need to add the default route entry
95     //
96     Status = Udp4->Routes (Udp4, FALSE, &mZeroIp4Addr, &mZeroIp4Addr, Gateway);
97     if (EFI_ERROR (Status)) {
98       //
99       // roll back
100       //
101       Udp4->Configure (Udp4, NULL);
102     }
103   }
104 
105   if (!EFI_ERROR (Status) && (*SrcPort == 0)) {
106     Udp4->GetModeData (Udp4, &Udp4CfgData, NULL, NULL, NULL);
107     *SrcPort = Udp4CfgData.StationPort;
108   }
109 
110   return Status;
111 }
112 
113 
114 /**
115   Convert number to ASCII value.
116 
117   @param  Number              Numeric value to convert to decimal ASCII value.
118   @param  Buffer              Buffer to place ASCII version of the Number.
119   @param  Length              Length of Buffer.
120 
121 **/
122 VOID
CvtNum(IN UINTN Number,IN UINT8 * Buffer,IN UINTN Length)123 CvtNum (
124   IN UINTN  Number,
125   IN UINT8  *Buffer,
126   IN UINTN   Length
127   )
128 {
129   UINTN Remainder;
130 
131   while (Length > 0) {
132     Remainder = Number % 10;
133     Number /= 10;
134     Length--;
135     Buffer[Length] = (UINT8) ('0' + Remainder);
136   }
137 }
138 
139 
140 /**
141   Convert unsigned int number to decimal number.
142 
143   @param      Number         The unsigned int number will be converted.
144   @param      Buffer         Pointer to the buffer to store the decimal number after transform.
145   @param[in]  BufferSize     The maxsize of the buffer.
146 
147   @return the length of the number after transform.
148 
149 **/
150 UINTN
UtoA10(IN UINTN Number,IN CHAR8 * Buffer,IN UINTN BufferSize)151 UtoA10 (
152   IN UINTN Number,
153   IN CHAR8 *Buffer,
154   IN UINTN BufferSize
155   )
156 {
157   UINTN Index;
158   CHAR8 TempStr[64];
159 
160   Index           = 63;
161   TempStr[Index]  = 0;
162 
163   do {
164     Index--;
165     TempStr[Index]  = (CHAR8) ('0' + (Number % 10));
166     Number          = Number / 10;
167   } while (Number != 0);
168 
169   AsciiStrCpyS (Buffer, BufferSize, &TempStr[Index]);
170 
171   return AsciiStrLen (Buffer);
172 }
173 
174 
175 /**
176   Convert ASCII numeric string to a UINTN value.
177 
178   @param  Buffer  Pointer to the 8-byte unsigned int value.
179 
180   @return UINTN value of the ASCII string.
181 
182 **/
183 UINT64
AtoU64(IN UINT8 * Buffer)184 AtoU64 (
185   IN UINT8 *Buffer
186   )
187 {
188   UINT64  Value;
189   UINT8   Character;
190 
191   Value = 0;
192   while ((Character = *Buffer++) != '\0') {
193     Value = MultU64x32 (Value, 10) + (Character - '0');
194   }
195 
196   return Value;
197 }
198 
199