Create this branch to work on loading of different Kernel-Debugger DLL providers...
[reactos.git] / base / applications / network / route / route.c
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 }