diff --git a/c/meterpreter/source/common/common_metapi.h b/c/meterpreter/source/common/common_metapi.h
index 138a8187..d617215a 100644
--- a/c/meterpreter/source/common/common_metapi.h
+++ b/c/meterpreter/source/common/common_metapi.h
@@ -186,4 +186,4 @@ typedef struct _MetApi
 
 extern MetApi* met_api;
 
-#endif
+#endif
\ No newline at end of file
diff --git a/c/meterpreter/source/extensions/stdapi/server/net/config/route.c b/c/meterpreter/source/extensions/stdapi/server/net/config/route.c
index 377e0f1b..dd52c94d 100644
--- a/c/meterpreter/source/extensions/stdapi/server/net/config/route.c
+++ b/c/meterpreter/source/extensions/stdapi/server/net/config/route.c
@@ -1,20 +1,67 @@
 #include "precomp.h"
+#include "common.h"
 #include "common_metapi.h"
+#include <netioapi.h>
+
+typedef NETIO_STATUS(NETIOAPI_API_* GETIPFORWARDTABLE2)(ADDRESS_FAMILY Family, PMIB_IPFORWARD_TABLE2* Table);
+
+typedef struct v6netmask
+{
+	unsigned int mask[4];
+} v6netmask;
 
 DWORD add_remove_route(Packet *request, BOOLEAN add);
 
+static unsigned int bit32mask(unsigned bits){
+    unsigned int netmask;
+    if (bits == 32)
+        netmask = 0xffffffff;
+    else{
+        netmask = ((0xffffffff << (32 - (bits % 32))) & 0xffffffff);
+    }
+    return netmask;
+}
+
+static void bit128mask(unsigned int bits, v6netmask* netmask){
+    unsigned int part = bit32mask(bits);
+    if (bits >= 96) {
+        netmask->mask[0] = 0xffffffff;
+        netmask->mask[1] = 0xffffffff;
+        netmask->mask[2] = 0xffffffff;
+        netmask->mask[3] = htonl(part);
+    }
+    else if (bits >= 64) {
+        netmask->mask[0] = 0xffffffff;
+        netmask->mask[1] = 0xffffffff;
+        netmask->mask[2] = htonl(part);
+        netmask->mask[3] = 0x0;
+    }
+    else if (bits >= 32) {
+        netmask->mask[0] = 0xffffffff;
+        netmask->mask[1] = htonl(part);
+        netmask->mask[2] = 0x0;
+        netmask->mask[3] = 0x0;
+    }
+    else {
+        netmask->mask[0] = htonl(part);
+        netmask->mask[1] = 0x0;
+        netmask->mask[2] = 0x0;
+        netmask->mask[3] = 0x0;
+    }
+    return;
+}
 /*
  * Returns zero or more routes to the requestor from the active routing table
  */
 DWORD request_net_config_get_routes(Remote *remote, Packet *packet)
 {
 	Packet *response = met_api->packet.create_response(packet);
-	DWORD result = ERROR_SUCCESS;
+	DWORD dwResult = ERROR_SUCCESS;
 	DWORD index;
 	DWORD metric_bigendian;
 
 	PMIB_IPFORWARDTABLE table_ipv4 = NULL;
-	PMIB_IPFORWARDTABLE table_ipv6 = NULL;
+	PMIB_IPFORWARD_TABLE2 table_ipv6 = NULL;
 	DWORD tableSize = sizeof(MIB_IPFORWARDROW) * 96;
 	char int_name[20];
 
@@ -23,42 +70,94 @@ DWORD request_net_config_get_routes(Remote *remote, Packet *packet)
 		// Allocate storage for the routing table
 		if (!(table_ipv4 = (PMIB_IPFORWARDTABLE)malloc(tableSize)))
 		{
-			result = ERROR_NOT_ENOUGH_MEMORY;
+			dwResult = ERROR_NOT_ENOUGH_MEMORY;
 			break;
 		}
 
 		// Get the routing table
 		if (GetIpForwardTable(table_ipv4, &tableSize, TRUE) != NO_ERROR)
 		{
-			result = GetLastError();
-			break;
+			BREAK_ON_ERROR("[NET] request_net_config_get_routes: GetIpForwardTable failed");
 		}
 
 		// Enumerate it
 		for (index = 0;
-		     index < table_ipv4->dwNumEntries;
-		     index++)
+			index < table_ipv4->dwNumEntries;
+			index++)
 		{
 			Tlv route[5];
-			memset(int_name, 0, 20);
+			memset(int_name, 0, sizeof(int_name));
 
-			route[0].header.type   = TLV_TYPE_SUBNET;
+			route[0].header.type = TLV_TYPE_SUBNET;
 			route[0].header.length = sizeof(DWORD);
-			route[0].buffer        = (PUCHAR)&table_ipv4->table[index].dwForwardDest;
-			route[1].header.type   = TLV_TYPE_NETMASK;
+			route[0].buffer = (PUCHAR)&table_ipv4->table[index].dwForwardDest;
+			route[1].header.type = TLV_TYPE_NETMASK;
 			route[1].header.length = sizeof(DWORD);
-			route[1].buffer        = (PUCHAR)&table_ipv4->table[index].dwForwardMask;
-			route[2].header.type   = TLV_TYPE_GATEWAY;
+			route[1].buffer = (PUCHAR)&table_ipv4->table[index].dwForwardMask;
+			route[2].header.type = TLV_TYPE_GATEWAY;
 			route[2].header.length = sizeof(DWORD);
-			route[2].buffer        = (PUCHAR)&table_ipv4->table[index].dwForwardNextHop;
+			route[2].buffer = (PUCHAR)&table_ipv4->table[index].dwForwardNextHop;
 
 			// we just get the interface index, not the name, because names can be __long__
-            _itoa(table_ipv4->table[index].dwForwardIfIndex, int_name, 10);
-    		route[3].header.type   = TLV_TYPE_STRING;
+			_itoa(table_ipv4->table[index].dwForwardIfIndex, int_name, 10);
+			route[3].header.type = TLV_TYPE_STRING;
+			route[3].header.length = (DWORD)strlen(int_name) + 1;
+			route[3].buffer = (PUCHAR)int_name;
+
+			metric_bigendian = htonl(table_ipv4->table[index].dwForwardMetric1);
+			route[4].header.type = TLV_TYPE_ROUTE_METRIC;
+			route[4].header.length = sizeof(DWORD);
+			route[4].buffer = (PUCHAR)&metric_bigendian;
+
+			met_api->packet.add_tlv_group(response, TLV_TYPE_NETWORK_ROUTE,
+				route, 5);
+		}
+
+		v6netmask v6_mask;
+		MIB_IPINTERFACE_ROW iface = { .Family = AF_INET6 };
+		GETIPFORWARDTABLE2 pGetIpForwardTable2 = (GETIPFORWARDTABLE2)GetProcAddress(GetModuleHandle(TEXT("Iphlpapi.dll")), "GetIpForwardTable2");
+
+		// GetIpForwardTable2 is only available on Windows Vista and later.
+		if (!pGetIpForwardTable2) {
+			break;
+		}
+		if (pGetIpForwardTable2(AF_INET6, &table_ipv6) != NO_ERROR) {
+			BREAK_ON_ERROR("[NET] request_net_config_get_routes: GetIpForwardTable2 failed");
+		}
+
+		// Enumerate it
+		for (index = 0;
+			index < table_ipv6->NumEntries;
+			index++)
+		{
+			Tlv route[5];
+			memset(int_name, 0, sizeof(int_name));
+			iface.InterfaceIndex = table_ipv6->Table[index].InterfaceIndex;
+			if (GetIpInterfaceEntry(&iface) != NO_ERROR)
+			{
+				CONTINUE_ON_ERROR("[NET] request_net_config_get_routes: GetIpInterfaceEntry failed");
+			}
+
+			route[0].header.type   = TLV_TYPE_SUBNET;
+			route[0].header.length = sizeof(DWORD)*4;
+			route[0].buffer        = (PUCHAR)&table_ipv6->Table[index].DestinationPrefix.Prefix.Ipv6.sin6_addr;
+
+			bit128mask(table_ipv6->Table[index].DestinationPrefix.PrefixLength, &v6_mask);
+			route[1].header.type   = TLV_TYPE_NETMASK;
+			route[1].header.length = sizeof(DWORD)*4;
+			route[1].buffer        = (PUCHAR)v6_mask.mask;
+
+			route[2].header.type   = TLV_TYPE_GATEWAY;
+			route[2].header.length = sizeof(DWORD)*4;
+			route[2].buffer        = (PUCHAR)&table_ipv6->Table[index].NextHop.Ipv6.sin6_addr;
+
+			// we just get the interface index, not the name, because names can be __long__
+			_itoa(table_ipv6->Table[index].InterfaceIndex, int_name, 10);
+			route[3].header.type   = TLV_TYPE_STRING;
 			route[3].header.length = (DWORD)strlen(int_name)+1;
 			route[3].buffer        = (PUCHAR)int_name;
 
-			metric_bigendian = htonl(table_ipv4->table[index].dwForwardMetric1);
+			metric_bigendian = htonl(table_ipv6->Table[index].Metric + iface.Metric);
 			route[4].header.type   = TLV_TYPE_ROUTE_METRIC;
 			route[4].header.length = sizeof(DWORD);
 			route[4].buffer        = (PUCHAR)&metric_bigendian;
@@ -66,7 +165,6 @@ DWORD request_net_config_get_routes(Remote *remote, Packet *packet)
 			met_api->packet.add_tlv_group(response, TLV_TYPE_NETWORK_ROUTE,
 					route, 5);
 		}
-
 	} while (0);
 
 	if(table_ipv4)
@@ -74,7 +172,7 @@ DWORD request_net_config_get_routes(Remote *remote, Packet *packet)
 	if(table_ipv6)
 		free(table_ipv6);
 
-	met_api->packet.transmit_response(result, remote, response);
+	met_api->packet.transmit_response(dwResult, remote, response);
 
 	return ERROR_SUCCESS;
 }