Skip to content

Commit 15d27da

Browse files
committed
Route on Windows
Route on Windows tentatively complete, Mac/Linux TODO
1 parent 325a98a commit 15d27da

8 files changed

Lines changed: 1563 additions & 1343 deletions

File tree

Foundation/Foundation_vs100.vcxproj

Lines changed: 1319 additions & 1317 deletions
Large diffs are not rendered by default.

Foundation/Foundation_vs100.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,9 @@
885885
<ClCompile Include="src\UTF32Encoding.cpp">
886886
<Filter>Text\Source Files</Filter>
887887
</ClCompile>
888+
<ClCompile Include="src\Error.cpp">
889+
<Filter>Core\Source Files</Filter>
890+
</ClCompile>
888891
</ItemGroup>
889892
<ItemGroup>
890893
<ClInclude Include="include\Poco\Any.h">
@@ -1832,6 +1835,9 @@
18321835
<ClInclude Include="include\Poco\NumericString.h">
18331836
<Filter>Core\Header Files</Filter>
18341837
</ClInclude>
1838+
<ClInclude Include="include\Poco\Error.h">
1839+
<Filter>Core\Header Files</Filter>
1840+
</ClInclude>
18351841
</ItemGroup>
18361842
<ItemGroup>
18371843
<ResourceCompile Include="src\pocomsg.rc">

Foundation/include/Poco/Error.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//
2+
// Error.h
3+
//
4+
// $Id: //poco/1.4/Foundation/include/Poco/Error.h#1 $
5+
//
6+
// Library: Foundation
7+
// Package: Core
8+
// Module: Error
9+
//
10+
// Definition of the Error class.
11+
//
12+
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
13+
// and Contributors.
14+
//
15+
// Permission is hereby granted, free of charge, to any person or organization
16+
// obtaining a copy of the software and accompanying documentation covered by
17+
// this license (the "Software") to use, reproduce, display, distribute,
18+
// execute, and transmit the Software, and to prepare derivative works of the
19+
// Software, and to permit third-parties to whom the Software is furnished to
20+
// do so, all subject to the following:
21+
//
22+
// The copyright notices in the Software and this entire statement, including
23+
// the above license grant, this restriction and the following disclaimer,
24+
// must be included in all copies of the Software, in whole or in part, and
25+
// all derivative works of the Software, unless such copies or derivative
26+
// works are solely in the form of machine-executable object code generated by
27+
// a source language processor.
28+
//
29+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31+
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
32+
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
33+
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
34+
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
35+
// DEALINGS IN THE SOFTWARE.
36+
//
37+
38+
39+
#ifndef Foundation_Error_INCLUDED
40+
#define Foundation_Error_INCLUDED
41+
42+
43+
#include "Poco/Foundation.h"
44+
45+
46+
namespace Poco {
47+
48+
49+
class Foundation_API Error
50+
/// The Error class provides utility functions
51+
/// for error reporting.
52+
{
53+
public:
54+
55+
#ifdef POCO_OS_FAMILY_WINDOWS
56+
static std::string getMessage(DWORD errorCode);
57+
/// Utility function translating numeric error code to string.
58+
#else
59+
static std::string getMessage(int errorCode);
60+
/// Utility function translating numeric error code to string.
61+
#endif
62+
};
63+
64+
65+
} // namespace Poco
66+
67+
68+
#endif // Foundation_Error_INCLUDED

Foundation/src/Error.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//
2+
// Error.cpp
3+
//
4+
// $Id: //poco/1.4/Foundation/src/Error.cpp#3 $
5+
//
6+
// Library: Foundation
7+
// Package: Core
8+
// Module: Error
9+
//
10+
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11+
// and Contributors.
12+
//
13+
// Permission is hereby granted, free of charge, to any person or organization
14+
// obtaining a copy of the software and accompanying documentation covered by
15+
// this license (the "Software") to use, reproduce, display, distribute,
16+
// execute, and transmit the Software, and to prepare derivative works of the
17+
// Software, and to permit third-parties to whom the Software is furnished to
18+
// do so, all subject to the following:
19+
//
20+
// The copyright notices in the Software and this entire statement, including
21+
// the above license grant, this restriction and the following disclaimer,
22+
// must be included in all copies of the Software, in whole or in part, and
23+
// all derivative works of the Software, unless such copies or derivative
24+
// works are solely in the form of machine-executable object code generated by
25+
// a source language processor.
26+
//
27+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29+
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
30+
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
31+
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
32+
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33+
// DEALINGS IN THE SOFTWARE.
34+
//
35+
36+
37+
#include "Poco/Foundation.h"
38+
#include "Poco/UnicodeConverter.h"
39+
#include "Poco/Error.h"
40+
#include <string>
41+
42+
43+
namespace Poco {
44+
45+
46+
#ifdef POCO_OS_FAMILY_WINDOWS
47+
48+
std::string Error::getMessage(DWORD errorCode)
49+
{
50+
std::string errMsg;
51+
DWORD dwFlg = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
52+
#if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING)
53+
LPWSTR lpMsgBuf = 0;
54+
if (FormatMessageW(dwFlg, 0, errorCode, 0, (LPWSTR) & lpMsgBuf, 0, NULL))
55+
UnicodeConverter::toUTF8(lpMsgBuf, errMsg);
56+
#else
57+
LPTSTR lpMsgBuf = 0;
58+
if (FormatMessageA(dwFlg, 0, errorCode, 0, (LPTSTR) & lpMsgBuf, 0, NULL))
59+
errMsg = lpMsgBuf;
60+
#endif
61+
LocalFree(lpMsgBuf);
62+
return errMsg;
63+
}
64+
65+
#else
66+
67+
std::string Error::getMessage(int errorCode)
68+
{
69+
#error todo
70+
char errmsg[256];
71+
return std::string(strerror_r(errorCode, errMsg, 256));
72+
}
73+
74+
#endif
75+
76+
77+
} // namespace Poco

Net/include/Poco/Net/Route.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
#include "Poco/Net/Net.h"
4444

4545

46-
#if defined(POCO_OS_FAMILY_WINDOWS)
46+
#if defined(POCO_OS_FAMILY_WINDOWS) && (_WIN32_WINNT >= 0x600) // only Vista/Longhorn and up
4747
#ifndef POCO_NET_HAS_ROUTE
4848
#define POCO_NET_HAS_ROUTE
4949
#endif

Net/src/NetworkInterface.cpp

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#if defined(POCO_OS_FAMILY_WINDOWS)
4444
#if defined(POCO_WIN32_UTF8)
4545
#include "Poco/UnicodeConverter.h"
46+
#include "Poco/Error.h"
4647
#endif
4748
#include <iphlpapi.h>
4849
#include <ipifcons.h>
@@ -892,24 +893,6 @@ IPAddress getBroadcastAddress(PIP_ADAPTER_PREFIX pPrefix, const IPAddress& addr,
892893
}
893894

894895

895-
std::string getErrorMessage(DWORD errorCode)
896-
{
897-
std::string errMsg;
898-
DWORD dwFlg = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
899-
#if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING)
900-
LPWSTR lpMsgBuf = 0;
901-
if (FormatMessageW(dwFlg, 0, errorCode, 0, (LPWSTR) & lpMsgBuf, 0, NULL))
902-
UnicodeConverter::toUTF8(lpMsgBuf, errMsg);
903-
#else
904-
LPTSTR lpMsgBuf = 0;
905-
if (FormatMessageA(dwFlg, 0, errorCode, 0, (LPTSTR) & lpMsgBuf, 0, NULL))
906-
errMsg = lpMsgBuf;
907-
#endif
908-
LocalFree(lpMsgBuf);
909-
return errMsg;
910-
}
911-
912-
913896
NetworkInterface::Type fromNative(DWORD type)
914897
{
915898
switch (type)
@@ -957,7 +940,7 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly)
957940
else if (ERROR_NO_DATA == dwRetVal) // no network interfaces found
958941
return result;
959942
else if (NO_ERROR != dwRetVal) // error occurred
960-
throw SystemException(format("An error occurred while trying to obtain list of network interfaces: [%s]", getErrorMessage(dwRetVal)));
943+
throw SystemException(format("An error occurred while trying to obtain list of network interfaces: [%s]", Error::getMessage(dwRetVal)));
961944
else
962945
break;
963946
} while ((ERROR_BUFFER_OVERFLOW == dwRetVal) && (++iterations <= 2));

Net/src/Route_WIN32.cpp

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,48 @@
3434
//
3535

3636

37+
#include "Poco/Error.h"
38+
39+
3740
namespace Poco {
3841
namespace Net {
3942

4043

44+
static unsigned int getCompleteMetric(PMIB_IPFORWARD_ROW2 pIp2)
45+
/// The route metric specified in the Metric member of the MIB_IPFORWARD_ROW2 structure
46+
/// represents just the route metric offset. The complete metric is a combination of this
47+
/// route metric offset added to the interface metric specified in the Metric member of
48+
/// the MIB_IPINTERFACE_ROW structure of the associated interface.
49+
{
50+
MIB_IPINTERFACE_ROW intfcRow;
51+
intfcRow.InterfaceLuid = pIp2->InterfaceLuid;
52+
intfcRow.InterfaceIndex = pIp2->InterfaceIndex;
53+
intfcRow.Family = pIp2->DestinationPrefix.Prefix.si_family;
54+
DWORD ret = GetIpInterfaceEntry(&intfcRow);
55+
if (NO_ERROR == ret) return pIp2->Metric + intfcRow.Metric;
56+
57+
std::string error;
58+
switch (ret)
59+
{
60+
case ERROR_FILE_NOT_FOUND:
61+
throw RuntimeException("Unknown network interface LUID or interface index");
62+
case ERROR_INVALID_PARAMETER:
63+
throw RuntimeException("An invalid parameter was passed to the function.");
64+
case ERROR_NOT_FOUND:
65+
throw RuntimeException("Network interface/family mismatch.");
66+
default:
67+
throw RuntimeException(Error::getMessage(ret));
68+
}
69+
}
70+
71+
4172
Route::RouteList Route::list(IPAddress::Family family)
4273
{
4374
std::time_t now;
44-
PMIB_IPFORWARD_TABLE2 pIpForwardTable2 = NULL;
75+
PMIB_IPFORWARD_TABLE2 pIpForwardTable2 = 0;
4576

4677
if (GetIpForwardTable2(((family == IPAddress::IPv4) ? AF_INET : AF_INET6), &pIpForwardTable2) != NO_ERROR)
47-
throw std::runtime_error("Couldn't fetch routing table");
78+
throw RuntimeException("Couldn't fetch routing table.");
4879

4980
::time(&now);
5081

@@ -59,8 +90,9 @@ Route::RouteList Route::list(IPAddress::Family family)
5990
IPAddress netmask(pIp2->DestinationPrefix.PrefixLength, family2);
6091
IPAddress nexthop(*(struct sockaddr *)&pIp2->NextHop);
6192

62-
Route route(dest, netmask, nexthop, pIp2->InterfaceIndex, nexthop.isWildcard() ? ROUTE_INDIRECT : ROUTE_INDIRECT);
63-
route.setMetric(pIp2->Metric);
93+
Route route(dest, netmask, nexthop, pIp2->InterfaceIndex, nexthop.isWildcard() ? ROUTE_DIRECT : ROUTE_INDIRECT);
94+
95+
route.setMetric(getCompleteMetric(pIp2));
6496
route.setAge(now - pIp2->Age);
6597
route.setProto((RouteProto) pIp2->Protocol);
6698

Net/testsuite/src/RouteTest.cpp

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "Poco/Net/IPAddress.h"
3737
#include "Poco/Net/Route.h"
3838
#include "Poco/Net/NetException.h"
39+
#include <iomanip>
3940

4041

4142
using Poco::Net::IPAddress;
@@ -66,14 +67,65 @@ RouteTest::~RouteTest()
6667
// with results we get back from NetworkInterface::list().
6768
//
6869

69-
void RouteTest::testDefaultRoute()
70+
void RouteTest::testAllRoutes()
7071
{
7172
Route::RouteList routes = Route::list(IPAddress::IPv4);
7273
assert(routes.size() >= 3);
74+
75+
std::cout << "Active IPv4 Routes:" << std::endl;
76+
std::cout << "=============================================================================" << std::endl;
77+
std::cout << std::setw(17) << "Destinaton"
78+
<< std::setw(17) << "Netmask"
79+
<< std::setw(17) << "Gateway"
80+
<< std::setw(17) << "Interface"
81+
<< std::setw(8) << "Metric" << std::endl;
82+
83+
Route::RouteList::const_iterator it = routes.begin();
84+
Route::RouteList::const_iterator end = routes.end();
85+
for (; it != end; ++it)
86+
{
87+
IPAddress ip = it->getNetworkInterface().firstAddress(IPAddress::IPv4);
88+
if (!ip.isLinkLocal())
89+
{
90+
std::string gateway = it->getNextHop().isWildcard() ? "On-link" : it->getNextHop().toString();
91+
std::cout << std::setw(17) << it->getDest().toString()
92+
<< std::setw(17) << it->getNetmask().toString()
93+
<< std::setw(17) << gateway
94+
<< std::setw(17) << ip.toString()
95+
<< std::setw(8) << it->getMetric() << std::endl;
96+
}
97+
}
98+
std::cout << "=============================================================================" << std::endl;
99+
100+
routes = Route::list(IPAddress::IPv6);
101+
assert(routes.size() >= 3);
102+
103+
std::cout << std::endl << "Active IPv6 Routes:" << std::endl;
104+
std::cout << "=============================================================" << std::endl;
105+
std::cout << std::setw(4) << "If"
106+
<< std::setw(7) << "Metric"
107+
<< std::setw(41) << "Destinaton"
108+
<< std::setw(8) << "Gateway"
109+
<< std::endl;
110+
111+
it = routes.begin();
112+
for (; it != end; ++it)
113+
{
114+
IPAddress ip = it->getNetworkInterface().firstAddress(IPAddress::IPv6);
115+
if (!ip.isLinkLocal())
116+
{
117+
std::string gateway = it->getNextHop().isWildcard() ? "On-link" : it->getNextHop().toString();
118+
std::cout << std::setw(4) << it->getIfIndex()
119+
<< std::setw(7) << it->getMetric()
120+
<< std::setw(41) << it->getDest().toString()
121+
<< std::setw(8) << gateway << std::endl;
122+
}
123+
}
124+
std::cout << "=============================================================" << std::endl;
73125
}
74126

75127

76-
void RouteTest::testAllRoutes()
128+
void RouteTest::testDefaultRoute()
77129
{
78130
Route::RouteList defaults = Route::defaults(IPAddress::IPv4);
79131
assert(defaults.size() >= 1);

0 commit comments

Comments
 (0)