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