42 s =
format (s,
"ICMP echo id %d seq %d%s",
43 clib_net_to_host_u16 (t->
id),
44 clib_net_to_host_u16 (t->
seq), t->
bound ?
"" :
" (unknown)");
70 net_icmp_id = h0->icmp_echo.id;
76 net_icmp_id = h0->icmp_echo.id;
84 clib_net_to_host_u16 (net_icmp_id));
101 (vm, bi0_copy))->unused, &nowts,
sizeof (nowts));
113 u32 n_left_from, *from;
118 while (n_left_from > 0)
134 tr->
id = h0->icmp_echo.id;
135 tr->
seq = h0->icmp_echo.seq;
153 .name =
"ip6-icmp-echo-reply",
154 .vector_size =
sizeof (
u32),
171 u32 n_left_from, *from;
176 while (n_left_from > 0)
192 tr->
id = h0->icmp_echo.id;
193 tr->
seq = h0->icmp_echo.seq;
211 .name =
"ip4-icmp-echo-reply",
212 .vector_size =
sizeof (
u32),
231 icmp46_echo->seq = clib_host_to_net_u16 (seq_host);
232 icmp46_echo->id = clib_host_to_net_u16 (id_host);
236 for (i = 0; i < data_len; i++)
237 icmp46_echo->data[i] = i % 256;
244 u32 sw_if_index,
u16 seq_host,
u16 id_host,
u16 data_len,
245 u32 burst,
u8 verbose)
247 icmp6_echo_request_header_t *h0;
249 int bogus_length = 0;
267 if (~0 == sw_if_index)
297 if (~0 == sw_if_index)
308 h0->ip6.ip_version_traffic_class_and_flow_label =
309 clib_host_to_net_u32 (0x6 << 28);
310 h0->ip6.payload_length = 0;
311 h0->ip6.protocol = IP_PROTOCOL_ICMP6;
312 h0->ip6.hop_limit = 255;
313 h0->ip6.dst_address = *pa6;
314 h0->ip6.src_address = *pa6;
319 &h0->ip6.dst_address,
320 &h0->ip6.src_address))
327 h0->icmp.type = ICMP6_echo_request;
329 h0->icmp.checksum = 0;
336 h0->ip6.payload_length =
337 clib_host_to_net_u16 (data_len +
sizeof (icmp46_header_t));
339 p0->
current_length = clib_net_to_host_u16 (h0->ip6.payload_length) +
343 h0->icmp.checksum = 0;
373 icmp4_echo_request_header_t *h0;
394 if (~0 == sw_if_index)
425 if (~0 == sw_if_index)
436 h0->ip4.checksum = 0;
437 h0->ip4.ip_version_and_header_length = 0x45;
440 h0->ip4.fragment_id = 0;
441 h0->ip4.flags_and_fragment_offset = 0;
443 h0->ip4.protocol = IP_PROTOCOL_ICMP;
444 h0->ip4.dst_address = *pa4;
445 h0->ip4.src_address = *pa4;
454 h0->ip4.src_address = *if_ip;
463 h0->icmp.type = ICMP4_echo_request;
465 h0->icmp.checksum = 0;
473 clib_host_to_net_u16 (data_len +
sizeof (icmp46_header_t) +
511 rtt -= h0->icmp_echo.time_sent;
513 "%d bytes from %U: icmp_seq=%d ttl=%d time=%.4f ms",
514 clib_host_to_net_u16 (h0->ip6.payload_length),
516 &h0->ip6.src_address,
517 clib_host_to_net_u16 (h0->icmp_echo.seq),
518 h0->ip6.hop_limit, rtt * 1000.0);
528 rtt -= h0->icmp_echo.time_sent;
530 clib_host_to_net_u16 (h0->ip4.length) -
531 (4 * (0xF & h0->ip4.ip_version_and_header_length));
534 "%d bytes from %U: icmp_seq=%d ttl=%d time=%.4f ms",
537 &h0->ip4.src_address,
538 clib_host_to_net_u16 (h0->icmp_echo.seq),
539 h0->ip4.ttl, rtt * 1000.0);
553 f64 ping_interval,
u32 ping_repeat,
u32 data_len,
554 u32 ping_burst,
u32 verbose)
562 u32 ping_run_index = 0;
565 static u32 rand_seed = 0;
574 vlib_cli_output (vm,
"ICMP ID collision at %d, incrementing", icmp_id);
583 for (i = 1; i <= ping_repeat; i++)
593 i, icmp_id, data_len, ping_burst, verbose)))
595 n_requests += ping_burst;
600 i, icmp_id, data_len, ping_burst, verbose)))
602 n_requests += ping_burst;
604 while ((i <= ping_repeat)
609 uword event_type, *event_data = 0;
619 for (i = 0; i <
vec_len (event_data); i++)
621 u32 bi0 = event_data[
i];
634 for (i = 0; i <
vec_len (event_data); i++)
636 u32 bi0 = event_data[
i];
659 n_requests) ? 0 : 100.0 * ((
float) n_requests -
660 (float) n_replies) / (float) n_requests;
662 "Statistics: %u sent, %u received, %f%% packet loss\n",
663 n_requests, n_replies, loss);
684 u8 ping_ip4, ping_ip6;
689 u32 sw_if_index, table_id;
692 ping_ip4 = ping_ip6 = 0;
713 "expecting IPv4 address but got `%U'",
727 "expecting IPv6 address but got `%U'",
735 "expecting IP4/IP6 address `%U'. Usage: ping <addr> [source <intf>] [size <datasz>] [repeat <count>] [verbose]",
741 if (!ping_ip4 && (
unformat (input,
"ipv4")))
748 else if (!ping_ip6 && (
unformat (input,
"ipv6")))
766 "unknown interface `%U'",
773 if (!
unformat (input,
"%u", &data_len))
777 "expecting size but got `%U'",
785 "%d is bigger than maximum allowed payload size %d",
790 else if (
unformat (input,
"table-id"))
792 if (!
unformat (input,
"%u", &table_id))
796 "expecting table-id but got `%U'",
801 else if (
unformat (input,
"interval"))
803 if (!
unformat (input,
"%f", &ping_interval))
807 "expecting interval (floating point number) got `%U'",
812 else if (
unformat (input,
"repeat"))
814 if (!
unformat (input,
"%u", &ping_repeat))
818 "expecting repeat count but got `%U'",
825 if (!
unformat (input,
"%u", &ping_burst))
829 "expecting burst count but got `%U'",
834 else if (
unformat (input,
"verbose"))
851 ping_ip6 ? &a6 : NULL, sw_if_index, ping_interval,
852 ping_repeat, data_len, ping_burst, verbose);
903 .short_help =
"ping {<ip-addr> | ipv4 <ip4-addr> | ipv6 <ip6-addr>}" 904 " [ipv4 <ip4-addr> | ipv6 <ip6-addr>] [source <interface>]" 905 " [size <pktsize>] [interval <sec>] [repeat <cnt>] [table-id <id>]"
char * ip6_lookup_next_nodes[]
char * ip4_lookup_next_nodes[]
#define hash_set(h, key, value)
static uword random_default_seed(void)
Default random seed (unix/linux user-mode)
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
#define hash_unset(h, key)
static void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
#define IP6_LOOKUP_NEXT_NODES
static void vlib_set_next_frame_buffer(vlib_main_t *vm, vlib_node_runtime_t *node, u32 next_index, u32 buffer_index)
ip_interface_address_t * if_address_pool
Pool of addresses that are assigned to interfaces.
vnet_main_t * vnet_get_main(void)
static uword vlib_current_process(vlib_main_t *vm)
static send_ip46_ping_result_t send_ip6_ping(vlib_main_t *vm, ip6_main_t *im, u32 table_id, ip6_address_t *pa6, u32 sw_if_index, u16 seq_host, u16 id_host, u16 data_len, u32 burst, u8 verbose)
static f64 vlib_time_now(vlib_main_t *vm)
static u16 init_icmp46_echo_request(icmp46_echo_request_t *icmp46_echo, u16 seq_host, u16 id_host, u16 data_len)
#define STRUCT_OFFSET_OF(t, f)
ip_lookup_main_t lookup_main
unformat_function_t unformat_vnet_sw_interface
static void print_ip6_icmp_reply(vlib_main_t *vm, u32 bi0)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
vlib_main_t ** vlib_mains
u8 * format_icmp_echo_trace(u8 *s, va_list *va)
static vlib_buffer_t * vlib_buffer_copy(vlib_main_t *vm, vlib_buffer_t *b)
vlib_node_registration_t ip4_lookup_node
(constructor) VLIB_REGISTER_NODE (ip4_lookup_node)
static uword ip4_icmp_echo_reply_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
u32 ip4_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
#define VLIB_INIT_FUNCTION(x)
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
#define clib_error_return(e, args...)
u32 ip6_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
static u32 vlib_get_buffer_index(vlib_main_t *vm, void *p)
Translate buffer pointer into buffer index.
void ip4_icmp_register_type(vlib_main_t *vm, icmp4_type_t type, u32 node_index)
static clib_error_t * ping_cli_init(vlib_main_t *vm)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
u16 current_length
Nbytes between current data and the end of this buffer.
static u32 ip6_fib_index_from_table_id(u32 table_id)
static send_ip46_ping_result_t send_ip4_ping(vlib_main_t *vm, ip4_main_t *im, u32 table_id, ip4_address_t *pa4, u32 sw_if_index, u16 seq_host, u16 id_host, u16 data_len, u32 burst, u8 verbose)
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
#define VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX
#define pool_put(P, E)
Free an object E in pool P.
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
fib_node_index_t ip4_fib_table_lookup(const ip4_fib_t *fib, const ip4_address_t *addr, u32 len)
#define IP4_LOOKUP_NEXT_NODES
static int ip6_src_address_for_packet(ip_lookup_main_t *lm, u32 sw_if_index, const ip6_address_t *dst, ip6_address_t *src)
#define VLIB_REGISTER_NODE(x,...)
#define PING_DEFAULT_INTERVAL
static_always_inline uword vlib_get_thread_index(void)
static vlib_node_registration_t ip6_icmp_echo_reply_node
(constructor) VLIB_REGISTER_NODE (ip6_icmp_echo_reply_node)
#define vec_free(V)
Free vector's memory (no header).
static void vlib_process_signal_event_mt(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
Signal event to process from any thread.
static ip4_fib_t * ip4_fib_get(u32 index)
Get the FIB at the given index.
static vlib_node_registration_t ip4_icmp_echo_reply_node
(constructor) VLIB_REGISTER_NODE (ip4_icmp_echo_reply_node)
static ip_csum_t ip_incremental_checksum(ip_csum_t sum, void *_data, uword n_bytes)
#define clib_memcpy(a, b, c)
u32 fib_node_index_t
A typedef of a node index.
static u32 ip4_fib_index_from_table_id(u32 table_id)
static void run_ping_ip46_address(vlib_main_t *vm, u32 table_id, ip4_address_t *pa4, ip6_address_t *pa6, u32 sw_if_index, f64 ping_interval, u32 ping_repeat, u32 data_len, u32 ping_burst, u32 verbose)
#define VLIB_CLI_COMMAND(x,...)
u32 * if_address_pool_index_by_sw_if_index
Head of doubly linked list of interface addresses for each software interface.
u16 ip6_tcp_udp_icmp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip6_header_t *ip0, int *bogus_lengthp)
vlib_node_registration_t ip6_lookup_node
(constructor) VLIB_REGISTER_NODE (ip6_lookup_node)
ip_lookup_main_t lookup_main
#define PING_MAXIMUM_DATA_SIZE
static void print_ip4_icmp_reply(vlib_main_t *vm, u32 bi0)
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
void icmp6_register_type(vlib_main_t *vm, icmp6_type_t type, u32 node_index)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
static void vlib_buffer_init_for_free_list(vlib_buffer_t *dst, vlib_buffer_free_list_t *fl)
static uword ip6_icmp_echo_reply_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static u32 random_u32(u32 *seed)
32-bit random number generator
ip4_main_t ip4_main
Global ip4 main structure.
static int signal_ip46_icmp_reply_event(u8 event_type, vlib_buffer_t *b0)
ping_run_t * ping_run_by_icmp_id
fib_node_index_t ip6_fib_table_lookup(u32 fib_index, const ip6_address_t *addr, u32 len)
#define PING_DEFAULT_DATA_LEN
static vlib_buffer_free_list_t * vlib_buffer_get_free_list(vlib_main_t *vm, vlib_buffer_free_list_index_t free_list_index)
static void * ip_interface_address_get_address(ip_lookup_main_t *lm, ip_interface_address_t *a)
static clib_error_t * ping_ip_address(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
static u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
static u16 ip4_header_checksum(ip4_header_t *i)
static u16 ip_csum_fold(ip_csum_t c)