Added simple route utility that uses iphlpapi to change the route table.
[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
19 #define IPBUF 17
20 #define IN_ADDR_OF(x) *((struct in_addr *)&(x))
21
22 int usage() {
23 fprintf( stderr,
24 "route usage:\n"
25 "route print\n"
26 " prints the route table\n"
27 "route add <target> [mask <mask>] <gw> [metric <m>]\n"
28 " adds a route\n"
29 "route delete <target> <gw>\n"
30 " deletes a route\n" );
31 return 1;
32 }
33
34 int print_routes() {
35 PMIB_IPFORWARDTABLE IpForwardTable;
36 DWORD Error;
37 ULONG Size = 0;
38 char Destination[IPBUF], Gateway[IPBUF], Netmask[IPBUF],
39 Index[IPBUF], Metric[IPBUF];
40 int i;
41
42 if( (Error = GetIpForwardTable( NULL, &Size, TRUE )) ==
43 ERROR_INSUFFICIENT_BUFFER ) {
44 IpForwardTable = malloc( Size );
45 Error = GetIpForwardTable( IpForwardTable, &Size, TRUE );
46 }
47
48 if( Error == ERROR_SUCCESS ) {
49 printf( "%-16s%-16s%-16s%-10s%-10s\n",
50 "Destination",
51 "Netmask",
52 "Gateway",
53 "Index",
54 "Metric" );
55 for( i = 0; i < IpForwardTable->dwNumEntries; i++ ) {
56 strcpy( Destination,
57 inet_ntoa( IN_ADDR_OF(IpForwardTable->table[i].
58 dwForwardDest) ) );
59 strcpy( Netmask,
60 inet_ntoa( IN_ADDR_OF(IpForwardTable->table[i].
61 dwForwardMask) ) );
62 strcpy( Gateway,
63 inet_ntoa( IN_ADDR_OF(IpForwardTable->table[i].
64 dwForwardNextHop) ) );
65
66 printf( "%-16s%-16s%-16s%-10d%-10d\n",
67 Destination,
68 Netmask,
69 Gateway,
70 IpForwardTable->table[i].dwForwardIfIndex,
71 IpForwardTable->table[i].dwForwardMetric1 );
72 }
73
74 free( IpForwardTable );
75
76 return ERROR_SUCCESS;
77 } else {
78 fprintf( stderr, "Route enumerate failed\n" );
79 return Error;
80 }
81 }
82
83 int convert_add_cmd_line( PMIB_IPFORWARDROW RowToAdd,
84 int argc, char **argv ) {
85 int i;
86
87 if( argc > 1 ) RowToAdd->dwForwardDest = inet_addr( argv[0] );
88 else return FALSE;
89 for( i = 1; i < argc; i++ ) {
90 if( !strcasecmp( argv[i], "mask" ) ) {
91 i++; if( i >= argc ) return FALSE;
92 RowToAdd->dwForwardMask = inet_addr( argv[i] );
93 } else if( !strcasecmp( argv[i], "metric" ) ) {
94 i++; if( i >= argc ) return FALSE;
95 RowToAdd->dwForwardMetric1 = atoi( argv[i] );
96 } else {
97 RowToAdd->dwForwardNextHop = inet_addr( argv[i] );
98 }
99 }
100
101 return TRUE;
102 }
103
104 int add_route( int argc, char **argv ) {
105 MIB_IPFORWARDROW RowToAdd = { 0 };
106 DWORD Error;
107
108 if( argc < 2 || !convert_add_cmd_line( &RowToAdd, argc, argv ) ) {
109 fprintf( stderr,
110 "route add usage:\n"
111 "route add <target> [mask <mask>] <gw> [metric <m>]\n"
112 " Adds a route to the IP route table.\n"
113 " <target> is the network or host to add a route to.\n"
114 " <mask> is the netmask to use (autodetected if unspecified)\n"
115 " <gw> is the gateway to use to access the network\n"
116 " <m> is the metric to use (lower is preferred)\n" );
117 return 1;
118 }
119
120 if( (Error = CreateIpForwardEntry( &RowToAdd )) == ERROR_SUCCESS )
121 return 0;
122
123 fprintf( stderr, "Route addition failed\n" );
124 return Error;
125 }
126
127 int del_route( int argc, char **argv ) {
128 MIB_IPFORWARDROW RowToDel = { 0 };
129 DWORD Error;
130
131 if( argc < 2 || !convert_add_cmd_line( &RowToDel, argc, argv ) ) {
132 fprintf( stderr,
133 "route delete usage:\n"
134 "route delete <target> <gw>\n"
135 " Removes a route from the IP route table.\n"
136 " <target> is the network or host to add a route to.\n"
137 " <gw> is the gateway to remove the route from.\n" );
138 return 1;
139 }
140
141 if( (Error = DeleteIpForwardEntry( &RowToDel )) == ERROR_SUCCESS )
142 return 0;
143
144 fprintf( stderr, "Route addition failed\n" );
145 return Error;
146 }
147
148 int main( int argc, char **argv ) {
149 if( argc < 2 ) return usage();
150 else if( !strcasecmp( argv[1], "print" ) )
151 return print_routes();
152 else if( !strcasecmp( argv[1], "add" ) )
153 return add_route( argc-2, argv+2 );
154 else if( !strcasecmp( argv[1], "delete" ) )
155 return del_route( argc-2, argv+2 );
156 else return usage();
157 }