40 s =
format (s,
"ICMP echo id %d seq %d%s",
41 clib_net_to_host_u16 (t->
id),
42 clib_net_to_host_u16 (t->
seq), t->
bound ?
"" :
" (unknown)");
68 net_icmp_id = h0->icmp_echo.id;
74 net_icmp_id = h0->icmp_echo.id;
82 clib_net_to_host_u16 (net_icmp_id));
99 (vm, bi0_copy))->unused, &nowts,
sizeof (nowts));
111 u32 n_left_from, *from;
116 while (n_left_from > 0)
132 tr->
id = h0->icmp_echo.id;
133 tr->
seq = h0->icmp_echo.seq;
151 .name =
"ip6-icmp-echo-reply",
152 .vector_size =
sizeof (
u32),
169 u32 n_left_from, *from;
174 while (n_left_from > 0)
190 tr->
id = h0->icmp_echo.id;
191 tr->
seq = h0->icmp_echo.seq;
209 .name =
"ip4-icmp-echo-reply",
210 .vector_size =
sizeof (
u32),
229 icmp46_echo->seq = clib_host_to_net_u16 (seq_host);
230 icmp46_echo->id = clib_host_to_net_u16 (id_host);
234 for (i = 0; i < data_len; i++)
235 icmp46_echo->data[i] = i % 256;
242 u32 sw_if_index,
u16 seq_host,
u16 id_host,
u16 data_len,
243 u32 burst,
u8 verbose)
245 icmp6_echo_request_header_t *h0;
247 int bogus_length = 0;
265 if (~0 == sw_if_index)
295 if (~0 == sw_if_index)
306 h0->ip6.ip_version_traffic_class_and_flow_label =
307 clib_host_to_net_u32 (0x6 << 28);
308 h0->ip6.payload_length = 0;
309 h0->ip6.protocol = IP_PROTOCOL_ICMP6;
310 h0->ip6.hop_limit = 255;
311 h0->ip6.dst_address = *pa6;
312 h0->ip6.src_address = *pa6;
321 h0->ip6.src_address = a[0];
324 h0->icmp.type = ICMP6_echo_request;
326 h0->icmp.checksum = 0;
333 h0->ip6.payload_length =
334 clib_host_to_net_u16 (data_len +
sizeof (icmp46_header_t));
336 p0->
current_length = clib_net_to_host_u16 (h0->ip6.payload_length) +
340 h0->icmp.checksum = 0;
370 icmp4_echo_request_header_t *h0;
391 if (~0 == sw_if_index)
422 if (~0 == sw_if_index)
433 h0->ip4.checksum = 0;
434 h0->ip4.ip_version_and_header_length = 0x45;
437 h0->ip4.fragment_id = 0;
438 h0->ip4.flags_and_fragment_offset = 0;
440 h0->ip4.protocol = IP_PROTOCOL_ICMP;
441 h0->ip4.dst_address = *pa4;
442 h0->ip4.src_address = *pa4;
451 h0->ip4.src_address = *if_ip;
460 h0->icmp.type = ICMP4_echo_request;
462 h0->icmp.checksum = 0;
470 clib_host_to_net_u16 (data_len +
sizeof (icmp46_header_t) +
508 rtt -= h0->icmp_echo.time_sent;
510 "%d bytes from %U: icmp_seq=%d ttl=%d time=%.4f ms",
511 clib_host_to_net_u16 (h0->ip6.payload_length),
513 &h0->ip6.src_address,
514 clib_host_to_net_u16 (h0->icmp_echo.seq),
515 h0->ip6.hop_limit, rtt * 1000.0);
525 rtt -= h0->icmp_echo.time_sent;
527 clib_host_to_net_u16 (h0->ip4.length) -
528 (4 * (0xF & h0->ip4.ip_version_and_header_length));
531 "%d bytes from %U: icmp_seq=%d ttl=%d time=%.4f ms",
534 &h0->ip4.src_address,
535 clib_host_to_net_u16 (h0->icmp_echo.seq),
536 h0->ip4.ttl, rtt * 1000.0);
550 f64 ping_interval,
u32 ping_repeat,
u32 data_len,
551 u32 ping_burst,
u32 verbose)
559 u32 ping_run_index = 0;
562 static u32 rand_seed = 0;
571 vlib_cli_output (vm,
"ICMP ID collision at %d, incrementing", icmp_id);
580 for (i = 1; i <= ping_repeat; i++)
590 i, icmp_id, data_len, ping_burst, verbose)))
592 n_requests += ping_burst;
597 i, icmp_id, data_len, ping_burst, verbose)))
599 n_requests += ping_burst;
601 while ((i <= ping_repeat)
606 uword event_type, *event_data = 0;
616 for (i = 0; i <
vec_len (event_data); i++)
618 u32 bi0 = event_data[
i];
631 for (i = 0; i <
vec_len (event_data); i++)
633 u32 bi0 = event_data[
i];
656 n_requests) ? 0 : 100.0 * ((
float) n_requests -
657 (float) n_replies) / (float) n_requests;
659 "Statistics: %u sent, %u received, %f%% packet loss\n",
660 n_requests, n_replies, loss);
681 u8 ping_ip4, ping_ip6;
686 u32 sw_if_index, table_id;
689 ping_ip4 = ping_ip6 = 0;
710 "expecting IPv4 address but got `%U'",
724 "expecting IPv6 address but got `%U'",
732 "expecting IP4/IP6 address `%U'. Usage: ping <addr> [source <intf>] [size <datasz>] [repeat <count>] [verbose]",
738 if (!ping_ip4 && (
unformat (input,
"ipv4")))
745 else if (!ping_ip6 && (
unformat (input,
"ipv6")))
763 "unknown interface `%U'",
770 if (!
unformat (input,
"%u", &data_len))
774 "expecting size but got `%U'",
782 "%d is bigger than maximum allowed payload size %d",
787 else if (
unformat (input,
"table-id"))
789 if (!
unformat (input,
"%u", &table_id))
793 "expecting table-id but got `%U'",
798 else if (
unformat (input,
"interval"))
800 if (!
unformat (input,
"%f", &ping_interval))
804 "expecting interval (floating point number) got `%U'",
809 else if (
unformat (input,
"repeat"))
811 if (!
unformat (input,
"%u", &ping_repeat))
815 "expecting repeat count but got `%U'",
822 if (!
unformat (input,
"%u", &ping_burst))
826 "expecting burst count but got `%U'",
831 else if (
unformat (input,
"verbose"))
848 ping_ip6 ? &a6 : NULL, sw_if_index, ping_interval,
849 ping_repeat, data_len, ping_burst, verbose);
900 .short_help =
"ping {<ip-addr> | ipv4 <ip4-addr> | ipv6 <ip6-addr>}" 901 " [ipv4 <ip4-addr> | ipv6 <ip6-addr>] [source <interface>]" 902 " [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)