diff --git a/sys/include/net/ng_ipv6/nc.h b/sys/include/net/ng_ipv6/nc.h
index 0421705bfe1810779b8639b3b6b69ee24686d943..46d09af883961bfea5d8510178565ee6364ce417 100644
--- a/sys/include/net/ng_ipv6/nc.h
+++ b/sys/include/net/ng_ipv6/nc.h
@@ -175,6 +175,24 @@ void ng_ipv6_nc_remove(kernel_pid_t iface, const ng_ipv6_addr_t *ipv6_addr);
  */
 ng_ipv6_nc_t *ng_ipv6_nc_get(kernel_pid_t iface, const ng_ipv6_addr_t *ipv6_addr);
 
+/**
+ * @brief   Gets next entry in neighbor cache after @p prev.
+ *
+ * @param[in] prev  Previous entry. NULL to start iteration.
+ *
+ * @return  The next entry in neighbor cache.
+ */
+ng_ipv6_nc_t *ng_ipv6_nc_get_next(ng_ipv6_nc_t *prev);
+
+/**
+ * @brief   Gets next reachable router entry in neighbor cache after @p prev.
+ *
+ * @param[in] prev  Previous router entry. NULL to start iteration.
+ *
+ * @return  The next reachable router entry in neighbor cache.
+ */
+ng_ipv6_nc_t *ng_ipv6_nc_get_next_router(ng_ipv6_nc_t *prev);
+
 /**
  * @brief   Searches for any neighbor cache entry fitting the @p ipv6_addr,
  *          where you currently can send a packet to (do not confuse with
diff --git a/sys/net/network_layer/ng_ipv6/nc/ng_ipv6_nc.c b/sys/net/network_layer/ng_ipv6/nc/ng_ipv6_nc.c
index 6aeb5fec0b78ae3e61f03479688b891d54aaf8bd..39ce430a734f29842bcc6c6e347562b8d995e609 100644
--- a/sys/net/network_layer/ng_ipv6/nc/ng_ipv6_nc.c
+++ b/sys/net/network_layer/ng_ipv6/nc/ng_ipv6_nc.c
@@ -136,6 +136,50 @@ ng_ipv6_nc_t *ng_ipv6_nc_get(kernel_pid_t iface, const ng_ipv6_addr_t *ipv6_addr
     return NULL;
 }
 
+ng_ipv6_nc_t *ng_ipv6_nc_get_next(ng_ipv6_nc_t *prev)
+{
+    if (prev == NULL) {
+        prev = ncache;
+    }
+    else {
+        prev++;     /* get next entry */
+    }
+
+    while (prev < (ncache + NG_IPV6_NC_SIZE)) { /* while not reached end */
+        if (!ng_ipv6_addr_is_unspecified(&(prev->ipv6_addr))) {
+            return prev;
+        }
+
+        prev++;
+    }
+
+    return NULL;
+}
+
+static inline bool _is_reachable(ng_ipv6_nc_t *entry)
+{
+    switch ((entry->flags & NG_IPV6_NC_STATE_MASK) >> NG_IPV6_NC_STATE_POS) {
+        case NG_IPV6_NC_STATE_UNREACHABLE:
+        case NG_IPV6_NC_STATE_INCOMPLETE:
+            return false;
+
+        default:
+            return true;
+    }
+}
+
+ng_ipv6_nc_t *ng_ipv6_nc_get_next_router(ng_ipv6_nc_t *prev)
+{
+    for (ng_ipv6_nc_t *router = ng_ipv6_nc_get_next(prev); router != NULL;
+         router = ng_ipv6_nc_get_next(router)) {
+        if (router->flags & NG_IPV6_NC_IS_ROUTER) {
+            return router;
+        }
+    }
+
+    return NULL;
+}
+
 ng_ipv6_nc_t *ng_ipv6_nc_get_reachable(kernel_pid_t iface,
                                        const ng_ipv6_addr_t *ipv6_addr)
 {
@@ -148,17 +192,11 @@ ng_ipv6_nc_t *ng_ipv6_nc_get_reachable(kernel_pid_t iface,
         return NULL;
     }
 
-    switch ((entry->flags & NG_IPV6_NC_STATE_MASK) >> NG_IPV6_NC_STATE_POS) {
-        case NG_IPV6_NC_STATE_UNREACHABLE:
-        case NG_IPV6_NC_STATE_INCOMPLETE:
-            DEBUG("ipv6_nc: Entry %s is unreachable (flags = 0x%02x)\n",
-                  ng_ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str)),
-                  entry->flags);
-            return NULL;
-
-        default:
-            return entry;
+    if (_is_reachable(entry)) {
+        return entry;
     }
+
+    return NULL;
 }
 
 ng_ipv6_nc_t *ng_ipv6_nc_still_reachable(const ng_ipv6_addr_t *ipv6_addr)
diff --git a/sys/shell/commands/sc_ipv6_nc.c b/sys/shell/commands/sc_ipv6_nc.c
index 032466100d66530e6c7f8002af08a72e9a741a35..615acf902892ae3afd62961ef414aee097339290 100644
--- a/sys/shell/commands/sc_ipv6_nc.c
+++ b/sys/shell/commands/sc_ipv6_nc.c
@@ -26,6 +26,64 @@
 /* maximum length of L2 address */
 #define MAX_L2_ADDR_LEN (8U)
 
+static void _print_nc_state(ng_ipv6_nc_t *entry)
+{
+    switch (entry->flags & NG_IPV6_NC_STATE_MASK) {
+        case NG_IPV6_NC_STATE_UNMANAGED:
+            printf("UNMANAGED");
+            break;
+
+        case NG_IPV6_NC_STATE_UNREACHABLE:
+            printf("UNREACHABLE");
+            break;
+
+        case NG_IPV6_NC_STATE_INCOMPLETE:
+            printf("INCOMPLETE");
+            break;
+
+        case NG_IPV6_NC_STATE_STALE:
+            printf("STALE");
+            break;
+
+        case NG_IPV6_NC_STATE_DELAY:
+            printf("DELAY");
+            break;
+
+        case NG_IPV6_NC_STATE_PROBE:
+            printf("PROBE");
+            break;
+
+        case NG_IPV6_NC_STATE_REACHABLE:
+            printf("REACHABLE");
+            break;
+
+        default:
+            printf("UNKNOWN");
+            break;
+    }
+}
+
+static void _print_nc_type(ng_ipv6_nc_t *entry)
+{
+    switch (entry->flags & NG_IPV6_NC_TYPE_MASK) {
+        case NG_IPV6_NC_TYPE_GC:
+            printf("GC");
+            break;
+
+        case NG_IPV6_NC_TYPE_TENTATIVE:
+            printf("T");
+            break;
+
+        case NG_IPV6_NC_TYPE_REGISTERED:
+            printf("R");
+            break;
+
+        default:
+            printf("-");
+            break;
+    }
+}
+
 static bool _is_iface(kernel_pid_t iface)
 {
 #ifdef MODULE_NG_NETIF
@@ -44,6 +102,30 @@ static bool _is_iface(kernel_pid_t iface)
 #endif
 }
 
+static int _ipv6_nc_list(void)
+{
+    char ipv6_str[NG_IPV6_ADDR_MAX_STR_LEN];
+    char l2addr_str[3 * MAX_L2_ADDR_LEN];
+
+    puts("IPv6 address                    if  L2 address                state      type");
+    puts("-----------------------------------------------------------------------------");
+
+    for (ng_ipv6_nc_t *entry = ng_ipv6_nc_get_next(NULL);
+         entry != NULL;
+         entry = ng_ipv6_nc_get_next(entry)) {
+        printf("%-30s  %2" PRIkernel_pid "  %-24s  ",
+               ng_ipv6_addr_to_str(ipv6_str, &entry->ipv6_addr, sizeof(ipv6_str)),
+               entry->iface,
+               ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str),
+                                    entry->l2_addr, entry->l2_addr_len));
+        _print_nc_state(entry);
+        _print_nc_type(entry);
+        puts("");
+    }
+
+    return 0;
+}
+
 static int _ipv6_nc_add(kernel_pid_t iface, char *ipv6_addr_str,
                         char *l2_addr_str)
 {
@@ -88,6 +170,10 @@ static int _ipv6_nc_del(char *ipv6_addr_str)
 
 int _ipv6_nc_manage(int argc, char **argv)
 {
+    if ((argc == 1) || (strcmp("list", argv[1]) == 0)) {
+        return _ipv6_nc_list();
+    }
+
     if (argc > 2) {
         if ((argc > 4) && (strcmp("add", argv[1]) == 0)) {
             kernel_pid_t iface = (kernel_pid_t)atoi(argv[2]);
@@ -105,11 +191,46 @@ int _ipv6_nc_manage(int argc, char **argv)
         }
     }
 
-    printf("usage: %s add <iface pid> <ipv6_addr> <l2_addr>\n"
-           "   or: %s del <ipv6_addr>\n", argv[0], argv[0]);
+    printf("usage: %s [list]\n"
+           "   or: %s add <iface pid> <ipv6_addr> <l2_addr>\n"
+           "   or: %s del <ipv6_addr>\n", argv[0], argv[0], argv[0]);
     return 1;
 }
 
+int _ipv6_nc_routers(int argc, char **argv)
+{
+    kernel_pid_t iface = KERNEL_PID_UNDEF;
+    char ipv6_str[NG_IPV6_ADDR_MAX_STR_LEN];
+
+    if (argc > 1) {
+        iface = atoi(argv[1]);
+
+        if (!_is_iface(iface)) {
+            printf("usage: %s [<iface pid>]\n", argv[0]);
+            return 1;
+        }
+    }
+
+    puts("if  Router                          state      type");
+    puts("---------------------------------------------------");
+
+    for (ng_ipv6_nc_t *entry = ng_ipv6_nc_get_next_router(NULL);
+         entry != NULL;
+         entry = ng_ipv6_nc_get_next_router(entry)) {
+        if ((iface != KERNEL_PID_UNDEF) && (iface != entry->iface)) {
+            continue;
+        }
+
+        printf("%2" PRIkernel_pid "  %-30s  ", entry->iface,
+               ng_ipv6_addr_to_str(ipv6_str, &entry->ipv6_addr, sizeof(ipv6_str)));
+        _print_nc_state(entry);
+        _print_nc_type(entry);
+        puts("");
+    }
+
+    return 0;
+}
+
 /**
  * @}
  */
diff --git a/sys/shell/commands/shell_commands.c b/sys/shell/commands/shell_commands.c
index 87ec5baa6da87bb55cd0dfa225ed01eee895a609..dc0714d500c7c86e46ae65c9aa1988e7fae7dbbb 100644
--- a/sys/shell/commands/shell_commands.c
+++ b/sys/shell/commands/shell_commands.c
@@ -165,6 +165,7 @@ extern int _fib_route_handler(int argc, char **argv);
 
 #ifdef MODULE_NG_IPV6_NC
 extern int _ipv6_nc_manage(int argc, char **argv);
+extern int _ipv6_nc_routers(int argc, char **argv);
 #endif
 
 const shell_command_t _shell_command_list[] = {
@@ -273,6 +274,7 @@ const shell_command_t _shell_command_list[] = {
 #endif
 #ifdef MODULE_NG_IPV6_NC
     {"ncache", "manage neighbor cache by hand", _ipv6_nc_manage },
+    {"routers", "IPv6 default router list", _ipv6_nc_routers },
 #endif
     {NULL, NULL, NULL}
 };
diff --git a/tests/unittests/tests-ipv6_nc/tests-ipv6_nc.c b/tests/unittests/tests-ipv6_nc/tests-ipv6_nc.c
index 3576a70ca983893613433bcda0f44fb3c571c6ca..93312386db98eccfb9218fef69a5f3a4c6395246 100644
--- a/tests/unittests/tests-ipv6_nc/tests-ipv6_nc.c
+++ b/tests/unittests/tests-ipv6_nc/tests-ipv6_nc.c
@@ -40,6 +40,13 @@
         } \
     }
 
+/* a third IPv6 addr for testing */
+#define THIRD_TEST_IPV6_ADDR    { { \
+            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
+            0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f \
+        } \
+    }
+
 static void set_up(void)
 {
     ng_ipv6_nc_init();
@@ -207,6 +214,91 @@ static void test_ipv6_nc_get__success_if_global(void)
     TEST_ASSERT_EQUAL_INT(0, entry->flags);
 }
 
+static void test_ipv6_nc_get_next__empty(void)
+{
+    TEST_ASSERT_NULL(ng_ipv6_nc_get_next(NULL));
+}
+
+static void test_ipv6_nc_get_next__1_entry(void)
+{
+    ng_ipv6_nc_t *entry = NULL;
+
+    test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
+
+    TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get_next(NULL)));
+    TEST_ASSERT_NULL(ng_ipv6_nc_get_next(entry));
+}
+
+static void test_ipv6_nc_get_next__2_entries(void)
+{
+    ng_ipv6_addr_t addr = OTHER_TEST_IPV6_ADDR;
+    ng_ipv6_nc_t *entry = NULL;
+
+    test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
+    TEST_ASSERT_EQUAL_INT(0, ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &addr,
+                                            TEST_STRING8, sizeof(TEST_STRING8) - 1, 0));
+
+
+    TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get_next(NULL)));
+    TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get_next(entry)));
+    TEST_ASSERT_NULL(ng_ipv6_nc_get_next(entry));
+}
+
+static void test_ipv6_nc_get_next__holey(void)
+{
+    ng_ipv6_addr_t addr1 = OTHER_TEST_IPV6_ADDR;
+    ng_ipv6_addr_t addr2 = THIRD_TEST_IPV6_ADDR;
+    ng_ipv6_nc_t *entry = NULL, *exp_entry = NULL;
+
+    /* adds DEFAULT_TEST_IPV6_ADDR and OTHER_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
+    test_ipv6_nc_get_next__2_entries();
+    TEST_ASSERT_EQUAL_INT(0, ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &addr2,
+                                            TEST_STRING8,
+                                            sizeof(TEST_STRING8) - 2, 0));
+    TEST_ASSERT_NOT_NULL((exp_entry = ng_ipv6_nc_get(DEFAULT_TEST_NETIF, &addr2)));
+    ng_ipv6_nc_remove(DEFAULT_TEST_NETIF, &addr1);
+
+    TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get_next(NULL)));
+    TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get_next(entry)));
+    TEST_ASSERT(exp_entry == entry);
+    TEST_ASSERT_NULL(ng_ipv6_nc_get_next(entry));
+}
+
+static void test_ipv6_nc_get_next_router__empty(void)
+{
+    TEST_ASSERT_NULL(ng_ipv6_nc_get_next_router(NULL));
+}
+
+static void test_ipv6_nc_get_next_router__first_entry(void)
+{
+    ng_ipv6_nc_t *entry = NULL;
+
+    /* adds DEFAULT_TEST_IPV6_ADDR and OTHER_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
+    test_ipv6_nc_get_next__2_entries();
+    TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get_next(NULL)));
+    entry->flags = (NG_IPV6_NC_STATE_REACHABLE << NG_IPV6_NC_STATE_POS);
+    entry->flags |= NG_IPV6_NC_IS_ROUTER;
+
+    TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get_next_router(NULL)));
+    TEST_ASSERT_NULL(ng_ipv6_nc_get_next_router(entry));
+}
+
+static void test_ipv6_nc_get_next_router__second_entry(void)
+{
+    ng_ipv6_nc_t *entry1 = NULL, *entry2 = NULL;
+
+    /* adds DEFAULT_TEST_IPV6_ADDR and OTHER_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
+    test_ipv6_nc_get_next__2_entries();
+    TEST_ASSERT_NOT_NULL((entry1 = ng_ipv6_nc_get_next(NULL)));
+    TEST_ASSERT_NOT_NULL((entry2 = ng_ipv6_nc_get_next(entry1)));
+    entry2->flags = (NG_IPV6_NC_STATE_REACHABLE << NG_IPV6_NC_STATE_POS);
+    entry2->flags |= NG_IPV6_NC_IS_ROUTER;
+
+    TEST_ASSERT_NOT_NULL((entry1 = ng_ipv6_nc_get_next_router(NULL)));
+    TEST_ASSERT(entry2 == entry1);
+    TEST_ASSERT_NULL(ng_ipv6_nc_get_next_router(entry1));
+}
+
 static void test_ipv6_nc_get_reachable__incomplete_if_local(void)
 {
     ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
@@ -318,6 +410,13 @@ Test *tests_ipv6_nc_tests(void)
         new_TestFixture(test_ipv6_nc_get__different_addr),
         new_TestFixture(test_ipv6_nc_get__success_if_local),
         new_TestFixture(test_ipv6_nc_get__success_if_global),
+        new_TestFixture(test_ipv6_nc_get_next__empty),
+        new_TestFixture(test_ipv6_nc_get_next__1_entry),
+        new_TestFixture(test_ipv6_nc_get_next__2_entries),
+        new_TestFixture(test_ipv6_nc_get_next__holey),
+        new_TestFixture(test_ipv6_nc_get_next_router__empty),
+        new_TestFixture(test_ipv6_nc_get_next_router__first_entry),
+        new_TestFixture(test_ipv6_nc_get_next_router__second_entry),
         new_TestFixture(test_ipv6_nc_get_reachable__incomplete_if_local),
         new_TestFixture(test_ipv6_nc_get_reachable__incomplete_if_global),
         new_TestFixture(test_ipv6_nc_get_reachable__reachable_if_local),