Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

391 lines
8.6 KiB

  1. /*
  2. *============================================================================
  3. * Copyright (c) 1994-95, Microsoft Corp.
  4. *
  5. * File: map.c
  6. *
  7. * Routes can be added to and deleted from the IP routing table by other
  8. * means. Therefore, it is necessary for any protocol using these functions
  9. * to reload the routing tables periodically.
  10. *============================================================================
  11. */
  12. #include "pchrip.h"
  13. #pragma hdrstop
  14. //----------------------------------------------------------------------------
  15. // GetIpAddressTable
  16. //
  17. // This function retrieves the list of addresses for the logical interfaces
  18. // configured on this system.
  19. //----------------------------------------------------------------------------
  20. DWORD
  21. GetIPAddressTable(
  22. OUT PMIB_IPADDRROW *lplpAddrTable,
  23. OUT LPDWORD lpdwAddrCount
  24. )
  25. {
  26. DWORD dwSize = 0, dwErr = 0;
  27. PMIB_IPADDRTABLE pmiatTable = NULL;
  28. *lplpAddrTable = NULL;
  29. *lpdwAddrCount = 0;
  30. do
  31. {
  32. //
  33. // retrieve ip address table. First call to find size of
  34. // structure to be allocated.
  35. //
  36. dwErr = GetIpAddrTable( pmiatTable, &dwSize, TRUE );
  37. if ( dwErr != ERROR_INSUFFICIENT_BUFFER )
  38. {
  39. dbgprintf( "GetIpAddrTable failed with error %x\n", dwErr );
  40. RipLogError( RIPLOG_ADDR_INIT_FAILED, 0, NULL, dwErr );
  41. break;
  42. }
  43. //
  44. // allocate requiste buffer
  45. //
  46. pmiatTable = HeapAlloc( GetProcessHeap(), 0 , dwSize );
  47. if ( pmiatTable == NULL )
  48. {
  49. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  50. dbgprintf( "GetIpAddrTable failed with error %x\n", dwErr );
  51. RipLogError( RIPLOG_ADDR_ALLOC_FAILED, 0, NULL, dwErr );
  52. break;
  53. }
  54. //
  55. // now retrieve address table
  56. //
  57. dwErr = GetIpAddrTable( pmiatTable, &dwSize, TRUE );
  58. if ( dwErr != NO_ERROR )
  59. {
  60. dbgprintf( "GetIpAddrTable failed with error %x\n", dwErr );
  61. RipLogError( RIPLOG_ADDR_INIT_FAILED, 0, NULL, dwErr );
  62. break;
  63. }
  64. *lpdwAddrCount = pmiatTable-> dwNumEntries;
  65. *lplpAddrTable = pmiatTable-> table;
  66. return NO_ERROR;
  67. } while ( FALSE );
  68. //
  69. // Error condition
  70. //
  71. if ( pmiatTable )
  72. {
  73. HeapFree( GetProcessHeap(), 0, pmiatTable );
  74. }
  75. return dwErr;
  76. }
  77. //----------------------------------------------------------------------------
  78. // FreeIPAddressTable
  79. //
  80. // This function releases the memory allocated for the IP address table by
  81. // the GetIpAddressTable API.
  82. //----------------------------------------------------------------------------
  83. DWORD
  84. FreeIPAddressTable(
  85. IN PMIB_IPADDRROW lpAddrTable
  86. )
  87. {
  88. PMIB_IPADDRTABLE pmiatTable = NULL;
  89. pmiatTable = CONTAINING_RECORD( lpAddrTable, MIB_IPADDRTABLE, table );
  90. if ( pmiatTable != NULL )
  91. {
  92. HeapFree( GetProcessHeap(), 0, pmiatTable );
  93. return NO_ERROR;
  94. }
  95. return ERROR_INVALID_PARAMETER;
  96. }
  97. //----------------------------------------------------------------------------
  98. // GetRouteTable
  99. //
  100. // This function retrieves the route table.
  101. //----------------------------------------------------------------------------
  102. DWORD
  103. GetRouteTable(
  104. OUT LPIPROUTE_ENTRY *lplpRouteTable,
  105. OUT LPDWORD lpdwRouteCount
  106. )
  107. {
  108. DWORD dwErr = (DWORD) -1, dwSize = 0;
  109. PMIB_IPFORWARDTABLE pmiftTable = NULL;
  110. *lplpRouteTable = NULL;
  111. *lpdwRouteCount = 0;
  112. do
  113. {
  114. //
  115. // get size of buffer required.
  116. //
  117. dwErr = GetIpForwardTable( pmiftTable, &dwSize, TRUE );
  118. if ( dwErr != ERROR_INSUFFICIENT_BUFFER )
  119. {
  120. dbgprintf( "GetIpNetTable failed with error %x\n", dwErr );
  121. RipLogError( RIPLOG_ROUTEINIT_FAILED, 0, NULL, dwErr );
  122. break;
  123. }
  124. //
  125. // allocate requiste buffer space
  126. //
  127. pmiftTable = HeapAlloc( GetProcessHeap(), 0, dwSize );
  128. if ( pmiftTable == NULL )
  129. {
  130. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  131. dbgprintf( "GetIpAddrTable failed with error %x\n", dwErr );
  132. RipLogError( RIPLOG_RTAB_INIT_FAILED, 0, NULL, dwErr );
  133. break;
  134. }
  135. //
  136. // now retrieve route table
  137. //
  138. dwErr = GetIpForwardTable( pmiftTable, &dwSize, TRUE );
  139. if ( dwErr != NO_ERROR )
  140. {
  141. dbgprintf( "GetIpNetTable failed with error %x\n", dwErr );
  142. RipLogError( RIPLOG_RTAB_INIT_FAILED, 0, NULL, dwErr );
  143. break;
  144. }
  145. *lpdwRouteCount = pmiftTable-> dwNumEntries;
  146. *lplpRouteTable = (LPIPROUTE_ENTRY) pmiftTable-> table;
  147. return NO_ERROR;
  148. } while ( FALSE );
  149. //
  150. // Error condition
  151. //
  152. if ( pmiftTable )
  153. {
  154. HeapFree( GetProcessHeap(), 0, pmiftTable );
  155. }
  156. return dwErr;
  157. }
  158. //----------------------------------------------------------------------------
  159. // FreeIPRouteTable
  160. //
  161. // This function releases the memory allocated for the IP route table by
  162. // the GetIpAddressTable API.
  163. //----------------------------------------------------------------------------
  164. DWORD
  165. FreeRouteTable(
  166. IN LPIPROUTE_ENTRY lpRouteTable
  167. )
  168. {
  169. PMIB_IPFORWARDTABLE pmiftTable = NULL;
  170. pmiftTable = CONTAINING_RECORD( lpRouteTable, MIB_IPFORWARDTABLE, table );
  171. if ( pmiftTable != NULL )
  172. {
  173. HeapFree( GetProcessHeap(), 0, pmiftTable );
  174. return NO_ERROR;
  175. }
  176. return ERROR_INVALID_PARAMETER;
  177. }
  178. //----------------------------------------------------------------------------
  179. // AddRoute
  180. //
  181. // This function adds a route to the IP stack
  182. //----------------------------------------------------------------------------
  183. DWORD
  184. AddRoute(
  185. IN DWORD dwProtocol,
  186. IN DWORD dwType,
  187. IN DWORD dwIndex,
  188. IN DWORD dwDestVal,
  189. IN DWORD dwMaskVal,
  190. IN DWORD dwGateVal,
  191. IN DWORD dwMetric
  192. )
  193. {
  194. DWORD dwErr = 0;
  195. MIB_IPFORWARDROW mifr;
  196. ZeroMemory( &mifr, sizeof( MIB_IPFORWARDROW ) );
  197. mifr.dwForwardDest = dwDestVal;
  198. mifr.dwForwardMask = dwMaskVal;
  199. mifr.dwForwardPolicy = 0;
  200. mifr.dwForwardNextHop = dwGateVal;
  201. mifr.dwForwardIfIndex = dwIndex;
  202. mifr.dwForwardType = dwType;
  203. mifr.dwForwardProto = MIB_IPPROTO_NT_AUTOSTATIC;
  204. mifr.dwForwardMetric1 = dwMetric;
  205. dwErr = CreateIpForwardEntry( &mifr );
  206. if ( dwErr == ERROR_ALREADY_EXISTS )
  207. {
  208. //
  209. // Bug # : 405469
  210. //
  211. // For the case where IPRIP (Rip Listener) is running at the
  212. // same time as the RemoteAccess service.
  213. // In this case the IPHLPAPI go via the IPRTRMGR to the stack
  214. // and trying to create a route that already exists will fail
  215. // with ERROR_ALREADY_EXISTS. To work around this case, set
  216. // the forward entry.
  217. //
  218. dwErr = SetIpForwardEntry( &mifr );
  219. }
  220. if ( dwErr != NO_ERROR )
  221. {
  222. dbgprintf( "Create/Set IpForwardEntry failed with error %x\n", dwErr );
  223. RipLogError( RIPLOG_ADD_ROUTE_FAILED, 0, NULL, dwErr );
  224. }
  225. return dwErr;
  226. }
  227. //----------------------------------------------------------------------------
  228. // DelRoute
  229. //
  230. // This function deletes a route to the IP stack
  231. //----------------------------------------------------------------------------
  232. DWORD
  233. DeleteRoute(
  234. IN DWORD dwIndex,
  235. IN DWORD dwDestVal,
  236. IN DWORD dwMaskVal,
  237. IN DWORD dwGateVal
  238. )
  239. {
  240. DWORD dwErr = 0;
  241. MIB_IPFORWARDROW mifr;
  242. ZeroMemory( &mifr, sizeof( MIB_IPFORWARDROW ) );
  243. mifr.dwForwardDest = dwDestVal;
  244. mifr.dwForwardMask = dwMaskVal;
  245. mifr.dwForwardPolicy = 0;
  246. mifr.dwForwardProto = MIB_IPPROTO_NT_AUTOSTATIC;
  247. mifr.dwForwardNextHop = dwGateVal;
  248. mifr.dwForwardIfIndex = dwIndex;
  249. dwErr = DeleteIpForwardEntry( &mifr );
  250. if ( dwErr != NO_ERROR )
  251. {
  252. dbgprintf( "DeleteIpForwardEntry failed with error %x\n", dwErr );
  253. RipLogError( RIPLOG_DELETE_ROUTE_FAILED, 0, NULL, dwErr );
  254. }
  255. return dwErr;
  256. }
  257. //----------------------------------------------------------------------------
  258. // DelRoute
  259. //
  260. // This function deletes a route to the IP stack
  261. //----------------------------------------------------------------------------
  262. DWORD
  263. ReloadIPAddressTable(
  264. OUT PMIB_IPADDRROW *lplpAddrTable,
  265. OUT LPDWORD lpdwAddrCount
  266. )
  267. {
  268. return GetIPAddressTable( lplpAddrTable, lpdwAddrCount );
  269. }