[ROUTE] Support the -f and -p options and and improve the help text

This commit is contained in:
Eric Kohl
2025-08-18 11:33:21 +02:00
parent 46c2a3cd09
commit 4ddebadc7e
2 changed files with 144 additions and 78 deletions

View File

@@ -10,14 +10,16 @@ STRINGTABLE
BEGIN
IDS_USAGE1 "\n\
Manipulates the network routing tables.\n\n\
ROUTE [command] [destination]\n\
[MASK netmask] [gateway] [METRIC metric]\n\n\
ROUTE [-f] [-p] command [destination]\n\
[MASK netmask] [gateway] [METRIC metric]\n\n\
-f Not supported yet.\n\n\
-p Not supported yet.\n\n\
command One of the following options:\n\
PRINT Prints the routes.\n\
ADD Add a new route.\n\
DELETE Deletes a route.\n\
destination Specifies the Host.\n\
netmask Specifies a network mask value for thei route entry.\n\
netmask Specifies a network mask value for the route entry.\n\
If not specified, it defaults to 255.255.255.255.\n\
gateway Specifies the Gateway.\n\
metric Specifies the Metric, ie. cost for the destination.\n\
@@ -33,11 +35,12 @@ route add <target> [mask <mask>] <gw> [metric <m>]\n\
<m> is the metric to use (lower is preferred)\n"
IDS_USAGE3 "\n\
route delete usage:\n\
route delete <target> <gw>\n\
Removes a route from the IP route table.\n\
<target> is the network or host to add a route to.\n\
<gw> is the gateway to remove the route from.\n"
Examples:\n\
> route PRINT ... prints all routes\n\
> route PRINT 156* ... prints all routes that match 156*\n\
> route ADD 156.0.0.0 MASK 255.0.0.0 156.0.1.12 METRIC 5\n\
destination^ netmask^ gateway^ metric^\n\n\
> route DELETE 156.0.0.0 ... deletes a route\n"
IDS_ROUTE_ADD_ERROR "Route addition failed\n"
IDS_ROUTE_DEL_ERROR "Route deletion failed\n"

View File

@@ -28,11 +28,8 @@
#define IPBUF 17
#define IN_ADDR_OF(x) *((struct in_addr *)&(x))
static int Usage()
{
ConResPrintf(StdErr, IDS_USAGE1);
return 1;
}
#define FLUSH_FLAG 0x1
#define PERSISTENT_FLAG 0x2
static
BOOL
@@ -86,25 +83,35 @@ MatchWildcard(
static
VOID
PrintMacAddress(
PBYTE Mac,
PWSTR Buffer)
_In_ PBYTE Mac,
_In_ PWSTR Buffer)
{
swprintf(Buffer, L"%02X %02X %02X %02X %02X %02X ",
Mac[0], Mac[1], Mac[2], Mac[3], Mac[4], Mac[5]);
}
static int PrintRoutes(PWSTR Filter)
static
int
PrintRoutes(
_In_ int argc,
_In_ WCHAR **argv,
_In_ int start,
_In_ int flags)
{
PMIB_IPFORWARDTABLE IpForwardTable = NULL;
PIP_ADAPTER_ADDRESSES pAdapterAddresses = NULL;
ULONG Size = 0;
DWORD Error = 0;
DWORD Error = ERROR_SUCCESS;
ULONG adaptOutBufLen = 15000;
WCHAR Destination[IPBUF], Gateway[IPBUF], Netmask[IPBUF];
unsigned int i;
BOOL EntriesFound;
ULONG Flags = GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
GAA_FLAG_SKIP_DNS_SERVER;
PWSTR Filter = NULL;
if (argc > start)
Filter = argv[start];
/* set required buffer size */
pAdapterAddresses = (PIP_ADAPTER_ADDRESSES)malloc(adaptOutBufLen);
@@ -116,7 +123,7 @@ static int PrintRoutes(PWSTR Filter)
if (GetAdaptersAddresses(AF_INET, Flags, NULL, pAdapterAddresses, &adaptOutBufLen) == ERROR_BUFFER_OVERFLOW)
{
free (pAdapterAddresses);
free(pAdapterAddresses);
pAdapterAddresses = (PIP_ADAPTER_ADDRESSES)malloc(adaptOutBufLen);
if (pAdapterAddresses == NULL)
{
@@ -125,9 +132,9 @@ static int PrintRoutes(PWSTR Filter)
}
}
if( (GetIpForwardTable( NULL, &Size, TRUE )) == ERROR_INSUFFICIENT_BUFFER )
if ((GetIpForwardTable(NULL, &Size, TRUE)) == ERROR_INSUFFICIENT_BUFFER)
{
if (!(IpForwardTable = malloc( Size )))
if (!(IpForwardTable = malloc(Size)))
{
Error = ERROR_NOT_ENOUGH_MEMORY;
goto Error;
@@ -160,7 +167,7 @@ static int PrintRoutes(PWSTR Filter)
ConResPrintf(StdOut, IDS_SEPARATOR);
ConResPrintf(StdOut, IDS_ACTIVE_ROUTES);
EntriesFound = FALSE;
for( i = 0; i < IpForwardTable->dwNumEntries; i++ )
for (i = 0; i < IpForwardTable->dwNumEntries; i++)
{
mbstowcs(Destination, inet_ntoa(IN_ADDR_OF(IpForwardTable->table[i].dwForwardDest)), IPBUF);
mbstowcs(Netmask, inet_ntoa(IN_ADDR_OF(IpForwardTable->table[i].dwForwardMask)), IPBUF);
@@ -182,7 +189,7 @@ static int PrintRoutes(PWSTR Filter)
if (Filter == NULL)
{
for( i = 0; i < IpForwardTable->dwNumEntries; i++ )
for (i = 0; i < IpForwardTable->dwNumEntries; i++)
{
if (IpForwardTable->table[i].dwForwardDest == 0)
{
@@ -197,108 +204,164 @@ static int PrintRoutes(PWSTR Filter)
ConResPrintf(StdOut, IDS_PERSISTENT_ROUTES);
ConResPrintf(StdOut, IDS_NONE);
free(IpForwardTable);
free(pAdapterAddresses);
return ERROR_SUCCESS;
}
else
{
Error:
if (pAdapterAddresses) free(pAdapterAddresses);
if (IpForwardTable) free(IpForwardTable);
if (pAdapterAddresses)
free(pAdapterAddresses);
if (IpForwardTable)
free(IpForwardTable);
if (Error != ERROR_SUCCESS)
ConResPrintf(StdErr, IDS_ROUTE_ENUM_ERROR);
return Error;
}
return (Error == ERROR_SUCCESS) ? 0 : 2;
}
static int convert_add_cmd_line( PMIB_IPFORWARDROW RowToAdd,
int argc, WCHAR **argv ) {
static int
ConvertAddCmdLine(
_Out_ PMIB_IPFORWARDROW RowToAdd,
_In_ int argc,
_In_ WCHAR **argv,
_In_ int start)
{
int i;
char addr[16];
if( argc > 1 )
if (argc > start)
{
wcstombs(addr, argv[0], 16);
RowToAdd->dwForwardDest = inet_addr( addr );
wcstombs(addr, argv[start], 16);
RowToAdd->dwForwardDest = inet_addr(addr);
}
else
return FALSE;
for( i = 1; i < argc; i++ )
for (i = start + 1; i < argc; i++)
{
if( !_wcsicmp( argv[i], L"mask" ) )
{
i++; if( i >= argc ) return FALSE;
wcstombs(addr, argv[i], 16);
RowToAdd->dwForwardMask = inet_addr( addr );
}
else if( !_wcsicmp( argv[i], L"metric" ) )
if (!_wcsicmp(argv[i], L"mask"))
{
i++;
if( i >= argc )
if (i >= argc)
return FALSE;
RowToAdd->dwForwardMetric1 = _wtoi( argv[i] );
wcstombs(addr, argv[i], 16);
RowToAdd->dwForwardMask = inet_addr(addr);
}
else if (!_wcsicmp(argv[i], L"metric"))
{
i++;
if (i >= argc)
return FALSE;
RowToAdd->dwForwardMetric1 = _wtoi(argv[i]);
}
else
{
wcstombs(addr, argv[i], 16);
RowToAdd->dwForwardNextHop = inet_addr( addr );
RowToAdd->dwForwardNextHop = inet_addr(addr);
}
}
return TRUE;
}
static int add_route( int argc, WCHAR **argv ) {
static
int
AddRoute(
_In_ int argc,
_In_ WCHAR **argv,
_In_ int start,
_In_ int flags)
{
MIB_IPFORWARDROW RowToAdd = { 0 };
DWORD Error;
if( argc < 2 || !convert_add_cmd_line( &RowToAdd, argc, argv ) )
{
ConResPrintf(StdErr, IDS_USAGE2);
if ((argc <= start) || !ConvertAddCmdLine(&RowToAdd, argc, argv, start))
return 1;
Error = CreateIpForwardEntry(&RowToAdd);
if (Error != ERROR_SUCCESS)
{
ConResPrintf(StdErr, IDS_ROUTE_ADD_ERROR);
return 2;
}
if( (Error = CreateIpForwardEntry( &RowToAdd )) == ERROR_SUCCESS )
return 0;
ConResPrintf(StdErr, IDS_ROUTE_ADD_ERROR);
return Error;
return 0;
}
static int del_route( int argc, WCHAR **argv )
static int
DeleteRoute(
_In_ int argc,
_In_ WCHAR **argv,
_In_ int start,
_In_ int flags)
{
MIB_IPFORWARDROW RowToDel = { 0 };
DWORD Error;
if( argc < 2 || !convert_add_cmd_line( &RowToDel, argc, argv ) )
{
ConResPrintf(StdErr, IDS_USAGE3);
if ((argc < start + 2) || !ConvertAddCmdLine(&RowToDel, argc, argv, start))
return 1;
Error = DeleteIpForwardEntry(&RowToDel);
if (Error != ERROR_SUCCESS)
{
ConResPrintf(StdErr, IDS_ROUTE_DEL_ERROR);
return 2;
}
if( (Error = DeleteIpForwardEntry( &RowToDel )) == ERROR_SUCCESS )
return 0;
ConResPrintf(StdErr, IDS_ROUTE_DEL_ERROR);
return Error;
return 0;
}
int wmain( int argc, WCHAR **argv )
int
wmain(
_In_ int argc,
_In_ WCHAR **argv)
{
int i, flags = 0, ret = 0;
/* Initialize the Console Standard Streams */
ConInitStdStreams();
if( argc < 2 )
return Usage();
else if ( !_wcsicmp( argv[1], L"print" ) )
return PrintRoutes((argc > 2) ? argv[2] : NULL);
else if( !_wcsicmp( argv[1], L"add" ) )
return add_route( argc-2, argv+2 );
else if( !_wcsicmp( argv[1], L"delete" ) )
return del_route( argc-2, argv+2 );
else
return Usage();
for (i = 1; i < argc; i++)
{
if (argv[i][0] == L'-' || argv[i][0] == L'/')
{
if (!_wcsicmp(&argv[i][1], L"f"))
{
flags |= FLUSH_FLAG;
}
else if (!_wcsicmp(&argv[i][1], L"p"))
{
flags |= PERSISTENT_FLAG;
}
else
{
ret = 1;
break;
}
}
else
{
if (!_wcsicmp(argv[i], L"print"))
ret = PrintRoutes(argc, argv, i + 1, flags);
else if (!_wcsicmp(argv[i], L"add"))
ret = AddRoute(argc, argv, i + 1, flags);
else if (!_wcsicmp(argv[i], L"delete"))
ret = DeleteRoute(argc, argv, i + 1, flags);
else
ret = 1;
break;
}
}
if (argc == 1)
ret = 1;
if (ret == 1)
{
ConResPrintf(StdErr, IDS_USAGE1);
// ConResPrintf(StdErr, IDS_USAGE2);
ConResPrintf(StdErr, IDS_USAGE3);
}
return (ret == 0) ? 0 : 1;
}