1
2 #include "protoRouteMgr.h"
3 #include "protoDebug.h"
4
5 #include <Iphlpapi.h>
6 #include <Iprtrmib.h>
7 #define MPR50 1
8 #ifndef _WIN32_WCE
9 #include <Routprot.h>
10 #endif // !_WIN32_WCE
11
12 class Win32RouteMgr : public ProtoRouteMgr
13 {
14 public:
15 Win32RouteMgr();
16 ~Win32RouteMgr();
17
18 virtual bool Open(const void* userData = NULL);
IsOpen() const19 virtual bool IsOpen() const {return true;}
20 virtual void Close();
21
22 virtual bool GetAllRoutes(ProtoAddress::Type addrType,
23 ProtoRouteTable& routeTable);
24
25 virtual bool GetRoute(const ProtoAddress& dst,
26 unsigned int prefixLen,
27 ProtoAddress& gw,
28 unsigned int& ifIndex,
29 int& metric);
30
31 virtual bool SetRoute(const ProtoAddress& dst,
32 unsigned int prefixLen,
33 const ProtoAddress& gw,
34 unsigned int ifIndex,
35 int metric);
36
37 virtual bool DeleteRoute(const ProtoAddress& dst,
38 unsigned int prefixLen,
39 const ProtoAddress& gw,
40 unsigned int ifIndex);
41
42 virtual bool SetForwarding(bool state);
43
44 // Network interface helper functions
GetInterfaceIndex(const char * interfaceName)45 virtual unsigned int GetInterfaceIndex(const char* interfaceName)
46 {
47 return ProtoSocket::GetInterfaceIndex(interfaceName);
48 }
GetInterfaceAddressList(unsigned int ifIndex,ProtoAddress::Type addrType,ProtoAddressList & addrList)49 virtual bool GetInterfaceAddressList(unsigned int ifIndex,
50 ProtoAddress::Type addrType,
51 ProtoAddressList& addrList)
52 {
53 char ifName[256];
54 bool result = ProtoSocket::GetInterfaceName(ifIndex, ifName, 255);
55 return result ? ProtoSocket::GetInterfaceAddressList(ifName, addrType, addrList) : false;
56 }
GetInterfaceName(unsigned int ifIndex,char * buffer,unsigned int buflen)57 virtual bool GetInterfaceName(unsigned int ifIndex,
58 char* buffer,
59 unsigned int buflen)
60 {
61 return ProtoSocket::GetInterfaceName(ifIndex, buffer, buflen);
62 }
63
64 private:
65
66
67 }; // end class Win32RouteMgr
68
Create(Type)69 ProtoRouteMgr* ProtoRouteMgr::Create(Type /*type*/)
70 {
71 // TBD - support alternative route mgr "types" (e.g. ZEBRA)
72 return static_cast<ProtoRouteMgr*>(new Win32RouteMgr);
73 }
74
Win32RouteMgr()75 Win32RouteMgr::Win32RouteMgr()
76 {
77 }
78
~Win32RouteMgr()79 Win32RouteMgr::~Win32RouteMgr()
80 {
81 }
82
Open(const void *)83 bool Win32RouteMgr::Open(const void* /*userData*/)
84 {
85 return true;
86
87 } // end Win32RouteMgr::Open()
88
Close()89 void Win32RouteMgr::Close()
90 {
91
92 } // end Win32RouteMgr::Close()
93
94
SetForwarding(bool state)95 bool Win32RouteMgr::SetForwarding(bool state)
96 {
97 MIB_IPSTATS ipStats;
98
99 ipStats.dwDefaultTTL = MIB_USE_CURRENT_TTL;
100 ipStats.dwForwarding = state ? MIB_IP_FORWARDING : MIB_IP_NOT_FORWARDING;
101 if (NO_ERROR == SetIpStatistics(&ipStats))
102 {
103 return true;
104 }
105 else
106 {
107 PLOG(PL_ERROR, "Win32RouteMgr::SetForwarding() SetIpStatistics() error: %s\n", GetErrorString());
108 return false;
109 }
110 } // end Win32RouteMgr::SetForwarding()
111
GetRoute(const ProtoAddress & dst,unsigned int prefixLen,ProtoAddress & gw,unsigned int & ifIndex,int & metric)112 bool Win32RouteMgr::GetRoute(const ProtoAddress& dst,
113 unsigned int prefixLen,
114 ProtoAddress& gw,
115 unsigned int& ifIndex,
116 int& metric)
117 {
118 ProtoRouteTable routeTable;
119
120 if (!GetAllRoutes(dst.GetType(), routeTable))
121 {
122 PLOG(PL_ERROR, "Win32RouteMgr::GetRoute() error getting system route table\n");
123 return false;
124 }
125 return routeTable.FindRoute(dst, prefixLen, gw, ifIndex, metric);
126 } // end Win32RouteMgr::GetRoute()
127
SetRoute(const ProtoAddress & dst,unsigned int prefixLen,const ProtoAddress & gw,unsigned int ifIndex,int metric)128 bool Win32RouteMgr::SetRoute(const ProtoAddress& dst,
129 unsigned int prefixLen,
130 const ProtoAddress& gw,
131 unsigned int ifIndex,
132 int metric)
133 {
134 if (ProtoAddress::IPv4 != dst.GetType())
135 {
136 PLOG(PL_ERROR, "Win32RouteMgr::SetRoute() error: IPv6 not yet supported\n");
137 return false;
138 }
139 if (0 == ifIndex)
140 {
141 PLOG(PL_ERROR, "Win32RouteMgr::SetRoute() error: ifIndex not specified!\n");
142 return false;
143 }
144 int oldmetric = 0;
145 ProtoAddress oldgw;
146 if(GetRoute(dst,prefixLen,oldgw,ifIndex,oldmetric))
147 DeleteRoute(dst,prefixLen,oldgw,ifIndex);
148 MIB_IPFORWARDROW entry;
149 memset(&entry, 0, sizeof(MIB_IPFORWARDROW));
150 entry.dwForwardDest = htonl(dst.IPv4GetAddress());
151 ProtoAddress mask;
152 mask.Reset(dst.GetType(), false);
153 mask.ApplyPrefixMask(prefixLen);
154 entry.dwForwardMask = htonl(mask.IPv4GetAddress());
155 if (gw.IsValid())
156 entry.dwForwardNextHop = htonl(gw.IPv4GetAddress());
157 else
158 entry.dwForwardNextHop = htonl(dst.IPv4GetAddress());
159 entry.dwForwardIfIndex = ifIndex;
160 entry.dwForwardProto = PROTO_IP_NETMGMT;
161
162 // First, attempt to set as an existing entry
163 if (NO_ERROR != SetIpForwardEntry(&entry))
164 {
165 if (NO_ERROR != CreateIpForwardEntry(&entry))
166 {
167 PLOG(PL_ERROR, "Win32RouteMgr::SetRoute() CreateIpForwardEntry() error\n");
168 return false;
169 }
170 else
171 {
172 return true;
173 }
174 }
175 else
176 {
177 return true;
178 }
179 } // end Win32RouteMgr::SetRoute()
180
DeleteRoute(const ProtoAddress & dst,unsigned int prefixLen,const ProtoAddress & gw,unsigned int ifIndex)181 bool Win32RouteMgr::DeleteRoute(const ProtoAddress& dst,
182 unsigned int prefixLen,
183 const ProtoAddress& gw,
184 unsigned int ifIndex)
185 {
186 if (ProtoAddress::IPv4 != dst.GetType())
187 {
188 PLOG(PL_ERROR, "Win32RouteMgr::DeleteRoute() error: IPv6 not yet supported\n");
189 return false;
190 }
191 if (0 == ifIndex)
192 {
193 PLOG(PL_ERROR, "Win32RouteMgr::DeleteRoute() error: ifIndex not specified!\n");
194 return false;
195 }
196 MIB_IPFORWARDROW entry;
197 memset(&entry, 0, sizeof(MIB_IPFORWARDROW));
198 entry.dwForwardDest = htonl(dst.IPv4GetAddress());
199 ProtoAddress mask;
200 mask.Reset(dst.GetType(), false);
201 mask.ApplyPrefixMask(prefixLen);
202 entry.dwForwardMask = htonl(mask.IPv4GetAddress());
203 if (gw.IsValid())
204 {
205 entry.dwForwardNextHop = htonl(gw.IPv4GetAddress());
206 }
207 else
208 {
209 entry.dwForwardNextHop = htonl(dst.IPv4GetAddress());
210 }
211 entry.dwForwardIfIndex = ifIndex;
212 entry.dwForwardProto = PROTO_IP_NETMGMT;
213
214 if (NO_ERROR != DeleteIpForwardEntry(&entry))
215 {
216 PLOG(PL_ERROR, "Win32RouteMgr::DeleteRoute() DeleteIpForwardEntry() error\n");
217 return false;
218 }
219 else
220 {
221 return true;
222 }
223 } // end Win32RouteMgr::DeleteRoute()
224
225
GetAllRoutes(ProtoAddress::Type addrType,ProtoRouteTable & routeTable)226 bool Win32RouteMgr::GetAllRoutes(ProtoAddress::Type addrType,
227 ProtoRouteTable& routeTable)
228 {
229 unsigned long bufferSize = 0;
230 GetIpForwardTable((MIB_IPFORWARDTABLE*)NULL, &bufferSize, FALSE);
231 char* buffer = new char[bufferSize];
232 if (NULL == buffer)
233 {
234 PLOG(PL_ERROR, "Win32RouteMgr::GetAllRoutes() new buffer[%lu] error\n", bufferSize);
235 return false;
236 }
237 MIB_IPFORWARDTABLE* fwdTable = (MIB_IPFORWARDTABLE*)buffer;
238 if (NO_ERROR != GetIpForwardTable(fwdTable, &bufferSize, FALSE))
239 {
240 PLOG(PL_ERROR, "Win32RouteMgr::GetAllRoutes() new MIB_IPFORWARDTABLE error\n");
241 delete[] buffer;
242 return false;
243 }
244 bool result = true;
245 DWORD numEntries = fwdTable->dwNumEntries;
246 for (DWORD i = 0 ; i < numEntries; i++)
247 {
248 MIB_IPFORWARDROW& entry = fwdTable->table[i];
249 ProtoAddress destination;
250 destination.SetRawHostAddress(ProtoAddress::IPv4, (char*)&entry.dwForwardDest, sizeof(DWORD));
251 ProtoAddress gateway;
252 gateway.SetRawHostAddress(ProtoAddress::IPv4, (char*)&entry.dwForwardNextHop, sizeof(DWORD));
253 ProtoAddress mask;
254 mask.SetRawHostAddress(ProtoAddress::IPv4, (char*)&entry.dwForwardMask, sizeof(DWORD));
255 unsigned int prefixLen = mask.GetPrefixLength();
256 if (!routeTable.SetRoute(destination, prefixLen, gateway, entry.dwForwardIfIndex, entry.dwForwardMetric1))
257 {
258 PLOG(PL_ERROR, "Win32RouteMgr::GetAllRoutes() error creating table entry\n");
259 result = false;
260 break;
261 }
262 }
263 delete[] buffer;
264 return result;
265 } // end Win32RouteMgr::GetAllRoutes()
266