Route on Windows

Route on Windows tentatively complete, Mac/Linux TODO
This commit is contained in:
aleks-f
2012-11-06 22:17:17 -06:00
parent 325a98a91f
commit 15d27daea6
8 changed files with 1563 additions and 1343 deletions

View File

@@ -43,6 +43,7 @@
#if defined(POCO_OS_FAMILY_WINDOWS)
#if defined(POCO_WIN32_UTF8)
#include "Poco/UnicodeConverter.h"
#include "Poco/Error.h"
#endif
#include <iphlpapi.h>
#include <ipifcons.h>
@@ -892,24 +893,6 @@ IPAddress getBroadcastAddress(PIP_ADAPTER_PREFIX pPrefix, const IPAddress& addr,
}
std::string getErrorMessage(DWORD errorCode)
{
std::string errMsg;
DWORD dwFlg = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
#if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING)
LPWSTR lpMsgBuf = 0;
if (FormatMessageW(dwFlg, 0, errorCode, 0, (LPWSTR) & lpMsgBuf, 0, NULL))
UnicodeConverter::toUTF8(lpMsgBuf, errMsg);
#else
LPTSTR lpMsgBuf = 0;
if (FormatMessageA(dwFlg, 0, errorCode, 0, (LPTSTR) & lpMsgBuf, 0, NULL))
errMsg = lpMsgBuf;
#endif
LocalFree(lpMsgBuf);
return errMsg;
}
NetworkInterface::Type fromNative(DWORD type)
{
switch (type)
@@ -957,7 +940,7 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
else if (ERROR_NO_DATA == dwRetVal) // no network interfaces found
return result;
else if (NO_ERROR != dwRetVal) // error occurred
throw SystemException(format("An error occurred while trying to obtain list of network interfaces: [%s]", getErrorMessage(dwRetVal)));
throw SystemException(format("An error occurred while trying to obtain list of network interfaces: [%s]", Error::getMessage(dwRetVal)));
else
break;
} while ((ERROR_BUFFER_OVERFLOW == dwRetVal) && (++iterations <= 2));

View File

@@ -34,17 +34,48 @@
//
#include "Poco/Error.h"
namespace Poco {
namespace Net {
static unsigned int getCompleteMetric(PMIB_IPFORWARD_ROW2 pIp2)
/// The route metric specified in the Metric member of the MIB_IPFORWARD_ROW2 structure
/// represents just the route metric offset. The complete metric is a combination of this
/// route metric offset added to the interface metric specified in the Metric member of
/// the MIB_IPINTERFACE_ROW structure of the associated interface.
{
MIB_IPINTERFACE_ROW intfcRow;
intfcRow.InterfaceLuid = pIp2->InterfaceLuid;
intfcRow.InterfaceIndex = pIp2->InterfaceIndex;
intfcRow.Family = pIp2->DestinationPrefix.Prefix.si_family;
DWORD ret = GetIpInterfaceEntry(&intfcRow);
if (NO_ERROR == ret) return pIp2->Metric + intfcRow.Metric;
std::string error;
switch (ret)
{
case ERROR_FILE_NOT_FOUND:
throw RuntimeException("Unknown network interface LUID or interface index");
case ERROR_INVALID_PARAMETER:
throw RuntimeException("An invalid parameter was passed to the function.");
case ERROR_NOT_FOUND:
throw RuntimeException("Network interface/family mismatch.");
default:
throw RuntimeException(Error::getMessage(ret));
}
}
Route::RouteList Route::list(IPAddress::Family family)
{
std::time_t now;
PMIB_IPFORWARD_TABLE2 pIpForwardTable2 = NULL;
PMIB_IPFORWARD_TABLE2 pIpForwardTable2 = 0;
if (GetIpForwardTable2(((family == IPAddress::IPv4) ? AF_INET : AF_INET6), &pIpForwardTable2) != NO_ERROR)
throw std::runtime_error("Couldn't fetch routing table");
throw RuntimeException("Couldn't fetch routing table.");
::time(&now);
@@ -59,8 +90,9 @@ Route::RouteList Route::list(IPAddress::Family family)
IPAddress netmask(pIp2->DestinationPrefix.PrefixLength, family2);
IPAddress nexthop(*(struct sockaddr *)&pIp2->NextHop);
Route route(dest, netmask, nexthop, pIp2->InterfaceIndex, nexthop.isWildcard() ? ROUTE_INDIRECT : ROUTE_INDIRECT);
route.setMetric(pIp2->Metric);
Route route(dest, netmask, nexthop, pIp2->InterfaceIndex, nexthop.isWildcard() ? ROUTE_DIRECT : ROUTE_INDIRECT);
route.setMetric(getCompleteMetric(pIp2));
route.setAge(now - pIp2->Age);
route.setProto((RouteProto) pIp2->Protocol);