18004b6f2ee5a197ec880378567a182ae4f23ed9
[reactos.git] / reactos / apps / utils / net / 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 <windows.h>
16 #include <iphlpapi.h>
17 #include <winsock2.h>
18 #include <tchar.h>
19
20 #define IPBUF 17
21 #define IN_ADDR_OF(x) *((struct in_addr *)&(x))
22
23 int usage()
24 {
25 fprintf( stderr,
26 "route usage:\n"
27 "route print\n"
28 " prints the route table\n"
29 "route add <target> [mask <mask>] <gw> [metric <m>]\n"
30 " adds a route\n"
31 "route delete <target> <gw>\n"
32 " deletes a route\n" );
33 return 1;
34 }
35
36 int print_routes()
37 {
38 PMIB_IPFORWARDTABLE IpForwardTable = NULL;
39 PIP_ADAPTER_INFO pAdapterInfo = NULL;
40 DWORD Error;
41 ULONG Size = 0;
42 ULONG adaptOutBufLen;
43 TCHAR DefGate[16];
44 char Destination[IPBUF], Gateway[IPBUF], Netmask[IPBUF];
45 unsigned int i;
46
47 /* set required buffer size */
48 pAdapterInfo = (IP_ADAPTER_INFO *) malloc( sizeof(IP_ADAPTER_INFO) );
49 if (GetAdaptersInfo( pAdapterInfo, &adaptOutBufLen) == ERROR_INSUFFICIENT_BUFFER)
50 pAdapterInfo = (IP_ADAPTER_INFO *) malloc (adaptOutBufLen);
51
52 if( (GetIpForwardTable( NULL, &Size, TRUE )) == ERROR_INSUFFICIENT_BUFFER )
53 IpForwardTable = malloc( Size );
54
55 if ((GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen) == NO_ERROR) &&
56 GetIpForwardTable( IpForwardTable, &Size, TRUE ) == NO_ERROR)
57 {
58 _tcsncpy(DefGate, pAdapterInfo->GatewayList.IpAddress.String, 16);
59 _tprintf(_T("===========================================================================\n"));
60 _tprintf(_T("Interface List\n"));
61 while (pAdapterInfo)
62 {
63 _tprintf(_T("0x%lu ........................... %s\n"), pAdapterInfo->Index, pAdapterInfo->Description);
64 pAdapterInfo = pAdapterInfo->Next;
65 }
66 _tprintf(_T("===========================================================================\n"));
67
68 _tprintf(_T("===========================================================================\n"));
69 _tprintf(_T("Active Routes:\n"));
70 printf( "%-27s%-17s%-14s%-11s%-10s\n",
71 "Network Destination",
72 "Netmask",
73 "Gateway",
74 "Interface",
75 "Metric" );
76 for( i = 0; i < IpForwardTable->dwNumEntries; i++ )
77 {
78 strcpy( Destination, inet_ntoa( IN_ADDR_OF(IpForwardTable->table[i].dwForwardDest) ) );
79 strcpy( Netmask, inet_ntoa( IN_ADDR_OF(IpForwardTable->table[i].dwForwardMask) ) );
80 strcpy( Gateway, inet_ntoa( IN_ADDR_OF(IpForwardTable->table[i].dwForwardNextHop) ) );
81
82 printf( "%17s%17s%17s%16ld%9ld\n",
83 Destination,
84 Netmask,
85 Gateway,
86 IpForwardTable->table[i].dwForwardIfIndex,
87 IpForwardTable->table[i].dwForwardMetric1 );
88 }
89 _tprintf(_T("Default Gateway:%18s\n"), DefGate);
90 _tprintf(_T("===========================================================================\n"));
91 _tprintf(_T("Persistent Routes:\n"));
92
93 free( IpForwardTable );
94
95 return ERROR_SUCCESS;
96 }
97 else
98 {
99 fprintf( stderr, "Route enumerate failed\n" );
100 return Error;
101 }
102 }
103
104 int convert_add_cmd_line( PMIB_IPFORWARDROW RowToAdd,
105 int argc, char **argv ) {
106 int i;
107
108 if( argc > 1 )
109 RowToAdd->dwForwardDest = inet_addr( argv[0] );
110 else
111 return FALSE;
112 for( i = 1; i < argc; i++ )
113 {
114 if( !strcasecmp( argv[i], "mask" ) )
115 {
116 i++; if( i >= argc ) return FALSE;
117 RowToAdd->dwForwardMask = inet_addr( argv[i] );
118 }
119 else if( !strcasecmp( argv[i], "metric" ) )
120 {
121 i++;
122 if( i >= argc )
123 return FALSE;
124 RowToAdd->dwForwardMetric1 = atoi( argv[i] );
125 }
126 else
127 RowToAdd->dwForwardNextHop = inet_addr( argv[i] );
128 }
129
130 return TRUE;
131 }
132
133 int add_route( int argc, char **argv ) {
134 MIB_IPFORWARDROW RowToAdd = { 0 };
135 DWORD Error;
136
137 if( argc < 2 || !convert_add_cmd_line( &RowToAdd, argc, argv ) )
138 {
139 fprintf( stderr,
140 "route add usage:\n"
141 "route add <target> [mask <mask>] <gw> [metric <m>]\n"
142 " Adds a route to the IP route table.\n"
143 " <target> is the network or host to add a route to.\n"
144 " <mask> is the netmask to use (autodetected if unspecified)\n"
145 " <gw> is the gateway to use to access the network\n"
146 " <m> is the metric to use (lower is preferred)\n" );
147 return 1;
148 }
149
150 if( (Error = CreateIpForwardEntry( &RowToAdd )) == ERROR_SUCCESS )
151 return 0;
152
153 fprintf( stderr, "Route addition failed\n" );
154 return Error;
155 }
156
157 int del_route( int argc, char **argv )
158 {
159 MIB_IPFORWARDROW RowToDel = { 0 };
160 DWORD Error;
161
162 if( argc < 2 || !convert_add_cmd_line( &RowToDel, argc, argv ) )
163 {
164 fprintf( stderr,
165 "route delete usage:\n"
166 "route delete <target> <gw>\n"
167 " Removes a route from the IP route table.\n"
168 " <target> is the network or host to add a route to.\n"
169 " <gw> is the gateway to remove the route from.\n" );
170 return 1;
171 }
172
173 if( (Error = DeleteIpForwardEntry( &RowToDel )) == ERROR_SUCCESS )
174 return 0;
175
176 fprintf( stderr, "Route addition failed\n" );
177 return Error;
178 }
179
180 int main( int argc, char **argv )
181 {
182
183 if( argc < 2 )
184 return usage();
185 else if ( !strcasecmp( argv[1], "print" ) )
186 return print_routes();
187 else if( !strcasecmp( argv[1], "add" ) )
188 return add_route( argc-2, argv+2 );
189 else if( !strcasecmp( argv[1], "delete" ) )
190 return del_route( argc-2, argv+2 );
191 else
192 return usage();
193 }