@@ -2659,24 +2659,60 @@ static enum net_verdict handle_ipv6_echo_reply(struct net_pkt *pkt,
26592659						struct  net_ipv6_hdr  * ip_hdr ,
26602660						struct  net_icmp_hdr  * icmp_hdr )
26612661{
2662- 	ARG_UNUSED (icmp_hdr );
2662+ 	NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE (icmp_access ,
2663+ 					      struct  net_icmpv6_echo_req );
2664+ 	u32_t  cycles ;
2665+ 	struct  net_icmpv6_echo_req  * icmp_echo ;
26632666
2664- 	PR_SHELL (shell_for_ping , "Received echo reply from %s to %s\n" ,
2667+ 	icmp_echo  =  (struct  net_icmpv6_echo_req  * )net_pkt_get_data (pkt , & icmp_access );
2668+ 	if  (icmp_echo  ==  NULL ) {
2669+ 		return  - NET_DROP ;
2670+ 	}
2671+ 
2672+ 	net_pkt_skip (pkt , sizeof (* icmp_echo ));
2673+ 	if  (net_pkt_read_be32 (pkt , & cycles )) {
2674+ 		return  - NET_DROP ;
2675+ 	}
2676+ 
2677+ 	cycles  =  k_cycle_get_32 () -  cycles ;
2678+ 
2679+ 	PR_SHELL (shell_for_ping , "%d bytes from %s to %s: icmp_seq=%d ttl=%d " 
2680+ #ifdef  CONFIG_IEEE802154 
2681+ 		 "rssi=%d " 
2682+ #endif 
2683+ #ifdef  CONFIG_FLOAT 
2684+ 		 "time=%.2f ms\n" ,
2685+ #else 
2686+ 		 "time=%d ms\n" ,
2687+ #endif 
2688+ 		 ntohs (ip_hdr -> len ) -  net_pkt_ipv6_ext_len (pkt ) -  NET_ICMPH_LEN ,
26652689		 net_sprint_ipv6_addr (& ip_hdr -> src ),
2666- 		 net_sprint_ipv6_addr (& ip_hdr -> dst ));
2690+ 		 net_sprint_ipv6_addr (& ip_hdr -> dst ),
2691+ 		 ntohs (icmp_echo -> sequence ),
2692+ 		 ip_hdr -> hop_limit ,
2693+ #ifdef  CONFIG_IEEE802154 
2694+ 		 net_pkt_ieee802154_rssi (pkt ),
2695+ #endif 
2696+ #ifdef  CONFIG_FLOAT 
2697+ 		 (SYS_CLOCK_HW_CYCLES_TO_NS (cycles ) / 1000000.f ));
2698+ #else 
2699+ 		 (SYS_CLOCK_HW_CYCLES_TO_NS (cycles ) / 1000000 ));
2700+ #endif 
26672701	k_sem_give (& ping_timeout );
2668- 	remove_ipv6_ping_handler ();
26692702
26702703	net_pkt_unref (pkt );
26712704	return  NET_OK ;
26722705}
26732706
2674- static  int  ping_ipv6 (const  struct  shell  * shell , char  * host )
2707+ static  int  ping_ipv6 (const  struct  shell  * shell ,
2708+ 			char  * host ,
2709+ 			unsigned int   count ,
2710+ 			unsigned int   interval )
26752711{
26762712	struct  in6_addr  ipv6_target ;
26772713	struct  net_if  * iface  =  net_if_get_default ();
26782714	struct  net_nbr  * nbr ;
2679- 	int  ret ;
2715+ 	int  ret   =   0 ;
26802716
26812717#if  defined(CONFIG_NET_ROUTE )
26822718	struct  net_route_entry  * route ;
@@ -2700,18 +2736,26 @@ static int ping_ipv6(const struct shell *shell, char *host)
27002736	}
27012737#endif 
27022738
2703- 	ret  =  net_icmpv6_send_echo_request (iface ,
2704- 					   & ipv6_target ,
2705- 					   sys_rand32_get (),
2706- 					   sys_rand32_get (),
2707- 					   NULL ,
2708- 					   0 );
2709- 	if  (ret ) {
2710- 		remove_ipv6_ping_handler ();
2711- 	} else  {
2712- 		PR ("Sent a ping to %s\n" , host );
2739+ 	PR ("PING %s\n" , host );
2740+ 
2741+ 	for  (int  i  =  0 ; i  <  count ; ++ i ) {
2742+ 		u32_t  time_stamp  =  htonl (k_cycle_get_32 ());
2743+ 
2744+ 		ret  =  net_icmpv6_send_echo_request (iface ,
2745+ 						   & ipv6_target ,
2746+ 						   sys_rand32_get (),
2747+ 						   i ,
2748+ 						   & time_stamp ,
2749+ 						   sizeof (time_stamp ));
2750+ 		if  (ret ) {
2751+ 			break ;
2752+ 		}
2753+ 
2754+ 		k_sleep (interval );
27132755	}
27142756
2757+ 	remove_ipv6_ping_handler ();
2758+ 
27152759	return  ret ;
27162760}
27172761#else 
@@ -2740,46 +2784,111 @@ static enum net_verdict handle_ipv4_echo_reply(struct net_pkt *pkt,
27402784						struct  net_ipv4_hdr  * ip_hdr ,
27412785						struct  net_icmp_hdr  * icmp_hdr )
27422786{
2743- 	PR_SHELL (shell_for_ping , "Received echo reply from %s to %s\n" ,
2787+ 	NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE (icmp_access ,
2788+ 					      struct  net_icmpv4_echo_req );
2789+ 	u32_t  cycles ;
2790+ 	struct  net_icmpv4_echo_req  * icmp_echo ;
2791+ 
2792+ 	icmp_echo  =  (struct  net_icmpv4_echo_req  * )net_pkt_get_data (pkt , & icmp_access );
2793+ 	if  (icmp_echo  ==  NULL ) {
2794+ 		return  - NET_DROP ;
2795+ 	}
2796+ 
2797+ 	net_pkt_skip (pkt , sizeof (* icmp_echo ));
2798+ 	if  (net_pkt_read_be32 (pkt , & cycles )) {
2799+ 		return  - NET_DROP ;
2800+ 	}
2801+ 
2802+ 	cycles  =  k_cycle_get_32 () -  cycles ;
2803+ 
2804+ 	PR_SHELL (shell_for_ping , "%d bytes from %s to %s: icmp_seq=%d ttl=%d " 
2805+ #ifdef  CONFIG_FLOAT 
2806+ 		 "time=%.2f ms\n" ,
2807+ #else 
2808+ 		 "time=%d ms\n" ,
2809+ #endif 
2810+ 		 ntohs (ip_hdr -> len ) -  net_pkt_ipv6_ext_len (pkt ) -  NET_ICMPH_LEN ,
27442811		 net_sprint_ipv4_addr (& ip_hdr -> src ),
2745- 		 net_sprint_ipv4_addr (& ip_hdr -> dst ));
2812+ 		 net_sprint_ipv4_addr (& ip_hdr -> dst ),
2813+ 		 ntohs (icmp_echo -> sequence ),
2814+ 		 ip_hdr -> ttl ,
2815+ #ifdef  CONFIG_FLOAT 
2816+ 		 (SYS_CLOCK_HW_CYCLES_TO_NS (cycles ) / 1000000.f ));
2817+ #else 
2818+ 		 (SYS_CLOCK_HW_CYCLES_TO_NS (cycles ) / 1000000 ));
2819+ #endif 
27462820	k_sem_give (& ping_timeout );
2747- 	remove_ipv4_ping_handler ();
27482821
27492822	net_pkt_unref (pkt );
27502823	return  NET_OK ;
27512824}
27522825
2753- static  int  ping_ipv4 (const  struct  shell  * shell , char  * host )
2826+ static  int  ping_ipv4 (const  struct  shell  * shell ,
2827+ 	char  * host ,
2828+ 	unsigned int   count ,
2829+ 	unsigned int   interval )
27542830{
27552831	struct  in_addr  ipv4_target ;
2756- 	int  ret ;
2832+ 	int  ret   =   0 ;
27572833
27582834	if  (net_addr_pton (AF_INET , host , & ipv4_target ) <  0 ) {
27592835		return  - EINVAL ;
27602836	}
27612837
2838+ 	struct  net_if  * iface  =  net_if_ipv4_select_src_iface (& ipv4_target );
2839+ 
27622840	net_icmpv4_register_handler (& ping4_handler );
27632841
2764- 	ret  =  net_icmpv4_send_echo_request (
2765- 		net_if_ipv4_select_src_iface (& ipv4_target ),
2766- 		& ipv4_target ,
2767- 		sys_rand32_get (),
2768- 		sys_rand32_get (),
2769- 		NULL ,
2770- 		0 );
2771- 	if  (ret ) {
2772- 		remove_ipv4_ping_handler ();
2773- 	} else  {
2774- 		PR ("Sent a ping to %s\n" , host );
2842+ 	PR ("PING %s\n" , host );
2843+ 
2844+ 	for  (int  i  =  0 ; i  <  count ; ++ i ) {
2845+ 		u32_t  time_stamp  =  htonl (k_cycle_get_32 ());
2846+ 
2847+ 		ret  =  net_icmpv4_send_echo_request (iface ,
2848+ 						   & ipv4_target ,
2849+ 						   sys_rand32_get (),
2850+ 						   i ,
2851+ 						   & time_stamp ,
2852+ 						   sizeof (time_stamp ));
2853+ 		if  (ret ) {
2854+ 			break ;
2855+ 		}
2856+ 
2857+ 		k_sleep (interval );
27752858	}
27762859
2860+ 	remove_ipv4_ping_handler ();
2861+ 
27772862	return  ret ;
27782863}
27792864#else 
27802865#define  ping_ipv4 (...) -ENOTSUP
27812866#define  remove_ipv4_ping_handler ()
27822867#endif  /* CONFIG_NET_IPV4 */ 
2868+ 
2869+ static  int  _parse_arg (size_t  * i , size_t  argc , char  * argv [])
2870+ {
2871+ 	int  res  =  -1 ;
2872+ 	const  char  * str  =  argv [* i ] +  2 ;
2873+ 	char  * endptr ;
2874+ 
2875+ 	if  (* str  ==  0 ) {
2876+ 		if  (* i  +  1  >= argc ) {
2877+ 			return  -1 ;
2878+ 		}
2879+ 
2880+ 		* i  +=  1 ;
2881+ 		str  =  argv [* i ];
2882+ 	}
2883+ 
2884+ 	res  =  strtol (str , & endptr , 10 );
2885+ 
2886+ 	if  (errno  ||  (endptr  ==  str )) {
2887+ 		return  -1 ;
2888+ 	}
2889+ 
2890+ 	return  res ;
2891+ }
27832892#endif  /* CONFIG_NET_IPV6 || CONFIG_NET_IPV4 */ 
27842893
27852894static  int  cmd_net_ping (const  struct  shell  * shell , size_t  argc , char  * argv [])
@@ -2791,12 +2900,42 @@ static int cmd_net_ping(const struct shell *shell, size_t argc, char *argv[])
27912900
27922901	return  - EOPNOTSUPP ;
27932902#else 
2794- 	char  * host ;
2903+ 	char  * host   =   NULL ;
27952904	int  ret ;
27962905
2797- 	ARG_UNUSED (argc );
2906+ 	int  count  =  3 ;
2907+ 	int  interval  =  1000 ;
2908+ 
2909+ 	for  (size_t  i  =  1 ; i  <  argc ; ++ i ) {
2910+ 
2911+ 		if  (* argv [i ] !=  '-' ) {
2912+ 			host  =  argv [i ];
2913+ 			continue ;
2914+ 		}
27982915
2799- 	host  =  argv [1 ];
2916+ 		switch  (argv [i ][1 ]) {
2917+ 		case  'c' :
2918+ 			count  =  _parse_arg (& i , argc , argv );
2919+ 			if  (count  <  0 ) {
2920+ 				PR_WARNING ("Parse error: %s\n" , argv [i ]);
2921+ 				return  - ENOEXEC ;
2922+ 			}
2923+ 
2924+ 
2925+ 			break ;
2926+ 		case  'i' :
2927+ 			interval  =  _parse_arg (& i , argc , argv );
2928+ 			if  (interval  <  0 ) {
2929+ 				PR_WARNING ("Parse error: %s\n" , argv [i ]);
2930+ 				return  - ENOEXEC ;
2931+ 			}
2932+ 
2933+ 			break ;
2934+ 		default :
2935+ 			PR_WARNING ("Unrecognized argument: %s\n" , argv [i ]);
2936+ 			return  - ENOEXEC ;
2937+ 		}
2938+ 	}
28002939
28012940	if  (!host ) {
28022941		PR_WARNING ("Target host missing\n" );
@@ -2806,7 +2945,7 @@ static int cmd_net_ping(const struct shell *shell, size_t argc, char *argv[])
28062945	shell_for_ping  =  shell ;
28072946
28082947	if  (IS_ENABLED (CONFIG_NET_IPV6 )) {
2809- 		ret  =  ping_ipv6 (shell , host );
2948+ 		ret  =  ping_ipv6 (shell , host ,  count ,  interval );
28102949		if  (!ret ) {
28112950			goto wait_reply ;
28122951		} else  if  (ret  ==  - EIO ) {
@@ -2816,7 +2955,7 @@ static int cmd_net_ping(const struct shell *shell, size_t argc, char *argv[])
28162955	}
28172956
28182957	if  (IS_ENABLED (CONFIG_NET_IPV4 )) {
2819- 		ret  =  ping_ipv4 (shell , host );
2958+ 		ret  =  ping_ipv4 (shell , host ,  count ,  interval );
28202959		if  (ret ) {
28212960			if  (ret  ==  - EIO ) {
28222961				PR_WARNING ("Cannot send IPv4 ping\n" );
@@ -3789,7 +3928,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_commands,
37893928		  cmd_net_mem ),
37903929	SHELL_CMD (nbr , & net_cmd_nbr , "Print neighbor information." ,
37913930		  cmd_net_nbr ),
3792- 	SHELL_CMD (ping , NULL , "Ping  a network host." , cmd_net_ping ),
3931+ 	SHELL_CMD (ping , NULL , "'net ping [-c count] [-i interval ms] <host>' ping  a network host." , cmd_net_ping ),
37933932	SHELL_CMD (route , NULL , "Show network route." , cmd_net_route ),
37943933	SHELL_CMD (stacks , NULL , "Show network stacks information." ,
37953934		  cmd_net_stacks ),
0 commit comments