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;
323 h0->ip6.src_address = a[0];
326 h0->icmp.type = ICMP6_echo_request;
328 h0->icmp.checksum = 0;
335 h0->ip6.payload_length =
336 clib_host_to_net_u16 (data_len +
sizeof (icmp46_header_t));
338 p0->
current_length = clib_net_to_host_u16 (h0->ip6.payload_length) +
342 h0->icmp.checksum = 0;
372 icmp4_echo_request_header_t *h0;
393 if (~0 == sw_if_index)
424 if (~0 == sw_if_index)
435 h0->ip4.checksum = 0;
436 h0->ip4.ip_version_and_header_length = 0x45;
439 h0->ip4.fragment_id = 0;
440 h0->ip4.flags_and_fragment_offset = 0;
442 h0->ip4.protocol = IP_PROTOCOL_ICMP;
443 h0->ip4.dst_address = *pa4;
444 h0->ip4.src_address = *pa4;
453 h0->ip4.src_address = *if_ip;
462 h0->icmp.type = ICMP4_echo_request;
464 h0->icmp.checksum = 0;
472 clib_host_to_net_u16 (data_len +
sizeof (icmp46_header_t) +
510 rtt -= h0->icmp_echo.time_sent;
512 "%d bytes from %U: icmp_seq=%d ttl=%d time=%.4f ms",
513 clib_host_to_net_u16 (h0->ip6.payload_length),
515 &h0->ip6.src_address,
516 clib_host_to_net_u16 (h0->icmp_echo.seq),
517 h0->ip6.hop_limit, rtt * 1000.0);
527 rtt -= h0->icmp_echo.time_sent;
529 clib_host_to_net_u16 (h0->ip4.length) -
530 (4 * (0xF & h0->ip4.ip_version_and_header_length));
533 "%d bytes from %U: icmp_seq=%d ttl=%d time=%.4f ms",
536 &h0->ip4.src_address,
537 clib_host_to_net_u16 (h0->icmp_echo.seq),
538 h0->ip4.ttl, rtt * 1000.0);
552 f64 ping_interval,
u32 ping_repeat,
u32 data_len,
553 u32 ping_burst,
u32 verbose)
561 u32 ping_run_index = 0;
564 static u32 rand_seed = 0;
573 vlib_cli_output (vm,
"ICMP ID collision at %d, incrementing", icmp_id);
582 for (i = 1; i <= ping_repeat; i++)
592 i, icmp_id, data_len, ping_burst, verbose)))
594 n_requests += ping_burst;
599 i, icmp_id, data_len, ping_burst, verbose)))
601 n_requests += ping_burst;
603 while ((i <= ping_repeat)
608 uword event_type, *event_data = 0;
618 for (i = 0; i <
vec_len (event_data); i++)
620 u32 bi0 = event_data[
i];
633 for (i = 0; i <
vec_len (event_data); i++)
635 u32 bi0 = event_data[
i];
658 n_requests) ? 0 : 100.0 * ((
float) n_requests -
659 (float) n_replies) / (float) n_requests;
661 "Statistics: %u sent, %u received, %f%% packet loss\n",
662 n_requests, n_replies, loss);
683 u8 ping_ip4, ping_ip6;
688 u32 sw_if_index, table_id;
691 ping_ip4 = ping_ip6 = 0;
712 "expecting IPv4 address but got `%U'",
726 "expecting IPv6 address but got `%U'",
734 "expecting IP4/IP6 address `%U'. Usage: ping <addr> [source <intf>] [size <datasz>] [repeat <count>] [verbose]",
740 if (!ping_ip4 && (
unformat (input,
"ipv4")))
747 else if (!ping_ip6 && (
unformat (input,
"ipv6")))
765 "unknown interface `%U'",
772 if (!
unformat (input,
"%u", &data_len))
776 "expecting size but got `%U'",
784 "%d is bigger than maximum allowed payload size %d",
789 else if (
unformat (input,
"table-id"))
791 if (!
unformat (input,
"%u", &table_id))
795 "expecting table-id but got `%U'",
800 else if (
unformat (input,
"interval"))
802 if (!
unformat (input,
"%f", &ping_interval))
806 "expecting interval (floating point number) got `%U'",
811 else if (
unformat (input,
"repeat"))
813 if (!
unformat (input,
"%u", &ping_repeat))
817 "expecting repeat count but got `%U'",
824 if (!
unformat (input,
"%u", &ping_burst))
828 "expecting burst count but got `%U'",
833 else if (
unformat (input,
"verbose"))
850 ping_ip6 ? &a6 : NULL, sw_if_index, ping_interval,
851 ping_repeat, data_len, ping_burst, verbose);
902 .short_help =
"ping {<ip-addr> | ipv4 <ip4-addr> | ipv6 <ip6-addr>}" 903 " [ipv4 <ip4-addr> | ipv6 <ip6-addr>] [source <interface>]" 904 " [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)
sll srl srl sll sra u16x4 i
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)
ip6_address_t * ip6_interface_first_address(ip6_main_t *im, u32 sw_if_index)
get first IPv6 interface address
#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)
ip_csum_t ip_incremental_checksum(ip_csum_t sum, void *_data, uword n_bytes)
#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
#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)
#define VLIB_BUFFER_IS_TRACED
#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)
#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
#define VLIB_REGISTER_NODE(x,...)
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, u32 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)