diff --git a/Makefile.dep b/Makefile.dep
index 5cbbf1db90aa41bf4d542e949978d4fffa598335..4c55e2e275e8de5234096ae957276bdc1e3d158f 100644
--- a/Makefile.dep
+++ b/Makefile.dep
@@ -141,6 +141,7 @@ endif
 
 ifneq (,$(filter gnrc_netif,$(USEMODULE)))
   USEMODULE += netif
+  USEMODULE += fmt
 endif
 
 ifneq (,$(filter ieee802154 nrfmin,$(USEMODULE)))
diff --git a/sys/net/gnrc/netif/gnrc_netif.c b/sys/net/gnrc/netif/gnrc_netif.c
index 61a5cf570bb9da74d64d8cf31f3fc58752696d1a..a60d05c5c2ac9b687fbaf6dd04550eb47e3def9d 100644
--- a/sys/net/gnrc/netif/gnrc_netif.c
+++ b/sys/net/gnrc/netif/gnrc_netif.c
@@ -28,6 +28,7 @@
 #ifdef MODULE_NETSTATS_IPV6
 #include "net/netstats.h"
 #endif
+#include "fmt.h"
 #include "log.h"
 #include "sched.h"
 
@@ -355,11 +356,6 @@ gnrc_netif_t *gnrc_netif_get_by_pid(kernel_pid_t pid)
     return NULL;
 }
 
-static inline char _half_byte_to_char(uint8_t half_byte)
-{
-    return (half_byte < 10) ? ('0' + half_byte) : ('a' + (half_byte - 10));
-}
-
 char *gnrc_netif_addr_to_str(const uint8_t *addr, size_t addr_len, char *out)
 {
     char *res = out;
@@ -367,8 +363,7 @@ char *gnrc_netif_addr_to_str(const uint8_t *addr, size_t addr_len, char *out)
     assert((out != NULL) && ((addr != NULL) || (addr_len == 0U)));
     out[0] = '\0';
     for (size_t i = 0; i < addr_len; i++) {
-        *(out++) = _half_byte_to_char(*(addr) >> 4);
-        *(out++) = _half_byte_to_char(*(addr++) & 0xf);
+        out += fmt_byte_hex((out), *(addr++));
         *(out++) = (i == (addr_len - 1)) ? '\0' : ':';
     }
     return res;
diff --git a/tests/gnrc_netif/main.c b/tests/gnrc_netif/main.c
index 5a0acd9a4d5bd0bbee9fca47ce3f8919e9f54baa..4a0d3b0d3fb493da58970aefc9f32f46385f6261 100644
--- a/tests/gnrc_netif/main.c
+++ b/tests/gnrc_netif/main.c
@@ -196,19 +196,19 @@ static void test_addr_to_str(void)
     TEST_ASSERT_EQUAL_STRING("", &out[0]);
     TEST_ASSERT(out == gnrc_netif_addr_to_str(ethernet_l2addr,
                                               sizeof(ethernet_l2addr), out));
-    TEST_ASSERT_EQUAL_STRING("3e:e6:b5:22:fd:0a", &out[0]);
+    TEST_ASSERT_EQUAL_STRING("3E:E6:B5:22:FD:0A", &out[0]);
     TEST_ASSERT(out == gnrc_netif_addr_to_str(ieee802154_l2addr_long,
                                               sizeof(ieee802154_l2addr_long),
                                               out));
-    TEST_ASSERT_EQUAL_STRING("3e:e6:b5:0f:19:22:fd:0a", &out[0]);
+    TEST_ASSERT_EQUAL_STRING("3E:E6:B5:0F:19:22:FD:0A", &out[0]);
     TEST_ASSERT(out == gnrc_netif_addr_to_str(ieee802154_l2addr_short,
                                               sizeof(ieee802154_l2addr_short),
                                               out));
-    TEST_ASSERT_EQUAL_STRING("fd:0a", &out[0]);
+    TEST_ASSERT_EQUAL_STRING("FD:0A", &out[0]);
     TEST_ASSERT(out == gnrc_netif_addr_to_str(netif0_l2addr,
                                               sizeof(netif0_l2addr),
                                               out));
-    TEST_ASSERT_EQUAL_STRING("3e:e7:b5:0f:19:22:fd:0a", &out[0]);
+    TEST_ASSERT_EQUAL_STRING("3E:E7:B5:0F:19:22:FD:0A", &out[0]);
 }
 
 static void test_addr_from_str(void)
@@ -220,16 +220,16 @@ static void test_addr_from_str(void)
 
     TEST_ASSERT_EQUAL_INT(0, gnrc_netif_addr_from_str("", out));
     TEST_ASSERT_EQUAL_INT(sizeof(ethernet_l2addr),
-                          gnrc_netif_addr_from_str("3e:e6:b5:22:fd:0a", out));
+                          gnrc_netif_addr_from_str("3E:E6:B5:22:FD:0A", out));
     TEST_ASSERT_EQUAL_INT(0, memcmp(ethernet_l2addr, out,
                                     sizeof(ethernet_l2addr)));
     TEST_ASSERT_EQUAL_INT(sizeof(ieee802154_l2addr_long),
-                          gnrc_netif_addr_from_str("3e:e6:b5:0f:19:22:fd:0a",
+                          gnrc_netif_addr_from_str("3E:E6:B5:0F:19:22:FD:0A",
                                                    out));
     TEST_ASSERT_EQUAL_INT(0, memcmp(ieee802154_l2addr_long, out,
                                     sizeof(ieee802154_l2addr_long)));
     TEST_ASSERT_EQUAL_INT(sizeof(ieee802154_l2addr_short),
-                          gnrc_netif_addr_from_str("fd:0a", out));
+                          gnrc_netif_addr_from_str("FD:0A", out));
     TEST_ASSERT_EQUAL_INT(0, memcmp(ieee802154_l2addr_short, out,
                                     sizeof(ieee802154_l2addr_short)));
 }
diff --git a/tests/gnrc_netif/tests/01-run.py b/tests/gnrc_netif/tests/01-run.py
index 36ce840217e26179d0e68608eadbac416d5c0238..7259c3fb89abf96dc3f2a24e627fd3152b49d896 100755
--- a/tests/gnrc_netif/tests/01-run.py
+++ b/tests/gnrc_netif/tests/01-run.py
@@ -83,8 +83,8 @@ def testfunc(child):
     child.expect(r"00000000~~ SNIP  1 - size:  \d+ byte, type: NETTYPE_NETIF \(-1\)")
     child.expect(r"if_pid: \d+  rssi: -?\d+  lqi: \d+")
     child.expect("flags: 0x0")
-    child.expect("src_l2addr: 3e:e6:b5:22:fd:0b")
-    child.expect("dst_l2addr: 3e:e6:b5:22:fd:0a")
+    child.expect("src_l2addr: 3E:E6:B5:22:FD:0B")
+    child.expect("dst_l2addr: 3E:E6:B5:22:FD:0A")
     child.expect("~~ PKT    -  2 snips, total size:  \d+ byte")
     # test_netapi_recv__empty_ieee802154_payload
     child.expect(r"pktdump dumping IEEE 802\.15\.4 packet with empty payload")
@@ -93,8 +93,8 @@ def testfunc(child):
     child.expect(r"00000000~~ SNIP  1 - size:  \d+ byte, type: NETTYPE_NETIF \(-1\)")
     child.expect(r"if_pid: \d+  rssi: -?\d+  lqi: \d+")
     child.expect("flags: 0x0")
-    child.expect("src_l2addr: 3e:e6:b5:0f:19:22:fd:0b")
-    child.expect("dst_l2addr: 3e:e6:b5:0f:19:22:fd:0a")
+    child.expect("src_l2addr: 3E:E6:B5:0F:19:22:FD:0B")
+    child.expect("dst_l2addr: 3E:E6:B5:0F:19:22:FD:0A")
     child.expect("~~ PKT    -  2 snips, total size:  \d+ byte")
     # test_netapi_recv__raw_ethernet_payload
     child.expect("pktdump dumping Ethernet packet with payload 12 34 45 56")
@@ -104,8 +104,8 @@ def testfunc(child):
     child.expect(r"~~ SNIP  1 - size:  \d+ byte, type: NETTYPE_NETIF \(-1\)")
     child.expect(r"if_pid: \d+  rssi: -?\d+  lqi: \d+")
     child.expect("flags: 0x0")
-    child.expect("src_l2addr: 3e:e6:b5:22:fd:0b")
-    child.expect("dst_l2addr: 3e:e6:b5:22:fd:0a")
+    child.expect("src_l2addr: 3E:E6:B5:22:FD:0B")
+    child.expect("dst_l2addr: 3E:E6:B5:22:FD:0A")
     child.expect("~~ PKT    -  2 snips, total size:  \d+ byte")
     # test_netapi_recv__raw_ieee802154_payload
     child.expect(r"pktdump dumping IEEE 802\.15\.4 packet with payload 12 34 45 56")
@@ -115,8 +115,8 @@ def testfunc(child):
     child.expect(r"~~ SNIP  1 - size:  \d+ byte, type: NETTYPE_NETIF \(-1\)")
     child.expect(r"if_pid: \d+  rssi: -?\d+  lqi: \d+")
     child.expect("flags: 0x0")
-    child.expect("src_l2addr: 3e:e6:b5:0f:19:22:fd:0b")
-    child.expect("dst_l2addr: 3e:e6:b5:0f:19:22:fd:0a")
+    child.expect("src_l2addr: 3E:E6:B5:0F:19:22:FD:0B")
+    child.expect("dst_l2addr: 3E:E6:B5:0F:19:22:FD:0A")
     child.expect("~~ PKT    -  2 snips, total size:  \d+ byte")
     # test_netapi_recv__ipv6_ethernet_payload
     child.expect("pktdump dumping IPv6 over Ethernet packet with payload 01")
@@ -132,8 +132,8 @@ def testfunc(child):
     child.expect(r"~~ SNIP  1 - size:  \d+ byte, type: NETTYPE_NETIF \(-1\)")
     child.expect(r"if_pid: \d+  rssi: -?\d+  lqi: \d+")
     child.expect("flags: 0x0")
-    child.expect("src_l2addr: 3e:e6:b5:22:fd:0b")
-    child.expect("dst_l2addr: 3e:e6:b5:22:fd:0a")
+    child.expect("src_l2addr: 3E:E6:B5:22:FD:0B")
+    child.expect("dst_l2addr: 3E:E6:B5:22:FD:0A")
     child.expect("~~ PKT    -  2 snips, total size:  \d+ byte")