TianoCore EDK2 master
Loading...
Searching...
No Matches
Dhcp4Option.c
Go to the documentation of this file.
1
9#include "Dhcp4Impl.h"
10
17 { DHCP4_TAG_NETMASK, DHCP_OPTION_IP, 1, 1, TRUE },
18 { DHCP4_TAG_TIME_OFFSET, DHCP_OPTION_INT32, 1, 1, FALSE },
19 { DHCP4_TAG_ROUTER, DHCP_OPTION_IP, 1, -1, TRUE },
20 { DHCP4_TAG_TIME_SERVER, DHCP_OPTION_IP, 1, -1, FALSE },
21 { DHCP4_TAG_NAME_SERVER, DHCP_OPTION_IP, 1, -1, FALSE },
22 { DHCP4_TAG_DNS_SERVER, DHCP_OPTION_IP, 1, -1, FALSE },
23 { DHCP4_TAG_LOG_SERVER, DHCP_OPTION_IP, 1, -1, FALSE },
24 { DHCP4_TAG_COOKIE_SERVER, DHCP_OPTION_IP, 1, -1, FALSE },
25 { DHCP4_TAG_LPR_SERVER, DHCP_OPTION_IP, 1, -1, FALSE },
26 { DHCP4_TAG_IMPRESS_SERVER, DHCP_OPTION_IP, 1, -1, FALSE },
27 { DHCP4_TAG_RL_SERVER, DHCP_OPTION_IP, 1, -1, FALSE },
28 { DHCP4_TAG_HOSTNAME, DHCP_OPTION_INT8, 1, -1, FALSE },
29 { DHCP4_TAG_BOOTFILE_LEN, DHCP_OPTION_INT16, 1, 1, FALSE },
30 { DHCP4_TAG_DUMP, DHCP_OPTION_INT8, 1, -1, FALSE },
31 { DHCP4_TAG_DOMAINNAME, DHCP_OPTION_INT8, 1, -1, FALSE },
32 { DHCP4_TAG_SWAP_SERVER, DHCP_OPTION_IP, 1, 1, FALSE },
33 { DHCP4_TAG_ROOTPATH, DHCP_OPTION_INT8, 1, -1, FALSE },
34 { DHCP4_TAG_EXTEND_PATH, DHCP_OPTION_INT8, 1, -1, FALSE },
35
36 { DHCP4_TAG_IPFORWARD, DHCP_OPTION_SWITCH, 1, 1, FALSE },
37 { DHCP4_TAG_NONLOCAL_SRR, DHCP_OPTION_SWITCH, 1, 1, FALSE },
38 { DHCP4_TAG_POLICY_SRR, DHCP_OPTION_IPPAIR, 1, -1, FALSE },
39 { DHCP4_TAG_EMTU, DHCP_OPTION_INT16, 1, 1, FALSE },
40 { DHCP4_TAG_TTL, DHCP_OPTION_INT8, 1, 1, FALSE },
41 { DHCP4_TAG_PATHMTU_AGE, DHCP_OPTION_INT32, 1, 1, FALSE },
42 { DHCP4_TAG_PATHMTU_PLATEAU, DHCP_OPTION_INT16, 1, -1, FALSE },
43
44 { DHCP4_TAG_IFMTU, DHCP_OPTION_INT16, 1, 1, FALSE },
45 { DHCP4_TAG_SUBNET_LOCAL, DHCP_OPTION_SWITCH, 1, 1, FALSE },
46 { DHCP4_TAG_BROADCAST, DHCP_OPTION_IP, 1, 1, FALSE },
47 { DHCP4_TAG_DISCOVER_MASK, DHCP_OPTION_SWITCH, 1, 1, FALSE },
48 { DHCP4_TAG_SUPPLY_MASK, DHCP_OPTION_SWITCH, 1, 1, FALSE },
49 { DHCP4_TAG_DISCOVER_ROUTE, DHCP_OPTION_SWITCH, 1, 1, FALSE },
50 { DHCP4_TAG_ROUTER_SOLICIT, DHCP_OPTION_IP, 1, 1, FALSE },
51 { DHCP4_TAG_STATIC_ROUTE, DHCP_OPTION_IPPAIR, 1, -1, FALSE },
52
53 { DHCP4_TAG_TRAILER, DHCP_OPTION_SWITCH, 1, 1, FALSE },
54 { DHCP4_TAG_ARPAGE, DHCP_OPTION_INT32, 1, 1, FALSE },
55 { DHCP4_TAG_ETHER_ENCAP, DHCP_OPTION_SWITCH, 1, 1, FALSE },
56
57 { DHCP4_TAG_TCP_TTL, DHCP_OPTION_INT8, 1, 1, FALSE },
58 { DHCP4_TAG_KEEP_INTERVAL, DHCP_OPTION_INT32, 1, 1, FALSE },
59 { DHCP4_TAG_KEEP_GARBAGE, DHCP_OPTION_SWITCH, 1, 1, FALSE },
60
61 { DHCP4_TAG_NIS_DOMAIN, DHCP_OPTION_INT8, 1, -1, FALSE },
62 { DHCP4_TAG_NIS_SERVER, DHCP_OPTION_IP, 1, -1, FALSE },
63 { DHCP4_TAG_NTP_SERVER, DHCP_OPTION_IP, 1, -1, FALSE },
64 { DHCP4_TAG_VENDOR, DHCP_OPTION_INT8, 1, -1, FALSE },
65 { DHCP4_TAG_NBNS, DHCP_OPTION_IP, 1, -1, FALSE },
66 { DHCP4_TAG_NBDD, DHCP_OPTION_IP, 1, -1, FALSE },
67 { DHCP4_TAG_NBTYPE, DHCP_OPTION_INT8, 1, 1, FALSE },
68 { DHCP4_TAG_NBSCOPE, DHCP_OPTION_INT8, 1, -1, FALSE },
69 { DHCP4_TAG_XFONT, DHCP_OPTION_IP, 1, -1, FALSE },
70 { DHCP4_TAG_XDM, DHCP_OPTION_IP, 1, -1, FALSE },
71
72 { DHCP4_TAG_REQUEST_IP, DHCP_OPTION_IP, 1, 1, FALSE },
73 { DHCP4_TAG_LEASE, DHCP_OPTION_INT32, 1, 1, TRUE },
74 { DHCP4_TAG_OVERLOAD, DHCP_OPTION_INT8, 1, 1, TRUE },
75 { DHCP4_TAG_MSG_TYPE, DHCP_OPTION_INT8, 1, 1, TRUE },
76 { DHCP4_TAG_SERVER_ID, DHCP_OPTION_IP, 1, 1, TRUE },
77 { DHCP4_TAG_PARA_LIST, DHCP_OPTION_INT8, 1, -1, FALSE },
78 { DHCP4_TAG_MESSAGE, DHCP_OPTION_INT8, 1, -1, FALSE },
79 { DHCP4_TAG_MAXMSG, DHCP_OPTION_INT16, 1, 1, FALSE },
80 { DHCP4_TAG_T1, DHCP_OPTION_INT32, 1, 1, TRUE },
81 { DHCP4_TAG_T2, DHCP_OPTION_INT32, 1, 1, TRUE },
82 { DHCP4_TAG_VENDOR_CLASS_ID, DHCP_OPTION_INT8, 1, -1, FALSE },
83 { DHCP4_TAG_CLIENT_ID, DHCP_OPTION_INT8, 2, -1, FALSE },
84
85 { DHCP4_TAG_NISPLUS, DHCP_OPTION_INT8, 1, -1, FALSE },
86 { DHCP4_TAG_NISPLUS_SERVER, DHCP_OPTION_IP, 1, -1, FALSE },
87
88 { DHCP4_TAG_TFTP, DHCP_OPTION_INT8, 1, -1, FALSE },
89 { DHCP4_TAG_BOOTFILE, DHCP_OPTION_INT8, 1, -1, FALSE },
90
91 { DHCP4_TAG_MOBILEIP, DHCP_OPTION_IP, 0, -1, FALSE },
92 { DHCP4_TAG_SMTP, DHCP_OPTION_IP, 1, -1, FALSE },
93 { DHCP4_TAG_POP3, DHCP_OPTION_IP, 1, -1, FALSE },
94 { DHCP4_TAG_NNTP, DHCP_OPTION_IP, 1, -1, FALSE },
95 { DHCP4_TAG_WWW, DHCP_OPTION_IP, 1, -1, FALSE },
96 { DHCP4_TAG_FINGER, DHCP_OPTION_IP, 1, -1, FALSE },
97 { DHCP4_TAG_IRC, DHCP_OPTION_IP, 1, -1, FALSE },
98 { DHCP4_TAG_STTALK, DHCP_OPTION_IP, 1, -1, FALSE },
99 { DHCP4_TAG_STDA, DHCP_OPTION_IP, 1, -1, FALSE },
100
101 { DHCP4_TAG_CLASSLESS_ROUTE, DHCP_OPTION_INT8, 5, -1, FALSE },
102};
103
115 IN UINT8 Tag
116 )
117{
118 INTN Left;
119 INTN Right;
120 INTN Middle;
121
122 Left = 0;
123 Right = sizeof (DhcpOptionFormats) / sizeof (DHCP_OPTION_FORMAT) - 1;
124
125 while (Right >= Left) {
126 Middle = (Left + Right) / 2;
127
128 if (Tag == DhcpOptionFormats[Middle].Tag) {
129 return &DhcpOptionFormats[Middle];
130 }
131
132 if (Tag < DhcpOptionFormats[Middle].Tag) {
133 Right = Middle - 1;
134 } else {
135 Left = Middle + 1;
136 }
137 }
138
139 return NULL;
140}
141
153BOOLEAN
155 IN DHCP_OPTION_FORMAT *Format,
156 IN UINT8 *OptValue,
157 IN INTN Len
158 )
159{
160 INTN Unit;
161 INTN Occur;
162 INTN Index;
163
164 Unit = 0;
165
166 switch (Format->Type) {
167 case DHCP_OPTION_SWITCH:
168 case DHCP_OPTION_INT8:
169 Unit = 1;
170 break;
171
172 case DHCP_OPTION_INT16:
173 Unit = 2;
174 break;
175
176 case DHCP_OPTION_INT32:
177 case DHCP_OPTION_IP:
178 Unit = 4;
179 break;
180
181 case DHCP_OPTION_IPPAIR:
182 Unit = 8;
183 break;
184 }
185
186 ASSERT (Unit != 0);
187
188 //
189 // Validate that the option appears in the full units.
190 //
191 if ((Len % Unit) != 0) {
192 return FALSE;
193 }
194
195 //
196 // Validate the occurrence of the option unit is with in [MinOccur, MaxOccur]
197 //
198 Occur = Len / Unit;
199
200 if (((Format->MinOccur != -1) && (Occur < Format->MinOccur)) ||
201 ((Format->MaxOccur != -1) && (Occur > Format->MaxOccur))
202 )
203 {
204 return FALSE;
205 }
206
207 //
208 // If the option is of type switch, only 0/1 are valid values.
209 //
210 if (Format->Type == DHCP_OPTION_SWITCH) {
211 for (Index = 0; Index < Occur; Index++) {
212 if ((OptValue[Index] != 0) && (OptValue[Index] != 1)) {
213 return FALSE;
214 }
215 }
216 }
217
218 return TRUE;
219}
220
236 IN UINT8 Tag,
237 IN INTN Len,
238 IN UINT8 *Data,
239 OUT DHCP_PARAMETER *Para
240 )
241{
242 switch (Tag) {
243 case DHCP4_TAG_NETMASK:
244 Para->NetMask = NetGetUint32 (Data);
245 break;
246
247 case DHCP4_TAG_ROUTER:
248 //
249 // Return the first router to consumer which is the preferred one
250 //
251 Para->Router = NetGetUint32 (Data);
252 break;
253
254 case DHCP4_TAG_LEASE:
255 Para->Lease = NetGetUint32 (Data);
256 break;
257
258 case DHCP4_TAG_OVERLOAD:
259 Para->Overload = *Data;
260
261 if ((Para->Overload < 1) || (Para->Overload > 3)) {
262 return EFI_INVALID_PARAMETER;
263 }
264
265 break;
266
267 case DHCP4_TAG_MSG_TYPE:
268 Para->DhcpType = *Data;
269
270 if ((Para->DhcpType < 1) || (Para->DhcpType > 9)) {
271 return EFI_INVALID_PARAMETER;
272 }
273
274 break;
275
276 case DHCP4_TAG_SERVER_ID:
277 Para->ServerId = NetGetUint32 (Data);
278 break;
279
280 case DHCP4_TAG_T1:
281 Para->T1 = NetGetUint32 (Data);
282 break;
283
284 case DHCP4_TAG_T2:
285 Para->T2 = NetGetUint32 (Data);
286 break;
287 }
288
289 return EFI_SUCCESS;
290}
291
310 IN UINT8 *Buffer,
311 IN INTN BufLen,
312 IN DHCP_CHECK_OPTION Check OPTIONAL,
313 IN VOID *Context,
314 OUT UINT8 *Overload OPTIONAL
315 )
316{
317 INTN Cur;
318 UINT8 Tag;
319 UINT8 Len;
320
321 Cur = 0;
322
323 while (Cur < BufLen) {
324 Tag = Buffer[Cur];
325
326 if (Tag == DHCP4_TAG_PAD) {
327 Cur++;
328 continue;
329 } else if (Tag == DHCP4_TAG_EOP) {
330 return EFI_SUCCESS;
331 }
332
333 Cur++;
334
335 if (Cur == BufLen) {
336 return EFI_INVALID_PARAMETER;
337 }
338
339 Len = Buffer[Cur++];
340
341 if (Cur + Len > BufLen) {
342 return EFI_INVALID_PARAMETER;
343 }
344
345 if ((Tag == DHCP4_TAG_OVERLOAD) && (Overload != NULL)) {
346 if (Len != 1) {
347 return EFI_INVALID_PARAMETER;
348 }
349
350 *Overload = Buffer[Cur];
351 }
352
353 if ((Check != NULL) && EFI_ERROR (Check (Tag, Len, Buffer + Cur, Context))) {
354 return EFI_INVALID_PARAMETER;
355 }
356
357 Cur += Len;
358 }
359
360 //
361 // Each option buffer is expected to end with an EOP
362 //
363 return EFI_INVALID_PARAMETER;
364}
365
383 IN EFI_DHCP4_PACKET *Packet,
384 IN DHCP_CHECK_OPTION Check OPTIONAL,
385 IN VOID *Context
386 )
387{
388 EFI_STATUS Status;
389 UINT8 Overload;
390
391 Overload = 0;
392
393 Status = DhcpIterateBufferOptions (
394 Packet->Dhcp4.Option,
395 Packet->Length - sizeof (EFI_DHCP4_HEADER) - sizeof (UINT32),
396 Check,
397 Context,
398 &Overload
399 );
400
401 if (EFI_ERROR (Status)) {
402 return Status;
403 }
404
405 if ((Overload == DHCP_OVERLOAD_FILENAME) || (Overload == DHCP_OVERLOAD_BOTH)) {
406 Status = DhcpIterateBufferOptions (
407 (UINT8 *)Packet->Dhcp4.Header.BootFileName,
408 128,
409 Check,
410 Context,
411 NULL
412 );
413
414 if (EFI_ERROR (Status)) {
415 return Status;
416 }
417 }
418
419 if ((Overload == DHCP_OVERLOAD_SVRNAME) || (Overload == DHCP_OVERLOAD_BOTH)) {
420 Status = DhcpIterateBufferOptions (
421 (UINT8 *)Packet->Dhcp4.Header.ServerName,
422 64,
423 Check,
424 Context,
425 NULL
426 );
427
428 if (EFI_ERROR (Status)) {
429 return Status;
430 }
431 }
432
433 return EFI_SUCCESS;
434}
435
452 IN UINT8 Tag,
453 IN UINT8 Len,
454 IN UINT8 *Data,
455 IN VOID *Context
456 )
457{
458 DHCP_OPTION_COUNT *OpCount;
459
460 OpCount = (DHCP_OPTION_COUNT *)Context;
461 OpCount[Tag].Offset = (UINT16)(OpCount[Tag].Offset + Len);
462
463 return EFI_SUCCESS;
464}
465
481 IN UINT8 Tag,
482 IN UINT8 Len,
483 IN UINT8 *Data,
484 IN VOID *Context
485 )
486{
487 DHCP_OPTION_CONTEXT *OptContext;
488 DHCP_OPTION_COUNT *OptCount;
489 DHCP_OPTION *Options;
490 UINT8 *Buf;
491 UINT8 Index;
492
493 OptContext = (DHCP_OPTION_CONTEXT *)Context;
494
495 OptCount = OptContext->OpCount;
496 Index = OptCount[Tag].Index;
497 Options = OptContext->Options;
498 Buf = OptContext->Buf;
499
500 if (Options[Index].Data == NULL) {
501 Options[Index].Tag = Tag;
502 Options[Index].Data = Buf + OptCount[Tag].Offset;
503 }
504
505 CopyMem (Buf + OptCount[Tag].Offset, Data, Len);
506
507 OptCount[Tag].Offset = (UINT16)(OptCount[Tag].Offset + Len);
508 Options[Index].Len = (UINT16)(Options[Index].Len + Len);
509 return EFI_SUCCESS;
510}
511
542 IN EFI_DHCP4_PACKET *Packet,
543 OUT INTN *Count,
544 OUT DHCP_OPTION **OptionPoint
545 )
546{
547 DHCP_OPTION_CONTEXT Context;
548 DHCP_OPTION *Options;
549 DHCP_OPTION_COUNT *OptCount;
550 EFI_STATUS Status;
551 UINT16 TotalLen;
552 INTN OptNum;
553 INTN Index;
554
555 ASSERT ((Count != NULL) && (OptionPoint != NULL));
556
557 //
558 // First compute how many options and how long each option is
559 // with the "Key indexed counting" algorithms.
560 //
561 OptCount = AllocateZeroPool (DHCP_MAX_OPTIONS * sizeof (DHCP_OPTION_COUNT));
562
563 if (OptCount == NULL) {
564 return EFI_OUT_OF_RESOURCES;
565 }
566
567 Status = DhcpIterateOptions (Packet, DhcpGetOptionLen, OptCount);
568
569 if (EFI_ERROR (Status)) {
570 goto ON_EXIT;
571 }
572
573 //
574 // Before the loop, Offset is the length of the option. After loop,
575 // OptCount[Index].Offset specifies the offset into the continuous
576 // option value buffer to put the data.
577 //
578 TotalLen = 0;
579 OptNum = 0;
580
581 for (Index = 0; Index < DHCP_MAX_OPTIONS; Index++) {
582 if (OptCount[Index].Offset != 0) {
583 OptCount[Index].Index = (UINT8)OptNum;
584
585 TotalLen = (UINT16)(TotalLen + OptCount[Index].Offset);
586 OptCount[Index].Offset = (UINT16)(TotalLen - OptCount[Index].Offset);
587
588 OptNum++;
589 }
590 }
591
592 *Count = OptNum;
593 *OptionPoint = NULL;
594
595 if (OptNum == 0) {
596 goto ON_EXIT;
597 }
598
599 //
600 // Allocate a buffer to hold the DHCP options, and after that, a
601 // continuous buffer to put all the options' data.
602 //
603 Options = AllocateZeroPool ((UINTN)(OptNum * sizeof (DHCP_OPTION)) + TotalLen);
604
605 if (Options == NULL) {
606 Status = EFI_OUT_OF_RESOURCES;
607 goto ON_EXIT;
608 }
609
610 Context.OpCount = OptCount;
611 Context.Options = Options;
612 Context.Buf = (UINT8 *)(Options + OptNum);
613
614 Status = DhcpIterateOptions (Packet, DhcpFillOption, &Context);
615
616 if (EFI_ERROR (Status)) {
617 FreePool (Options);
618 goto ON_EXIT;
619 }
620
621 *OptionPoint = Options;
622
623ON_EXIT:
624 FreePool (OptCount);
625 return Status;
626}
627
642 IN EFI_DHCP4_PACKET *Packet,
643 OUT DHCP_PARAMETER **Para OPTIONAL
644 )
645{
646 DHCP_PARAMETER Parameter;
647 DHCP_OPTION_FORMAT *Format;
648 DHCP_OPTION *AllOption;
649 DHCP_OPTION *Option;
650 EFI_STATUS Status;
651 BOOLEAN Updated;
652 INTN Count;
653 INTN Index;
654
655 if (Para != NULL) {
656 *Para = NULL;
657 }
658
659 AllOption = NULL;
660
661 Status = DhcpParseOption (Packet, &Count, &AllOption);
662 if (EFI_ERROR (Status) || (Count == 0)) {
663 return Status;
664 }
665
666 ASSERT (AllOption != NULL);
667
668 Updated = FALSE;
669 ZeroMem (&Parameter, sizeof (Parameter));
670
671 for (Index = 0; Index < Count; Index++) {
672 Option = &AllOption[Index];
673
674 //
675 // Find the format of the option then validate it.
676 //
677 Format = DhcpFindOptionFormat (Option->Tag);
678
679 if (Format == NULL) {
680 continue;
681 }
682
683 if (!DhcpOptionIsValid (Format, Option->Data, Option->Len)) {
684 Status = EFI_INVALID_PARAMETER;
685 goto ON_EXIT;
686 }
687
688 //
689 // Get the client interested parameters
690 //
691 if (Format->Alert && (Para != NULL)) {
692 Updated = TRUE;
693 Status = DhcpGetParameter (Option->Tag, Option->Len, Option->Data, &Parameter);
694
695 if (EFI_ERROR (Status)) {
696 goto ON_EXIT;
697 }
698 }
699 }
700
701 if (Updated && (Para != NULL)) {
702 *Para = AllocateCopyPool (sizeof (DHCP_PARAMETER), &Parameter);
703 if (*Para == NULL) {
704 Status = EFI_OUT_OF_RESOURCES;
705 goto ON_EXIT;
706 }
707 }
708
709ON_EXIT:
710 FreePool (AllOption);
711 return Status;
712}
713
726UINT8 *
728 OUT UINT8 *Buf,
729 IN UINT8 Tag,
730 IN UINT16 DataLen,
731 IN UINT8 *Data
732 )
733{
734 INTN Index;
735 INTN Len;
736
737 ASSERT (DataLen != 0);
738
739 for (Index = 0; Index < (DataLen + 254) / 255; Index++) {
740 Len = MIN (255, DataLen - Index * 255);
741
742 *(Buf++) = Tag;
743 *(Buf++) = (UINT8)Len;
744 CopyMem (Buf, Data + Index * 255, (UINTN)Len);
745
746 Buf += Len;
747 }
748
749 return Buf;
750}
751
771 IN EFI_DHCP4_PACKET *SeedPacket,
772 IN UINT32 DeleteCount,
773 IN UINT8 *DeleteList OPTIONAL,
774 IN UINT32 AppendCount,
775 IN EFI_DHCP4_PACKET_OPTION *AppendList[] OPTIONAL,
776 OUT EFI_DHCP4_PACKET **NewPacket
777 )
778{
779 DHCP_OPTION *Mark;
780 DHCP_OPTION *SeedOptions;
781 EFI_DHCP4_PACKET *Packet;
782 EFI_STATUS Status;
783 INTN Count;
784 UINT32 Index;
785 UINT32 Len;
786 UINT8 *Buf;
787
788 //
789 // Use an array of DHCP_OPTION to mark the existence
790 // and position of each valid options.
791 //
792 Mark = AllocatePool (sizeof (DHCP_OPTION) * DHCP_MAX_OPTIONS);
793
794 if (Mark == NULL) {
795 return EFI_OUT_OF_RESOURCES;
796 }
797
798 for (Index = 0; Index < DHCP_MAX_OPTIONS; Index++) {
799 Mark[Index].Tag = (UINT8)Index;
800 Mark[Index].Len = 0;
801 }
802
803 //
804 // Get list of the options from the seed packet, then put
805 // them to the mark array according to their tags.
806 //
807 SeedOptions = NULL;
808 Status = DhcpParseOption (SeedPacket, &Count, &SeedOptions);
809
810 if (EFI_ERROR (Status)) {
811 goto ON_ERROR;
812 }
813
814 if (SeedOptions != NULL) {
815 for (Index = 0; Index < (UINT32)Count; Index++) {
816 Mark[SeedOptions[Index].Tag] = SeedOptions[Index];
817 }
818 }
819
820 //
821 // Mark the option's length is zero if it is in the DeleteList.
822 //
823 for (Index = 0; Index < DeleteCount; Index++) {
824 Mark[DeleteList[Index]].Len = 0;
825 }
826
827 //
828 // Add or replace the option if it is in the append list.
829 //
830 for (Index = 0; Index < AppendCount; Index++) {
831 Mark[AppendList[Index]->OpCode].Len = AppendList[Index]->Length;
832 Mark[AppendList[Index]->OpCode].Data = AppendList[Index]->Data;
833 }
834
835 //
836 // compute the new packet length. No need to add 1 byte for
837 // EOP option since EFI_DHCP4_PACKET includes one extra byte
838 // for option. It is necessary to split the option if it is
839 // longer than 255 bytes.
840 //
841 Len = sizeof (EFI_DHCP4_PACKET);
842
843 for (Index = 0; Index < DHCP_MAX_OPTIONS; Index++) {
844 if (Mark[Index].Len != 0) {
845 Len += ((Mark[Index].Len + 254) / 255) * 2 + Mark[Index].Len;
846 }
847 }
848
849 Status = EFI_OUT_OF_RESOURCES;
850 Packet = (EFI_DHCP4_PACKET *)AllocatePool (Len);
851
852 if (Packet == NULL) {
853 goto ON_ERROR;
854 }
855
856 Packet->Size = Len;
857 Packet->Length = 0;
858 CopyMem (&Packet->Dhcp4.Header, &SeedPacket->Dhcp4.Header, sizeof (Packet->Dhcp4.Header));
859 Packet->Dhcp4.Magik = DHCP_OPTION_MAGIC;
860 Buf = Packet->Dhcp4.Option;
861
862 for (Index = 0; Index < DHCP_MAX_OPTIONS; Index++) {
863 if (Mark[Index].Len != 0) {
864 Buf = DhcpAppendOption (Buf, Mark[Index].Tag, Mark[Index].Len, Mark[Index].Data);
865 }
866 }
867
868 *(Buf++) = DHCP4_TAG_EOP;
869 Packet->Length = sizeof (EFI_DHCP4_HEADER) + sizeof (UINT32)
870 + (UINT32)(Buf - Packet->Dhcp4.Option);
871
872 *NewPacket = Packet;
873 Status = EFI_SUCCESS;
874
875ON_ERROR:
876 if (SeedOptions != NULL) {
877 FreePool (SeedOptions);
878 }
879
880 FreePool (Mark);
881 return Status;
882}
UINT64 UINTN
INT64 INTN
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS DhcpParseOption(IN EFI_DHCP4_PACKET *Packet, OUT INTN *Count, OUT DHCP_OPTION **OptionPoint)
Definition: Dhcp4Option.c:541
EFI_STATUS DhcpFillOption(IN UINT8 Tag, IN UINT8 Len, IN UINT8 *Data, IN VOID *Context)
Definition: Dhcp4Option.c:480
EFI_STATUS DhcpGetParameter(IN UINT8 Tag, IN INTN Len, IN UINT8 *Data, OUT DHCP_PARAMETER *Para)
Definition: Dhcp4Option.c:235
EFI_STATUS DhcpIterateBufferOptions(IN UINT8 *Buffer, IN INTN BufLen, IN DHCP_CHECK_OPTION Check OPTIONAL, IN VOID *Context, OUT UINT8 *Overload OPTIONAL)
Definition: Dhcp4Option.c:309
EFI_STATUS DhcpBuild(IN EFI_DHCP4_PACKET *SeedPacket, IN UINT32 DeleteCount, IN UINT8 *DeleteList OPTIONAL, IN UINT32 AppendCount, IN EFI_DHCP4_PACKET_OPTION *AppendList[] OPTIONAL, OUT EFI_DHCP4_PACKET **NewPacket)
Definition: Dhcp4Option.c:770
DHCP_OPTION_FORMAT * DhcpFindOptionFormat(IN UINT8 Tag)
Definition: Dhcp4Option.c:114
BOOLEAN DhcpOptionIsValid(IN DHCP_OPTION_FORMAT *Format, IN UINT8 *OptValue, IN INTN Len)
Definition: Dhcp4Option.c:154
EFI_STATUS DhcpGetOptionLen(IN UINT8 Tag, IN UINT8 Len, IN UINT8 *Data, IN VOID *Context)
Definition: Dhcp4Option.c:451
EFI_STATUS DhcpIterateOptions(IN EFI_DHCP4_PACKET *Packet, IN DHCP_CHECK_OPTION Check OPTIONAL, IN VOID *Context)
Definition: Dhcp4Option.c:382
DHCP_OPTION_FORMAT DhcpOptionFormats[]
Definition: Dhcp4Option.c:16
EFI_STATUS DhcpValidateOptions(IN EFI_DHCP4_PACKET *Packet, OUT DHCP_PARAMETER **Para OPTIONAL)
Definition: Dhcp4Option.c:641
UINT8 * DhcpAppendOption(OUT UINT8 *Buf, IN UINT8 Tag, IN UINT16 DataLen, IN UINT8 *Data)
Definition: Dhcp4Option.c:727
#define DHCP_OPTION_MAGIC
Definition: Dhcp4Option.h:16
#define DHCP4_TAG_PAD
Definition: Dhcp.h:19
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
#define NULL
Definition: Base.h:319
#define MIN(a, b)
Definition: Base.h:1007
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
UINT32 EFIAPI NetGetUint32(IN UINT8 *Buf)
Definition: DxeNetLib.c:1033
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
UINT8 Option[1]
Definition: Dhcp4.h:93
UINT32 Length
Definition: Dhcp4.h:79
EFI_DHCP4_HEADER Header
Definition: Dhcp4.h:85
UINT32 Size
Definition: Dhcp4.h:74
UINT32 Magik
Definition: Dhcp4.h:89