mirror of
https://github.com/pocoproject/poco.git
synced 2025-02-20 14:24:35 +01:00
Route on Windows
Route on Windows tentatively complete, Mac/Linux TODO
This commit is contained in:
parent
325a98a91f
commit
15d27daea6
File diff suppressed because it is too large
Load Diff
@ -885,6 +885,9 @@
|
||||
<ClCompile Include="src\UTF32Encoding.cpp">
|
||||
<Filter>Text\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Error.cpp">
|
||||
<Filter>Core\Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\Poco\Any.h">
|
||||
@ -1832,6 +1835,9 @@
|
||||
<ClInclude Include="include\Poco\NumericString.h">
|
||||
<Filter>Core\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\Error.h">
|
||||
<Filter>Core\Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="src\pocomsg.rc">
|
||||
|
68
Foundation/include/Poco/Error.h
Normal file
68
Foundation/include/Poco/Error.h
Normal file
@ -0,0 +1,68 @@
|
||||
//
|
||||
// Error.h
|
||||
//
|
||||
// $Id: //poco/1.4/Foundation/include/Poco/Error.h#1 $
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: Error
|
||||
//
|
||||
// Definition of the Error class.
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#ifndef Foundation_Error_INCLUDED
|
||||
#define Foundation_Error_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Foundation.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
class Foundation_API Error
|
||||
/// The Error class provides utility functions
|
||||
/// for error reporting.
|
||||
{
|
||||
public:
|
||||
|
||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||
static std::string getMessage(DWORD errorCode);
|
||||
/// Utility function translating numeric error code to string.
|
||||
#else
|
||||
static std::string getMessage(int errorCode);
|
||||
/// Utility function translating numeric error code to string.
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
|
||||
|
||||
#endif // Foundation_Error_INCLUDED
|
77
Foundation/src/Error.cpp
Normal file
77
Foundation/src/Error.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
//
|
||||
// Error.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/Foundation/src/Error.cpp#3 $
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Core
|
||||
// Module: Error
|
||||
//
|
||||
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/Foundation.h"
|
||||
#include "Poco/UnicodeConverter.h"
|
||||
#include "Poco/Error.h"
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
#ifdef POCO_OS_FAMILY_WINDOWS
|
||||
|
||||
std::string Error::getMessage(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;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
std::string Error::getMessage(int errorCode)
|
||||
{
|
||||
#error todo
|
||||
char errmsg[256];
|
||||
return std::string(strerror_r(errorCode, errMsg, 256));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace Poco
|
@ -43,7 +43,7 @@
|
||||
#include "Poco/Net/Net.h"
|
||||
|
||||
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS)
|
||||
#if defined(POCO_OS_FAMILY_WINDOWS) && (_WIN32_WINNT >= 0x600) // only Vista/Longhorn and up
|
||||
#ifndef POCO_NET_HAS_ROUTE
|
||||
#define POCO_NET_HAS_ROUTE
|
||||
#endif
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "Poco/Net/IPAddress.h"
|
||||
#include "Poco/Net/Route.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
using Poco::Net::IPAddress;
|
||||
@ -66,14 +67,65 @@ RouteTest::~RouteTest()
|
||||
// with results we get back from NetworkInterface::list().
|
||||
//
|
||||
|
||||
void RouteTest::testDefaultRoute()
|
||||
void RouteTest::testAllRoutes()
|
||||
{
|
||||
Route::RouteList routes = Route::list(IPAddress::IPv4);
|
||||
assert(routes.size() >= 3);
|
||||
|
||||
std::cout << "Active IPv4 Routes:" << std::endl;
|
||||
std::cout << "=============================================================================" << std::endl;
|
||||
std::cout << std::setw(17) << "Destinaton"
|
||||
<< std::setw(17) << "Netmask"
|
||||
<< std::setw(17) << "Gateway"
|
||||
<< std::setw(17) << "Interface"
|
||||
<< std::setw(8) << "Metric" << std::endl;
|
||||
|
||||
Route::RouteList::const_iterator it = routes.begin();
|
||||
Route::RouteList::const_iterator end = routes.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
IPAddress ip = it->getNetworkInterface().firstAddress(IPAddress::IPv4);
|
||||
if (!ip.isLinkLocal())
|
||||
{
|
||||
std::string gateway = it->getNextHop().isWildcard() ? "On-link" : it->getNextHop().toString();
|
||||
std::cout << std::setw(17) << it->getDest().toString()
|
||||
<< std::setw(17) << it->getNetmask().toString()
|
||||
<< std::setw(17) << gateway
|
||||
<< std::setw(17) << ip.toString()
|
||||
<< std::setw(8) << it->getMetric() << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << "=============================================================================" << std::endl;
|
||||
|
||||
routes = Route::list(IPAddress::IPv6);
|
||||
assert(routes.size() >= 3);
|
||||
|
||||
std::cout << std::endl << "Active IPv6 Routes:" << std::endl;
|
||||
std::cout << "=============================================================" << std::endl;
|
||||
std::cout << std::setw(4) << "If"
|
||||
<< std::setw(7) << "Metric"
|
||||
<< std::setw(41) << "Destinaton"
|
||||
<< std::setw(8) << "Gateway"
|
||||
<< std::endl;
|
||||
|
||||
it = routes.begin();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
IPAddress ip = it->getNetworkInterface().firstAddress(IPAddress::IPv6);
|
||||
if (!ip.isLinkLocal())
|
||||
{
|
||||
std::string gateway = it->getNextHop().isWildcard() ? "On-link" : it->getNextHop().toString();
|
||||
std::cout << std::setw(4) << it->getIfIndex()
|
||||
<< std::setw(7) << it->getMetric()
|
||||
<< std::setw(41) << it->getDest().toString()
|
||||
<< std::setw(8) << gateway << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << "=============================================================" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void RouteTest::testAllRoutes()
|
||||
void RouteTest::testDefaultRoute()
|
||||
{
|
||||
Route::RouteList defaults = Route::defaults(IPAddress::IPv4);
|
||||
assert(defaults.size() >= 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user