110 * IPv6 funcions will end with _ipv6 in the transport modules.
111 * IPv6 macros:
112 * Some macros end with _V6; e.g. ILL_FRAG_HASH_V6
113 * Some macros start with V6_; e.g. V6_OR_V4_INADDR_ANY
114 * And then there are ..V4_PART_OF_V6.
115 * The intent is that macros in the ip module end with _V6.
116 * IPv6 global variables will start with ipv6_
117 * IPv6 structures will start with ipv6
118 * IPv6 defined constants should start with IPV6_
119 * (but then there are NDP_DEFAULT_VERS_PRI_AND_FLOW, etc)
120 */
121
122 /*
123 * ip6opt_ls is used to enable IPv6 (via /etc/system on TX systems).
124 * We need to do this because we didn't obtain the IP6OPT_LS (0x0a)
125 * from IANA. This mechanism will remain in effect until an official
126 * number is obtained.
127 */
128 uchar_t ip6opt_ls;
129
130 const in6_addr_t ipv6_all_ones =
131 { 0xffffffffU, 0xffffffffU, 0xffffffffU, 0xffffffffU };
132 const in6_addr_t ipv6_all_zeros = { 0, 0, 0, 0 };
133
134 #ifdef _BIG_ENDIAN
135 const in6_addr_t ipv6_unspecified_group = { 0xff000000U, 0, 0, 0 };
136 #else /* _BIG_ENDIAN */
137 const in6_addr_t ipv6_unspecified_group = { 0x000000ffU, 0, 0, 0 };
138 #endif /* _BIG_ENDIAN */
139
140 #ifdef _BIG_ENDIAN
141 const in6_addr_t ipv6_loopback = { 0, 0, 0, 0x00000001U };
142 #else /* _BIG_ENDIAN */
143 const in6_addr_t ipv6_loopback = { 0, 0, 0, 0x01000000U };
144 #endif /* _BIG_ENDIAN */
145
146 #ifdef _BIG_ENDIAN
147 const in6_addr_t ipv6_all_hosts_mcast = { 0xff020000U, 0, 0, 0x00000001U };
148 #else /* _BIG_ENDIAN */
149 const in6_addr_t ipv6_all_hosts_mcast = { 0x000002ffU, 0, 0, 0x01000000U };
150 #endif /* _BIG_ENDIAN */
151
152 #ifdef _BIG_ENDIAN
153 const in6_addr_t ipv6_all_rtrs_mcast = { 0xff020000U, 0, 0, 0x00000002U };
154 #else /* _BIG_ENDIAN */
155 const in6_addr_t ipv6_all_rtrs_mcast = { 0x000002ffU, 0, 0, 0x02000000U };
156 #endif /* _BIG_ENDIAN */
157
158 #ifdef _BIG_ENDIAN
159 const in6_addr_t ipv6_all_v2rtrs_mcast = { 0xff020000U, 0, 0, 0x00000016U };
160 #else /* _BIG_ENDIAN */
161 const in6_addr_t ipv6_all_v2rtrs_mcast = { 0x000002ffU, 0, 0, 0x16000000U };
162 #endif /* _BIG_ENDIAN */
163
164 #ifdef _BIG_ENDIAN
165 const in6_addr_t ipv6_solicited_node_mcast =
166 { 0xff020000U, 0, 0x00000001U, 0xff000000U };
167 #else /* _BIG_ENDIAN */
168 const in6_addr_t ipv6_solicited_node_mcast =
169 { 0x000002ffU, 0, 0x01000000U, 0x000000ffU };
170 #endif /* _BIG_ENDIAN */
171
172 static boolean_t icmp_inbound_verify_v6(mblk_t *, icmp6_t *, ip_recv_attr_t *);
173 static void icmp_inbound_too_big_v6(icmp6_t *, ip_recv_attr_t *);
174 static void icmp_pkt_v6(mblk_t *, void *, size_t, const in6_addr_t *,
175 ip_recv_attr_t *);
176 static void icmp_redirect_v6(mblk_t *, ip6_t *, nd_redirect_t *,
177 ip_recv_attr_t *);
178 static void icmp_send_redirect_v6(mblk_t *, in6_addr_t *,
179 in6_addr_t *, ip_recv_attr_t *);
180 static void icmp_send_reply_v6(mblk_t *, ip6_t *, icmp6_t *,
181 ip_recv_attr_t *);
182 static boolean_t ip_source_routed_v6(ip6_t *, mblk_t *, ip_stack_t *);
183
184 /*
185 * icmp_inbound_v6 deals with ICMP messages that are handled by IP.
186 * If the ICMP message is consumed by IP, i.e., it should not be delivered
187 * to any IPPROTO_ICMP raw sockets, then it returns NULL.
188 * Likewise, if the ICMP error is misformed (too short, etc), then it
189 * returns NULL. The caller uses this to determine whether or not to send
|
110 * IPv6 funcions will end with _ipv6 in the transport modules.
111 * IPv6 macros:
112 * Some macros end with _V6; e.g. ILL_FRAG_HASH_V6
113 * Some macros start with V6_; e.g. V6_OR_V4_INADDR_ANY
114 * And then there are ..V4_PART_OF_V6.
115 * The intent is that macros in the ip module end with _V6.
116 * IPv6 global variables will start with ipv6_
117 * IPv6 structures will start with ipv6
118 * IPv6 defined constants should start with IPV6_
119 * (but then there are NDP_DEFAULT_VERS_PRI_AND_FLOW, etc)
120 */
121
122 /*
123 * ip6opt_ls is used to enable IPv6 (via /etc/system on TX systems).
124 * We need to do this because we didn't obtain the IP6OPT_LS (0x0a)
125 * from IANA. This mechanism will remain in effect until an official
126 * number is obtained.
127 */
128 uchar_t ip6opt_ls;
129
130 const in6_addr_t ipv6_all_ones = {
131 {{ 0xffffffffU, 0xffffffffU, 0xffffffffU, 0xffffffffU }}};
132 const in6_addr_t ipv6_all_zeros = {{{ 0, 0, 0, 0 }}};
133
134 #ifdef _BIG_ENDIAN
135 const in6_addr_t ipv6_unspecified_group = {{{ 0xff000000U, 0, 0, 0 }}};
136 #else /* _BIG_ENDIAN */
137 const in6_addr_t ipv6_unspecified_group = {{{ 0x000000ffU, 0, 0, 0 }}};
138 #endif /* _BIG_ENDIAN */
139
140 #ifdef _BIG_ENDIAN
141 const in6_addr_t ipv6_loopback = {{{ 0, 0, 0, 0x00000001U }}};
142 #else /* _BIG_ENDIAN */
143 const in6_addr_t ipv6_loopback = {{{ 0, 0, 0, 0x01000000U }}};
144 #endif /* _BIG_ENDIAN */
145
146 #ifdef _BIG_ENDIAN
147 const in6_addr_t ipv6_all_hosts_mcast = {{{ 0xff020000U, 0, 0, 0x00000001U }}};
148 #else /* _BIG_ENDIAN */
149 const in6_addr_t ipv6_all_hosts_mcast = {{{ 0x000002ffU, 0, 0, 0x01000000U }}};
150 #endif /* _BIG_ENDIAN */
151
152 #ifdef _BIG_ENDIAN
153 const in6_addr_t ipv6_all_rtrs_mcast = {{{ 0xff020000U, 0, 0, 0x00000002U }}};
154 #else /* _BIG_ENDIAN */
155 const in6_addr_t ipv6_all_rtrs_mcast = {{{ 0x000002ffU, 0, 0, 0x02000000U }}};
156 #endif /* _BIG_ENDIAN */
157
158 #ifdef _BIG_ENDIAN
159 const in6_addr_t ipv6_all_v2rtrs_mcast = {{{ 0xff020000U, 0, 0, 0x00000016U }}};
160 #else /* _BIG_ENDIAN */
161 const in6_addr_t ipv6_all_v2rtrs_mcast = {{{ 0x000002ffU, 0, 0, 0x16000000U }}};
162 #endif /* _BIG_ENDIAN */
163
164 #ifdef _BIG_ENDIAN
165 const in6_addr_t ipv6_solicited_node_mcast = {
166 {{ 0xff020000U, 0, 0x00000001U, 0xff000000U }}};
167 #else /* _BIG_ENDIAN */
168 const in6_addr_t ipv6_solicited_node_mcast = {
169 {{ 0x000002ffU, 0, 0x01000000U, 0x000000ffU }}};
170 #endif /* _BIG_ENDIAN */
171
172 static boolean_t icmp_inbound_verify_v6(mblk_t *, icmp6_t *, ip_recv_attr_t *);
173 static void icmp_inbound_too_big_v6(icmp6_t *, ip_recv_attr_t *);
174 static void icmp_pkt_v6(mblk_t *, void *, size_t, const in6_addr_t *,
175 ip_recv_attr_t *);
176 static void icmp_redirect_v6(mblk_t *, ip6_t *, nd_redirect_t *,
177 ip_recv_attr_t *);
178 static void icmp_send_redirect_v6(mblk_t *, in6_addr_t *,
179 in6_addr_t *, ip_recv_attr_t *);
180 static void icmp_send_reply_v6(mblk_t *, ip6_t *, icmp6_t *,
181 ip_recv_attr_t *);
182 static boolean_t ip_source_routed_v6(ip6_t *, mblk_t *, ip_stack_t *);
183
184 /*
185 * icmp_inbound_v6 deals with ICMP messages that are handled by IP.
186 * If the ICMP message is consumed by IP, i.e., it should not be delivered
187 * to any IPPROTO_ICMP raw sockets, then it returns NULL.
188 * Likewise, if the ICMP error is misformed (too short, etc), then it
189 * returns NULL. The caller uses this to determine whether or not to send
|