|
|
//=============================================================================
// Copyright (c) 2001 Microsoft Corporation
// Abstract:
// This module implements IPv6 configuration commands.
//=============================================================================
#include "precomp.h"
#pragma hdrstop
typedef enum { ACTION_ADD, ACTION_SET } ACTION;
DWORD GetTime( IN PWCHAR pwszLife) { PWCHAR pwcUnit; DWORD dwUnits, dwLife = 0; if (!_wcsnicmp(pwszLife, TOKEN_VALUE_INFINITE, wcslen(pwszLife))) { return INFINITE_LIFETIME; }
while ((pwcUnit = wcspbrk(pwszLife, L"sSmMhHdD")) != NULL) { switch (*pwcUnit) { case L's': case L'S': dwUnits = SECONDS; break; case L'm': case L'M': dwUnits = MINUTES; break; case L'h': case L'H': dwUnits = HOURS; break; case L'd': case L'D': dwUnits = DAYS; break; } *pwcUnit = L'\0'; dwLife += wcstoul(pwszLife, NULL, 10) * dwUnits; pwszLife = pwcUnit + 1; if (*pwszLife == L'\0') return dwLife; } return dwLife + wcstoul(pwszLife, NULL, 10); }
/////////////////////////////////////////////////////////////////////////////
// Commands related to addresses
/////////////////////////////////////////////////////////////////////////////
DWORD HandleAddSetAddress( IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN ACTION Action, OUT BOOL *pbDone ) { DWORD dwErr, i; TAG_TYPE pttTags[] = {{TOKEN_INTERFACE, TRUE, FALSE}, {TOKEN_ADDRESS, TRUE, FALSE}, {TOKEN_TYPE, FALSE, FALSE}, {TOKEN_VALIDLIFETIME, FALSE, FALSE}, {TOKEN_PREFERREDLIFETIME, FALSE, FALSE}, {TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; PWCHAR pwszIfFriendlyName = NULL; IN6_ADDR ipAddress; TOKEN_VALUE rgtvTypeEnum[] = {{ TOKEN_VALUE_UNICAST, ADE_UNICAST }, { TOKEN_VALUE_ANYCAST, ADE_ANYCAST }}; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }}; DWORD dwType = ADE_UNICAST; DWORD dwValidLifetime = INFINITE_LIFETIME; DWORD dwPreferredLifetime = INFINITE_LIFETIME; BOOL bPersistent = TRUE;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // INTERFACE
pwszIfFriendlyName = ppwcArguments[i + dwCurrentIndex]; break;
case 1: // ADDRESS
dwErr = GetIpv6Address(ppwcArguments[i + dwCurrentIndex], &ipAddress); break;
case 2: // TYPE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvTypeEnum), rgtvTypeEnum, &dwType); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
case 3: // VALIDLIFETIME
dwValidLifetime = GetTime(ppwcArguments[dwCurrentIndex + i]); break;
case 4: // PREFERREDLIFETIME
dwPreferredLifetime = GetTime(ppwcArguments[dwCurrentIndex + i]); break;
case 5: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return UpdateAddress(pwszIfFriendlyName, &ipAddress, dwType, dwValidLifetime, dwPreferredLifetime, bPersistent); }
DWORD HandleAddAddress( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { return HandleAddSetAddress(ppwcArguments, dwCurrentIndex, dwArgCount, ACTION_ADD, pbDone); }
DWORD HandleSetAddress( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { return HandleAddSetAddress(ppwcArguments, dwCurrentIndex, dwArgCount, ACTION_SET, pbDone); }
DWORD HandleDelAddress( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr, i; TAG_TYPE pttTags[] = {{TOKEN_INTERFACE, TRUE, FALSE}, {TOKEN_ADDRESS, TRUE, FALSE}, {TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; PWCHAR pwszIfFriendlyName = NULL; IN6_ADDR ipAddress; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }}; DWORD dwType = ADE_UNICAST; BOOL bPersistent = TRUE;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // INTERFACE
pwszIfFriendlyName = ppwcArguments[i + dwCurrentIndex]; break;
case 1: // ADDRESS
dwErr = GetIpv6Address(ppwcArguments[i + dwCurrentIndex], &ipAddress); break;
case 2: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return UpdateAddress(pwszIfFriendlyName, &ipAddress, dwType, 0, 0, bPersistent); }
DWORD HandleShowAddress( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_INTERFACE, FALSE, FALSE}, {TOKEN_LEVEL, FALSE, FALSE}, {TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; PWCHAR pwszIfFriendlyName = NULL; DWORD i; BOOL bPersistent = FALSE; FORMAT Format = FORMAT_NORMAL; TOKEN_VALUE rgtvLevelEnum[] = {{ TOKEN_VALUE_NORMAL, FORMAT_NORMAL }, { TOKEN_VALUE_VERBOSE, FORMAT_VERBOSE }}; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }};
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // INTERFACE
pwszIfFriendlyName = ppwcArguments[i + dwCurrentIndex]; Format = FORMAT_VERBOSE; break;
case 1: // LEVEL
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvLevelEnum), rgtvLevelEnum, (DWORD*)&Format); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
case 2: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return QueryAddressTable(pwszIfFriendlyName, Format, bPersistent); }
DWORD HandleShowJoins( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_INTERFACE, FALSE, FALSE}, {TOKEN_LEVEL, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; PWCHAR pwszIfFriendlyName = NULL; DWORD i; FORMAT Format = FORMAT_NORMAL; TOKEN_VALUE rgtvLevelEnum[] = {{ TOKEN_VALUE_NORMAL, FORMAT_NORMAL }, { TOKEN_VALUE_VERBOSE, FORMAT_VERBOSE }};
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // INTERFACE
pwszIfFriendlyName = ppwcArguments[i + dwCurrentIndex]; break;
case 1: // LEVEL
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvLevelEnum), rgtvLevelEnum, (DWORD*)&Format); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return QueryMulticastAddressTable(pwszIfFriendlyName, Format); }
/////////////////////////////////////////////////////////////////////////////
// Commands related to mobility
/////////////////////////////////////////////////////////////////////////////
TOKEN_VALUE rgtvSecurityEnum[] = { { TOKEN_VALUE_ENABLED, TRUE }, { TOKEN_VALUE_DISABLED, FALSE }, };
DWORD HandleSetMobility( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_SECURITY, FALSE, FALSE}, {TOKEN_BINDINGCACHELIMIT, FALSE, FALSE}, {TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }}; DWORD i, dwEnableSecurity = -1, dwBindingCacheLimit = -1; BOOL bPersistent = TRUE;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 1, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // SECURITY
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvSecurityEnum), rgtvSecurityEnum, &dwEnableSecurity); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
case 1: // BINDINGCACHELIMIT
dwBindingCacheLimit = wcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10); break;
case 2: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return UpdateMobilityParameters(dwEnableSecurity, dwBindingCacheLimit, bPersistent); }
DWORD HandleShowMobility( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; DWORD i; BOOL bPersistent = FALSE; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }};
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return QueryMobilityParameters(FORMAT_NORMAL, bPersistent); }
DWORD HandleShowBindingCacheEntries( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { return QueryBindingCache(); }
/////////////////////////////////////////////////////////////////////////////
// Commands related to other global parameters
/////////////////////////////////////////////////////////////////////////////
DWORD HandleSetGlobal( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr, i; TAG_TYPE pttTags[] = {{TOKEN_DEFAULTCURHOPLIMIT, FALSE, FALSE}, {TOKEN_NEIGHBORCACHELIMIT, FALSE, FALSE}, {TOKEN_DESTINATIONCACHELIMIT, FALSE, FALSE}, {TOKEN_REASSEMBLYLIMIT, FALSE, FALSE}, {TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }}; DWORD dwDefaultCurHopLimit = -1; DWORD dwNeighborCacheLimit = -1; DWORD dwRouteCacheLimit = -1; DWORD dwReassemblyLimit = -1; BOOL bPersistent = TRUE;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 1, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // DEFAULTCURHOPLIMIT
dwDefaultCurHopLimit = wcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10); break;
case 1: // NEIGHBORCACHELIMIT
dwNeighborCacheLimit = wcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10); break;
case 2: // DESTINATIONCACHELIMIT
dwRouteCacheLimit = wcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10); break;
case 3: // REASSEMBLYLIMIT
dwReassemblyLimit = wcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10); break;
case 4: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return UpdateGlobalParameters(dwDefaultCurHopLimit, dwNeighborCacheLimit, dwRouteCacheLimit, dwReassemblyLimit, bPersistent); }
DWORD HandleShowGlobal( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; DWORD i; BOOL bPersistent = FALSE; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }};
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return QueryGlobalParameters(FORMAT_NORMAL, bPersistent); }
DWORD HandleSetPrivacy( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr, i; TAG_TYPE pttTags[] = {{TOKEN_STATE, FALSE, FALSE}, {TOKEN_MAXDADATTEMPTS, FALSE, FALSE}, {TOKEN_MAXVALIDLIFETIME, FALSE, FALSE}, {TOKEN_MAXPREFERREDLIFETIME, FALSE, FALSE}, {TOKEN_REGENERATETIME, FALSE, FALSE}, {TOKEN_MAXRANDOMTIME, FALSE, FALSE}, {TOKEN_RANDOMTIME, FALSE, FALSE}, {TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; TOKEN_VALUE rgtvStateEnum[] = {{ TOKEN_VALUE_DISABLED, USE_ANON_NO }, { TOKEN_VALUE_ENABLED, USE_ANON_YES }}; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }}; DWORD dwState = -1; DWORD dwMaxDadAttempts = -1; DWORD dwMaxValidLifetime = -1; DWORD dwMaxPrefLifetime = -1; DWORD dwRegenerateTime = -1; DWORD dwMaxRandomTime = -1; DWORD dwRandomTime = -1; BOOL bPersistent = TRUE;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 1, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // STATE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStateEnum), rgtvStateEnum, &dwState); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
case 1: // MAXDADATTEMPTS
dwMaxDadAttempts = wcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10); break;
case 2: // MAXVALIDLIFETIME
dwMaxValidLifetime = GetTime(ppwcArguments[dwCurrentIndex + i]); break;
case 3: // MAXPREFLIFETIME
dwMaxPrefLifetime = GetTime(ppwcArguments[dwCurrentIndex + i]); break;
case 4: // REGENERATETIME
dwRegenerateTime = GetTime(ppwcArguments[dwCurrentIndex + i]); break;
case 5: // MAXRANDOMTIME
dwMaxRandomTime = GetTime(ppwcArguments[dwCurrentIndex + i]); break;
case 6: // RANDOMTIME
dwRandomTime = GetTime(ppwcArguments[dwCurrentIndex + i]); break;
case 7: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return UpdatePrivacyParameters(dwState, dwMaxDadAttempts, dwMaxValidLifetime, dwMaxPrefLifetime, dwRegenerateTime, dwMaxRandomTime, dwRandomTime, bPersistent); }
DWORD HandleShowPrivacy( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; DWORD i; BOOL bPersistent = FALSE; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }};
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return QueryPrivacyParameters(FORMAT_NORMAL, bPersistent); }
/////////////////////////////////////////////////////////////////////////////
// Commands related to interfaces
/////////////////////////////////////////////////////////////////////////////
DWORD HandleAddV6V4Tunnel( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_INTERFACE, TRUE, FALSE}, {TOKEN_LOCALADDRESS, TRUE, FALSE}, {TOKEN_REMOTEADDRESS, TRUE, FALSE}, {TOKEN_NEIGHBORDISCOVERY, FALSE, FALSE}, {TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; DWORD i, dwNeighborDiscovery = FALSE; IN_ADDR ipLocalAddr, ipRemoteAddr; PWCHAR pwszFriendlyName; TOKEN_VALUE rgtvNDEnum[] = {{ TOKEN_VALUE_DISABLED, FALSE }, { TOKEN_VALUE_ENABLED, TRUE }}; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }}; BOOL bPersistent = TRUE;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // INTERFACE
pwszFriendlyName = ppwcArguments[i + dwCurrentIndex]; break;
case 1: // LOCALADDRESS
dwErr = GetIpv4Address(ppwcArguments[i + dwCurrentIndex], &ipLocalAddr); break;
case 2: // REMOTEADDRESS
dwErr = GetIpv4Address(ppwcArguments[i + dwCurrentIndex], &ipRemoteAddr); break;
case 3: // NEIGHBORDISCOVERY
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvNDEnum), rgtvNDEnum, &dwNeighborDiscovery); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
case 4: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
dwErr = AddTunnelInterface(pwszFriendlyName, &ipLocalAddr, &ipRemoteAddr, IPV6_IF_TYPE_TUNNEL_V6V4, dwNeighborDiscovery, bPersistent);
if (dwErr == ERROR_INVALID_HANDLE) { DisplayMessage(g_hModule, EMSG_INVALID_ADDRESS); dwErr = ERROR_SUPPRESS_OUTPUT; }
return dwErr; }
DWORD HandleAdd6over4Tunnel( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_INTERFACE, TRUE, FALSE}, {TOKEN_LOCALADDRESS, TRUE, FALSE}, {TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }}; DWORD i, dwEnableSecurity; PWCHAR pwszFriendlyName; IN_ADDR ipLocalAddr; BOOL bPersistent = TRUE;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // INTERFACE
pwszFriendlyName = ppwcArguments[i + dwCurrentIndex]; break;
case 1: // LOCALADDRESS
dwErr = GetIpv4Address(ppwcArguments[i + dwCurrentIndex], &ipLocalAddr); break;
case 2: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
dwErr = AddTunnelInterface(pwszFriendlyName, &ipLocalAddr, NULL, IPV6_IF_TYPE_TUNNEL_6OVER4, TRUE, bPersistent);
if (dwErr == ERROR_INVALID_HANDLE) { DisplayMessage(g_hModule, EMSG_INVALID_ADDRESS); dwErr = ERROR_SUPPRESS_OUTPUT; }
return dwErr; }
DWORD HandleSetInterface( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_INTERFACE, TRUE, FALSE}, {TOKEN_FORWARDING, FALSE, FALSE}, {TOKEN_ADVERTISE, FALSE, FALSE}, {TOKEN_MTU, FALSE, FALSE}, {TOKEN_SITEID, FALSE, FALSE}, {TOKEN_METRIC, FALSE, FALSE}, {TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; TOKEN_VALUE rgtvEnum[] = {{ TOKEN_VALUE_DISABLED, FALSE }, { TOKEN_VALUE_ENABLED, TRUE }}; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }}; PWCHAR pwszIfFriendlyName = NULL; DWORD i, dwMtu = 0, dwSiteId = 0, dwMetric = -1; DWORD dwAdvertise = -1, dwForwarding = -1; BOOL bPersistent = TRUE;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // INTERFACE
pwszIfFriendlyName = ppwcArguments[i + dwCurrentIndex]; break;
case 1: // FORWARDING
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvEnum), rgtvEnum, &dwForwarding); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
case 2: // ADVERTISE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvEnum), rgtvEnum, &dwAdvertise); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
case 3: // MTU
dwMtu = wcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10); break;
case 4: // SITEID
dwSiteId = wcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10); break;
case 5: // METRIC
dwMetric = wcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10); break;
case 6: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return UpdateInterface(pwszIfFriendlyName, dwForwarding, dwAdvertise, dwMtu, dwSiteId, dwMetric, bPersistent); }
DWORD HandleDelInterface( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_INTERFACE, TRUE, FALSE}, {TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; PWCHAR pwszIfFriendlyName = NULL; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }}; DWORD i; BOOL bPersistent = TRUE;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // INTERFACE
pwszIfFriendlyName = ppwcArguments[i + dwCurrentIndex]; break;
case 1: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return DeleteInterface(pwszIfFriendlyName, bPersistent); }
DWORD HandleShowInterface( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_INTERFACE, FALSE, FALSE}, {TOKEN_LEVEL, FALSE, FALSE}, {TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; PWCHAR pwszIfFriendlyName = NULL; DWORD i; FORMAT Format = FORMAT_NORMAL; TOKEN_VALUE rgtvLevelEnum[] = {{ TOKEN_VALUE_NORMAL, FORMAT_NORMAL }, { TOKEN_VALUE_VERBOSE, FORMAT_VERBOSE }}; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }}; BOOL bPersistent = FALSE;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // INTERFACE
pwszIfFriendlyName = ppwcArguments[i + dwCurrentIndex]; Format = FORMAT_VERBOSE; break;
case 1: // LEVEL
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvLevelEnum), rgtvLevelEnum, (DWORD*)&Format); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
case 2: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return QueryInterface(pwszIfFriendlyName, Format, bPersistent); }
DWORD HandleRenew( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_INTERFACE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; PWCHAR pwszIfFriendlyName = NULL; DWORD i;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // INTERFACE
pwszIfFriendlyName = ppwcArguments[i + dwCurrentIndex]; break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return RenewInterface(pwszIfFriendlyName); }
/////////////////////////////////////////////////////////////////////////////
// Commands related to the neighbor cache
/////////////////////////////////////////////////////////////////////////////
DWORD HandleDelNeighbors( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_INTERFACE, FALSE, FALSE}, {TOKEN_ADDRESS, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; PWCHAR pwszIfFriendlyName = NULL; DWORD i; IN6_ADDR ipAddress, *pipAddress = NULL;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // INTERFACE
pwszIfFriendlyName = ppwcArguments[i + dwCurrentIndex]; break;
case 1: // ADDRESS
dwErr = GetIpv6Address(ppwcArguments[i + dwCurrentIndex], &ipAddress); pipAddress = &ipAddress; break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return FlushNeighborCache(pwszIfFriendlyName, pipAddress); }
DWORD HandleShowNeighbors( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_INTERFACE, FALSE, FALSE}, {TOKEN_ADDRESS, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; PWCHAR pwszIfFriendlyName = NULL; DWORD i; IN6_ADDR ipAddress, *pipAddress = NULL;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // INTERFACE
pwszIfFriendlyName = ppwcArguments[i + dwCurrentIndex]; break;
case 1: // ADDRESS
dwErr = GetIpv6Address(ppwcArguments[i + dwCurrentIndex], &ipAddress); pipAddress = &ipAddress; break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return QueryNeighborCache(pwszIfFriendlyName, pipAddress); }
/////////////////////////////////////////////////////////////////////////////
// Commands related to the prefix policies
/////////////////////////////////////////////////////////////////////////////
DWORD HandleAddSetPrefixPolicy( IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN ACTION Action, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_PREFIX, TRUE, FALSE}, {TOKEN_PRECEDENCE, TRUE, FALSE}, {TOKEN_LABEL, TRUE, FALSE}, {TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }}; DWORD i, dwPrefixLength, dwPrecedence = -1, dwLabel = -1; IN6_ADDR ipAddress; BOOL bPersistent = TRUE;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // PREFIX
dwErr = GetIpv6Prefix(ppwcArguments[i + dwCurrentIndex], &ipAddress, &dwPrefixLength); break;
case 1: // PRECEDENCE
dwPrecedence = wcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10); break;
case 2: // LABEL
dwLabel = wcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10); break;
case 3: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return UpdatePrefixPolicy(&ipAddress, dwPrefixLength, dwPrecedence, dwLabel, bPersistent); }
DWORD HandleAddPrefixPolicy( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { return HandleAddSetPrefixPolicy(ppwcArguments, dwCurrentIndex, dwArgCount, ACTION_ADD, pbDone); }
DWORD HandleSetPrefixPolicy( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { return HandleAddSetPrefixPolicy(ppwcArguments, dwCurrentIndex, dwArgCount, ACTION_SET, pbDone); }
DWORD HandleDelPrefixPolicy( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_PREFIX, TRUE, FALSE}, {TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }}; DWORD i, dwPrefixLength; IN6_ADDR ipAddress; BOOL bPersistent = TRUE;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // PREFIX
dwErr = GetIpv6Prefix(ppwcArguments[i + dwCurrentIndex], &ipAddress, &dwPrefixLength); break;
case 1: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return DeletePrefixPolicy(&ipAddress, dwPrefixLength, bPersistent); }
DWORD HandleShowPrefixPolicy( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; DWORD i; BOOL bPersistent = FALSE; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }};
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return QueryPrefixPolicy(FORMAT_NORMAL, bPersistent); }
/////////////////////////////////////////////////////////////////////////////
// Commands related to routes
/////////////////////////////////////////////////////////////////////////////
DWORD HandleAddSetRoute( IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN ACTION Action, OUT BOOL *pbDone ) { DWORD dwErr, i; TAG_TYPE pttTags[] = {{TOKEN_PREFIX, TRUE, FALSE}, {TOKEN_INTERFACE, TRUE, FALSE}, {TOKEN_NEXTHOP, FALSE, FALSE}, {TOKEN_SITEPREFIXLENGTH, FALSE, FALSE}, {TOKEN_METRIC, FALSE, FALSE}, {TOKEN_PUBLISH, FALSE, FALSE}, {TOKEN_VALIDLIFETIME, FALSE, FALSE}, {TOKEN_PREFERREDLIFETIME, FALSE, FALSE}, {TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; TOKEN_VALUE rgtvPublishEnum[] = { {TOKEN_VALUE_NO, PUBLISH_NO }, {TOKEN_VALUE_AGE, PUBLISH_AGE }, {TOKEN_VALUE_YES, PUBLISH_IMMORTAL }}; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }}; DWORD dwPrefixLength, dwMetric = ROUTE_PREF_HIGHEST; DWORD dwSitePrefixLength = 0; IN6_ADDR ipPrefix, ipNextHop, *pipNextHop = NULL; PWCHAR pwszIfFriendlyName; PUBLISH Publish = PUBLISH_NO; DWORD dwValidLifetime = INFINITE_LIFETIME; DWORD dwPreferredLifetime = INFINITE_LIFETIME; BOOL bPersistent = TRUE;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // PREFIX
dwErr = GetIpv6Prefix(ppwcArguments[i + dwCurrentIndex], &ipPrefix, &dwPrefixLength); break;
case 1: // INTERFACE
pwszIfFriendlyName = ppwcArguments[dwCurrentIndex + i]; break;
case 2: // NEXTHOP
pipNextHop = &ipNextHop; dwErr = GetIpv6Address(ppwcArguments[i + dwCurrentIndex], &ipNextHop); break;
case 3: // SITEPREFIXLENGTH
dwSitePrefixLength = wcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10); break;
case 4: // METRIC
dwMetric = wcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10); break;
case 5: // PUBLISH
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvPublishEnum), rgtvPublishEnum, (DWORD*)&Publish); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
case 6: // VALIDLIFETIME
dwValidLifetime = GetTime(ppwcArguments[dwCurrentIndex + i]); break;
case 7: // PREFERREDLIFETIME
dwPreferredLifetime = GetTime(ppwcArguments[dwCurrentIndex + i]); break;
case 8: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
if ((dwPreferredLifetime == INFINITE_LIFETIME) && (dwValidLifetime != INFINITE_LIFETIME)) { dwPreferredLifetime = dwValidLifetime; }
// Disallow persistent aging routes with non-infinite valid lifetimes,
// since every reboot they would come back, and then go away after
// the lifetime expires. This would be very confusing, and so we
// just disallow it.
if ((Publish != PUBLISH_IMMORTAL) && (dwValidLifetime != INFINITE_LIFETIME) && (bPersistent == TRUE)) { return ERROR_INVALID_PARAMETER; // DisplayMessage(g_hModule, EMSG_CANT_PERSIST_AGING_ROUTES);
// return ERROR_SUPPRESS_OUTPUT;
}
return UpdateRouteTable(&ipPrefix, dwPrefixLength, pwszIfFriendlyName, pipNextHop, dwMetric, Publish, dwSitePrefixLength, dwValidLifetime, dwPreferredLifetime, bPersistent); }
DWORD HandleAddRoute( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { return HandleAddSetRoute(ppwcArguments, dwCurrentIndex, dwArgCount, ACTION_ADD, pbDone); }
DWORD HandleSetRoute( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { return HandleAddSetRoute(ppwcArguments, dwCurrentIndex, dwArgCount, ACTION_SET, pbDone); }
DWORD HandleDelRoute( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr, i; TAG_TYPE pttTags[] = {{TOKEN_PREFIX, TRUE, FALSE}, {TOKEN_INTERFACE, TRUE, FALSE}, {TOKEN_NEXTHOP, FALSE, FALSE}, {TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }}; DWORD dwPrefixLength, dwMetric = ROUTE_PREF_HIGHEST; DWORD dwSitePrefixLength = 0; IN6_ADDR ipPrefix, ipNextHop, *pipNextHop = NULL; PWCHAR pwszIfFriendlyName; PUBLISH Publish = PUBLISH_NO; BOOL bPersistent = TRUE;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // PREFIX
dwErr = GetIpv6Prefix(ppwcArguments[i + dwCurrentIndex], &ipPrefix, &dwPrefixLength); break;
case 1: // INTERFACE
pwszIfFriendlyName = ppwcArguments[dwCurrentIndex + i]; break;
case 2: // NEXTHOP
pipNextHop = &ipNextHop; dwErr = GetIpv6Address(ppwcArguments[i + dwCurrentIndex], &ipNextHop); break;
case 3: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return UpdateRouteTable(&ipPrefix, dwPrefixLength, pwszIfFriendlyName, pipNextHop, dwMetric, Publish, dwSitePrefixLength, 0, 0, bPersistent); }
DWORD HandleShowRoutes( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_LEVEL, FALSE, FALSE}, {TOKEN_STORE, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; DWORD i; IN6_ADDR ipAddress, *pipAddress = NULL; TOKEN_VALUE rgtvLevelEnum[] = {{ TOKEN_VALUE_NORMAL, FORMAT_NORMAL }, { TOKEN_VALUE_VERBOSE, FORMAT_VERBOSE }}; TOKEN_VALUE rgtvStoreEnum[] = {{ TOKEN_VALUE_ACTIVE, FALSE }, { TOKEN_VALUE_PERSISTENT, TRUE }}; FORMAT Format = FORMAT_NORMAL; BOOL bPersistent = FALSE;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // LEVEL
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvLevelEnum), rgtvLevelEnum, (DWORD*)&Format); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
case 1: // STORE
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvStoreEnum), rgtvStoreEnum, &bPersistent); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return QueryRouteTable(Format, bPersistent); }
/////////////////////////////////////////////////////////////////////////////
// Commands related to the destination cache
/////////////////////////////////////////////////////////////////////////////
DWORD HandleDelDestinationCache( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_INTERFACE, FALSE, FALSE}, {TOKEN_ADDRESS, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; PWCHAR pwszIfFriendlyName = NULL; DWORD i; IN6_ADDR ipAddress, *pipAddress = NULL;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // INTERFACE
pwszIfFriendlyName = ppwcArguments[i + dwCurrentIndex]; break;
case 1: // ADDRESS
dwErr = GetIpv6Address(ppwcArguments[i + dwCurrentIndex], &ipAddress); pipAddress = &ipAddress; break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return FlushRouteCache(pwszIfFriendlyName, pipAddress); }
DWORD HandleShowDestinationCache( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr; TAG_TYPE pttTags[] = {{TOKEN_INTERFACE, FALSE, FALSE}, {TOKEN_ADDRESS, FALSE, FALSE}, {TOKEN_LEVEL, FALSE, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; PWCHAR pwszIfFriendlyName = NULL; DWORD i; IN6_ADDR ipAddress, *pipAddress = NULL; FORMAT Format = FORMAT_NORMAL; TOKEN_VALUE rgtvLevelEnum[] = {{ TOKEN_VALUE_NORMAL, FORMAT_NORMAL }, { TOKEN_VALUE_VERBOSE, FORMAT_VERBOSE }};
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, sizeof(pttTags)/sizeof(TAG_TYPE), rgdwTagType );
for (i=0; (dwErr == NO_ERROR) && (i<dwArgCount-dwCurrentIndex); i++) { switch(rgdwTagType[i]) { case 0: // INTERFACE
pwszIfFriendlyName = ppwcArguments[i + dwCurrentIndex]; break;
case 1: // ADDRESS
dwErr = GetIpv6Address(ppwcArguments[i + dwCurrentIndex], &ipAddress); pipAddress = &ipAddress; Format = FORMAT_VERBOSE; break;
case 2: // LEVEL
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvLevelEnum), rgtvLevelEnum, (DWORD*)&Format); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; } break;
default: dwErr = ERROR_INVALID_SYNTAX; break; } }
if (dwErr isnot NO_ERROR) { return dwErr; }
// Now do the work
return QueryRouteCache(pwszIfFriendlyName, pipAddress, Format); }
/////////////////////////////////////////////////////////////////////////////
// Commands related to the site prefix table
/////////////////////////////////////////////////////////////////////////////
DWORD HandleShowSitePrefixes( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { return QuerySitePrefixTable(FORMAT_NORMAL); }
/////////////////////////////////////////////////////////////////////////////
// Commands related to installation
/////////////////////////////////////////////////////////////////////////////
DWORD HandleInstall( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { return AddOrRemoveIpv6(TRUE); }
DWORD HandleReset( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { DWORD dwErr;
#if TEREDO
dwErr = ResetTeredo(); if (dwErr != NO_ERROR) { return dwErr; } #endif // TEREDO
return ResetIpv6Config(TRUE); }
DWORD HandleUninstall( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { return AddOrRemoveIpv6(FALSE); }
/////////////////////////////////////////////////////////////////////////////
// Commands related to deprecated functionality
/////////////////////////////////////////////////////////////////////////////
#define KEY_ENABLE_6OVER4 L"Enable6over4"
#define KEY_ENABLE_V4COMPAT L"EnableV4Compat"
#define BM_ENABLE_6OVER4 0x01
#define BM_ENABLE_V4COMPAT 0x02
DWORD HandleSetState( 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 stEnable6over4; STATE stEnableV4Compat; DWORD dwBitVector = 0; TAG_TYPE pttTags[] = {{TOKEN_6OVER4, FALSE, FALSE}, {TOKEN_V4COMPAT, 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: // 6OVER4
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvEnums), rgtvEnums, (PDWORD)&stEnable6over4); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; }
dwBitVector |= BM_ENABLE_6OVER4; break;
case 1: // V4COMPAT
dwErr = MatchEnumTag(NULL, ppwcArguments[dwCurrentIndex + i], NUM_TOKENS_IN_TABLE(rgtvEnums), rgtvEnums, (PDWORD)&stEnableV4Compat); if (dwErr isnot NO_ERROR) { dwErr = ERROR_INVALID_PARAMETER; break; }
dwBitVector |= BM_ENABLE_V4COMPAT; 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_6OVER4) { dwErr = SetInteger(hGlobal, KEY_ENABLE_6OVER4, stEnable6over4); if (dwErr != NO_ERROR) return dwErr; }
if (dwBitVector & BM_ENABLE_V4COMPAT) { dwErr = SetInteger(hGlobal, KEY_ENABLE_V4COMPAT, stEnableV4Compat); if (dwErr != NO_ERROR) return dwErr; }
RegCloseKey(hGlobal);
Ip6to4PokeService();
return ERROR_OKAY; }
DWORD ShowIpv6StateConfig( IN BOOL Dumping ) { DWORD dwErr = NO_ERROR; HKEY hGlobal; STATE stEnable6over4; STATE stEnableV4Compat;
dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_GLOBAL, 0, KEY_QUERY_VALUE, &hGlobal);
if (dwErr != NO_ERROR) { hGlobal = INVALID_HANDLE_VALUE; dwErr = NO_ERROR; }
stEnable6over4 = GetInteger(hGlobal, KEY_ENABLE_6OVER4, VAL_DEFAULT); stEnableV4Compat = GetInteger(hGlobal, KEY_ENABLE_V4COMPAT, VAL_DEFAULT);
RegCloseKey(hGlobal);
if (Dumping) { if ((stEnable6over4 != VAL_DEFAULT) || (stEnableV4Compat != VAL_DEFAULT)) {
DisplayMessageT(DMP_IP6TO4_SET_STATE);
if (stEnable6over4 != VAL_DEFAULT) { DisplayMessageT(DMP_STRING_ARG, TOKEN_6OVER4, pwszStateString[stEnable6over4]); }
if (stEnableV4Compat != VAL_DEFAULT) { DisplayMessageT(DMP_STRING_ARG, TOKEN_V4COMPAT, pwszStateString[stEnableV4Compat]); }
DisplayMessage(g_hModule, MSG_NEWLINE); } } else { DisplayMessage(g_hModule, MSG_6OVER4_STATE, pwszStateString[stEnable6over4]);
// DisplayMessage(g_hModule, MSG_V4COMPAT_STATE,
// pwszStateString[stEnableV4Compat]);
}
return dwErr; }
DWORD HandleShowState( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { return ShowIpv6StateConfig(FALSE); }
#define KEY_DNS_SERVER_LIST L"NameServer"
DWORD GetDnsServerList( IN PWCHAR pwszIfFriendlyName, IN PIP_ADAPTER_ADDRESSES pAdapterInfo, OUT IN6_ADDR **ppipDnsList, OUT DWORD *pdwNumEntries ) /*++
Routine Description:
Reads the list of DNS servers from the registry and returns them in an array which includes space for at least one more server. The caller is responsible for freeing this space with FREE().
--*/ { HKEY hInterfaces = INVALID_HANDLE_VALUE, hIf = INVALID_HANDLE_VALUE; DWORD dwErr = NO_ERROR, Count = 0; WCHAR Servers[800], *p, *pend; DWORD i; IN6_ADDR *pipDnsList = NULL; SOCKADDR_IN6 saddr; DWORD Length; PCHAR pszAdapterName;
dwErr = MapFriendlyNameToAdapterName(NULL, pwszIfFriendlyName, pAdapterInfo, &pszAdapterName); if (dwErr != NO_ERROR) { goto Cleanup; }
Servers[0] = L'\0';
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_IPV6_INTERFACES, 0, GENERIC_READ, &hInterfaces) != NO_ERROR) { goto HaveString; }
if (RegOpenKeyExA(hInterfaces, pszAdapterName, 0, GENERIC_READ, &hIf) == NO_ERROR) { GetString(hIf, KEY_DNS_SERVER_LIST, Servers, 800); }
HaveString: // Count one server for each delimiter, plus one at the end, plus
// one more which the caller might want to add to the array which
// we allocate.
for (p = Servers; *p; p++) { if (*p == ' ' || *p == ',' || *p == ';') { Count++; } } Count += 2;
//
// Now allocate an array of IN6_ADDR structures, and copy all the
// addresses into it.
//
pipDnsList = MALLOC(sizeof(IN6_ADDR) * Count); if (pipDnsList == NULL) { dwErr = GetLastError(); goto Cleanup; }
Count = 0; for (p = wcstok(Servers, L" ,;"); p; p = wcstok(NULL, L" ,;")) { Length = sizeof(saddr); if (WSAStringToAddressW(p, AF_INET6, NULL, (LPSOCKADDR)&saddr, &Length) == NO_ERROR) { pipDnsList[Count++] = saddr.sin6_addr; } }
Cleanup: if (hIf != INVALID_HANDLE_VALUE) { RegCloseKey(hIf); } if (hInterfaces != INVALID_HANDLE_VALUE) { RegCloseKey(hInterfaces); }
*pdwNumEntries = Count; *ppipDnsList = pipDnsList; return dwErr; }
DWORD SetDnsServerList( IN PWCHAR pwszIfFriendlyName, IN PIP_ADAPTER_ADDRESSES pAdapterInfo, IN IN6_ADDR *pipDnsList, IN DWORD dwNumEntries ) /*++
Routine Description:
Writes the list of DNS servers to the registry, overwriting any previously list.
--*/ { DWORD dwErr; WCHAR Servers[800], *p = Servers; ULONG LengthLeft = 800, Length; DWORD i; SOCKADDR_IN6 saddr; HKEY hInterfaces, hIf; PCHAR pszAdapterName;
dwErr = MapFriendlyNameToAdapterName(NULL, pwszIfFriendlyName, pAdapterInfo, &pszAdapterName); if (dwErr != NO_ERROR) { return dwErr; }
dwErr = RegCreateKeyEx(HKEY_LOCAL_MACHINE, KEY_IPV6_INTERFACES, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hInterfaces, NULL);
if (dwErr != NO_ERROR) { return dwErr; }
dwErr = RegCreateKeyExA(hInterfaces, pszAdapterName, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hIf, NULL);
if (dwErr != NO_ERROR) { RegCloseKey(hInterfaces);
return dwErr; }
// Compose the string value, making sure to prevent a buffer overrun.
Servers[0] = L'\0'; ZeroMemory(&saddr, sizeof(saddr)); saddr.sin6_family = AF_INET6; for (i = 0; i < dwNumEntries; i++) { saddr.sin6_addr = pipDnsList[i]; Length = LengthLeft; if (WSAAddressToStringW((LPSOCKADDR)&saddr, sizeof(saddr), NULL, p, &Length) != NO_ERROR) { continue; }
// Update string taking into account that Length includes the NULL
// byte.
LengthLeft -= Length; p += (Length-1); *p++ = L' '; } if (p > Servers) { // Null out final delimiter.
p--; *p = '\0'; }
dwErr = SetString(hIf, KEY_DNS_SERVER_LIST, Servers);
RegCloseKey(hIf); RegCloseKey(hInterfaces);
return dwErr; }
DWORD HandleAddDns( 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; TAG_TYPE pttTags[] = {{TOKEN_INTERFACE, NS_REQ_PRESENT, FALSE}, {TOKEN_ADDRESS, NS_REQ_PRESENT, FALSE}, {TOKEN_INDEX, NS_REQ_ZERO, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; DWORD i; PWCHAR pwszIfFriendlyName = NULL; IN6_ADDR ipAddress; DWORD dwIndex = -1; HKEY hInterfaces, hIf; IN6_ADDR *ipDnsList; DWORD dwNumEntries; PIP_ADAPTER_ADDRESSES pAdapterInfo = NULL;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, 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: // INTERFACE
pwszIfFriendlyName = ppwcArguments[i + dwCurrentIndex]; break;
case 1: // ADDRESS
dwErr = GetIpv6Address(ppwcArguments[i + dwCurrentIndex], &ipAddress); break;
case 2: // INDEX
dwIndex = wcstoul(ppwcArguments[dwCurrentIndex + i], NULL, 10); break;
default: dwErr = ERROR_INVALID_SYNTAX; break; }
if (dwErr isnot NO_ERROR) { return dwErr; } }
dwErr = MyGetAdaptersInfo(&pAdapterInfo); if (dwErr != NO_ERROR) { goto Cleanup; }
dwErr = GetDnsServerList(pwszIfFriendlyName, pAdapterInfo, &ipDnsList, &dwNumEntries); if (dwErr != NO_ERROR) { goto Cleanup; }
if ((dwIndex == -1) || (dwIndex-1 == dwNumEntries)) { // Append server.
ipDnsList[dwNumEntries++] = ipAddress; } else if ((dwIndex == 0) || (dwIndex > dwNumEntries)) { dwErr = ERROR_INVALID_PARAMETER; goto Cleanup; } else { dwIndex--;
// Insert server at location 'dwIndex'.
for (i = dwNumEntries; i > dwIndex; i--) { ipDnsList[i] = ipDnsList[i-1]; } ipDnsList[dwIndex] = ipAddress; dwNumEntries++; }
dwErr = SetDnsServerList(pwszIfFriendlyName, pAdapterInfo, ipDnsList, dwNumEntries);
Cleanup: if (ipDnsList != NULL) { FREE(ipDnsList); } if (pAdapterInfo != NULL) { FREE(pAdapterInfo); }
if (dwErr == NO_ERROR) { dwErr = ERROR_OKAY; } return dwErr; }
DWORD HandleDelDns( 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; TAG_TYPE pttTags[] = {{TOKEN_INTERFACE, NS_REQ_PRESENT, FALSE}, {TOKEN_ADDRESS, NS_REQ_PRESENT, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; DWORD i; PWCHAR pwszIfFriendlyName = NULL; IN6_ADDR ipAddress; IN6_ADDR *ipDnsList; BOOL bAll = FALSE; DWORD dwNumEntries; PIP_ADAPTER_ADDRESSES pAdapterInfo = NULL;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, 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: // INTERFACE
pwszIfFriendlyName = ppwcArguments[i + dwCurrentIndex]; break;
case 1: // ADDRESS
{ DWORD dwRes; TOKEN_VALUE rgEnums[] = {{TOKEN_VALUE_ALL, 1}};
dwErr = MatchEnumTag(g_hModule, ppwcArguments[i + dwCurrentIndex], NUM_TOKENS_IN_TABLE(rgEnums), rgEnums, &dwRes); if (NO_ERROR == dwErr) { bAll = TRUE; } else { dwErr = GetIpv6Address(ppwcArguments[i + dwCurrentIndex], &ipAddress); } break; }
default: dwErr = ERROR_INVALID_SYNTAX; break; }
if (dwErr isnot NO_ERROR) { return dwErr; } }
dwErr = MyGetAdaptersInfo(&pAdapterInfo); if (dwErr != NO_ERROR) { goto Cleanup; }
dwErr = GetDnsServerList(pwszIfFriendlyName, pAdapterInfo, &ipDnsList, &dwNumEntries); if (dwErr != NO_ERROR) { goto Cleanup; }
if (bAll) { // Delete all entries.
dwNumEntries = 0; } else { // Find and delete the specified entry.
for (i = 0; i < dwNumEntries; i++) { if (!memcmp(&ipAddress, &ipDnsList[i], sizeof(ipAddress))) { break; } } if (i == dwNumEntries) { goto Cleanup; }
for (; i + 1 < dwNumEntries; i++) { ipDnsList[i] = ipDnsList[i+1]; } dwNumEntries--; }
dwErr = SetDnsServerList(pwszIfFriendlyName, pAdapterInfo, ipDnsList, dwNumEntries);
Cleanup: if (ipDnsList != NULL) { FREE(ipDnsList); } if (pAdapterInfo != NULL) { FREE(pAdapterInfo); }
if (dwErr == NO_ERROR) { dwErr = ERROR_OKAY; } return dwErr; }
DWORD ShowIfDnsServers( IN BOOL bDump, IN PIP_ADAPTER_ADDRESSES pAdapterInfo, IN PWCHAR pwszIfFriendlyName, IN OUT BOOL *pbHeaderDone ) { DWORD i, dwErr; WCHAR buff[NI_MAXHOST]; SOCKADDR_IN6 saddr; DWORD Length, dwNumEntries; IN6_ADDR *ipDnsList;
dwErr = GetDnsServerList(pwszIfFriendlyName, pAdapterInfo, &ipDnsList, &dwNumEntries); if (dwErr != NO_ERROR) { goto Error; }
if (!bDump && (dwNumEntries > 0)) { // DisplayMessage(g_hModule, MSG_DNS_SERVER_HEADER, pwszIfFriendlyName);
*pbHeaderDone = TRUE; }
ZeroMemory(&saddr, sizeof(saddr)); saddr.sin6_family = AF_INET6; for (i = 0; i < dwNumEntries; i++) { saddr.sin6_addr = ipDnsList[i]; Length = sizeof(saddr); if (WSAAddressToStringW((LPSOCKADDR)&saddr, sizeof(saddr), NULL, buff, &Length) != NO_ERROR) { continue; }
if (bDump) { DisplayMessageT(DMP_IPV6_ADD_DNS); DisplayMessageT(DMP_QUOTED_STRING_ARG, TOKEN_INTERFACE, pwszIfFriendlyName); DisplayMessageT(DMP_STRING_ARG, TOKEN_ADDRESS, buff); DisplayMessage(g_hModule, MSG_NEWLINE); } else { // DisplayMessage(g_hModule, MSG_DNS_SERVER, i+1, buff);
} }
Error: if (ipDnsList != NULL) { FREE(ipDnsList); } return dwErr; }
DWORD ShowDnsServers( IN BOOL bDump, IN PWCHAR pwszIfFriendlyName ) { PIP_ADAPTER_ADDRESSES pIf, pAdapterInfo = NULL; DWORD dwErr; BOOL bHeaderDone = FALSE;
dwErr = MyGetAdaptersInfo(&pAdapterInfo); if (dwErr != NO_ERROR) { return dwErr; }
if (pwszIfFriendlyName == NULL) { for (pIf = pAdapterInfo; (dwErr == NO_ERROR) && pIf; pIf = pIf->Next) { if (pIf->Ipv6IfIndex == 0) { continue; } dwErr = ShowIfDnsServers(bDump, pAdapterInfo, pIf->FriendlyName, &bHeaderDone); } } else { dwErr = ShowIfDnsServers(bDump, pAdapterInfo, pwszIfFriendlyName, &bHeaderDone); }
if (!bDump) { if (!bHeaderDone) { DisplayMessage(g_hModule, MSG_IP_NO_ENTRIES); } if (dwErr == NO_ERROR) { dwErr = ERROR_SUPPRESS_OUTPUT; } }
FREE(pAdapterInfo); return dwErr; }
DWORD HandleShowDns( 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; TAG_TYPE pttTags[] = {{TOKEN_INTERFACE, NS_REQ_ZERO, FALSE}}; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; DWORD i; PWCHAR pwszIfFriendlyName = NULL;
// Parse arguments
dwErr = PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, 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: // INTERFACE
pwszIfFriendlyName = ppwcArguments[i + dwCurrentIndex]; break;
default: dwErr = ERROR_INVALID_SYNTAX; break; }
if (dwErr isnot NO_ERROR) { return dwErr; } }
dwErr = ShowDnsServers(FALSE, pwszIfFriendlyName); if (dwErr == NO_ERROR) { dwErr = ERROR_OKAY; }
return dwErr; }
|