mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
c06335b71b
Previously `shell_commands` was a "catch-all" module that included shell commands for each and every used module that has a shell companion. Instead, the new `shell_cmds` module is now used to provide shell commands as individually selectable submodules, e.g. `cmd_gnrc_icmpv6_echo` now provides the ICMPv6 echo command (a.k.a. ping). To still have a "catch all" module to pull in shell commands of modules already used, `shell_cmds_default` was introduced. `shell_commands` depends now on `shell_cmds_default` for backward compatibility, but has been deprecated. New apps should use `shell_cmds_default` instead. For a handful of shell commands individual selection was already possible. Those modules now depend on the corresponding `cmd_%` module and they have been deprecated.
285 lines
7.6 KiB
C
285 lines
7.6 KiB
C
/*
|
|
* Copyright (C) 2015, 2016 INRIA.
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
/**
|
|
* @ingroup sys_shell_commands
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief Shell commands to interact with the CCN-Lite stack
|
|
*
|
|
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
|
*
|
|
* @}
|
|
*/
|
|
|
|
#include <string.h>
|
|
|
|
#include "ccn-lite-riot.h"
|
|
#include "ccnl-pkt-ndntlv.h"
|
|
#include "net/gnrc/netif.h"
|
|
#include "random.h"
|
|
#include "sched.h"
|
|
#include "shell.h"
|
|
|
|
#define BUF_SIZE (64)
|
|
|
|
#define MAX_ADDR_LEN (GNRC_NETIF_L2ADDR_MAXLEN)
|
|
|
|
static unsigned char _int_buf[BUF_SIZE];
|
|
|
|
static unsigned char _out[CCNL_MAX_PACKET_SIZE];
|
|
|
|
/* usage for open command */
|
|
static void _open_usage(void)
|
|
{
|
|
puts("ccnl <interface>");
|
|
}
|
|
|
|
static int _ccnl_open(int argc, char **argv)
|
|
{
|
|
/* check if already running */
|
|
if (ccnl_relay.ifcount >= CCNL_MAX_INTERFACES) {
|
|
puts("Already opened max. number of interfaces for CCN!");
|
|
return -1;
|
|
}
|
|
|
|
/* check if parameter is given */
|
|
if (argc != 2) {
|
|
_open_usage();
|
|
return -1;
|
|
}
|
|
|
|
/* check if given number is a valid netif PID */
|
|
int pid = atoi(argv[1]);
|
|
if (gnrc_netif_get_by_pid(pid) == NULL) {
|
|
printf("%i is not a valid interface!\n", pid);
|
|
return -1;
|
|
}
|
|
|
|
ccnl_start();
|
|
|
|
/* set the relay's PID, configure the interface to interface to use CCN
|
|
* nettype */
|
|
if (ccnl_open_netif(pid, GNRC_NETTYPE_CCN) < 0) {
|
|
puts("Error registering at network interface!");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
SHELL_COMMAND(ccnl_open, "opens an interface or socket", _ccnl_open);
|
|
|
|
static void _content_usage(char *argv)
|
|
{
|
|
printf("usage: %s [URI] [content]\n"
|
|
"prints the CS if called without parameters:\n"
|
|
"%% %s /riot/peter/schmerzl RIOT\n",
|
|
argv, argv);
|
|
}
|
|
|
|
static int _ccnl_content(int argc, char **argv)
|
|
{
|
|
if (argc < 2) {
|
|
ccnl_cs_dump(&ccnl_relay);
|
|
return 0;
|
|
}
|
|
if (argc == 2) {
|
|
_content_usage(argv[0]);
|
|
return -1;
|
|
}
|
|
|
|
int arg_len;
|
|
char buf[BUF_SIZE+1]; /* add one extra space to fit trailing '\0' */
|
|
|
|
unsigned pos = 0;
|
|
for (int i = 2; (i < argc) && (pos < BUF_SIZE); ++i) {
|
|
arg_len = strlen(argv[i]);
|
|
if ((pos + arg_len) > BUF_SIZE) {
|
|
arg_len = BUF_SIZE - pos;
|
|
}
|
|
strncpy(&buf[pos], argv[i], arg_len);
|
|
pos += arg_len;
|
|
/* increment pos _after_ adding ' ' */
|
|
buf[pos++] = ' ';
|
|
}
|
|
/* decrement pos _before_ to overwrite last ' ' with '\0' */
|
|
buf[--pos] = '\0';
|
|
|
|
arg_len = strlen(buf);
|
|
|
|
struct ccnl_prefix_s *prefix = ccnl_URItoPrefix(argv[1], CCNL_SUITE_NDNTLV, NULL);
|
|
size_t offs = CCNL_MAX_PACKET_SIZE;
|
|
size_t reslen = 0;
|
|
arg_len = ccnl_ndntlv_prependContent(prefix, (unsigned char*) buf, arg_len, NULL, NULL, &offs, _out, &reslen);
|
|
|
|
ccnl_prefix_free(prefix);
|
|
|
|
unsigned char *olddata;
|
|
unsigned char *data = olddata = _out + offs;
|
|
|
|
size_t len;
|
|
uint64_t typ;
|
|
|
|
if (ccnl_ndntlv_dehead(&data, &reslen, &typ, &len) ||
|
|
typ != NDN_TLV_Data) {
|
|
return -1;
|
|
}
|
|
|
|
struct ccnl_content_s *c = 0;
|
|
struct ccnl_pkt_s *pk = ccnl_ndntlv_bytes2pkt(typ, olddata, &data, &reslen);
|
|
c = ccnl_content_new(&pk);
|
|
c->flags |= CCNL_CONTENT_FLAGS_STATIC;
|
|
msg_t m = { .type = CCNL_MSG_CS_ADD, .content.ptr = c };
|
|
|
|
if(msg_send(&m, ccnl_event_loop_pid) < 1){
|
|
puts("could not add content");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
SHELL_COMMAND(ccnl_cs, "shows CS or creates content and populates it",
|
|
_ccnl_content);
|
|
|
|
static struct ccnl_face_s *_intern_face_get(char *addr_str)
|
|
{
|
|
/* initialize address with 0xFF for broadcast */
|
|
uint8_t relay_addr[MAX_ADDR_LEN];
|
|
memset(relay_addr, UINT8_MAX, MAX_ADDR_LEN);
|
|
size_t addr_len = gnrc_netif_addr_from_str(addr_str, relay_addr);
|
|
|
|
if (addr_len == 0) {
|
|
printf("Error: %s is not a valid link layer address\n", addr_str);
|
|
return NULL;
|
|
}
|
|
|
|
sockunion sun;
|
|
sun.sa.sa_family = AF_PACKET;
|
|
memcpy(&(sun.linklayer.sll_addr), relay_addr, addr_len);
|
|
sun.linklayer.sll_halen = addr_len;
|
|
sun.linklayer.sll_protocol = htons(ETHERTYPE_NDN);
|
|
|
|
/* TODO: set correct interface instead of always 0 */
|
|
struct ccnl_face_s *fibface = ccnl_get_face_or_create(&ccnl_relay, 0, &sun.sa, sizeof(sun.linklayer));
|
|
|
|
return fibface;
|
|
}
|
|
|
|
static int _intern_fib_add(char *pfx, char *addr_str)
|
|
{
|
|
int suite = CCNL_SUITE_NDNTLV;
|
|
struct ccnl_prefix_s *prefix = ccnl_URItoPrefix(pfx, suite, NULL);
|
|
if (!prefix) {
|
|
puts("Error: prefix could not be created!");
|
|
return -1;
|
|
}
|
|
|
|
struct ccnl_face_s *fibface = _intern_face_get(addr_str);
|
|
if (fibface == NULL) {
|
|
return -1;
|
|
}
|
|
fibface->flags |= CCNL_FACE_FLAGS_STATIC;
|
|
|
|
if (ccnl_fib_add_entry(&ccnl_relay, prefix, fibface) != 0) {
|
|
printf("Error adding (%s : %s) to the FIB\n", pfx, addr_str);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void _interest_usage(char *arg)
|
|
{
|
|
printf("usage: %s <URI> [relay]\n"
|
|
"%% %s /riot/peter/schmerzl (classic lookup)\n",
|
|
arg, arg);
|
|
}
|
|
|
|
static int _ccnl_interest(int argc, char **argv)
|
|
{
|
|
if (argc < 2) {
|
|
_interest_usage(argv[0]);
|
|
return -1;
|
|
}
|
|
|
|
if (argc > 2) {
|
|
if (_intern_fib_add(argv[1], argv[2]) < 0) {
|
|
_interest_usage(argv[0]);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
memset(_int_buf, '\0', BUF_SIZE);
|
|
|
|
struct ccnl_prefix_s *prefix = ccnl_URItoPrefix(argv[1], CCNL_SUITE_NDNTLV, NULL);
|
|
int res = ccnl_send_interest(prefix, _int_buf, BUF_SIZE, NULL);
|
|
ccnl_prefix_free(prefix);
|
|
|
|
return res;
|
|
}
|
|
|
|
SHELL_COMMAND(ccnl_int, "sends an interest", _ccnl_interest);
|
|
|
|
static void _ccnl_fib_usage(char *argv)
|
|
{
|
|
printf("usage: %s [<action> <options>]\n"
|
|
"prints the FIB if called without parameters:\n"
|
|
"%% %s\n"
|
|
"<action> may be one of the following\n"
|
|
" * \"add\" - adds an entry to the FIB, requires a prefix and a next-hop address, e.g.\n"
|
|
" %s add /riot/peter/schmerzl ab:cd:ef:01:23:45:67:89\n"
|
|
" * \"del\" - deletes an entry to the FIB, requires a prefix or a next-hop address, e.g.\n"
|
|
" %s del /riot/peter/schmerzl\n"
|
|
" %s del ab:cd:ef:01:23:45:67:89\n",
|
|
argv, argv, argv, argv, argv);
|
|
}
|
|
|
|
static int _ccnl_fib(int argc, char **argv)
|
|
{
|
|
if (argc < 2) {
|
|
ccnl_fib_show(&ccnl_relay);
|
|
}
|
|
else if ((argc == 3) && (strncmp(argv[1], "del", 3) == 0)) {
|
|
int suite = CCNL_SUITE_NDNTLV;
|
|
if (strchr(argv[2], '/')) {
|
|
struct ccnl_prefix_s *prefix = ccnl_URItoPrefix(argv[2], suite, NULL);
|
|
if (!prefix) {
|
|
puts("Error: prefix could not be created!");
|
|
return -1;
|
|
}
|
|
int res = ccnl_fib_rem_entry(&ccnl_relay, prefix, NULL);
|
|
ccnl_prefix_free(prefix);
|
|
return res;
|
|
}
|
|
else {
|
|
struct ccnl_face_s *face = _intern_face_get(argv[2]);
|
|
if (face == NULL) {
|
|
printf("There is no face for address %s\n", argv[1]);
|
|
return -1;
|
|
}
|
|
int res = ccnl_fib_rem_entry(&ccnl_relay, NULL, face);
|
|
return res;
|
|
}
|
|
}
|
|
else if ((argc == 4) && (strncmp(argv[1], "add", 3) == 0)) {
|
|
if (_intern_fib_add(argv[2], argv[3]) < 0) {
|
|
_ccnl_fib_usage(argv[0]);
|
|
return -1;
|
|
}
|
|
}
|
|
else {
|
|
_ccnl_fib_usage(argv[0]);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
SHELL_COMMAND(ccnl_fib, "shows or modifies the CCN-Lite FIB", _ccnl_fib);
|