TianoCore EDK2 master
Loading...
Searching...
No Matches
Ip4Option.c
Go to the documentation of this file.
1
9#include "Ip4Impl.h"
10
24BOOLEAN
26 IN UINT8 *Option,
27 IN UINT32 OptionLen,
28 IN BOOLEAN Rcvd
29 )
30{
31 UINT32 Cur;
32 UINT32 Len;
33 UINT32 Point;
34
35 Cur = 0;
36
37 while (Cur < OptionLen) {
38 switch (Option[Cur]) {
39 case IP4_OPTION_NOP:
40 Cur++;
41 break;
42
43 case IP4_OPTION_EOP:
44 Cur = OptionLen;
45 break;
46
47 case IP4_OPTION_LSRR:
48 case IP4_OPTION_SSRR:
49 case IP4_OPTION_RR:
50 Len = Option[Cur + 1];
51 Point = Option[Cur + 2];
52
53 //
54 // SRR/RR options are formatted as |Type|Len|Point|Ip1|Ip2|...
55 //
56 if ((OptionLen - Cur < Len) || (Len < 3) || ((Len - 3) % 4 != 0)) {
57 return FALSE;
58 }
59
60 if ((Point > Len + 1) || (Point % 4 != 0)) {
61 return FALSE;
62 }
63
64 //
65 // The Point must point pass the last entry if the packet is received
66 // by us. It must point to 4 if the packet is to be sent by us for
67 // source route option.
68 //
69 if ((Option[Cur] != IP4_OPTION_RR) &&
70 ((Rcvd && (Point != Len + 1)) || (!Rcvd && (Point != 4))))
71 {
72 return FALSE;
73 }
74
75 Cur += Len;
76 break;
77
78 default:
79 Len = Option[Cur + 1];
80
81 if ((OptionLen - Cur < Len) || (Len < 2)) {
82 return FALSE;
83 }
84
85 Cur = Cur + Len;
86 break;
87 }
88 }
89
90 return TRUE;
91}
92
112 IN UINT8 *Option,
113 IN UINT32 OptionLen,
114 IN BOOLEAN FirstFragment,
115 IN OUT UINT8 *Buf OPTIONAL,
116 IN OUT UINT32 *BufLen
117 )
118{
119 UINT8 OptBuf[40];
120 UINT32 Cur;
121 UINT32 Next;
122 UINT8 Type;
123 UINT32 Len;
124
125 ASSERT ((BufLen != NULL) && (OptionLen <= 40));
126
127 Cur = 0;
128 Next = 0;
129
130 while (Cur < OptionLen) {
131 Type = Option[Cur];
132 Len = Option[Cur + 1];
133
134 if (Type == IP4_OPTION_NOP) {
135 //
136 // Keep the padding, in case that the sender wants to align
137 // the option, say, to 4 bytes
138 //
139 OptBuf[Next] = IP4_OPTION_NOP;
140 Next++;
141 Cur++;
142 } else if (Type == IP4_OPTION_EOP) {
143 //
144 // Don't append the EOP to avoid including only a EOP option
145 //
146 break;
147 } else {
148 //
149 // don't copy options that is only valid for the first fragment
150 //
151 if (FirstFragment || ((Type & IP4_OPTION_COPY_MASK) != 0)) {
152 CopyMem (OptBuf + Next, Option + Cur, Len);
153 Next += Len;
154 }
155
156 Cur += Len;
157 }
158 }
159
160 //
161 // Don't append an EOP only option.
162 //
163 if (Next == 0) {
164 *BufLen = 0;
165 return EFI_SUCCESS;
166 }
167
168 //
169 // Append an EOP if the end of option doesn't coincide with the
170 // end of the IP header, that is, isn't aligned to 4 bytes..
171 //
172 if ((Next % 4) != 0) {
173 OptBuf[Next] = IP4_OPTION_EOP;
174 Next++;
175 }
176
177 //
178 // Head length is in the unit of 4 bytes. Now, Len is the
179 // actual option length to appear in the IP header.
180 //
181 Len = ((Next + 3) &~0x03);
182
183 //
184 // If the buffer is too small, set the BufLen then return
185 //
186 if ((Buf == NULL) || (*BufLen < Len)) {
187 *BufLen = Len;
188 return EFI_BUFFER_TOO_SMALL;
189 }
190
191 //
192 // Copy the option to the Buf, zero the buffer first to pad
193 // the options with NOP to align to 4 bytes.
194 //
195 ZeroMem (Buf, Len);
196 CopyMem (Buf, OptBuf, Next);
197 *BufLen = Len;
198 return EFI_SUCCESS;
199}
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS Ip4CopyOption(IN UINT8 *Option, IN UINT32 OptionLen, IN BOOLEAN FirstFragment, IN OUT UINT8 *Buf OPTIONAL, IN OUT UINT32 *BufLen)
Definition: Ip4Option.c:111
BOOLEAN Ip4OptionIsValid(IN UINT8 *Option, IN UINT32 OptionLen, IN BOOLEAN Rcvd)
Definition: Ip4Option.c:25
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112