]>
git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/Ip4Dxe/Ip4Option.c
2 IP4 option support functions.
4 Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
13 Validate the IP4 option format for both the packets we received
16 @param[in] Option The first byte of the option
17 @param[in] OptionLen The length of the whole option
18 @param[in] Rcvd The option is from the packet we received if TRUE,
19 otherwise the option we wants to transmit.
21 @retval TRUE The option is properly formatted
22 @retval FALSE The option is malformatted
38 while (Cur
< OptionLen
) {
39 switch (Option
[Cur
]) {
51 Len
= Option
[Cur
+ 1];
52 Point
= Option
[Cur
+ 2];
55 // SRR/RR options are formatted as |Type|Len|Point|Ip1|Ip2|...
57 if ((OptionLen
- Cur
< Len
) || (Len
< 3) || ((Len
- 3) % 4 != 0)) {
61 if ((Point
> Len
+ 1) || (Point
% 4 != 0)) {
66 // The Point must point pass the last entry if the packet is received
67 // by us. It must point to 4 if the packet is to be sent by us for
68 // source route option.
70 if ((Option
[Cur
] != IP4_OPTION_RR
) &&
71 ((Rcvd
&& (Point
!= Len
+ 1)) || (!Rcvd
&& (Point
!= 4)))) {
80 Len
= Option
[Cur
+ 1];
82 if ((OptionLen
- Cur
< Len
) || (Len
< 2)) {
97 Copy the option from the original option to buffer. It
98 handles the details such as:
99 1. whether copy the single IP4 option to the first/non-first
101 2. Pad the options copied over to aligned to 4 bytes.
103 @param[in] Option The original option to copy from
104 @param[in] OptionLen The length of the original option
105 @param[in] FirstFragment Whether it is the first fragment
106 @param[in, out] Buf The buffer to copy options to. NULL
107 @param[in, out] BufLen The length of the buffer
109 @retval EFI_SUCCESS The options are copied over
110 @retval EFI_BUFFER_TOO_SMALL Buf is NULL or BufLen provided is too small.
117 IN BOOLEAN FirstFragment
,
118 IN OUT UINT8
*Buf
, OPTIONAL
119 IN OUT UINT32
*BufLen
128 ASSERT ((BufLen
!= NULL
) && (OptionLen
<= 40));
133 while (Cur
< OptionLen
) {
135 Len
= Option
[Cur
+ 1];
137 if (Type
== IP4_OPTION_NOP
) {
139 // Keep the padding, in case that the sender wants to align
140 // the option, say, to 4 bytes
142 OptBuf
[Next
] = IP4_OPTION_NOP
;
146 } else if (Type
== IP4_OPTION_EOP
) {
148 // Don't append the EOP to avoid including only a EOP option
154 // don't copy options that is only valid for the first fragment
156 if (FirstFragment
|| (Type
& IP4_OPTION_COPY_MASK
) != 0) {
157 CopyMem (OptBuf
+ Next
, Option
+ Cur
, Len
);
166 // Don't append an EOP only option.
174 // Append an EOP if the end of option doesn't coincide with the
175 // end of the IP header, that is, isn't aligned to 4 bytes..
177 if ((Next
% 4) != 0) {
178 OptBuf
[Next
] = IP4_OPTION_EOP
;
183 // Head length is in the unit of 4 bytes. Now, Len is the
184 // actual option length to appear in the IP header.
186 Len
= ((Next
+ 3) &~0x03);
189 // If the buffer is too small, set the BufLen then return
191 if ((Buf
== NULL
) || (*BufLen
< Len
)) {
193 return EFI_BUFFER_TOO_SMALL
;
197 // Copy the option to the Buf, zero the buffer first to pad
198 // the options with NOP to align to 4 bytes.
201 CopyMem (Buf
, OptBuf
, Next
);