1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

sys: shell: ping6: require device parameter for link-local addresses

This commit is contained in:
Kaspar Schleiser 2016-02-03 16:04:32 +01:00
parent 79c68e033b
commit 951f1300a0

View File

@ -38,9 +38,10 @@ static char ipv6_str[IPV6_ADDR_MAX_STR_LEN];
static void usage(char **argv)
{
printf("%s [<count>] <ipv6 addr> [<payload_len>] [<delay in ms>] [<stats interval>]\n", argv[0]);
printf("%s [<count>] <ipv6 addr>[%%<interface>] [<payload_len>] [<delay in ms>] [<stats interval>]\n", argv[0]);
puts("defaults:");
puts(" count = 3");
puts(" interface = first interface if only one present, only needed for link-local addresses");
puts(" payload_len = 4");
puts(" delay = 1000");
puts(" stats interval = count");
@ -148,6 +149,7 @@ int _icmpv6_ping(int argc, char **argv)
uint32_t delay = 1 * SEC_IN_MS;
char *addr_str;
ipv6_addr_t addr;
kernel_pid_t src_iface;
msg_t msg;
gnrc_netreg_entry_t *ipv6_entry, my_entry = { NULL, ICMPV6_ECHO_REP,
thread_getpid() };
@ -170,7 +172,6 @@ int _icmpv6_ping(int argc, char **argv)
stat_interval = count;
addr_str = argv[1 + param_offset];
if (argc > (2 + param_offset)) {
payload_len = atoi(argv[2 + param_offset]);
}
@ -186,11 +187,43 @@ int _icmpv6_ping(int argc, char **argv)
return 1;
}
src_iface = ipv6_addr_split_iface(addr_str);
if (src_iface == -1) {
src_iface = KERNEL_PID_UNDEF;
}
if (ipv6_addr_from_str(&addr, addr_str) == NULL) {
puts("error: malformed address");
return 1;
}
if (ipv6_addr_is_link_local(&addr) || (src_iface != KERNEL_PID_UNDEF)) {
kernel_pid_t ifs[GNRC_NETIF_NUMOF];
size_t ifnum = gnrc_netif_get(ifs);
if (src_iface == KERNEL_PID_UNDEF) {
if (ifnum == 1) {
src_iface = ifs[0];
}
else {
puts("error: link local target needs interface parameter (use \"<address>%<ifnum>\")\n");
return 1;
}
}
else {
int valid = 0;
for (size_t i = 0; i < ifnum && i < GNRC_NETIF_NUMOF; i++) {
if (ifs[i] == src_iface) {
valid = 1;
break;
}
}
if (!valid) {
printf("error: %"PRIkernel_pid" is not a valid interface.\n", src_iface);
return 1;
}
}
}
if (gnrc_netreg_register(GNRC_NETTYPE_ICMPV6, &my_entry) < 0) {
puts("error: network registry is full");
return 1;
@ -229,6 +262,18 @@ int _icmpv6_ping(int argc, char **argv)
continue;
}
if (src_iface != KERNEL_PID_UNDEF) {
pkt = gnrc_pktbuf_add(pkt, NULL, sizeof(gnrc_netif_hdr_t),
GNRC_NETTYPE_NETIF);
if (pkt == NULL) {
puts("error: packet buffer full");
continue;
}
((gnrc_netif_hdr_t *)pkt->data)->if_pid = src_iface;
}
start = xtimer_now();
if (gnrc_netapi_send(ipv6_entry->pid, pkt) < 1) {
puts("error: unable to send ICMPv6 echo request\n");