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