1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** NetX Component */
17 /** */
18 /** Internet Control Message Protocol (ICMP) */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define NX_SOURCE_CODE
24
25
26 /* Include necessary system files. */
27
28 #include "nx_api.h"
29 #include "nx_ipv6.h"
30 #include "nx_icmpv6.h"
31 #include "nx_packet.h"
32
33 #ifdef NX_IPSEC_ENABLE
34 #include "nx_ipsec.h"
35 #endif /* NX_IPSEC_ENABLE */
36
37
38 #ifdef FEATURE_NX_IPV6
39
40
41 #ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY
42
43 /**************************************************************************/
44 /* */
45 /* FUNCTION RELEASE */
46 /* */
47 /* _nx_icmpv6_process_packet_too_big PORTABLE C */
48 /* 6.1 */
49 /* AUTHOR */
50 /* */
51 /* Yuxin Zhou, Microsoft Corporation */
52 /* */
53 /* DESCRIPTION */
54 /* */
55 /* This function handles an ICMPv6 error message indicating the next */
56 /* hop or beyond has a smaller MTU that the packet payload. It sets */
57 /* the IP task MTU to the next hop MTU in the option header. */
58 /* */
59 /* This function is called from IP thread periodic process routine. */
60 /* It starts the minimum Path MTU Discovery process if the interface */
61 /* address after the IP instance is initialized and its MTU established*/
62 /* by the Ethernet driver. */
63 /* */
64 /* INPUT */
65 /* */
66 /* ip_ptr Pointer to IP instance */
67 /* packet_ptr Pointer to Packet Too Big */
68 /* ICMPv6 packet received */
69 /* */
70 /* OUTPUT */
71 /* */
72 /* NX_SUCCESS Successful completion */
73 /* */
74 /* CALLS */
75 /* */
76 /* _nx_icmpv6_dest_table_find Find destination in table and */
77 /* update path MTU in table */
78 /* memset Set the memory */
79 /* */
80 /* CALLED BY */
81 /* */
82 /* */
83 /* RELEASE HISTORY */
84 /* */
85 /* DATE NAME DESCRIPTION */
86 /* */
87 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
88 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
89 /* resulting in version 6.1 */
90 /* */
91 /**************************************************************************/
_nx_icmpv6_process_packet_too_big(NX_IP * ip_ptr,NX_PACKET * packet_ptr)92 UINT _nx_icmpv6_process_packet_too_big(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
93 {
94
95 UINT status = NX_INVALID_MTU_DATA;
96 NX_ICMPV6_OPTION_MTU *icmpv6_mtu_option_ptr;
97 ULONG mtu;
98 NX_IPV6_DESTINATION_ENTRY *dest_entry_ptr;
99 ULONG *original_destination_ip;
100 ULONG default_next_hop_address[4];
101 NX_IPV6_HEADER *ip_header_ptr, *original_ip_header_ptr;
102 NX_INTERFACE *if_ptr;
103
104 /* Add debug information. */
105 NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
106
107 #ifndef NX_DISABLE_RX_SIZE_CHECKING
108 if (packet_ptr -> nx_packet_length < sizeof(NX_ICMPV6_OPTION_MTU))
109 {
110 #ifndef NX_DISABLE_ICMP_INFO
111
112 /* Increment the ICMP invalid message count. */
113 ip_ptr -> nx_ip_icmp_invalid_packets++;
114 #endif
115
116 /* Invalid ICMP message, just release it. */
117 _nx_packet_release(packet_ptr);
118 return(NX_NOT_SUCCESSFUL);
119 }
120 #endif /* NX_DISABLE_RX_SIZE_CHECKING */
121
122 memset(&default_next_hop_address[0], 0, (4 * sizeof(ULONG)));
123
124 if_ptr = packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address_attached;
125
126 /* Set a local pointer to the ICMPv6 Option data. */
127 /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary */
128 icmpv6_mtu_option_ptr = (NX_ICMPV6_OPTION_MTU *)packet_ptr -> nx_packet_prepend_ptr;
129
130 /* Parse the original sender data. */
131 /*lint -e{929} -e{826} -e{740} suppress cast of pointer to pointer, since it is necessary */
132 original_ip_header_ptr = (NX_IPV6_HEADER *)(&(icmpv6_mtu_option_ptr -> nx_icmpv6_option_mtu_message));
133
134 /* Extract the original sender from the IP header. */
135 packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV6_HEADER);
136
137 /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary */
138 ip_header_ptr = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_ip_header;
139
140
141 /* Yes this looks like a valid IP header for the original offending packet. */
142 original_destination_ip = original_ip_header_ptr -> nx_ip_header_destination_ip;
143 NX_IPV6_ADDRESS_CHANGE_ENDIAN(original_destination_ip);
144 COPY_IPV6_ADDRESS(ip_header_ptr -> nx_ip_header_source_ip, &default_next_hop_address[0]);
145
146 /* Handle endianness. */
147 NX_CHANGE_ULONG_ENDIAN(icmpv6_mtu_option_ptr -> nx_icmpv6_option_mtu_path_mtu);
148
149 /* Create a local variable for convenience. */
150 mtu = icmpv6_mtu_option_ptr -> nx_icmpv6_option_mtu_path_mtu;
151
152 /* MTU data is valid if it is non zero, and is no more than the driver MTU. */
153 if ((mtu > 0) && (mtu <= if_ptr -> nx_interface_ip_mtu_size))
154 {
155
156 /* Add destination table. */
157 status = _nx_icmpv6_dest_table_add(ip_ptr, original_destination_ip,
158 &dest_entry_ptr, &default_next_hop_address[0], mtu, 0,
159 packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr);
160 }
161
162 /* Release the packet. */
163 _nx_packet_release(packet_ptr);
164
165 /* Return the completion code. */
166 return(status);
167 }
168 #endif /* NX_ENABLE_IPV6_PATH_MTU_DISCOVERY */
169
170
171 #endif /* FEATURE_NX_IPV6 */
172
173