diff --git a/sys/include/net/gnrc/netreg.h b/sys/include/net/gnrc/netreg.h
index 11455c703ac0ecfd11494529a682b9a2c36ff78b..cea7d13635c5356d36957bdd364eb725932d92f4 100644
--- a/sys/include/net/gnrc/netreg.h
+++ b/sys/include/net/gnrc/netreg.h
@@ -333,6 +333,19 @@ void gnrc_netreg_unregister(gnrc_nettype_t type, gnrc_netreg_entry_t *entry);
  */
 gnrc_netreg_entry_t *gnrc_netreg_lookup(gnrc_nettype_t type, uint32_t demux_ctx);
 
+/**
+ * @brief   Returns number of entries with the same gnrc_netreg_entry_t::type and
+ *          gnrc_netreg_entry_t::demux_ctx.
+ *
+ * @param[in] type      Type of the protocol.
+ * @param[in] demux_ctx The demultiplexing context for the registered thread.
+ *                      See gnrc_netreg_entry_t::demux_ctx.
+ *
+ * @return  Number of entries with the same gnrc_netreg_entry_t::type and
+ *          gnrc_netreg_entry_t::demux_ctx as the given parameters.
+ */
+int gnrc_netreg_num(gnrc_nettype_t type, uint32_t demux_ctx);
+
 /**
  * @brief   Returns the next entry after @p entry with the same
  *          gnrc_netreg_entry_t::type and gnrc_netreg_entry_t::demux_ctx as the
diff --git a/sys/net/gnrc/netapi/gnrc_netapi.c b/sys/net/gnrc/netapi/gnrc_netapi.c
index afe5998813ad613e5b72dd0a009a68d45cbd2fb2..9d7fbee96ee7b232fe20a900f0db8883e4d9a4cc 100644
--- a/sys/net/gnrc/netapi/gnrc_netapi.c
+++ b/sys/net/gnrc/netapi/gnrc_netapi.c
@@ -94,52 +94,54 @@ static inline int _snd_rcv_mbox(mbox_t *mbox, uint16_t type, gnrc_pktsnip_t *pkt
 int gnrc_netapi_dispatch(gnrc_nettype_t type, uint32_t demux_ctx,
                          uint16_t cmd, gnrc_pktsnip_t *pkt)
 {
-    int numof = 0;
-    gnrc_netreg_entry_t *sendto = gnrc_netreg_lookup(type, demux_ctx);
+    int numof = gnrc_netreg_num(type, demux_ctx);
 
-    while (sendto) {
-        if (numof != 0) {
-            gnrc_pktbuf_hold(pkt, 1);
-        }
+    if (numof != 0) {
+        gnrc_netreg_entry_t *sendto = gnrc_netreg_lookup(type, demux_ctx);
+
+        gnrc_pktbuf_hold(pkt, numof - 1);
+
+        while (sendto) {
 #if defined(MODULE_GNRC_NETAPI_MBOX) || defined(MODULE_GNRC_NETAPI_CALLBACKS)
-        int release = 0;
-        switch (sendto->type) {
-            case GNRC_NETREG_TYPE_DEFAULT:
-                if (_snd_rcv(sendto->target.pid, cmd, pkt) < 1) {
-                    /* unable to dispatch packet */
-                    release = 1;
-                }
-                break;
+            int release = 0;
+            switch (sendto->type) {
+                case GNRC_NETREG_TYPE_DEFAULT:
+                    if (_snd_rcv(sendto->target.pid, cmd, pkt) < 1) {
+                        /* unable to dispatch packet */
+                        release = 1;
+                    }
+                    break;
 #ifdef MODULE_GNRC_NETAPI_MBOX
-            case GNRC_NETREG_TYPE_MBOX:
-                if (_snd_rcv_mbox(sendto->target.mbox, cmd, pkt) < 1) {
-                    /* unable to dispatch packet */
-                    release = 1;
-                }
-                break;
+                case GNRC_NETREG_TYPE_MBOX:
+                    if (_snd_rcv_mbox(sendto->target.mbox, cmd, pkt) < 1) {
+                        /* unable to dispatch packet */
+                        release = 1;
+                    }
+                    break;
 #endif
 #ifdef MODULE_GNRC_NETAPI_CALLBACKS
-            case GNRC_NETREG_TYPE_CB:
-                sendto->target.cbd->cb(cmd, pkt, sendto->target.cbd->ctx);
-                break;
+                case GNRC_NETREG_TYPE_CB:
+                    sendto->target.cbd->cb(cmd, pkt, sendto->target.cbd->ctx);
+                    break;
 #endif
-            default:
-                /* unknown dispatch type */
-                release = 1;
-                break;
-        }
-        if (release) {
-            gnrc_pktbuf_release(pkt);
-        }
+                default:
+                    /* unknown dispatch type */
+                    release = 1;
+                    break;
+            }
+            if (release) {
+                gnrc_pktbuf_release(pkt);
+            }
 #else
-        if (_snd_rcv(sendto->target.pid, cmd, pkt) < 1) {
-            /* unable to dispatch packet */
-            gnrc_pktbuf_release(pkt);
-        }
+            if (_snd_rcv(sendto->target.pid, cmd, pkt) < 1) {
+                /* unable to dispatch packet */
+                gnrc_pktbuf_release(pkt);
+            }
 #endif
-        numof++;
-        sendto = gnrc_netreg_getnext(sendto);
+            sendto = gnrc_netreg_getnext(sendto);
+        }
     }
+
     return numof;
 }
 
diff --git a/sys/net/gnrc/netreg/gnrc_netreg.c b/sys/net/gnrc/netreg/gnrc_netreg.c
index 8d8ef83462185590a0d45a2b7131031e388142c1..b77f76fbae179ee00a0b708a9f222cf73932f8e5 100644
--- a/sys/net/gnrc/netreg/gnrc_netreg.c
+++ b/sys/net/gnrc/netreg/gnrc_netreg.c
@@ -96,6 +96,17 @@ gnrc_netreg_entry_t *gnrc_netreg_lookup(gnrc_nettype_t type, uint32_t demux_ctx)
     return _netreg_lookup(NULL, type, demux_ctx);
 }
 
+int gnrc_netreg_num(gnrc_nettype_t type, uint32_t demux_ctx)
+{
+    int num = 0;
+    gnrc_netreg_entry_t *entry = NULL;
+
+    while((entry = _netreg_lookup(entry, type, demux_ctx)) != NULL) {
+        num++;
+    }
+    return num;
+}
+
 gnrc_netreg_entry_t *gnrc_netreg_getnext(gnrc_netreg_entry_t *entry)
 {
     return (entry ? _netreg_lookup(entry, 0, entry->demux_ctx) : NULL);
diff --git a/tests/unittests/tests-netreg/tests-netreg.c b/tests/unittests/tests-netreg/tests-netreg.c
index 2416dac42481a1e25bc28c4f72f8da33db38bb7e..b56a68861f9fc85335fe8a5bf8d73fb1d6ca62ee 100644
--- a/tests/unittests/tests-netreg/tests-netreg.c
+++ b/tests/unittests/tests-netreg/tests-netreg.c
@@ -85,13 +85,6 @@ void test_netreg_unregister__success3(void)
     TEST_ASSERT_NULL(gnrc_netreg_lookup(GNRC_NETTYPE_TEST, TEST_UINT16));
 }
 
-void test_netreg_lookup__empty(void)
-{
-    TEST_ASSERT_NULL(gnrc_netreg_lookup(GNRC_NETTYPE_TEST, TEST_UINT16));
-    TEST_ASSERT_NULL(gnrc_netreg_lookup(GNRC_NETTYPE_TEST, TEST_UINT16 + 1));
-    TEST_ASSERT_NULL(gnrc_netreg_lookup(GNRC_NETTYPE_TEST, GNRC_NETREG_DEMUX_CTX_ALL));
-}
-
 void test_netreg_lookup__wrong_type_undef(void)
 {
     TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_register(GNRC_NETTYPE_TEST, &entries[0]));
@@ -104,17 +97,31 @@ void test_netreg_lookup__wrong_type_numof(void)
     TEST_ASSERT_NULL(gnrc_netreg_lookup(GNRC_NETTYPE_NUMOF, TEST_UINT16));
 }
 
-void test_netreg_lookup__2_entries(void)
+void test_netreg_num__empty(void)
+{
+    TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_num(GNRC_NETTYPE_TEST, TEST_UINT16));
+    TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_num(GNRC_NETTYPE_TEST, TEST_UINT16 + 1));
+    TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_num(GNRC_NETTYPE_TEST, GNRC_NETREG_DEMUX_CTX_ALL));
+}
+
+void test_netreg_num__wrong_type_undef(void)
 {
-    gnrc_netreg_entry_t *res = NULL;
-    /* add first entry, first lookup != NULL; second == NULL */
     TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_register(GNRC_NETTYPE_TEST, &entries[0]));
-    TEST_ASSERT_NOT_NULL((res = gnrc_netreg_lookup(GNRC_NETTYPE_TEST, TEST_UINT16)));
-    TEST_ASSERT_NULL((res = gnrc_netreg_getnext(res)));
-    /* add second entry, both lookups != NULL */
+    TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_num(GNRC_NETTYPE_UNDEF, TEST_UINT16));
+}
+
+void test_netreg_num__wrong_type_numof(void)
+{
+    TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_register(GNRC_NETTYPE_TEST, &entries[0]));
+    TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_num(GNRC_NETTYPE_NUMOF, TEST_UINT16));
+}
+
+void test_netreg_num__2_entries(void)
+{
+    TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_register(GNRC_NETTYPE_TEST, &entries[0]));
+    TEST_ASSERT_EQUAL_INT(1, gnrc_netreg_num(GNRC_NETTYPE_TEST, TEST_UINT16));
     TEST_ASSERT_EQUAL_INT(0, gnrc_netreg_register(GNRC_NETTYPE_TEST, &entries[1]));
-    TEST_ASSERT_NOT_NULL((res = gnrc_netreg_lookup(GNRC_NETTYPE_TEST, TEST_UINT16)));
-    TEST_ASSERT_NOT_NULL((res = gnrc_netreg_getnext(res)));
+    TEST_ASSERT_EQUAL_INT(2, gnrc_netreg_num(GNRC_NETTYPE_TEST, TEST_UINT16));
 }
 
 void test_netreg_getnext__NULL(void)
@@ -127,7 +134,7 @@ void test_netreg_getnext__2_entries(void)
 {
     gnrc_netreg_entry_t *res = NULL;
 
-    test_netreg_lookup__2_entries();
+    test_netreg_num__2_entries();
     TEST_ASSERT_NOT_NULL((res = gnrc_netreg_lookup(GNRC_NETTYPE_TEST, TEST_UINT16)));
     TEST_ASSERT_NOT_NULL(gnrc_netreg_getnext(res));
 }
@@ -140,10 +147,12 @@ Test *tests_netreg_tests(void)
         new_TestFixture(test_netreg_unregister__success),
         new_TestFixture(test_netreg_unregister__success2),
         new_TestFixture(test_netreg_unregister__success3),
-        new_TestFixture(test_netreg_lookup__empty),
         new_TestFixture(test_netreg_lookup__wrong_type_undef),
         new_TestFixture(test_netreg_lookup__wrong_type_numof),
-        new_TestFixture(test_netreg_lookup__2_entries),
+        new_TestFixture(test_netreg_num__empty),
+        new_TestFixture(test_netreg_num__wrong_type_undef),
+        new_TestFixture(test_netreg_num__wrong_type_numof),
+        new_TestFixture(test_netreg_num__2_entries),
         new_TestFixture(test_netreg_getnext__NULL),
         new_TestFixture(test_netreg_getnext__2_entries),
     };