19 #ifndef __included_ip6_to_ip4_h__
20 #define __included_ip6_to_ip4_h__
49 #define frag_id_6to4(id) ((id) ^ ((id) >> 16))
66 u32 buff_len,
u8 * l4_protocol,
u16 * l4_offset,
67 u16 * frag_hdr_offset)
69 ip6_ext_header_t *last_hdr, *frag_hdr;
72 (
vm,
b,
ip6, IP_PROTOCOL_IPV6_FRAGMENTATION, &
length, &frag_hdr,
82 *frag_hdr_offset = (
u8 *) frag_hdr - (
u8 *)
ip6;
88 *l4_protocol = last_hdr->next_hdr;
93 *l4_protocol =
ip6->protocol;
95 *l4_offset =
sizeof (*ip6) +
length;
97 return (buff_len < (*l4_offset + 4)) ||
98 (clib_net_to_host_u16 (
ip6->payload_length) <
99 (*l4_offset + 4 -
sizeof (*ip6)));
120 u32 * tcp_ack_number,
u32 * tcp_seq_number)
128 (
vm,
b,
ip6, buffer_len, &l4_protocol, &l4_offset, &frag_offset))
141 if (l4_protocol == IP_PROTOCOL_TCP || l4_protocol == IP_PROTOCOL_UDP)
147 if (icmp_type_or_tcp_flags && l4_protocol == IP_PROTOCOL_TCP)
149 if (tcp_ack_number && l4_protocol == IP_PROTOCOL_TCP)
151 if (tcp_seq_number && l4_protocol == IP_PROTOCOL_TCP)
154 else if (l4_protocol == IP_PROTOCOL_ICMP6)
156 icmp46_header_t *
icmp = (icmp46_header_t *) (l4);
157 if (icmp_type_or_tcp_flags)
158 *icmp_type_or_tcp_flags = ((icmp46_header_t *) (l4))->
type;
159 if (
icmp->type == ICMP6_echo_request)
166 else if (
icmp->type == ICMP6_echo_reply)
173 else if (clib_net_to_host_u16 (
ip6->payload_length) >= 64)
177 u8 inner_l4_protocol;
179 u16 inner_frag_offset;
182 ip6_pay_len = clib_net_to_host_u16 (
ip6->payload_length);
186 &inner_l4_protocol, &inner_l4_offset,
190 if (inner_frag_offset &&
193 inner_frag_offset))))
196 inner_l4 =
u8_ptr_add (inner_ip6, inner_l4_offset);
197 if (inner_l4_protocol == IP_PROTOCOL_TCP ||
198 inner_l4_protocol == IP_PROTOCOL_UDP)
205 else if (inner_l4_protocol == IP_PROTOCOL_ICMP6)
207 icmp46_header_t *inner_icmp = (icmp46_header_t *) (inner_l4);
208 if (inner_icmp->type == ICMP6_echo_request)
215 else if (inner_icmp->type == ICMP6_echo_reply)
242 case ICMP6_echo_request:
243 icmp->type = ICMP4_echo_request;
245 case ICMP6_echo_reply:
246 icmp->type = ICMP4_echo_reply;
248 case ICMP6_destination_unreachable:
253 case ICMP6_destination_unreachable_no_route_to_destination:
254 case ICMP6_destination_unreachable_beyond_scope_of_source_address:
255 case ICMP6_destination_unreachable_address_unreachable:
256 icmp->type = ICMP4_destination_unreachable;
258 ICMP4_destination_unreachable_destination_unreachable_host;
260 case ICMP6_destination_unreachable_destination_administratively_prohibited:
262 ICMP4_destination_unreachable;
264 ICMP4_destination_unreachable_communication_administratively_prohibited;
266 case ICMP6_destination_unreachable_port_unreachable:
267 icmp->type = ICMP4_destination_unreachable;
268 icmp->code = ICMP4_destination_unreachable_port_unreachable;
274 case ICMP6_packet_too_big:
277 icmp->type = ICMP4_destination_unreachable;
280 u32 advertised_mtu = clib_net_to_host_u32 (*((
u32 *) (
icmp + 1)));
281 advertised_mtu -= 20;
283 ((
u16 *) (
icmp))[3] = clib_host_to_net_u16 (advertised_mtu);
287 case ICMP6_time_exceeded:
290 icmp->type = ICMP4_time_exceeded;
293 case ICMP6_parameter_problem:
298 case ICMP6_parameter_problem_erroneous_header_field:
299 icmp->type = ICMP4_parameter_problem;
300 icmp->code = ICMP4_parameter_problem_pointer_indicates_error;
301 u32 pointer = clib_net_to_host_u32 (*((
u32 *) (
icmp + 1)));
308 case ICMP6_parameter_problem_unrecognized_next_header:
309 icmp->type = ICMP4_destination_unreachable;
310 icmp->code = ICMP4_destination_unreachable_port_unreachable;
312 case ICMP6_parameter_problem_unrecognized_option:
334 return (clib_net_to_host_u32 (ip_version_traffic_class_and_flow_label)
357 icmp46_header_t *
icmp;
360 ip6_address_t old_src, old_dst;
363 ip6_pay_len = clib_net_to_host_u16 (
ip6->payload_length);
364 icmp = (icmp46_header_t *) (
ip6 + 1);
368 if (
ip6->protocol != IP_PROTOCOL_ICMP6)
377 u16 *inner_L4_checksum, inner_l4_offset, inner_frag_offset,
379 u8 *inner_l4, inner_protocol;
391 &inner_protocol, &inner_l4_offset, &inner_frag_offset))
394 inner_l4 =
u8_ptr_add (inner_ip6, inner_l4_offset);
397 if (inner_frag_offset)
399 ip6_frag_hdr_t *inner_frag =
400 (ip6_frag_hdr_t *)
u8_ptr_add (inner_ip6, inner_frag_offset);
401 inner_frag_id =
frag_id_6to4 (inner_frag->identification);
409 if (inner_protocol == IP_PROTOCOL_TCP)
413 else if (inner_protocol == IP_PROTOCOL_UDP)
417 else if (inner_protocol == IP_PROTOCOL_ICMP6)
419 icmp46_header_t *inner_icmp = (icmp46_header_t *) inner_l4;
421 inner_icmp->type = (inner_icmp->type == ICMP6_echo_request) ?
422 ICMP4_echo_request : ICMP4_echo_reply;
423 inner_protocol = IP_PROTOCOL_ICMP;
424 inner_L4_checksum = &inner_icmp->checksum;
431 old_src.as_u64[0] = inner_ip6->
src_address.as_u64[0];
432 old_src.as_u64[1] = inner_ip6->
src_address.as_u64[1];
433 old_dst.as_u64[0] = inner_ip6->
dst_address.as_u64[0];
434 old_dst.as_u64[1] = inner_ip6->
dst_address.as_u64[1];
436 if ((
rv = inner_fn (inner_ip6, inner_ip4, inner_ctx)) != 0)
446 sizeof (*
ip4) +
sizeof (*
ip6) - inner_l4_offset);
451 inner_ip4->
protocol = inner_protocol;
454 if (inner_ip4->
protocol == IP_PROTOCOL_ICMP)
457 icmp46_header_t *inner_icmp = (icmp46_header_t *) inner_l4;
458 inner_icmp->checksum = 0;
461 clib_net_to_host_u16 (inner_ip4->
length)
462 - sizeof (*inner_ip4));
468 csum = *inner_L4_checksum;
494 ip4->ip_version_and_header_length =
497 ip4->fragment_id = 0;
498 ip4->flags_and_fragment_offset = 0;
499 ip4->ttl =
ip6->hop_limit;
500 ip4->protocol = IP_PROTOCOL_ICMP;
504 NULL) ? sizeof (*
ip4) : (2 *
sizeof (*
ip4) -
512 clib_net_to_host_u16 (
ip4->length) -