1 /* Poor man's route 2 * 3 * Supported commands: 4 * 5 * "print" 6 * "add" target ["mask" mask] gw ["metric" metric] 7 * "delete" target gw 8 * 9 * Goals: 10 * 11 * Flexible, simple 12 */ 13 14 #define WIN32_NO_STATUS 15 #include <stdarg.h> 16 #include <windef.h> 17 #include <winbase.h> 18 #include <stdio.h> 19 #include <malloc.h> 20 #define _INC_WINDOWS 21 #include <winsock2.h> 22 #include <iphlpapi.h> 23 #include <tchar.h> 24 25 #define IPBUF 17 26 #define IN_ADDR_OF(x) *((struct in_addr *)&(x)) 27 28 static int Usage() 29 { 30 _ftprintf( stderr, 31 _T("route usage:\n") 32 _T("route print\n") 33 _T(" prints the route table\n") 34 _T("route add <target> [mask <mask>] <gw> [metric <m>]\n") 35 _T(" adds a route\n") 36 _T("route delete <target> <gw>\n") 37 _T(" deletes a route\n") ); 38 return 1; 39 } 40 41 static int PrintRoutes() 42 { 43 PMIB_IPFORWARDTABLE IpForwardTable = NULL; 44 PIP_ADAPTER_INFO pAdapterInfo = NULL; 45 ULONG Size = 0; 46 DWORD Error = 0; 47 ULONG adaptOutBufLen = sizeof(IP_ADAPTER_INFO); 48 TCHAR DefGate[16]; 49 TCHAR Destination[IPBUF], Gateway[IPBUF], Netmask[IPBUF]; 50 unsigned int i; 51 52 /* set required buffer size */ 53 pAdapterInfo = (IP_ADAPTER_INFO *) malloc( adaptOutBufLen ); 54 if (pAdapterInfo == NULL) 55 { 56 Error = ERROR_NOT_ENOUGH_MEMORY; 57 goto Error; 58 } 59 if (GetAdaptersInfo( pAdapterInfo, &adaptOutBufLen) == ERROR_BUFFER_OVERFLOW) 60 { 61 free (pAdapterInfo); 62 pAdapterInfo = (IP_ADAPTER_INFO *) malloc (adaptOutBufLen); 63 if (pAdapterInfo == NULL) 64 { 65 Error = ERROR_NOT_ENOUGH_MEMORY; 66 goto Error; 67 } 68 } 69 70 if( (GetIpForwardTable( NULL, &Size, TRUE )) == ERROR_INSUFFICIENT_BUFFER ) 71 { 72 if (!(IpForwardTable = malloc( Size ))) 73 { 74 Error = ERROR_NOT_ENOUGH_MEMORY; 75 goto Error; 76 } 77 } 78 79 if (((Error = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen)) == NO_ERROR) && 80 ((Error = GetIpForwardTable(IpForwardTable, &Size, TRUE)) == NO_ERROR)) 81 { 82 _stprintf(DefGate, 83 #ifdef UNICODE 84 _T("%hs"), 85 #else 86 _T("%s"), 87 #endif 88 pAdapterInfo->GatewayList.IpAddress.String); 89 _tprintf(_T("===========================================================================\n")); 90 _tprintf(_T("Interface List\n")); 91 /* FIXME - sort by the index! */ 92 while (pAdapterInfo) 93 { 94 #ifdef UNICODE 95 _tprintf(_T("0x%lu ........................... %hs\n"), 96 #else 97 _tprintf(_T("0x%lu ........................... %s\n"), 98 #endif 99 pAdapterInfo->Index, pAdapterInfo->Description); 100 pAdapterInfo = pAdapterInfo->Next; 101 } 102 _tprintf(_T("===========================================================================\n")); 103 104 _tprintf(_T("===========================================================================\n")); 105 _tprintf(_T("Active Routes:\n")); 106 _tprintf( _T("%-27s%-17s%-14s%-11s%-10s\n"), 107 _T("Network Destination"), 108 _T("Netmask"), 109 _T("Gateway"), 110 _T("Interface"), 111 _T("Metric") ); 112 for( i = 0; i < IpForwardTable->dwNumEntries; i++ ) 113 { 114 _stprintf( Destination, 115 #ifdef UNICODE 116 _T("%hs"), 117 #else 118 _T("%s"), 119 #endif 120 inet_ntoa( IN_ADDR_OF(IpForwardTable->table[i].dwForwardDest) ) ); 121 _stprintf( Netmask, 122 #ifdef UNICODE 123 _T("%hs"), 124 #else 125 _T("%s"), 126 #endif 127 inet_ntoa( IN_ADDR_OF(IpForwardTable->table[i].dwForwardMask) ) ); 128 _stprintf( Gateway, 129 #ifdef UNICODE 130 _T("%hs"), 131 #else 132 _T("%s"), 133 #endif 134 inet_ntoa( IN_ADDR_OF(IpForwardTable->table[i].dwForwardNextHop) ) ); 135 136 _tprintf( _T("%17s%17s%17s%16ld%9ld\n"), 137 Destination, 138 Netmask, 139 Gateway, 140 IpForwardTable->table[i].dwForwardIfIndex, 141 IpForwardTable->table[i].dwForwardMetric1 ); 142 } 143 _tprintf(_T("Default Gateway:%18s\n"), DefGate); 144 _tprintf(_T("===========================================================================\n")); 145 _tprintf(_T("Persistent Routes:\n")); 146 147 free(IpForwardTable); 148 free(pAdapterInfo); 149 150 return ERROR_SUCCESS; 151 } 152 else 153 { 154 Error: 155 if (pAdapterInfo) free(pAdapterInfo); 156 if (IpForwardTable) free(IpForwardTable); 157 _ftprintf( stderr, _T("Route enumerate failed\n") ); 158 return Error; 159 } 160 } 161 162 static int convert_add_cmd_line( PMIB_IPFORWARDROW RowToAdd, 163 int argc, TCHAR **argv ) { 164 int i; 165 #ifdef UNICODE 166 char addr[16]; 167 #endif 168 169 if( argc > 1 ) 170 { 171 #ifdef UNICODE 172 sprintf( addr, "%ls", argv[0] ); 173 RowToAdd->dwForwardDest = inet_addr( addr ); 174 #else 175 RowToAdd->dwForwardDest = inet_addr( argv[0] ); 176 #endif 177 } 178 else 179 return FALSE; 180 for( i = 1; i < argc; i++ ) 181 { 182 if( !_tcscmp( argv[i], _T("mask") ) ) 183 { 184 i++; if( i >= argc ) return FALSE; 185 #ifdef UNICODE 186 sprintf( addr, "%ls", argv[i] ); 187 RowToAdd->dwForwardMask = inet_addr( addr ); 188 #else 189 RowToAdd->dwForwardMask = inet_addr( argv[i] ); 190 #endif 191 } 192 else if( !_tcscmp( argv[i], _T("metric") ) ) 193 { 194 i++; 195 if( i >= argc ) 196 return FALSE; 197 RowToAdd->dwForwardMetric1 = _ttoi( argv[i] ); 198 } 199 else 200 { 201 #ifdef UNICODE 202 sprintf( addr, "%ls", argv[i] ); 203 RowToAdd->dwForwardNextHop = inet_addr( addr ); 204 #else 205 RowToAdd->dwForwardNextHop = inet_addr( argv[i] ); 206 #endif 207 } 208 } 209 210 return TRUE; 211 } 212 213 static int add_route( int argc, TCHAR **argv ) { 214 MIB_IPFORWARDROW RowToAdd = { 0 }; 215 DWORD Error; 216 217 if( argc < 2 || !convert_add_cmd_line( &RowToAdd, argc, argv ) ) 218 { 219 _ftprintf( stderr, 220 _T("route add usage:\n") 221 _T("route add <target> [mask <mask>] <gw> [metric <m>]\n") 222 _T(" Adds a route to the IP route table.\n") 223 _T(" <target> is the network or host to add a route to.\n") 224 _T(" <mask> is the netmask to use (autodetected if unspecified)\n") 225 _T(" <gw> is the gateway to use to access the network\n") 226 _T(" <m> is the metric to use (lower is preferred)\n") ); 227 return 1; 228 } 229 230 if( (Error = CreateIpForwardEntry( &RowToAdd )) == ERROR_SUCCESS ) 231 return 0; 232 233 _ftprintf( stderr, _T("Route addition failed\n") ); 234 return Error; 235 } 236 237 static int del_route( int argc, TCHAR **argv ) 238 { 239 MIB_IPFORWARDROW RowToDel = { 0 }; 240 DWORD Error; 241 242 if( argc < 2 || !convert_add_cmd_line( &RowToDel, argc, argv ) ) 243 { 244 _ftprintf( stderr, 245 _T("route delete usage:\n") 246 _T("route delete <target> <gw>\n") 247 _T(" Removes a route from the IP route table.\n") 248 _T(" <target> is the network or host to add a route to.\n") 249 _T(" <gw> is the gateway to remove the route from.\n") ); 250 return 1; 251 } 252 253 if( (Error = DeleteIpForwardEntry( &RowToDel )) == ERROR_SUCCESS ) 254 return 0; 255 256 _ftprintf( stderr, _T("Route addition failed\n") ); 257 return Error; 258 } 259 260 int _tmain( int argc, TCHAR **argv ) 261 { 262 if( argc < 2 ) 263 return Usage(); 264 else if ( !_tcscmp( argv[1], _T("print") ) ) 265 return PrintRoutes(); 266 else if( !_tcscmp( argv[1], _T("add") ) ) 267 return add_route( argc-2, argv+2 ); 268 else if( !_tcscmp( argv[1], _T("delete") ) ) 269 return del_route( argc-2, argv+2 ); 270 else 271 return Usage(); 272 } 273