net/shell: Add ping reply handlers and a timeout
Thus the ping command is more user-friendly: at least user knows the ping got a reply or not. Change-Id: I740a2f77d288f6287ac04c908f3d517a49df57d2 Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
19af4eee4f
commit
e98f2e0b6a
1 changed files with 110 additions and 13 deletions
|
@ -783,41 +783,128 @@ static int shell_cmd_nbr(int argc, char *argv[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET_IPV6) || defined(CONFIG_NET_IPV4)
|
||||||
|
|
||||||
|
K_SEM_DEFINE(ping_timeout, 0, 1);
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPV6)
|
#if defined(CONFIG_NET_IPV6)
|
||||||
|
|
||||||
|
static enum net_verdict _handle_ipv6_echo_reply(struct net_buf *buf);
|
||||||
|
|
||||||
|
static struct net_icmpv6_handler ping6_handler = {
|
||||||
|
.type = NET_ICMPV6_ECHO_REPLY,
|
||||||
|
.code = 0,
|
||||||
|
.handler = _handle_ipv6_echo_reply,
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void _remove_ipv6_ping_handler(void)
|
||||||
|
{
|
||||||
|
net_icmpv6_unregister_handler(&ping6_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum net_verdict _handle_ipv6_echo_reply(struct net_buf *buf)
|
||||||
|
{
|
||||||
|
char addr[NET_IPV6_ADDR_LEN];
|
||||||
|
|
||||||
|
snprintk(addr, sizeof(addr), "%s",
|
||||||
|
net_sprint_ipv6_addr(&NET_IPV6_BUF(buf)->dst));
|
||||||
|
|
||||||
|
printk("Received echo reply from %s to %s\n",
|
||||||
|
net_sprint_ipv6_addr(&NET_IPV6_BUF(buf)->src), addr);
|
||||||
|
|
||||||
|
k_sem_give(&ping_timeout);
|
||||||
|
_remove_ipv6_ping_handler();
|
||||||
|
|
||||||
|
return NET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static int _ping_ipv6(char *host)
|
static int _ping_ipv6(char *host)
|
||||||
{
|
{
|
||||||
struct in6_addr ipv6_target;
|
struct in6_addr ipv6_target;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (net_addr_pton(AF_INET6, host, &ipv6_target) < 0) {
|
if (net_addr_pton(AF_INET6, host, &ipv6_target) < 0) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return net_icmpv6_send_echo_request(net_if_get_default(),
|
net_icmpv6_register_handler(&ping6_handler);
|
||||||
&ipv6_target,
|
|
||||||
sys_rand32_get(),
|
ret = net_icmpv6_send_echo_request(net_if_get_default(),
|
||||||
sys_rand32_get());
|
&ipv6_target,
|
||||||
|
sys_rand32_get(),
|
||||||
|
sys_rand32_get());
|
||||||
|
if (ret) {
|
||||||
|
_remove_ipv6_ping_handler();
|
||||||
|
} else {
|
||||||
|
printk("Sent a ping to %s\n", host);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define _ping_ipv6(...) -EINVAL
|
#define _ping_ipv6(...) -EINVAL
|
||||||
|
#define _remove_ipv6_ping_handler()
|
||||||
#endif /* CONFIG_NET_IPV6 */
|
#endif /* CONFIG_NET_IPV6 */
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPV4)
|
#if defined(CONFIG_NET_IPV4)
|
||||||
|
|
||||||
|
static enum net_verdict _handle_ipv4_echo_reply(struct net_buf *buf);
|
||||||
|
|
||||||
|
static struct net_icmpv4_handler ping4_handler = {
|
||||||
|
.type = NET_ICMPV4_ECHO_REPLY,
|
||||||
|
.code = 0,
|
||||||
|
.handler = _handle_ipv4_echo_reply,
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void _remove_ipv4_ping_handler(void)
|
||||||
|
{
|
||||||
|
net_icmpv4_unregister_handler(&ping4_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum net_verdict _handle_ipv4_echo_reply(struct net_buf *buf)
|
||||||
|
{
|
||||||
|
char addr[NET_IPV4_ADDR_LEN];
|
||||||
|
|
||||||
|
snprintk(addr, sizeof(addr), "%s",
|
||||||
|
net_sprint_ipv4_addr(&NET_IPV4_BUF(buf)->dst));
|
||||||
|
|
||||||
|
printk("Received echo reply from %s to %s\n",
|
||||||
|
net_sprint_ipv4_addr(&NET_IPV4_BUF(buf)->src), addr);
|
||||||
|
|
||||||
|
k_sem_give(&ping_timeout);
|
||||||
|
_remove_ipv4_ping_handler();
|
||||||
|
|
||||||
|
return NET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static int _ping_ipv4(char *host)
|
static int _ping_ipv4(char *host)
|
||||||
{
|
{
|
||||||
struct in_addr ipv4_target;
|
struct in_addr ipv4_target;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (net_addr_pton(AF_INET, host, &ipv4_target) < 0) {
|
if (net_addr_pton(AF_INET, host, &ipv4_target) < 0) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return net_icmpv4_send_echo_request(net_if_get_default(),
|
net_icmpv4_register_handler(&ping4_handler);
|
||||||
&ipv4_target,
|
|
||||||
sys_rand32_get(),
|
ret = net_icmpv4_send_echo_request(net_if_get_default(),
|
||||||
sys_rand32_get());
|
&ipv4_target,
|
||||||
|
sys_rand32_get(),
|
||||||
|
sys_rand32_get());
|
||||||
|
if (ret) {
|
||||||
|
_remove_ipv4_ping_handler();
|
||||||
|
} else {
|
||||||
|
printk("Sent a ping to %s\n", host);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define _ping_ipv4(...) -EINVAL
|
#define _ping_ipv4(...) -EINVAL
|
||||||
|
#define _remove_ipv4_ping_handler()
|
||||||
#endif /* CONFIG_NET_IPV4 */
|
#endif /* CONFIG_NET_IPV4 */
|
||||||
|
#endif /* CONFIG_NET_IPV6 || CONFIG_NET_IPV4 */
|
||||||
|
|
||||||
static int shell_cmd_ping(int argc, char *argv[])
|
static int shell_cmd_ping(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -834,19 +921,29 @@ static int shell_cmd_ping(int argc, char *argv[])
|
||||||
|
|
||||||
ret = _ping_ipv6(host);
|
ret = _ping_ipv6(host);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
return 0;
|
goto wait_reply;
|
||||||
} else if (ret == -EIO) {
|
} else if (ret == -EIO) {
|
||||||
printk("Cannot send IPv6 ping\n");
|
printk("Cannot send IPv6 ping\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = _ping_ipv4(host);
|
ret = _ping_ipv4(host);
|
||||||
if (ret == -EIO) {
|
if (ret) {
|
||||||
printk("Cannot send IPv4 ping\n");
|
if (ret == -EIO) {
|
||||||
|
printk("Cannot send IPv4 ping\n");
|
||||||
|
} else if (ret == -EINVAL) {
|
||||||
|
printk("Invalid IP address\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == -EINVAL) {
|
wait_reply:
|
||||||
printk("Invalid IP address\n");
|
ret = k_sem_take(&ping_timeout, K_SECONDS(2));
|
||||||
|
if (ret == -EAGAIN) {
|
||||||
|
printk("Ping timeout\n");
|
||||||
|
_remove_ipv6_ping_handler();
|
||||||
|
_remove_ipv4_ping_handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue