/* * Copyright (C) 2015 Martin Landsmann * * 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 Provides shell commands to manage and show FIB Entries * * @author 2015 Martin Landsmann * * @} */ #include #include #include #include #include "thread.h" #include "inet_pton.h" #include "ng_fib.h" #define INFO1_TXT "fibroute add via dev " #define INFO2_TXT " [lifetime ]" #define INFO3_TXT " - the destination address\n" \ " - the address of the next-hop towards the \n" \ " - the device id of the Interface to use\n" #define INFO4_TXT " - optional lifetime in ms when the entry automatically invalidates\n" #define INFO5_TXT "fibroute del \n" \ " - the destination address of the entry to be deleted\n" static unsigned char tmp_ipv4_dst[INADDRSZ]; /**< buffer for ipv4 address conversion */ static unsigned char tmp_ipv4_nxt[INADDRSZ]; /**< buffer for ipv4 address conversion */ static unsigned char tmp_ipv6_dst[IN6ADDRSZ]; /**< buffer for ipv6 address conversion */ static unsigned char tmp_ipv6_nxt[IN6ADDRSZ]; /**< buffer for ipv6 address conversion */ static void _fib_usage(int info) { switch (info) { case 1: { puts("\nbrief: adds a new entry to the FIB.\nusage: " INFO1_TXT "\n" INFO3_TXT); break; } case 2: { puts("\nbrief: adds a new entry to the FIB.\nusage: " INFO1_TXT INFO2_TXT "\n" INFO3_TXT INFO4_TXT); break; } case 3: { puts("\nbrief: deletes an entry from the FIB.\nusage: " INFO5_TXT); break; } default: break; }; } int _fib_route_handler(int argc, char **argv) { /* e.g. fibroute right now dont care about the adress/protocol family */ if (argc == 1) { fib_print_routes(); return 0; } /* e.g. firoute [add|del] */ if (argc == 2) { if ((strcmp("add", argv[1]) == 0)) { _fib_usage(2); } else if ((strcmp("del", argv[1]) == 0)) { _fib_usage(3); } else { puts("\nunrecognized parameter1.\nPlease enter fibroute [add|del] for more information."); } return 1; } if (argc > 2 && !((strcmp("add", argv[1]) == 0) || (strcmp("del", argv[1]) == 0))) { puts("\nunrecognized parameter2.\nPlease enter fibroute [add|del] for more information."); return 1; } /* e.g. fibroute del */ if (argc == 3) { if (inet_pton(AF_INET6, argv[2], tmp_ipv6_dst)) { fib_remove_entry(tmp_ipv6_dst, IN6ADDRSZ); } else if (inet_pton(AF_INET, argv[2], tmp_ipv4_dst)) { fib_remove_entry(tmp_ipv4_dst, INADDRSZ); } else { fib_remove_entry((uint8_t *)argv[2], (strlen(argv[2]))); } return 0; } /* e.g. fibroute add via dev */ if (argc == 7) { if ((strcmp("add", argv[1]) == 0) && (strcmp("via", argv[3]) == 0) && (strcmp("dev", argv[5]) == 0)) { unsigned char *dst = (unsigned char *)argv[2]; size_t dst_size = (strlen(argv[2])); uint32_t dst_flags = 0xffff; unsigned char *nxt = (unsigned char *)argv[4]; size_t nxt_size = (strlen(argv[4])); uint32_t nxt_flags = 0xffff; /* determine destination address */ if (inet_pton(AF_INET6, argv[2], tmp_ipv6_dst)) { dst = tmp_ipv6_dst; dst_size = IN6ADDRSZ; dst_flags = AF_INET6; } else if (inet_pton(AF_INET, argv[2], tmp_ipv4_dst)) { dst = tmp_ipv4_dst; dst_size = INADDRSZ; dst_flags = AF_INET; } /* determine next-hop address */ if (inet_pton(AF_INET6, argv[4], tmp_ipv6_nxt)) { nxt = tmp_ipv6_nxt; nxt_size = IN6ADDRSZ; nxt_flags = AF_INET6; } else if (inet_pton(AF_INET, argv[4], tmp_ipv4_nxt)) { nxt = tmp_ipv4_nxt; nxt_size = INADDRSZ; nxt_flags = AF_INET; } fib_add_entry((kernel_pid_t) atoi(argv[6]), dst, dst_size, dst_flags, nxt, nxt_size, nxt_flags, FIB_LIFETIME_NO_EXPIRE); } else { _fib_usage(1); return 1; } return 0; } /* e.g. fibroute add via dev lifetime */ if (argc == 9) { if ((strcmp("add", argv[1]) == 0) && (strcmp("via", argv[3]) == 0) && (strcmp("dev", argv[5]) == 0) && (strcmp("lifetime", argv[7]) == 0)) { unsigned char *dst = (unsigned char *)argv[2]; size_t dst_size = (strlen(argv[2])); uint32_t dst_flags = 0xffff; unsigned char *nxt = (unsigned char *)argv[4]; size_t nxt_size = (strlen(argv[4])); uint32_t nxt_flags = 0xffff; /* determine destination address */ if (inet_pton(AF_INET6, argv[2], tmp_ipv6_dst)) { dst = tmp_ipv6_dst; dst_size = IN6ADDRSZ; dst_flags = AF_INET6; } else if (inet_pton(AF_INET, argv[2], tmp_ipv4_dst)) { dst = tmp_ipv4_dst; dst_size = INADDRSZ; dst_flags = AF_INET; } /* determine next-hop address */ if (inet_pton(AF_INET6, argv[4], tmp_ipv6_nxt)) { nxt = tmp_ipv6_nxt; nxt_size = IN6ADDRSZ; nxt_flags = AF_INET6; } else if (inet_pton(AF_INET, argv[4], tmp_ipv4_nxt)) { nxt = tmp_ipv4_nxt; nxt_size = INADDRSZ; nxt_flags = AF_INET; } fib_add_entry((kernel_pid_t) atoi(argv[6]), dst, dst_size, dst_flags, nxt, nxt_size, nxt_flags, (uint32_t)atoi(argv[8])); } else { _fib_usage(2); return 1; } return 0; } puts("\nunrecognized parameters.\nPlease enter fibroute [add|del] for more information."); return 1; }