]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_udp.c
remove unnecessary check for NULL pointer.
[mirror_edk2.git] / EdkModulePkg / Universal / Network / PxeBc / Dxe / pxe_bc_udp.c
CommitLineData
878ddf1f 1/*++\r
2\r
e5f461a8 3Copyright (c) 2006 - 2007, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
878ddf1f 11\r
12Module Name:\r
13 pxe_bc_udp.c\r
14\r
15Abstract:\r
16\r
17--*/\r
18\r
19\r
4cbd855e 20#include "Bc.h"\r
878ddf1f 21\r
22//\r
23// //////////////////////////////////////////////////////////////////////\r
24//\r
25// Udp Write Routine - called by base code - e.g. TFTP - already locked\r
26//\r
27EFI_STATUS\r
28UdpWrite (\r
29 IN PXE_BASECODE_DEVICE *Private,\r
30 IN UINT16 OpFlags,\r
31 IN EFI_IP_ADDRESS *DestIpPtr,\r
32 IN EFI_PXE_BASE_CODE_UDP_PORT *DestPortPtr,\r
33 IN EFI_IP_ADDRESS *GatewayIpPtr, OPTIONAL\r
34 IN EFI_IP_ADDRESS *SrcIpPtr, OPTIONAL\r
35 IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPortPtr, OPTIONAL\r
36 IN UINTN *HeaderSizePtr, OPTIONAL\r
37 IN VOID *HeaderPtr, OPTIONAL\r
38 IN UINTN *BufferSizeptr,\r
39 IN VOID *BufferPtr\r
40 )\r
41/*++\r
42Routine description:\r
43 UDP write packet.\r
44\r
45Parameters:\r
46 Private := Pointer to PxeBc interface\r
e5f461a8 47 OpFlags :=\r
48 DestIpPtr :=\r
49 DestPortPtr :=\r
50 GatewayIpPtr :=\r
51 SrcIpPtr :=\r
52 SrcPortPtr :=\r
53 HeaderSizePtr :=\r
54 HeaderPtr :=\r
55 BufferSizeptr :=\r
56 BufferPtr :=\r
878ddf1f 57\r
58Returns:\r
e5f461a8 59 EFI_SUCCESS :=\r
60 EFI_INVALID_PARAMETER :=\r
61 other :=\r
878ddf1f 62--*/\r
63{\r
64 UINTN TotalLength;\r
65 UINTN HeaderSize;\r
66 EFI_PXE_BASE_CODE_UDP_PORT DefaultSrcPort;\r
67\r
68 //\r
69 //\r
70 //\r
71 HeaderSize = (HeaderSizePtr != NULL) ? *HeaderSizePtr : 0;\r
72 DefaultSrcPort = 0;\r
73\r
74 //\r
75 // check parameters\r
76 //\r
77 if (BufferSizeptr == NULL ||\r
78 BufferPtr == NULL ||\r
79 DestIpPtr == NULL ||\r
80 DestPortPtr == NULL ||\r
81 (HeaderSizePtr != NULL && *HeaderSizePtr == 0) ||\r
82 (HeaderSize != 0 && HeaderPtr == NULL) ||\r
83 (GatewayIpPtr != NULL && !IS_INADDR_UNICAST(GatewayIpPtr)) ||\r
84 (OpFlags &~(EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT | EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT))\r
85 ) {\r
86 DEBUG (\r
87 (EFI_D_WARN,\r
88 "\nUdpWrite() Exit #1 %xh (%r)",\r
89 EFI_INVALID_PARAMETER,\r
90 EFI_INVALID_PARAMETER)\r
91 );\r
92\r
93 return EFI_INVALID_PARAMETER;\r
94 }\r
95\r
96 TotalLength = *BufferSizeptr + HeaderSize + sizeof (UDPV4_HEADER);\r
97\r
98 if (TotalLength > 0x0000ffff) {\r
99 DEBUG (\r
100 (EFI_D_WARN,\r
101 "\nUdpWrite() Exit #2 %xh (%r)",\r
102 EFI_BAD_BUFFER_SIZE,\r
103 EFI_BAD_BUFFER_SIZE)\r
104 );\r
105\r
106 return EFI_BAD_BUFFER_SIZE;\r
107 }\r
108\r
109 if (SrcIpPtr == NULL) {\r
110 SrcIpPtr = &Private->EfiBc.Mode->StationIp;\r
111 }\r
112\r
113 if (SrcPortPtr == NULL) {\r
114 SrcPortPtr = &DefaultSrcPort;\r
115 OpFlags |= EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT;\r
116 }\r
117\r
118 if (OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) {\r
119 *SrcPortPtr = Private->RandomPort;\r
120\r
121 if (++Private->RandomPort == 0) {\r
122 Private->RandomPort = PXE_RND_PORT_LOW;\r
123 }\r
124 }\r
125\r
126#define IpTxBuffer ((IPV4_BUFFER *) Private->TransmitBufferPtr)\r
127 //\r
128 // build pseudo header and udp header in transmit buffer\r
129 //\r
130#define Udpv4Base ((UDPV4_HEADERS *) (IpTxBuffer->u.Data - sizeof (UDPV4_PSEUDO_HEADER)))\r
131\r
132 Udpv4Base->Udpv4PseudoHeader.SrcAddr.L = SrcIpPtr->Addr[0];\r
133 Udpv4Base->Udpv4PseudoHeader.DestAddr.L = DestIpPtr->Addr[0];\r
134 Udpv4Base->Udpv4PseudoHeader.Zero = 0;\r
135 Udpv4Base->Udpv4PseudoHeader.Protocol = PROT_UDP;\r
136 Udpv4Base->Udpv4PseudoHeader.TotalLength = HTONS (TotalLength);\r
137 Udpv4Base->Udpv4Header.SrcPort = HTONS (*SrcPortPtr);\r
138 Udpv4Base->Udpv4Header.DestPort = HTONS (*DestPortPtr);\r
139 Udpv4Base->Udpv4Header.TotalLength = Udpv4Base->Udpv4PseudoHeader.TotalLength;\r
140 Udpv4Base->Udpv4Header.Checksum = 0;\r
141\r
142 if (HeaderSize != 0) {\r
143 CopyMem (IpTxBuffer->u.Udp.Data, HeaderPtr, HeaderSize);\r
144 }\r
145\r
146 HeaderSize += sizeof (UDPV4_HEADER);\r
147\r
148 Udpv4Base->Udpv4Header.Checksum = IpChecksum2 (\r
149 (UINT16 *) Udpv4Base,\r
150 HeaderSize + sizeof (UDPV4_PSEUDO_HEADER),\r
151 (UINT16 *) BufferPtr,\r
152 (UINT16) *BufferSizeptr\r
153 );\r
154\r
155 if (Udpv4Base->Udpv4Header.Checksum == 0) {\r
156 Udpv4Base->Udpv4Header.Checksum = 0xffff;\r
157 //\r
158 // transmit zero checksum as ones complement\r
159 //\r
160 }\r
161\r
162 return Ip4Send (\r
163 Private,\r
164 OpFlags,\r
165 PROT_UDP,\r
166 Udpv4Base->Udpv4PseudoHeader.SrcAddr.L,\r
167 Udpv4Base->Udpv4PseudoHeader.DestAddr.L,\r
168 (GatewayIpPtr) ? GatewayIpPtr->Addr[0] : 0,\r
169 HeaderSize,\r
170 BufferPtr,\r
171 *BufferSizeptr\r
172 );\r
173}\r
174//\r
175// //////////////////////////////////////////////////////////\r
176//\r
177// BC Udp Write Routine\r
178//\r
179EFI_STATUS\r
180EFIAPI\r
181BcUdpWrite (\r
182 IN EFI_PXE_BASE_CODE_PROTOCOL *This,\r
183 IN UINT16 OpFlags,\r
184 IN EFI_IP_ADDRESS *DestIpPtr,\r
185 IN EFI_PXE_BASE_CODE_UDP_PORT *DestPortPtr,\r
186 IN EFI_IP_ADDRESS *GatewayIpPtr, OPTIONAL\r
187 IN EFI_IP_ADDRESS *SrcIpPtr, OPTIONAL\r
188 IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPortPtr, OPTIONAL\r
189 IN UINTN *HeaderSizePtr, OPTIONAL\r
190 IN VOID *HeaderPtr, OPTIONAL\r
191 IN UINTN *BufferSizeptr,\r
192 IN VOID *BufferPtr\r
193 )\r
194/*++\r
195Routine description:\r
196 UDP write API entry point.\r
197\r
198Parameters:\r
199 This := Pointer to PxeBc interface.\r
e5f461a8 200 OpFlags :=\r
201 DestIpPtr :=\r
202 DestPortPtr :=\r
203 GatewayIpPtr :=\r
204 SrcIpPtr :=\r
205 SrcPortPtr :=\r
206 HeaderSizePtr :=\r
207 HeaderPtr :=\r
208 BufferSizeptr :=\r
209 BufferPtr :=\r
878ddf1f 210\r
211Returns:\r
e5f461a8 212 EFI_SUCCESS :=\r
213 other :=\r
878ddf1f 214--*/\r
215{\r
216 EFI_STATUS StatCode;\r
217 PXE_BASECODE_DEVICE *Private;\r
218\r
219 //\r
220 // Lock the instance data and make sure started\r
221 //\r
222 StatCode = EFI_SUCCESS;\r
223\r
224 if (This == NULL) {\r
225 DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));\r
226 return EFI_INVALID_PARAMETER;\r
227 }\r
228\r
229 Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);\r
230\r
231 if (Private == NULL) {\r
232 DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));\r
233 return EFI_INVALID_PARAMETER;\r
234 }\r
235\r
236 EfiAcquireLock (&Private->Lock);\r
237\r
238 if (This->Mode == NULL || !This->Mode->Started) {\r
239 DEBUG ((EFI_D_ERROR, "BC was not started."));\r
240 EfiReleaseLock (&Private->Lock);\r
241 return EFI_NOT_STARTED;\r
242 }\r
243\r
244 Private->Function = EFI_PXE_BASE_CODE_FUNCTION_UDP_WRITE;\r
245\r
246 //\r
247 // Issue BC command\r
248 //\r
249 StatCode = UdpWrite (\r
250 Private,\r
251 OpFlags,\r
252 DestIpPtr,\r
253 DestPortPtr,\r
254 GatewayIpPtr,\r
255 SrcIpPtr,\r
256 SrcPortPtr,\r
257 HeaderSizePtr,\r
258 HeaderPtr,\r
259 BufferSizeptr,\r
260 BufferPtr\r
261 );\r
262\r
263 //\r
264 // Unlock the instance data\r
265 //\r
266 EfiReleaseLock (&Private->Lock);\r
267 return StatCode;\r
268}\r
269//\r
270// /////////////////////////////////////////////////////////////////////\r
271//\r
272// Udp Read Routine - called by base code - e.g. TFTP - already locked\r
273//\r
274EFI_STATUS\r
275UdpRead (\r
276 IN PXE_BASECODE_DEVICE *Private,\r
277 IN UINT16 OpFlags,\r
278 IN OUT EFI_IP_ADDRESS *DestIpPtr, OPTIONAL\r
279 IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPortPtr, OPTIONAL\r
280 IN OUT EFI_IP_ADDRESS *SrcIpPtr, OPTIONAL\r
281 IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPortPtr, OPTIONAL\r
282 IN UINTN *HeaderSizePtr, OPTIONAL\r
283 IN VOID *HeaderPtr, OPTIONAL\r
284 IN OUT UINTN *BufferSizeptr,\r
285 IN VOID *BufferPtr,\r
286 EFI_EVENT TimeoutEvent\r
287 )\r
288/*++\r
289Routine description:\r
290 UDP read packet.\r
291\r
292Parameters:\r
293 Private := Pointer to PxeBc interface\r
e5f461a8 294 OpFlags :=\r
295 DestIpPtr :=\r
296 DestPortPtr :=\r
297 SrcIpPtr :=\r
298 SrcPortPtr :=\r
299 HeaderSizePtr :=\r
300 HeaderPtr :=\r
301 BufferSizeptr :=\r
302 BufferPtr :=\r
878ddf1f 303 TimeoutEvent :=\r
304\r
305Returns:\r
e5f461a8 306 EFI_SUCCESS :=\r
307 EFI_INVALID_PARAMETER :=\r
308 other :=\r
878ddf1f 309--*/\r
310{\r
311 EFI_STATUS StatCode;\r
312 EFI_IP_ADDRESS TmpSrcIp;\r
313 EFI_IP_ADDRESS TmpDestIp;\r
314 UINTN BufferSize;\r
315 UINTN HeaderSize;\r
316\r
317 //\r
318 // combination structure of pseudo header/udp header\r
319 //\r
320#pragma pack (1)\r
321 struct {\r
322 UDPV4_PSEUDO_HEADER Udpv4PseudoHeader;\r
323 UDPV4_HEADER Udpv4Header;\r
324 UINT8 ProtHdr[64];\r
325 } Hdrs;\r
326#pragma pack ()\r
327\r
328 HeaderSize = (HeaderSizePtr != NULL) ? *HeaderSizePtr : 0;\r
329 //\r
330 // read [with filtering]\r
331 // check parameters\r
332 //\r
333 if (BufferSizeptr == NULL ||\r
334 BufferPtr == NULL ||\r
335 (HeaderSize != 0 && HeaderPtr == NULL) ||\r
336 (OpFlags &~UDP_FILTER_MASK)\r
337 //\r
338 // if filtering on a particular IP/Port, need it\r
339 //\r
340 ||\r
341 (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP) && SrcIpPtr == NULL) ||\r
342 (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) && SrcPortPtr == NULL) ||\r
343 (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) && DestPortPtr == NULL)\r
344 ) {\r
345 DEBUG ((EFI_D_INFO, "\nUdpRead() Exit #1 Invalid Parameter"));\r
346 return EFI_INVALID_PARAMETER;\r
347 }\r
348\r
349 //\r
350 // in case we loop\r
351 //\r
352 BufferSize = *BufferSizeptr;\r
353 //\r
354 // we need source and dest IPs for pseudo header\r
355 //\r
356 if (SrcIpPtr == NULL) {\r
357 SrcIpPtr = &TmpSrcIp;\r
358 }\r
359\r
360 if (DestIpPtr == NULL) {\r
361 DestIpPtr = &TmpDestIp;\r
362 CopyMem (&TmpDestIp, &Private->EfiBc.Mode->StationIp, sizeof (TmpDestIp));\r
363 }\r
364\r
878ddf1f 365 for (;;) {\r
366 *BufferSizeptr = BufferSize;\r
367\r
368 StatCode = IpReceive (\r
369 Private,\r
370 OpFlags,\r
371 SrcIpPtr,\r
372 DestIpPtr,\r
373 PROT_UDP,\r
374 &Hdrs.Udpv4Header,\r
375 HeaderSize + sizeof Hdrs.Udpv4Header,\r
376 BufferPtr,\r
377 BufferSizeptr,\r
378 TimeoutEvent\r
379 );\r
380\r
381 if (StatCode == EFI_SUCCESS || StatCode == EFI_BUFFER_TOO_SMALL) {\r
382 UINT16 SPort;\r
383 UINT16 DPort;\r
384\r
385 SPort = NTOHS (Hdrs.Udpv4Header.SrcPort);\r
386 DPort = NTOHS (Hdrs.Udpv4Header.DestPort);\r
387\r
388 //\r
389 // do filtering\r
390 //\r
391 if (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) && *SrcPortPtr != SPort) {\r
392 continue;\r
393 }\r
394\r
395 if (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) && *DestPortPtr != DPort) {\r
396 continue;\r
397 }\r
398 //\r
399 // check checksum\r
400 //\r
401 if (StatCode == EFI_SUCCESS && Hdrs.Udpv4Header.Checksum) {\r
402 Hdrs.Udpv4PseudoHeader.SrcAddr.L = SrcIpPtr->Addr[0];\r
403 Hdrs.Udpv4PseudoHeader.DestAddr.L = DestIpPtr->Addr[0];\r
404 Hdrs.Udpv4PseudoHeader.Zero = 0;\r
405 Hdrs.Udpv4PseudoHeader.Protocol = PROT_UDP;\r
406 Hdrs.Udpv4PseudoHeader.TotalLength = Hdrs.Udpv4Header.TotalLength;\r
407\r
408 if (Hdrs.Udpv4Header.Checksum == 0xffff) {\r
409 Hdrs.Udpv4Header.Checksum = 0;\r
410 }\r
411\r
412 if (IpChecksum2 (\r
413 (UINT16 *) &Hdrs.Udpv4PseudoHeader,\r
414 HeaderSize + sizeof (Hdrs.Udpv4PseudoHeader) + sizeof (Hdrs.Udpv4Header),\r
415 (UINT16 *) BufferPtr,\r
416 *BufferSizeptr\r
417 )) {\r
418 DEBUG (\r
419 (EFI_D_INFO,\r
420 "\nUdpRead() Hdrs.Udpv4PseudoHeader == %Xh",\r
421 &Hdrs.Udpv4PseudoHeader)\r
422 );\r
423 DEBUG (\r
424 (EFI_D_INFO,\r
425 "\nUdpRead() Header size == %d",\r
426 HeaderSize + sizeof (Hdrs.Udpv4PseudoHeader))\r
427 );\r
428 DEBUG (\r
429 (EFI_D_INFO,\r
430 "\nUdpRead() BufferPtr == %Xh",\r
431 BufferPtr)\r
432 );\r
433 DEBUG (\r
434 (EFI_D_INFO,\r
435 "\nUdpRead() Buffer size == %d",\r
436 *BufferSizeptr)\r
437 );\r
438 DEBUG ((EFI_D_INFO, "\nUdpRead() Exit #2 Device Error"));\r
439 return EFI_DEVICE_ERROR;\r
440 }\r
441 }\r
442 //\r
443 // all passed\r
444 //\r
445 if (SrcPortPtr != NULL) {\r
446 *SrcPortPtr = SPort;\r
447 }\r
448\r
449 if (DestPortPtr != NULL) {\r
450 *DestPortPtr = DPort;\r
451 }\r
452\r
453 if (HeaderSize != 0) {\r
454 CopyMem (HeaderPtr, Hdrs.ProtHdr, HeaderSize);\r
455 }\r
456 }\r
457\r
4ba61e5e 458 if ((StatCode != EFI_SUCCESS) && (StatCode != EFI_TIMEOUT)) {\r
878ddf1f 459 DEBUG (\r
460 (EFI_D_INFO,\r
461 "\nUdpRead() Exit #3 %Xh %r",\r
462 StatCode,\r
463 StatCode)\r
464 );\r
465 }\r
466\r
467 return StatCode;\r
468 }\r
469}\r
470//\r
471// //////////////////////////////////////////////////////////\r
472//\r
473// BC Udp Read Routine\r
474//\r
475EFI_STATUS\r
476EFIAPI\r
477BcUdpRead (\r
478 IN EFI_PXE_BASE_CODE_PROTOCOL *This,\r
479 IN UINT16 OpFlags,\r
480 IN OUT EFI_IP_ADDRESS *DestIp, OPTIONAL\r
481 IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort, OPTIONAL\r
482 IN OUT EFI_IP_ADDRESS *SrcIp, OPTIONAL\r
483 IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort, OPTIONAL\r
484 IN UINTN *HeaderSize, OPTIONAL\r
485 IN VOID *HeaderPtr, OPTIONAL\r
486 IN OUT UINTN *BufferSize,\r
487 IN VOID *BufferPtr\r
488 )\r
489/*++\r
490Routine description:\r
491 UDP read API entry point.\r
492\r
493Parameters:\r
494 This := Pointer to PxeBc interface.\r
e5f461a8 495 OpFlags :=\r
496 DestIpPtr :=\r
497 DestPortPtr :=\r
498 SrcIpPtr :=\r
499 SrcPortPtr :=\r
500 HeaderSizePtr :=\r
501 HeaderPtr :=\r
502 BufferSizeptr :=\r
503 BufferPtr :=\r
878ddf1f 504\r
505Returns:\r
e5f461a8 506 EFI_SUCCESS :=\r
507 other :=\r
878ddf1f 508--*/\r
509{\r
510 EFI_STATUS StatCode;\r
511 PXE_BASECODE_DEVICE *Private;\r
512\r
513 //\r
514 // Lock the instance data and make sure started\r
515 //\r
516 StatCode = EFI_SUCCESS;\r
517\r
518 if (This == NULL) {\r
519 DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));\r
520 return EFI_INVALID_PARAMETER;\r
521 }\r
522\r
523 Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);\r
524\r
525 if (Private == NULL) {\r
526 DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));\r
527 return EFI_INVALID_PARAMETER;\r
528 }\r
529\r
530 EfiAcquireLock (&Private->Lock);\r
531\r
532 if (This->Mode == NULL || !This->Mode->Started) {\r
533 DEBUG ((EFI_D_ERROR, "BC was not started."));\r
534 EfiReleaseLock (&Private->Lock);\r
535 return EFI_NOT_STARTED;\r
536 }\r
537\r
538 Private->Function = EFI_PXE_BASE_CODE_FUNCTION_UDP_READ;\r
539\r
540 //\r
541 // Issue BC command\r
542 //\r
543 StatCode = UdpRead (\r
544 Private,\r
545 OpFlags,\r
546 DestIp,\r
547 DestPort,\r
548 SrcIp,\r
549 SrcPort,\r
550 HeaderSize,\r
551 HeaderPtr,\r
552 BufferSize,\r
553 BufferPtr,\r
554 0\r
555 );\r
556\r
557 //\r
558 // Unlock the instance data and return\r
559 //\r
560 EfiReleaseLock (&Private->Lock);\r
561 return StatCode;\r
562}\r
563\r
564/* eof - pxe_bc_udp.c */\r