584 lines
13 KiB
C
584 lines
13 KiB
C
#include "inc.h"
|
|
|
|
CMD_ENTRY g_rgMainCmdTable[] =
|
|
{
|
|
{TOKEN_ROUTE, HandleRoute},
|
|
{TOKEN_ADDRESS, HandleAddress},
|
|
{TOKEN_INTERFACE, HandleInterface},
|
|
{TOKEN_ARP, HandleArp},
|
|
};
|
|
|
|
HMODULE g_hModule;
|
|
|
|
DWORD
|
|
_cdecl
|
|
wmain(
|
|
int argc,
|
|
wchar_t *argv[]
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
|
|
Locks
|
|
|
|
|
|
Arguments
|
|
|
|
|
|
Return Value
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LONG lIndex;
|
|
|
|
setlocale(LC_ALL,
|
|
"");
|
|
|
|
if(argc < 2)
|
|
{
|
|
DisplayMessage(HMSG_IPKERN_USAGE);
|
|
|
|
return ERROR;
|
|
}
|
|
|
|
g_hModule = GetModuleHandle(NULL);
|
|
|
|
if(g_hModule is NULL)
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
lIndex = ParseCommand(g_rgMainCmdTable,
|
|
sizeof(g_rgMainCmdTable)/sizeof(CMD_ENTRY),
|
|
argv[1]);
|
|
|
|
if(lIndex is -1)
|
|
{
|
|
DisplayMessage(HMSG_IPKERN_USAGE);
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
g_rgMainCmdTable[lIndex].pfnHandler(argc - 1,
|
|
&argv[1]);
|
|
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
BOOL
|
|
MatchToken(
|
|
IN PWCHAR pwszToken,
|
|
IN DWORD dwTokenId
|
|
)
|
|
{
|
|
WCHAR pwszTemp[MAX_TOKEN_LENGTH] = L"\0";
|
|
|
|
if(!LoadStringW(g_hModule,
|
|
dwTokenId,
|
|
pwszTemp,
|
|
MAX_TOKEN_LENGTH))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if(!_wcsicmp(pwszToken, pwszTemp))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
LONG
|
|
ParseCommand(
|
|
PCMD_ENTRY pCmdTable,
|
|
LONG lNumEntries,
|
|
PWCHAR pwszFirstArg
|
|
)
|
|
{
|
|
LONG i;
|
|
|
|
for(i = 0; i < lNumEntries; i++)
|
|
{
|
|
if(MatchToken(pwszFirstArg,
|
|
pCmdTable[i].dwTokenId))
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
DWORD
|
|
DisplayMessage(
|
|
DWORD dwMsgId,
|
|
...
|
|
)
|
|
{
|
|
DWORD dwMsglen = 0;
|
|
PWCHAR pwszOutput;
|
|
va_list arglist;
|
|
WCHAR rgwcInput[MAX_MSG_LENGTH];
|
|
|
|
pwszOutput = NULL;
|
|
|
|
do
|
|
{
|
|
va_start(arglist, dwMsgId);
|
|
|
|
if(!LoadStringW(g_hModule,
|
|
dwMsgId,
|
|
rgwcInput,
|
|
MAX_MSG_LENGTH))
|
|
{
|
|
break;
|
|
}
|
|
|
|
dwMsglen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
|
|
rgwcInput,
|
|
0,
|
|
0L,
|
|
(PWCHAR)&pwszOutput,
|
|
0,
|
|
&arglist);
|
|
|
|
if(dwMsglen is 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
wprintf( L"%s", pwszOutput );
|
|
|
|
}while(FALSE);
|
|
|
|
|
|
if(pwszOutput)
|
|
{
|
|
LocalFree(pwszOutput);
|
|
}
|
|
|
|
return dwMsglen;
|
|
}
|
|
|
|
PWCHAR
|
|
MakeString(
|
|
DWORD dwMsgId,
|
|
...
|
|
)
|
|
{
|
|
DWORD dwMsglen;
|
|
PWCHAR pwszOutput;
|
|
va_list arglist;
|
|
WCHAR rgwcInput[MAX_MSG_LENGTH];
|
|
|
|
pwszOutput = NULL;
|
|
|
|
do
|
|
{
|
|
va_start(arglist,
|
|
dwMsgId);
|
|
|
|
if(!LoadStringW(g_hModule,
|
|
dwMsgId,
|
|
rgwcInput,
|
|
MAX_MSG_LENGTH))
|
|
{
|
|
break;
|
|
}
|
|
|
|
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_STRING,
|
|
rgwcInput,
|
|
0,
|
|
0L, // Default country ID.
|
|
(PWCHAR)&pwszOutput,
|
|
0,
|
|
&arglist);
|
|
|
|
}while(FALSE);
|
|
|
|
return pwszOutput;
|
|
}
|
|
|
|
|
|
VOID
|
|
FreeString(
|
|
PWCHAR pwszString
|
|
)
|
|
{
|
|
LocalFree(pwszString);
|
|
}
|
|
|
|
|
|
//
|
|
// This preinitialized array defines the strings to be used.
|
|
// The index of each row corresponds to the value for a byte
|
|
// in an IP address. The first three bytes of each row are the
|
|
// char/string value for the byte, and the fourth byte in each row is
|
|
// the length of the string required for the byte. This approach
|
|
// allows a fast implementation with no jumps.
|
|
//
|
|
|
|
static const WCHAR NToUWCharStrings[][4] =
|
|
{
|
|
L'0', L'x', L'x', 1,
|
|
L'1', L'x', L'x', 1,
|
|
L'2', L'x', L'x', 1,
|
|
L'3', L'x', L'x', 1,
|
|
L'4', L'x', L'x', 1,
|
|
L'5', L'x', L'x', 1,
|
|
L'6', L'x', L'x', 1,
|
|
L'7', L'x', L'x', 1,
|
|
L'8', L'x', L'x', 1,
|
|
L'9', L'x', L'x', 1,
|
|
L'1', L'0', L'x', 2,
|
|
L'1', L'1', L'x', 2,
|
|
L'1', L'2', L'x', 2,
|
|
L'1', L'3', L'x', 2,
|
|
L'1', L'4', L'x', 2,
|
|
L'1', L'5', L'x', 2,
|
|
L'1', L'6', L'x', 2,
|
|
L'1', L'7', L'x', 2,
|
|
L'1', L'8', L'x', 2,
|
|
L'1', L'9', L'x', 2,
|
|
L'2', L'0', L'x', 2,
|
|
L'2', L'1', L'x', 2,
|
|
L'2', L'2', L'x', 2,
|
|
L'2', L'3', L'x', 2,
|
|
L'2', L'4', L'x', 2,
|
|
L'2', L'5', L'x', 2,
|
|
L'2', L'6', L'x', 2,
|
|
L'2', L'7', L'x', 2,
|
|
L'2', L'8', L'x', 2,
|
|
L'2', L'9', L'x', 2,
|
|
L'3', L'0', L'x', 2,
|
|
L'3', L'1', L'x', 2,
|
|
L'3', L'2', L'x', 2,
|
|
L'3', L'3', L'x', 2,
|
|
L'3', L'4', L'x', 2,
|
|
L'3', L'5', L'x', 2,
|
|
L'3', L'6', L'x', 2,
|
|
L'3', L'7', L'x', 2,
|
|
L'3', L'8', L'x', 2,
|
|
L'3', L'9', L'x', 2,
|
|
L'4', L'0', L'x', 2,
|
|
L'4', L'1', L'x', 2,
|
|
L'4', L'2', L'x', 2,
|
|
L'4', L'3', L'x', 2,
|
|
L'4', L'4', L'x', 2,
|
|
L'4', L'5', L'x', 2,
|
|
L'4', L'6', L'x', 2,
|
|
L'4', L'7', L'x', 2,
|
|
L'4', L'8', L'x', 2,
|
|
L'4', L'9', L'x', 2,
|
|
L'5', L'0', L'x', 2,
|
|
L'5', L'1', L'x', 2,
|
|
L'5', L'2', L'x', 2,
|
|
L'5', L'3', L'x', 2,
|
|
L'5', L'4', L'x', 2,
|
|
L'5', L'5', L'x', 2,
|
|
L'5', L'6', L'x', 2,
|
|
L'5', L'7', L'x', 2,
|
|
L'5', L'8', L'x', 2,
|
|
L'5', L'9', L'x', 2,
|
|
L'6', L'0', L'x', 2,
|
|
L'6', L'1', L'x', 2,
|
|
L'6', L'2', L'x', 2,
|
|
L'6', L'3', L'x', 2,
|
|
L'6', L'4', L'x', 2,
|
|
L'6', L'5', L'x', 2,
|
|
L'6', L'6', L'x', 2,
|
|
L'6', L'7', L'x', 2,
|
|
L'6', L'8', L'x', 2,
|
|
L'6', L'9', L'x', 2,
|
|
L'7', L'0', L'x', 2,
|
|
L'7', L'1', L'x', 2,
|
|
L'7', L'2', L'x', 2,
|
|
L'7', L'3', L'x', 2,
|
|
L'7', L'4', L'x', 2,
|
|
L'7', L'5', L'x', 2,
|
|
L'7', L'6', L'x', 2,
|
|
L'7', L'7', L'x', 2,
|
|
L'7', L'8', L'x', 2,
|
|
L'7', L'9', L'x', 2,
|
|
L'8', L'0', L'x', 2,
|
|
L'8', L'1', L'x', 2,
|
|
L'8', L'2', L'x', 2,
|
|
L'8', L'3', L'x', 2,
|
|
L'8', L'4', L'x', 2,
|
|
L'8', L'5', L'x', 2,
|
|
L'8', L'6', L'x', 2,
|
|
L'8', L'7', L'x', 2,
|
|
L'8', L'8', L'x', 2,
|
|
L'8', L'9', L'x', 2,
|
|
L'9', L'0', L'x', 2,
|
|
L'9', L'1', L'x', 2,
|
|
L'9', L'2', L'x', 2,
|
|
L'9', L'3', L'x', 2,
|
|
L'9', L'4', L'x', 2,
|
|
L'9', L'5', L'x', 2,
|
|
L'9', L'6', L'x', 2,
|
|
L'9', L'7', L'x', 2,
|
|
L'9', L'8', L'x', 2,
|
|
L'9', L'9', L'x', 2,
|
|
L'1', L'0', L'0', 3,
|
|
L'1', L'0', L'1', 3,
|
|
L'1', L'0', L'2', 3,
|
|
L'1', L'0', L'3', 3,
|
|
L'1', L'0', L'4', 3,
|
|
L'1', L'0', L'5', 3,
|
|
L'1', L'0', L'6', 3,
|
|
L'1', L'0', L'7', 3,
|
|
L'1', L'0', L'8', 3,
|
|
L'1', L'0', L'9', 3,
|
|
L'1', L'1', L'0', 3,
|
|
L'1', L'1', L'1', 3,
|
|
L'1', L'1', L'2', 3,
|
|
L'1', L'1', L'3', 3,
|
|
L'1', L'1', L'4', 3,
|
|
L'1', L'1', L'5', 3,
|
|
L'1', L'1', L'6', 3,
|
|
L'1', L'1', L'7', 3,
|
|
L'1', L'1', L'8', 3,
|
|
L'1', L'1', L'9', 3,
|
|
L'1', L'2', L'0', 3,
|
|
L'1', L'2', L'1', 3,
|
|
L'1', L'2', L'2', 3,
|
|
L'1', L'2', L'3', 3,
|
|
L'1', L'2', L'4', 3,
|
|
L'1', L'2', L'5', 3,
|
|
L'1', L'2', L'6', 3,
|
|
L'1', L'2', L'7', 3,
|
|
L'1', L'2', L'8', 3,
|
|
L'1', L'2', L'9', 3,
|
|
L'1', L'3', L'0', 3,
|
|
L'1', L'3', L'1', 3,
|
|
L'1', L'3', L'2', 3,
|
|
L'1', L'3', L'3', 3,
|
|
L'1', L'3', L'4', 3,
|
|
L'1', L'3', L'5', 3,
|
|
L'1', L'3', L'6', 3,
|
|
L'1', L'3', L'7', 3,
|
|
L'1', L'3', L'8', 3,
|
|
L'1', L'3', L'9', 3,
|
|
L'1', L'4', L'0', 3,
|
|
L'1', L'4', L'1', 3,
|
|
L'1', L'4', L'2', 3,
|
|
L'1', L'4', L'3', 3,
|
|
L'1', L'4', L'4', 3,
|
|
L'1', L'4', L'5', 3,
|
|
L'1', L'4', L'6', 3,
|
|
L'1', L'4', L'7', 3,
|
|
L'1', L'4', L'8', 3,
|
|
L'1', L'4', L'9', 3,
|
|
L'1', L'5', L'0', 3,
|
|
L'1', L'5', L'1', 3,
|
|
L'1', L'5', L'2', 3,
|
|
L'1', L'5', L'3', 3,
|
|
L'1', L'5', L'4', 3,
|
|
L'1', L'5', L'5', 3,
|
|
L'1', L'5', L'6', 3,
|
|
L'1', L'5', L'7', 3,
|
|
L'1', L'5', L'8', 3,
|
|
L'1', L'5', L'9', 3,
|
|
L'1', L'6', L'0', 3,
|
|
L'1', L'6', L'1', 3,
|
|
L'1', L'6', L'2', 3,
|
|
L'1', L'6', L'3', 3,
|
|
L'1', L'6', L'4', 3,
|
|
L'1', L'6', L'5', 3,
|
|
L'1', L'6', L'6', 3,
|
|
L'1', L'6', L'7', 3,
|
|
L'1', L'6', L'8', 3,
|
|
L'1', L'6', L'9', 3,
|
|
L'1', L'7', L'0', 3,
|
|
L'1', L'7', L'1', 3,
|
|
L'1', L'7', L'2', 3,
|
|
L'1', L'7', L'3', 3,
|
|
L'1', L'7', L'4', 3,
|
|
L'1', L'7', L'5', 3,
|
|
L'1', L'7', L'6', 3,
|
|
L'1', L'7', L'7', 3,
|
|
L'1', L'7', L'8', 3,
|
|
L'1', L'7', L'9', 3,
|
|
L'1', L'8', L'0', 3,
|
|
L'1', L'8', L'1', 3,
|
|
L'1', L'8', L'2', 3,
|
|
L'1', L'8', L'3', 3,
|
|
L'1', L'8', L'4', 3,
|
|
L'1', L'8', L'5', 3,
|
|
L'1', L'8', L'6', 3,
|
|
L'1', L'8', L'7', 3,
|
|
L'1', L'8', L'8', 3,
|
|
L'1', L'8', L'9', 3,
|
|
L'1', L'9', L'0', 3,
|
|
L'1', L'9', L'1', 3,
|
|
L'1', L'9', L'2', 3,
|
|
L'1', L'9', L'3', 3,
|
|
L'1', L'9', L'4', 3,
|
|
L'1', L'9', L'5', 3,
|
|
L'1', L'9', L'6', 3,
|
|
L'1', L'9', L'7', 3,
|
|
L'1', L'9', L'8', 3,
|
|
L'1', L'9', L'9', 3,
|
|
L'2', L'0', L'0', 3,
|
|
L'2', L'0', L'1', 3,
|
|
L'2', L'0', L'2', 3,
|
|
L'2', L'0', L'3', 3,
|
|
L'2', L'0', L'4', 3,
|
|
L'2', L'0', L'5', 3,
|
|
L'2', L'0', L'6', 3,
|
|
L'2', L'0', L'7', 3,
|
|
L'2', L'0', L'8', 3,
|
|
L'2', L'0', L'9', 3,
|
|
L'2', L'1', L'0', 3,
|
|
L'2', L'1', L'1', 3,
|
|
L'2', L'1', L'2', 3,
|
|
L'2', L'1', L'3', 3,
|
|
L'2', L'1', L'4', 3,
|
|
L'2', L'1', L'5', 3,
|
|
L'2', L'1', L'6', 3,
|
|
L'2', L'1', L'7', 3,
|
|
L'2', L'1', L'8', 3,
|
|
L'2', L'1', L'9', 3,
|
|
L'2', L'2', L'0', 3,
|
|
L'2', L'2', L'1', 3,
|
|
L'2', L'2', L'2', 3,
|
|
L'2', L'2', L'3', 3,
|
|
L'2', L'2', L'4', 3,
|
|
L'2', L'2', L'5', 3,
|
|
L'2', L'2', L'6', 3,
|
|
L'2', L'2', L'7', 3,
|
|
L'2', L'2', L'8', 3,
|
|
L'2', L'2', L'9', 3,
|
|
L'2', L'3', L'0', 3,
|
|
L'2', L'3', L'1', 3,
|
|
L'2', L'3', L'2', 3,
|
|
L'2', L'3', L'3', 3,
|
|
L'2', L'3', L'4', 3,
|
|
L'2', L'3', L'5', 3,
|
|
L'2', L'3', L'6', 3,
|
|
L'2', L'3', L'7', 3,
|
|
L'2', L'3', L'8', 3,
|
|
L'2', L'3', L'9', 3,
|
|
L'2', L'4', L'0', 3,
|
|
L'2', L'4', L'1', 3,
|
|
L'2', L'4', L'2', 3,
|
|
L'2', L'4', L'3', 3,
|
|
L'2', L'4', L'4', 3,
|
|
L'2', L'4', L'5', 3,
|
|
L'2', L'4', L'6', 3,
|
|
L'2', L'4', L'7', 3,
|
|
L'2', L'4', L'8', 3,
|
|
L'2', L'4', L'9', 3,
|
|
L'2', L'5', L'0', 3,
|
|
L'2', L'5', L'1', 3,
|
|
L'2', L'5', L'2', 3,
|
|
L'2', L'5', L'3', 3,
|
|
L'2', L'5', L'4', 3,
|
|
L'2', L'5', L'5', 3
|
|
};
|
|
|
|
VOID
|
|
NetworkToUnicode(
|
|
IN DWORD dwAddress,
|
|
OUT PWCHAR pwszBuffer
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function takes an Internet address structure specified by the
|
|
in parameter. It returns an UNICODE string representing the address
|
|
in ".'' notation as "a.b.c.d". Note that unlike inet_ntoa, this requires
|
|
the user to supply a buffer. This is good because all of the TLS crap
|
|
now can be thrown out - and the function is leaner and meaner. Ofcourse
|
|
this does make it incompatible with inet_ntoa since the parameters are
|
|
different. And it makes it less safe since bad buffers will cause an
|
|
a.v.
|
|
|
|
Arguments:
|
|
|
|
iaAddress A structure which represents an Internet host address.
|
|
pwszBufer User supplied buffer to ATLEAST WCHAR[16]. Since there is
|
|
no try/except - you will crash if you dont supply a "good"
|
|
buffer. The formatted address is returned in this buffer
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PBYTE p;
|
|
PWCHAR b;
|
|
|
|
|
|
b = pwszBuffer;
|
|
|
|
//
|
|
// In an unrolled loop, calculate the string value for each of the four
|
|
// bytes in an IP address. Note that for values less than 100 we will
|
|
// do one or two extra assignments, but we save a test/jump with this
|
|
// algorithm.
|
|
//
|
|
|
|
p = (PBYTE)&dwAddress;
|
|
|
|
*b = NToUWCharStrings[*p][0];
|
|
*(b+1) = NToUWCharStrings[*p][1];
|
|
*(b+2) = NToUWCharStrings[*p][2];
|
|
b += NToUWCharStrings[*p][3];
|
|
*b++ = L'.';
|
|
|
|
p++;
|
|
*b = NToUWCharStrings[*p][0];
|
|
*(b+1) = NToUWCharStrings[*p][1];
|
|
*(b+2) = NToUWCharStrings[*p][2];
|
|
b += NToUWCharStrings[*p][3];
|
|
*b++ = L'.';
|
|
|
|
p++;
|
|
*b = NToUWCharStrings[*p][0];
|
|
*(b+1) = NToUWCharStrings[*p][1];
|
|
*(b+2) = NToUWCharStrings[*p][2];
|
|
b += NToUWCharStrings[*p][3];
|
|
*b++ = L'.';
|
|
|
|
p++;
|
|
*b = NToUWCharStrings[*p][0];
|
|
*(b+1) = NToUWCharStrings[*p][1];
|
|
*(b+2) = NToUWCharStrings[*p][2];
|
|
b += NToUWCharStrings[*p][3];
|
|
*b = UNICODE_NULL;
|
|
}
|
|
|
|
DWORD
|
|
UnicodeToNetwork(
|
|
PWCHAR pwszAddr
|
|
)
|
|
{
|
|
CHAR szAddr[MAX_TOKEN_LENGTH + 1];
|
|
INT iCount;
|
|
|
|
iCount = WideCharToMultiByte(CP_ACP,
|
|
0,
|
|
pwszAddr,
|
|
wcslen(pwszAddr),
|
|
szAddr,
|
|
MAX_TOKEN_LENGTH,
|
|
NULL,
|
|
NULL);
|
|
|
|
szAddr[iCount] = '\0';
|
|
|
|
return inet_addr(szAddr);
|
|
}
|
|
|