windows-nt/Source/XPSP1/NT/net/tcpip/tpipv6/ipv6mon/6to4.c
2020-09-26 16:20:57 +08:00

1252 lines
32 KiB
C

//=============================================================================
// Copyright (c) 2000 Microsoft Corporation
// Abstract:
// This module implements 6to4 configuration commands.
//=============================================================================
#include "precomp.h"
#pragma hdrstop
#define KEY_ENABLE_RESOLUTION L"EnableResolution"
#define KEY_ENABLE_ROUTING L"EnableRouting"
#define KEY_ENABLE_SITELOCALS L"EnableSiteLocals"
#define KEY_RESOLUTION_INTERVAL L"ResolutionInterval"
#define KEY_UNDO_ON_STOP L"UndoOnStop"
#define KEY_RELAY_NAME L"RelayName"
PWCHAR
pwszStateString[] = {
TOKEN_VALUE_DEFAULT,
TOKEN_VALUE_AUTOMATIC,
TOKEN_VALUE_ENABLED,
TOKEN_VALUE_DISABLED,
};
// The guid for this context
//
GUID g_Ip6to4Guid = IP6TO4_GUID;
// The commands supported in this context
//
CMD_ENTRY g_Ip6to4SetCmdTable[] =
{
CREATE_CMD_ENTRY(IP6TO4_SET_INTERFACE,Ip6to4HandleSetInterface),
CREATE_CMD_ENTRY(IP6TO4_SET_RELAY, Ip6to4HandleSetRelay),
CREATE_CMD_ENTRY(IP6TO4_SET_ROUTING, Ip6to4HandleSetRouting),
CREATE_CMD_ENTRY(IP6TO4_SET_STATE, Ip6to4HandleSetState),
};
CMD_ENTRY g_Ip6to4ShowCmdTable[] =
{
CREATE_CMD_ENTRY(IP6TO4_SHOW_INTERFACE,Ip6to4HandleShowInterface),
CREATE_CMD_ENTRY(IP6TO4_SHOW_RELAY, Ip6to4HandleShowRelay),
CREATE_CMD_ENTRY(IP6TO4_SHOW_ROUTING, Ip6to4HandleShowRouting),
CREATE_CMD_ENTRY(IP6TO4_SHOW_STATE, Ip6to4HandleShowState),
};
CMD_GROUP_ENTRY g_Ip6to4CmdGroups[] =
{
CREATE_CMD_GROUP_ENTRY(GROUP_SET, g_Ip6to4SetCmdTable),
CREATE_CMD_GROUP_ENTRY(GROUP_SHOW, g_Ip6to4ShowCmdTable),
};
ULONG g_ulIp6to4NumGroups = sizeof(g_Ip6to4CmdGroups)/sizeof(CMD_GROUP_ENTRY);
CMD_ENTRY g_Ip6to4TopCmds[] =
{
CREATE_CMD_ENTRY(IP6TO4_RESET, Ip6to4HandleReset),
};
ULONG g_ulNumIp6to4TopCmds = sizeof(g_Ip6to4TopCmds)/sizeof(CMD_ENTRY);
#if 0
TOKEN_VALUE AdminStates[] = {
{ VAL_AUTOMATIC, TOKEN_AUTOMATIC },
{ VAL_ENABLED, TOKEN_ENABLED },
{ VAL_DISABLED, TOKEN_DISABLED },
{ VAL_DEFAULT, TOKEN_DEFAULT },
};
#endif
BOOL
GetString(
IN HKEY hKey,
IN LPCTSTR lpName,
IN PWCHAR pwszBuff,
IN ULONG ulLength)
{
DWORD dwErr, dwType;
ULONG ulSize, ulValue;
WCHAR buff[NI_MAXHOST];
ulSize = sizeof(ulValue);
dwErr = RegQueryValueEx(hKey, lpName, NULL, &dwType, (PBYTE)pwszBuff,
&ulLength);
if (dwErr != ERROR_SUCCESS) {
return FALSE;
}
if (dwType != REG_SZ) {
return FALSE;
}
return TRUE;
}
ULONG
GetInteger(
IN HKEY hKey,
IN LPCTSTR lpName,
IN ULONG ulDefault)
{
DWORD dwErr, dwType;
ULONG ulSize, ulValue;
char buff[20];
ulSize = sizeof(ulValue);
dwErr = RegQueryValueEx(hKey, lpName, NULL, &dwType, (PBYTE)&ulValue,
&ulSize);
if (dwErr != ERROR_SUCCESS) {
return ulDefault;
}
if (dwType != REG_DWORD) {
return ulDefault;
}
return ulValue;
}
DWORD
SetInteger(
IN HKEY hKey,
IN LPCTSTR lpName,
IN ULONG ulValue)
{
DWORD dwErr;
ULONG ulOldValue;
ulOldValue = GetInteger(hKey, lpName, VAL_DEFAULT);
if (ulValue == ulOldValue) {
return NO_ERROR;
}
if (ulValue == VAL_DEFAULT) {
dwErr = RegDeleteValue(hKey, lpName);
if (dwErr == ERROR_FILE_NOT_FOUND) {
dwErr = NO_ERROR;
}
} else {
dwErr = RegSetValueEx(hKey, lpName, 0, REG_DWORD, (PBYTE)&ulValue,
sizeof(ulValue));
}
return dwErr;
}
DWORD
SetString(
IN HKEY hKey,
IN LPCTSTR lpName,
IN PWCHAR pwcValue)
{
DWORD dwErr;
if (!pwcValue[0] || !_wcsicmp(pwcValue, TOKEN_VALUE_DEFAULT)) {
dwErr = RegDeleteValue(hKey, lpName);
if (dwErr == ERROR_FILE_NOT_FOUND) {
dwErr = NO_ERROR;
}
} else {
dwErr = RegSetValueEx(hKey, lpName, 0, REG_SZ, (PBYTE)pwcValue,
(wcslen(pwcValue)+1) * sizeof(WCHAR));
}
return dwErr;
}
DWORD
WINAPI
Ip6to4StartHelper(
IN CONST GUID *pguidParent,
IN DWORD dwVersion)
/*++
Routine Description
Used to initialize the helper.
Arguments
pguidParent Ifmon's guid
pfnRegisterContext
Return Value
NO_ERROR
other error code
--*/
{
DWORD dwErr = NO_ERROR;
NS_CONTEXT_ATTRIBUTES attMyAttributes;
// Initialize
//
ZeroMemory(&attMyAttributes, sizeof(attMyAttributes));
attMyAttributes.pwszContext = L"6to4";
attMyAttributes.guidHelper = g_Ip6to4Guid;
attMyAttributes.dwVersion = IP6TO4_VERSION;
attMyAttributes.dwFlags = 0;
attMyAttributes.pfnDumpFn = Ip6to4Dump;
attMyAttributes.ulNumTopCmds= g_ulNumIp6to4TopCmds;
attMyAttributes.pTopCmds = (CMD_ENTRY (*)[])&g_Ip6to4TopCmds;
attMyAttributes.ulNumGroups = g_ulIp6to4NumGroups;
attMyAttributes.pCmdGroups = (CMD_GROUP_ENTRY (*)[])&g_Ip6to4CmdGroups;
dwErr = RegisterContext( &attMyAttributes );
if (dwErr != NO_ERROR) {
return dwErr;
}
//
// Register ISATAP context.
//
return IsatapStartHelper(pguidParent, dwVersion);
}
DWORD
Ip6to4PokeService()
{
SC_HANDLE hService, hSCManager;
BOOL bResult;
SERVICE_STATUS ServiceStatus;
DWORD dwErr = NO_ERROR;
hSCManager = OpenSCManager(NULL, NULL, GENERIC_READ);
if (hSCManager == NULL) {
return GetLastError();
}
do {
hService = OpenService(hSCManager, L"6to4", SERVICE_ALL_ACCESS);
if (hService == NULL) {
dwErr = GetLastError();
break;
}
// Tell the 6to4 service to re-read its config info
if (!ControlService(hService,
SERVICE_CONTROL_PARAMCHANGE,
&ServiceStatus)) {
dwErr = GetLastError();
}
CloseServiceHandle(hService);
} while (FALSE);
CloseServiceHandle(hSCManager);
return dwErr;
}
DWORD
Ip6to4StopService()
{
SC_HANDLE hService, hSCManager;
BOOL bResult;
SERVICE_STATUS ServiceStatus;
DWORD dwErr = NO_ERROR;
hSCManager = OpenSCManager(NULL, NULL, GENERIC_READ);
if (hSCManager == NULL) {
return GetLastError();
}
do {
hService = OpenService(hSCManager, L"6to4", SERVICE_ALL_ACCESS);
if (hService == NULL) {
dwErr = GetLastError();
break;
}
// Tell the 6to4 service to stop
if (!ControlService(hService,
SERVICE_CONTROL_STOP,
&ServiceStatus)) {
dwErr = GetLastError();
}
CloseServiceHandle(hService);
} while (FALSE);
CloseServiceHandle(hSCManager);
return dwErr;
}
DWORD
Ip6to4QueryServiceStatus(
IN LPSERVICE_STATUS pStatus)
{
SC_HANDLE hService, hSCManager;
BOOL bResult;
SERVICE_STATUS ServiceStatus;
DWORD dwErr = NO_ERROR;
hSCManager = OpenSCManager(NULL, NULL, GENERIC_READ);
if (hSCManager == NULL) {
return GetLastError();
}
do {
hService = OpenService(hSCManager, L"6to4", GENERIC_READ);
if (hService == NULL) {
dwErr = GetLastError();
break;
}
if (!QueryServiceStatus(hService, pStatus)) {
dwErr = GetLastError();
}
CloseServiceHandle(hService);
} while (FALSE);
CloseServiceHandle(hSCManager);
return dwErr;
}
DWORD
Ip6to4StartService()
{
SC_HANDLE hService, hSCManager;
BOOL bResult;
SERVICE_STATUS ServiceStatus;
DWORD dwErr = NO_ERROR;
hSCManager = OpenSCManager(NULL, NULL, GENERIC_READ);
if (hSCManager == NULL) {
return GetLastError();
}
do {
hService = OpenService(hSCManager, L"6to4", SERVICE_ALL_ACCESS);
if (hService == NULL) {
dwErr = GetLastError();
break;
}
// Tell the 6to4 service to start
if (!StartService(hService, 0, NULL)) {
dwErr = GetLastError();
}
CloseServiceHandle(hService);
} while (FALSE);
CloseServiceHandle(hSCManager);
return dwErr;
}
TOKEN_VALUE rgtvEnums[] = {
{ TOKEN_VALUE_AUTOMATIC, VAL_AUTOMATIC },
{ TOKEN_VALUE_ENABLED, VAL_ENABLED },
{ TOKEN_VALUE_DISABLED, VAL_DISABLED },
{ TOKEN_VALUE_DEFAULT, VAL_DEFAULT },
};
#define BM_ENABLE_ROUTING 0x01
#define BM_ENABLE_SITELOCALS 0x02
DWORD
Ip6to4HandleSetInterface(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
{
DWORD dwErr = NO_ERROR;
HKEY hInterfaces, hIf;
STATE stEnableRouting;
DWORD dwBitVector = 0;
TAG_TYPE pttTags[] = {{TOKEN_NAME, TRUE, FALSE},
{TOKEN_ROUTING, TRUE, FALSE}};
DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
DWORD dwNumArg;
DWORD i;
WCHAR wszInterfaceName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
DWORD dwBufferSize = sizeof(wszInterfaceName);
PWCHAR wszIfFriendlyName = NULL;
// Parse arguments
dwErr = PreprocessCommand(g_hModule,
ppwcArguments,
dwCurrentIndex,
dwArgCount,
pttTags,
sizeof(pttTags)/sizeof(TAG_TYPE),
2,
sizeof(pttTags)/sizeof(TAG_TYPE),
rgdwTagType );
if (dwErr isnot NO_ERROR) {
return dwErr;
}
for (i=0; i<dwArgCount-dwCurrentIndex; i++) {
switch(rgdwTagType[i]) {
case 0: // NAME
dwErr = Connect();
if (dwErr isnot NO_ERROR) {
break;
}
dwErr = GetIfNameFromFriendlyName(ppwcArguments[i + dwCurrentIndex],
wszInterfaceName, &dwBufferSize);
Disconnect();
if (dwErr isnot NO_ERROR)
{
DisplayMessage(g_hModule, EMSG_INVALID_INTERFACE,
ppwcArguments[i + dwCurrentIndex]);
dwErr = ERROR_SUPPRESS_OUTPUT;
break;
}
wszIfFriendlyName = ppwcArguments[i + dwCurrentIndex];
break;
case 1: // STATE
dwErr = MatchEnumTag(NULL,
ppwcArguments[dwCurrentIndex + i],
NUM_TOKENS_IN_TABLE(rgtvEnums),
rgtvEnums,
(PDWORD)&stEnableRouting);
if (dwErr isnot NO_ERROR) {
dwErr = ERROR_INVALID_PARAMETER;
break;
}
dwBitVector |= BM_ENABLE_ROUTING;
break;
default:
dwErr = ERROR_INVALID_SYNTAX;
break;
}
if (dwErr isnot NO_ERROR) {
return dwErr;
}
}
// Now do the sets
dwErr = RegCreateKeyEx(HKEY_LOCAL_MACHINE, KEY_INTERFACES, 0,
NULL, 0, KEY_ALL_ACCESS, NULL, &hInterfaces, NULL);
if (dwErr != NO_ERROR) {
return dwErr;
}
dwErr = RegCreateKeyEx(hInterfaces, wszInterfaceName, 0,
NULL, 0, KEY_ALL_ACCESS, NULL, &hIf, NULL);
if (dwErr != NO_ERROR) {
RegCloseKey(hInterfaces);
return dwErr;
}
if (dwBitVector & BM_ENABLE_ROUTING) {
dwErr = SetInteger(hIf, KEY_ENABLE_ROUTING, stEnableRouting);
if (dwErr != NO_ERROR)
return dwErr;
}
RegCloseKey(hIf);
RegCloseKey(hInterfaces);
Ip6to4PokeService();
return ERROR_OKAY;
}
DWORD
Ip6to4HandleSetRouting(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
{
DWORD dwErr = NO_ERROR;
HKEY hGlobal;
STATE stEnableRouting;
STATE stEnableSiteLocals;
DWORD dwBitVector = 0;
TAG_TYPE pttTags[] = {{TOKEN_ROUTING, FALSE, FALSE},
{TOKEN_SITELOCALS, FALSE, FALSE}};
DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
DWORD dwNumArg;
DWORD i;
// Parse arguments
dwErr = PreprocessCommand(g_hModule,
ppwcArguments,
dwCurrentIndex,
dwArgCount,
pttTags,
sizeof(pttTags)/sizeof(TAG_TYPE),
1,
sizeof(pttTags)/sizeof(TAG_TYPE),
rgdwTagType );
if (dwErr isnot NO_ERROR) {
return dwErr;
}
for (i=0; i<dwArgCount-dwCurrentIndex; i++) {
switch(rgdwTagType[i]) {
case 0: // STATE
dwErr = MatchEnumTag(NULL,
ppwcArguments[dwCurrentIndex + i],
NUM_TOKENS_IN_TABLE(rgtvEnums),
rgtvEnums,
(PDWORD)&stEnableRouting);
if (dwErr isnot NO_ERROR) {
dwErr = ERROR_INVALID_PARAMETER;
break;
}
dwBitVector |= BM_ENABLE_ROUTING;
break;
case 1: // SITELOCALS
dwErr = MatchEnumTag(NULL,
ppwcArguments[dwCurrentIndex + i],
NUM_TOKENS_IN_TABLE(rgtvEnums),
rgtvEnums,
(PDWORD)&stEnableSiteLocals);
if (dwErr isnot NO_ERROR) {
dwErr = ERROR_INVALID_PARAMETER;
break;
}
dwBitVector |= BM_ENABLE_SITELOCALS;
break;
default:
dwErr = ERROR_INVALID_SYNTAX;
break;
}
if (dwErr isnot NO_ERROR) {
return dwErr;
}
}
// Now do the sets
dwErr = RegCreateKeyEx(HKEY_LOCAL_MACHINE, KEY_GLOBAL, 0,
NULL, 0, KEY_ALL_ACCESS, NULL, &hGlobal, NULL);
if (dwErr != NO_ERROR) {
return dwErr;
}
if (dwBitVector & BM_ENABLE_ROUTING) {
dwErr = SetInteger(hGlobal, KEY_ENABLE_ROUTING, stEnableRouting);
if (dwErr != NO_ERROR)
return dwErr;
}
if (dwBitVector & BM_ENABLE_SITELOCALS) {
dwErr = SetInteger(hGlobal, KEY_ENABLE_SITELOCALS, stEnableSiteLocals);
if (dwErr != NO_ERROR)
return dwErr;
}
RegCloseKey(hGlobal);
Ip6to4PokeService();
return ERROR_OKAY;
}
#define BM_ENABLE_RESOLUTION 0x01
#define BM_RELAY_NAME 0x02
#define BM_RESOLUTION_INTERVAL 0x04
DWORD
Ip6to4HandleSetRelay(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
{
DWORD dwErr = NO_ERROR;
HKEY hGlobal;
STATE stEnableResolution;
ULONG ulResolutionInterval;
PWCHAR pwszRelayName;
DWORD dwBitVector = 0;
TAG_TYPE pttTags[] = {{TOKEN_RELAY_NAME, FALSE, FALSE},
{TOKEN_STATE, FALSE, FALSE},
{TOKEN_INTERVAL, FALSE, FALSE}};
DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
DWORD dwNumArg;
DWORD i;
// Parse arguments
dwErr = PreprocessCommand(g_hModule,
ppwcArguments,
dwCurrentIndex,
dwArgCount,
pttTags,
sizeof(pttTags)/sizeof(TAG_TYPE),
1,
sizeof(pttTags)/sizeof(TAG_TYPE),
rgdwTagType );
if (dwErr isnot NO_ERROR) {
return dwErr;
}
for (i=0; i<dwArgCount-dwCurrentIndex; i++) {
switch(rgdwTagType[i]) {
case 0: // RELAYNAME
pwszRelayName = ppwcArguments[dwCurrentIndex + i];
dwBitVector |= BM_RELAY_NAME;
break;
case 1: // STATE
dwErr = MatchEnumTag(NULL,
ppwcArguments[dwCurrentIndex + i],
NUM_TOKENS_IN_TABLE(rgtvEnums),
rgtvEnums,
(PDWORD)&stEnableResolution);
if (dwErr isnot NO_ERROR) {
dwErr = ERROR_INVALID_PARAMETER;
break;
}
dwBitVector |= BM_ENABLE_RESOLUTION;
break;
case 2: // INTERVAL
ulResolutionInterval = wcstoul(ppwcArguments[dwCurrentIndex + i],
NULL, 10);
dwBitVector |= BM_RESOLUTION_INTERVAL;
break;
default:
dwErr = ERROR_INVALID_SYNTAX;
break;
}
if (dwErr isnot NO_ERROR) {
return dwErr;
}
}
// Now do the sets
dwErr = RegCreateKeyEx(HKEY_LOCAL_MACHINE, KEY_GLOBAL, 0,
NULL, 0, KEY_ALL_ACCESS, NULL, &hGlobal, NULL);
if (dwErr != NO_ERROR) {
return dwErr;
}
if (dwBitVector & BM_ENABLE_RESOLUTION) {
dwErr = SetInteger(hGlobal, KEY_ENABLE_RESOLUTION, stEnableResolution);
if (dwErr != NO_ERROR)
return dwErr;
}
if (dwBitVector & BM_RELAY_NAME) {
dwErr = SetString(hGlobal, KEY_RELAY_NAME, pwszRelayName);
if (dwErr != NO_ERROR)
return dwErr;
}
if (dwBitVector & BM_RESOLUTION_INTERVAL) {
dwErr = SetInteger(hGlobal, KEY_RESOLUTION_INTERVAL, ulResolutionInterval);
if (dwErr != NO_ERROR)
return dwErr;
}
RegCloseKey(hGlobal);
Ip6to4PokeService();
return ERROR_OKAY;
}
#define BM_ENABLE_6TO4 0x01
#define BM_UNDO_ON_STOP 0x02
DWORD
Ip6to4HandleSetState(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
{
DWORD dwErr = NO_ERROR;
HKEY hGlobal;
STATE stEnable6to4;
STATE stUndoOnStop;
DWORD dwBitVector = 0;
TAG_TYPE pttTags[] = {{TOKEN_STATE, FALSE, FALSE},
{TOKEN_UNDO_ON_STOP, FALSE, FALSE}};
DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
DWORD dwNumArg;
DWORD i;
// Parse arguments
dwErr = PreprocessCommand(g_hModule,
ppwcArguments,
dwCurrentIndex,
dwArgCount,
pttTags,
sizeof(pttTags)/sizeof(TAG_TYPE),
1,
sizeof(pttTags)/sizeof(TAG_TYPE),
rgdwTagType );
if (dwErr isnot NO_ERROR) {
return dwErr;
}
for (i=0; i<dwArgCount-dwCurrentIndex; i++) {
switch(rgdwTagType[i]) {
case 0: // STATE
dwErr = MatchEnumTag(NULL,
ppwcArguments[dwCurrentIndex + i],
NUM_TOKENS_IN_TABLE(rgtvEnums),
rgtvEnums,
(PDWORD)&stEnable6to4);
if (dwErr isnot NO_ERROR) {
dwErr = ERROR_INVALID_PARAMETER;
break;
}
dwBitVector |= BM_ENABLE_6TO4;
break;
case 1: // UNDOONSTOP
dwErr = MatchEnumTag(NULL,
ppwcArguments[dwCurrentIndex + i],
NUM_TOKENS_IN_TABLE(rgtvEnums),
rgtvEnums,
(PDWORD)&stUndoOnStop);
if (dwErr isnot NO_ERROR) {
dwErr = ERROR_INVALID_PARAMETER;
break;
}
dwBitVector |= BM_UNDO_ON_STOP;
break;
default:
dwErr = ERROR_INVALID_SYNTAX;
break;
}
if (dwErr isnot NO_ERROR) {
return dwErr;
}
}
// Now do the sets
dwErr = RegCreateKeyEx(HKEY_LOCAL_MACHINE, KEY_GLOBAL, 0,
NULL, 0, KEY_ALL_ACCESS, NULL, &hGlobal, NULL);
if (dwErr != NO_ERROR) {
return dwErr;
}
if (dwBitVector & BM_ENABLE_6TO4) {
if (stEnable6to4 == VAL_ENABLED) {
dwErr = Ip6to4StartService();
} else if (stEnable6to4 == VAL_DISABLED) {
dwErr = Ip6to4StopService();
}
}
if (dwBitVector & BM_UNDO_ON_STOP) {
dwErr = SetInteger(hGlobal, KEY_UNDO_ON_STOP, stUndoOnStop);
if (dwErr != NO_ERROR)
return dwErr;
}
RegCloseKey(hGlobal);
Ip6to4PokeService();
return ERROR_OKAY;
}
DWORD
ShowInterfaceConfig(
IN BOOL bDump)
{
DWORD dwErr = NO_ERROR;
HKEY hInterfaces, hIf;
STATE stEnableRouting;
int i;
WCHAR wszInterfaceName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
DWORD dwBufferSize;
WCHAR wszIfFriendlyName[MAX_INTERFACE_NAME_LEN + 1];
dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_INTERFACES, 0, GENERIC_READ,
&hInterfaces);
if (dwErr != NO_ERROR) {
if (!bDump) {
DisplayMessage(g_hModule, MSG_IP_NO_ENTRIES);
}
return ERROR_SUPPRESS_OUTPUT;
}
dwErr = Connect();
if (dwErr isnot NO_ERROR) {
return dwErr;
}
for (i=0; ; i++) {
dwBufferSize = MAX_INTERFACE_NAME_LEN + 1;
dwErr = RegEnumKeyEx(hInterfaces, i, wszInterfaceName, &dwBufferSize,
0, NULL, NULL, NULL);
if (dwErr != NO_ERROR) {
if (dwErr == ERROR_NO_MORE_ITEMS) {
dwErr = NO_ERROR;
}
break;
}
dwBufferSize = sizeof(wszIfFriendlyName);
dwErr = GetFriendlyNameFromIfName(wszInterfaceName,
wszIfFriendlyName,
&dwBufferSize);
if (dwErr != NO_ERROR) {
wcscpy(wszIfFriendlyName, wszInterfaceName);
}
dwErr = RegOpenKeyEx(hInterfaces, wszInterfaceName, 0, GENERIC_READ,
&hIf);
if (dwErr != NO_ERROR) {
break;
}
stEnableRouting = GetInteger(hIf,
KEY_ENABLE_ROUTING,
VAL_DEFAULT);
if (bDump) {
if (stEnableRouting != VAL_DEFAULT) {
DisplayMessageT(DMP_IP6TO4_SET_INTERFACE);
DisplayMessageT(DMP_QUOTED_STRING_ARG,
TOKEN_NAME,
wszIfFriendlyName);
DisplayMessageT(DMP_STRING_ARG,
TOKEN_ROUTING,
pwszStateString[stEnableRouting]);
DisplayMessage(g_hModule, MSG_NEWLINE);
}
} else {
if (i==0) {
DisplayMessage(g_hModule, MSG_INTERFACE_HEADER);
}
DisplayMessage(g_hModule, MSG_INTERFACE_ROUTING_STATE,
pwszStateString[stEnableRouting],
wszIfFriendlyName);
}
}
RegCloseKey(hInterfaces);
Disconnect();
return dwErr;
}
DWORD
Ip6to4HandleShowInterface(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
{
return ShowInterfaceConfig(FALSE);
}
DWORD
ShowRoutingConfig(
IN BOOL bDump)
{
DWORD dwErr = NO_ERROR;
HKEY hGlobal;
STATE stEnableRouting;
STATE stEnableSiteLocals;
dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_GLOBAL, 0, KEY_QUERY_VALUE,
&hGlobal);
if (dwErr != NO_ERROR) {
hGlobal = INVALID_HANDLE_VALUE;
dwErr = NO_ERROR;
}
stEnableRouting = GetInteger(hGlobal,
KEY_ENABLE_ROUTING,
VAL_DEFAULT);
stEnableSiteLocals = GetInteger(hGlobal,
KEY_ENABLE_SITELOCALS,
VAL_DEFAULT);
RegCloseKey(hGlobal);
if (bDump) {
if ((stEnableRouting != VAL_DEFAULT)
|| (stEnableSiteLocals != VAL_DEFAULT)) {
DisplayMessageT(DMP_IP6TO4_SET_ROUTING);
if (stEnableRouting != VAL_DEFAULT) {
DisplayMessageT(DMP_STRING_ARG,
TOKEN_ROUTING,
pwszStateString[stEnableRouting]);
}
if (stEnableSiteLocals != VAL_DEFAULT) {
DisplayMessageT(DMP_STRING_ARG,
TOKEN_SITELOCALS,
pwszStateString[stEnableSiteLocals]);
}
DisplayMessage(g_hModule, MSG_NEWLINE);
}
} else {
DisplayMessage(g_hModule, MSG_ROUTING_STATE,
pwszStateString[stEnableRouting]);
DisplayMessage(g_hModule, MSG_SITELOCALS_STATE,
pwszStateString[stEnableSiteLocals]);
}
return dwErr;
}
DWORD
Ip6to4HandleShowRouting(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
{
return ShowRoutingConfig(FALSE);
}
DWORD
ShowRelayConfig(
IN BOOL bDump)
{
DWORD dwErr = NO_ERROR;
HKEY hGlobal;
STATE stEnableResolution;
ULONG ulResolutionInterval;
WCHAR pwszRelayName[NI_MAXHOST];
BOOL bHaveRelayName;
dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_GLOBAL, 0, KEY_QUERY_VALUE,
&hGlobal);
if (dwErr != NO_ERROR) {
hGlobal = INVALID_HANDLE_VALUE;
dwErr = NO_ERROR;
}
stEnableResolution = GetInteger(hGlobal,
KEY_ENABLE_RESOLUTION,
VAL_DEFAULT);
bHaveRelayName = GetString(hGlobal, KEY_RELAY_NAME, pwszRelayName,
NI_MAXHOST);
ulResolutionInterval = GetInteger(hGlobal,
KEY_RESOLUTION_INTERVAL,
0);
RegCloseKey(hGlobal);
if (bDump) {
if (bHaveRelayName || (stEnableResolution != VAL_DEFAULT)
|| (ulResolutionInterval > 0)) {
DisplayMessageT(DMP_IP6TO4_SET_RELAY);
if (bHaveRelayName) {
DisplayMessageT(DMP_STRING_ARG, TOKEN_NAME,
pwszRelayName);
}
if (stEnableResolution != VAL_DEFAULT) {
DisplayMessageT(DMP_STRING_ARG,
TOKEN_STATE,
pwszStateString[stEnableResolution]);
}
if (ulResolutionInterval > 0) {
DisplayMessageT(DMP_INTEGER_ARG, TOKEN_INTERVAL,
ulResolutionInterval);
}
DisplayMessage(g_hModule, MSG_NEWLINE);
}
} else {
DisplayMessage(g_hModule, MSG_RELAY_NAME);
if (bHaveRelayName) {
DisplayMessage(g_hModule, MSG_STRING, pwszRelayName);
} else {
DisplayMessage(g_hModule, MSG_STRING, TOKEN_VALUE_DEFAULT);
}
DisplayMessage(g_hModule, MSG_RESOLUTION_STATE,
pwszStateString[stEnableResolution]);
DisplayMessage(g_hModule, MSG_RESOLUTION_INTERVAL);
if (ulResolutionInterval) {
DisplayMessage(g_hModule, MSG_MINUTES, ulResolutionInterval);
} else {
DisplayMessage(g_hModule, MSG_STRING, TOKEN_VALUE_DEFAULT);
}
}
return dwErr;
}
DWORD
Ip6to4HandleShowRelay(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
{
return ShowRelayConfig(FALSE);
}
DWORD
Ip6to4HandleReset(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
{
HKEY hGlobal;
DWORD dwErr;
// Nuke global params
dwErr = RegDeleteKey(HKEY_LOCAL_MACHINE, KEY_GLOBAL);
if ((dwErr != NO_ERROR) && (dwErr != ERROR_FILE_NOT_FOUND)) {
return dwErr;
}
// Nuke all interface config
dwErr = SHDeleteKey(HKEY_LOCAL_MACHINE, KEY_INTERFACES);
if ((dwErr != NO_ERROR) && (dwErr != ERROR_FILE_NOT_FOUND)) {
return dwErr;
}
// Start/poke the service
Ip6to4PokeService();
return ERROR_OKAY;
}
DWORD
ShowStateConfig(
IN BOOL bDump)
{
DWORD dwErr = NO_ERROR;
HKEY hGlobal;
STATE stEnable6to4;
STATE stUndoOnStop;
SERVICE_STATUS ServiceStatus;
DWORD dwCurrentState;
dwErr = Ip6to4QueryServiceStatus(&ServiceStatus);
if (dwErr != NO_ERROR) {
return dwErr;
}
if (ServiceStatus.dwCurrentState == SERVICE_STOPPED) {
stEnable6to4 = VAL_DISABLED;
} else {
stEnable6to4 = VAL_ENABLED;
}
dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_GLOBAL, 0, KEY_QUERY_VALUE,
&hGlobal);
if (dwErr != NO_ERROR) {
hGlobal = INVALID_HANDLE_VALUE;
dwErr = NO_ERROR;
}
stUndoOnStop = GetInteger(hGlobal,
KEY_UNDO_ON_STOP,
VAL_DEFAULT);
RegCloseKey(hGlobal);
if (bDump) {
if ((stEnable6to4 != VAL_DEFAULT) || (stUndoOnStop != VAL_DEFAULT)) {
DisplayMessageT(DMP_IP6TO4_SET_STATE);
if (stEnable6to4 != VAL_DEFAULT) {
DisplayMessageT(DMP_STRING_ARG, TOKEN_STATE,
pwszStateString[stEnable6to4]);
}
if (stUndoOnStop != VAL_DEFAULT) {
DisplayMessageT(DMP_STRING_ARG, TOKEN_UNDO_ON_STOP,
pwszStateString[stUndoOnStop]);
}
DisplayMessage(g_hModule, MSG_NEWLINE);
}
} else {
DisplayMessage(g_hModule, MSG_IP6TO4_STATE,
pwszStateString[stEnable6to4]);
DisplayMessage(g_hModule, MSG_UNDO_ON_STOP_STATE,
pwszStateString[stUndoOnStop]);
}
return dwErr;
}
DWORD
Ip6to4HandleShowState(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
{
return ShowStateConfig(FALSE);
}
DWORD
WINAPI
Ip6to4Dump(
IN LPCWSTR pwszRouter,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwArgCount,
IN LPCVOID pvData
)
/*++
Routine Description
Used when dumping all contexts
Arguments
Return Value
NO_ERROR
--*/
{
DWORD dwErr;
HANDLE hFile = (HANDLE)-1;
DisplayMessage( g_hModule, DMP_IP6TO4_HEADER );
DisplayMessageT(DMP_IP6TO4_PUSHD);
ShowStateConfig(TRUE);
ShowRelayConfig(TRUE);
ShowRoutingConfig(TRUE);
ShowInterfaceConfig(TRUE);
DisplayMessageT(DMP_IP6TO4_POPD);
DisplayMessage( g_hModule, DMP_IP6TO4_FOOTER );
return NO_ERROR;
}