]>
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
12 Validate the IP4 option format for both the packets we received
15 @param[in] Option The first byte of the option
16 @param[in] OptionLen The length of the whole option
17 @param[in] Rcvd The option is from the packet we received if TRUE,
18 otherwise the option we wants to transmit.
20 @retval TRUE The option is properly formatted
21 @retval FALSE The option is malformatted
37 while (Cur
< OptionLen
) {
38 switch (Option
[Cur
]) {
50 Len
= Option
[Cur
+ 1];
51 Point
= Option
[Cur
+ 2];
54 // SRR/RR options are formatted as |Type|Len|Point|Ip1|Ip2|...
56 if ((OptionLen
- Cur
< Len
) || (Len
< 3) || ((Len
- 3) % 4 != 0)) {
60 if ((Point
> Len
+ 1) || (Point
% 4 != 0)) {
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.
69 if ((Option
[Cur
] != IP4_OPTION_RR
) &&
70 ((Rcvd
&& (Point
!= Len
+ 1)) || (!Rcvd
&& (Point
!= 4))))
79 Len
= Option
[Cur
+ 1];
81 if ((OptionLen
- Cur
< Len
) || (Len
< 2)) {
94 Copy the option from the original option to buffer. It
95 handles the details such as:
96 1. whether copy the single IP4 option to the first/non-first
98 2. Pad the options copied over to aligned to 4 bytes.
100 @param[in] Option The original option to copy from
101 @param[in] OptionLen The length of the original option
102 @param[in] FirstFragment Whether it is the first fragment
103 @param[in, out] Buf The buffer to copy options to. NULL
104 @param[in, out] BufLen The length of the buffer
106 @retval EFI_SUCCESS The options are copied over
107 @retval EFI_BUFFER_TOO_SMALL Buf is NULL or BufLen provided is too small.
114 IN BOOLEAN FirstFragment
,
115 IN OUT UINT8
*Buf OPTIONAL
,
116 IN OUT UINT32
*BufLen
125 ASSERT ((BufLen
!= NULL
) && (OptionLen
<= 40));
130 while (Cur
< OptionLen
) {
132 Len
= Option
[Cur
+ 1];
134 if (Type
== IP4_OPTION_NOP
) {
136 // Keep the padding, in case that the sender wants to align
137 // the option, say, to 4 bytes
139 OptBuf
[Next
] = IP4_OPTION_NOP
;
142 } else if (Type
== IP4_OPTION_EOP
) {
144 // Don't append the EOP to avoid including only a EOP option
149 // don't copy options that is only valid for the first fragment
151 if (FirstFragment
|| ((Type
& IP4_OPTION_COPY_MASK
) != 0)) {
152 CopyMem (OptBuf
+ Next
, Option
+ Cur
, Len
);
161 // Don't append an EOP only option.
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..
172 if ((Next
% 4) != 0) {
173 OptBuf
[Next
] = IP4_OPTION_EOP
;
178 // Head length is in the unit of 4 bytes. Now, Len is the
179 // actual option length to appear in the IP header.
181 Len
= ((Next
+ 3) &~0x03);
184 // If the buffer is too small, set the BufLen then return
186 if ((Buf
== NULL
) || (*BufLen
< Len
)) {
188 return EFI_BUFFER_TOO_SMALL
;
192 // Copy the option to the Buf, zero the buffer first to pad
193 // the options with NOP to align to 4 bytes.
196 CopyMem (Buf
, OptBuf
, Next
);