|
|
/*++
Copyright (c) 1998-1999 Microsoft Corporation
Module Name:
routing\netsh\ip\iphandle.c
Abstract:
Fns to get command options
Revision History:
Anand Mahalingam 7/10/98 Created
--*/
#include "precomp.h"
#pragma hdrstop
#undef EXTRA_DEBUG
#define SHOW_IF_FILTER 0
#define SHOW_INTERFACE 1
#define SHOW_PERSISTENTROUTE 2
extern ULONG g_ulNumTopCmds; extern ULONG g_ulNumGroups;
extern CMD_GROUP_ENTRY g_IpCmdGroups[]; extern CMD_ENTRY g_IpCmds[];
DWORD PreHandleCommand( IN LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount,
IN TAG_TYPE *pttTags, IN DWORD dwTagCount, IN DWORD dwMinArgs, IN DWORD dwMaxArgs, OUT DWORD *pdwTagType ) { ZeroMemory(pdwTagType, sizeof(DWORD) * dwMaxArgs); return PreprocessCommand(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, dwTagCount, dwMinArgs, dwMaxArgs, pdwTagType); }
DWORD HandleIpUpdate( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone )
/*++
Routine Description:
Updates IP autostatic routes on an interface Arguments:
Return Value:
NO_ERROR
--*/
{ TAG_TYPE rgTags[] = {TOKEN_NAME, TRUE,FALSE}; DWORD dwErr, dwSize, dwTagType = -1; WCHAR rgwcIfName[MAX_INTERFACE_NAME_LEN+1];
if (dwArgCount != 3) { //
// Need the name of the interface
//
return ERROR_INVALID_SYNTAX; }
dwErr = MatchTagsInCmdLine(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, rgTags, sizeof(rgTags)/sizeof(TAG_TYPE), &dwTagType);
if(dwErr isnot NO_ERROR) { if(dwErr is ERROR_INVALID_OPTION_TAG) { return ERROR_INVALID_SYNTAX; }
return dwErr; }
if(dwTagType isnot 0) { return ERROR_INVALID_SYNTAX; }
dwSize = sizeof(rgwcIfName);
IpmontrGetIfNameFromFriendlyName(ppwcArguments[dwCurrentIndex], rgwcIfName, &dwSize);
dwErr = UpdateAutoStaticRoutes(rgwcIfName);
return dwErr; }
// (almost) borrowed from netsh\if\utils.c
// compares dwAddress against all valid masks (all 33 of them!) till a match
BOOL ValidMask(DWORD dwAddress) { DWORD i, dwMask;
dwAddress = ntohl(dwAddress); // dwAddress is in network byte order
for (i=0, dwMask=0; i<33; (dwMask = ((dwMask>>1) + 0x80000000)), i++) { if (dwAddress == dwMask) return TRUE; }
return FALSE; }
DWORD IpAddDelIfFilter( PWCHAR *ppwcArguments, DWORD dwCurrentIndex, DWORD dwArgCount, BOOL bAdd )
/*++
Routine Description:
Gets options for add/del interface filters
Arguments: ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg bAdd - To add or to delete
Return Value:
NO_ERROR --*/
{ FILTER_INFO fi; DWORD dwBitVector = 0, dwNumParsed = 0; DWORD dwErr = NO_ERROR,dwRes; PDWORD pdwTagType; DWORD dwNumOpt, dwStatus = (DWORD) -1; DWORD dwNumTags = 11, dwNumArg, i, j, dwFilterType; WCHAR wszIfName[MAX_INTERFACE_NAME_LEN + 1] = L"\0"; BOOL bTags = FALSE, bOkay = TRUE; TAG_TYPE pttTags[] = {{TOKEN_NAME,TRUE,FALSE}, {TOKEN_FILTER_TYPE,TRUE,FALSE}, {TOKEN_SOURCE_ADDRESS,TRUE,FALSE}, {TOKEN_SOURCE_MASK,TRUE,FALSE}, {TOKEN_DEST_ADDRESS,TRUE,FALSE}, {TOKEN_DEST_MASK,TRUE,FALSE}, {TOKEN_PROTOCOL,TRUE,FALSE}, {TOKEN_SOURCE_PORT,TRUE,FALSE}, {TOKEN_DEST_PORT,TRUE,FALSE}, {TOKEN_TYPE,TRUE,FALSE}, {TOKEN_CODE,TRUE,FALSE}};
if (dwCurrentIndex >= dwArgCount) { //
// No arguments specified
//
return ERROR_SHOW_USAGE; }
ZeroMemory(&fi, sizeof(fi)); dwNumArg = dwArgCount - dwCurrentIndex;
pdwTagType = HeapAlloc(GetProcessHeap(), 0, dwNumArg * sizeof(DWORD));
if (pdwTagType is NULL) { DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY); return ERROR_NOT_ENOUGH_MEMORY; }
dwErr = MatchTagsInCmdLine(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, dwNumTags, pdwTagType);
if (dwErr isnot NO_ERROR) { if (dwErr is ERROR_INVALID_OPTION_TAG) { dwErr = ERROR_INVALID_SYNTAX; // show usage
}
HeapFree(GetProcessHeap(),0,pdwTagType); return dwErr; }
bTags = TRUE;
for ( i = 0; i < dwNumArg; i++) { switch (pdwTagType[i]) { case 0 : { DWORD BufLen = sizeof(wszIfName); GetInterfaceName(ppwcArguments[i + dwCurrentIndex], wszIfName, BufLen, &dwNumParsed);
// no filters allowed on INTERNAL/LOOPBACK interfaces
if (!_wcsicmp(wszIfName, L"internal") or !_wcsicmp(wszIfName, L"loopback")) { DisplayMessage(g_hModule, MSG_IP_BAD_INTERFACE_TYPE, wszIfName); dwErr = ERROR_INVALID_PARAMETER; i = dwNumArg; } break; }
case 1: { TOKEN_VALUE rgEnums[] = {{TOKEN_VALUE_INPUT, IP_IN_FILTER_INFO}, {TOKEN_VALUE_OUTPUT, IP_OUT_FILTER_INFO}, {TOKEN_VALUE_DIAL, IP_DEMAND_DIAL_FILTER_INFO}};
//
// Tag FILTERTYPE
//
dwErr = MatchEnumTag(g_hModule, ppwcArguments[i + dwCurrentIndex], sizeof(rgEnums)/sizeof(TOKEN_VALUE), rgEnums, &dwRes);
if(dwErr != NO_ERROR) { DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE, pttTags[pdwTagType[i]].pwszTag, ppwcArguments[i + dwCurrentIndex]);
DisplayMessage( g_hModule, MSG_IP_BAD_OPTION_ENUMERATION, pttTags[pdwTagType[i]].pwszTag ); for (i=0; i<sizeof(rgEnums)/sizeof(TOKEN_VALUE); i++) { DisplayMessageT( L" %1!s!\n", rgEnums[i].pwszToken ); }
i = dwNumArg; dwErr = NO_ERROR; bOkay = FALSE; break; }
dwFilterType = dwRes;
break; }
case 2: { dwErr = GetIpAddress(ppwcArguments[i + dwCurrentIndex], &fi.dwSrcAddr); if(dwErr is ERROR_INVALID_PARAMETER) { DisplayMessage(g_hModule, MSG_IP_BAD_IP_ADDR, ppwcArguments[i + dwCurrentIndex]);
DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE, pttTags[pdwTagType[i]].pwszTag, ppwcArguments[i + dwCurrentIndex]); dwErr = ERROR_INVALID_PARAMETER; i = dwNumArg; break; }
//
// Get the src mask too.
//
if (pdwTagType[i+1] != 3) { //
// Addr Mask pair not present
//
dwErr = ERROR_INVALID_SYNTAX; i = dwNumArg; break; }
dwErr = GetIpAddress(ppwcArguments[i + 1 + dwCurrentIndex], &fi.dwSrcMask);
if ((dwErr is ERROR_INVALID_PARAMETER) or (!ValidMask(fi.dwSrcMask)) or ((fi.dwSrcAddr & fi.dwSrcMask) isnot fi.dwSrcAddr)) { DisplayMessage(g_hModule, MSG_IP_BAD_IP_ADDR, ppwcArguments[i + 1 + dwCurrentIndex]);
DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE, pttTags[pdwTagType[i + 1]].pwszTag, ppwcArguments[i + dwCurrentIndex + 1]);
dwErr = ERROR_INVALID_PARAMETER;
i = dwNumArg;
break; }
i++; break; }
case 4 : { dwErr = GetIpAddress(ppwcArguments[i + dwCurrentIndex], &fi.dwDstAddr); if(dwErr is ERROR_INVALID_PARAMETER) { DisplayMessage(g_hModule, MSG_IP_BAD_IP_ADDR, ppwcArguments[i + dwCurrentIndex]); DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE, pttTags[pdwTagType[i]].pwszTag, ppwcArguments[i + dwCurrentIndex]);
dwErr = ERROR_INVALID_PARAMETER;
i = dwNumArg;
break; }
//
// Get the dst mask too.
//
if (pdwTagType[i+1] != 5) { //
// Addr Mask pair not present
//
dwErr = ERROR_INVALID_SYNTAX; i = dwNumArg; break; }
dwErr = GetIpAddress(ppwcArguments[i + 1 + dwCurrentIndex], &fi.dwDstMask);
if ((dwErr is ERROR_INVALID_PARAMETER) or (!ValidMask(fi.dwDstMask)) or ((fi.dwDstAddr & fi.dwDstMask) isnot fi.dwDstAddr)) { DisplayMessage(g_hModule, MSG_IP_BAD_IP_ADDR, ppwcArguments[i + 1 + dwCurrentIndex]);
DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE, pttTags[pdwTagType[i + 1]].pwszTag, ppwcArguments[i + 1 + dwCurrentIndex]);
dwErr = ERROR_INVALID_PARAMETER;
i = dwNumArg;
break; }
i++;
break; }
case 6: { TOKEN_VALUE rgEnums[] = { {TOKEN_VALUE_ANY, FILTER_PROTO_ANY}, {TOKEN_VALUE_TCP, FILTER_PROTO_TCP}, {TOKEN_VALUE_TCP_ESTAB, FILTER_PROTO_TCP}, {TOKEN_VALUE_UDP, FILTER_PROTO_UDP}, {TOKEN_VALUE_ICMP, FILTER_PROTO_ICMP} }; if (MatchEnumTag(g_hModule, ppwcArguments[i + dwCurrentIndex], sizeof(rgEnums)/sizeof(TOKEN_VALUE), rgEnums, &dwRes) != NO_ERROR) { //
// In this case see if its a valid value
//
dwRes = wcstoul(ppwcArguments[i + dwCurrentIndex], NULL, 10);
if((dwRes < 1) || (dwRes > 255)) { DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE, pttTags[pdwTagType[i]].pwszTag, ppwcArguments[i + dwCurrentIndex]);
DisplayMessage( g_hModule, MSG_IP_BAD_OPTION_ENUMERATION, pttTags[pdwTagType[i]].pwszTag ); for (i=0; i<sizeof(rgEnums)/sizeof(TOKEN_VALUE); i++) { DisplayMessageT( L" %1!s!\n", rgEnums[i].pwszToken ); }
i = dwNumArg; dwErr = NO_ERROR; bOkay = FALSE; break; } }
fi.dwProtocol = dwRes;
switch (fi.dwProtocol) { case FILTER_PROTO_ANY : //
// We are done
//
fi.wSrcPort = fi.wDstPort = 0; break;
case FILTER_PROTO_TCP : // TCP and TCP_ESTABLISHED have same protocol number
if (!MatchToken(ppwcArguments[i + dwCurrentIndex], TOKEN_VALUE_TCP)) { fi.fLateBound |= TCP_ESTABLISHED_FLAG; } // continue processing as we could for UDP...
case FILTER_PROTO_UDP : //
// Get the src and dst ports too
//
if (i + 2 >= dwNumArg) { dwErr = ERROR_INVALID_SYNTAX; i = dwNumArg; break; } if (bTags && (pdwTagType[i+1] != 7 || pdwTagType[i+2] != 8)) { dwErr = ERROR_INVALID_SYNTAX; i = dwNumArg; break; }
fi.wSrcPort = htons((WORD)wcstoul(ppwcArguments[i + 1 + dwCurrentIndex], NULL, 10));
fi.wDstPort = htons((WORD)wcstoul(ppwcArguments[i + 2 + dwCurrentIndex], NULL, 10));
i += 2;
break;
case FILTER_PROTO_ICMP :
//
// Get the src and dst ports too
//
if (i + 2 >= dwNumArg) { dwErr = ERROR_INVALID_SYNTAX; i = dwNumArg; break; }
// src and dest ports acted upon as type and code
if (bTags && (pdwTagType[i+1] != 7 || pdwTagType[i+2] != 8) && (pdwTagType[i+1] != 9 || pdwTagType[i+2] != 10)) { dwErr = ERROR_INVALID_SYNTAX; i = dwNumArg; break; }
fi.wSrcPort = (BYTE)wcstoul(ppwcArguments[i + 1 + dwCurrentIndex], NULL, 10);
fi.wDstPort = (BYTE)wcstoul(ppwcArguments[i + 2 + dwCurrentIndex], NULL, 10);
i += 2;
break;
default: { //
// any 'other' protocol
//
fi.wSrcPort = fi.wDstPort = 0; break; } }
break; } default: { i = dwNumArg; dwErr = ERROR_INVALID_SYNTAX; break; } } }
HeapFree(GetProcessHeap(), 0, pdwTagType);
switch(dwErr) { case NO_ERROR : break;
default: return dwErr; }
if (!bOkay) { return NO_ERROR; }
//
// Make sure all parameters are present
//
if ( !pttTags[0].bPresent || !pttTags[1].bPresent || !pttTags[2].bPresent || !pttTags[3].bPresent || !pttTags[4].bPresent || !pttTags[5].bPresent || !pttTags[6].bPresent ) { DisplayMessage(g_hModule, MSG_CANT_FIND_EOPT);
return ERROR_INVALID_SYNTAX; } dwErr = AddDelFilterInfo(fi, wszIfName, dwFilterType, bAdd);
return dwErr; }
DWORD HandleIpAddIfFilter( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone )
/*++
Routine Description:
Gets options for add interface filters
Arguments:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR --*/ { return IpAddDelIfFilter(ppwcArguments, dwCurrentIndex, dwArgCount, TRUE); }
DWORD HandleIpDelIfFilter( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone )
/*++
Routine Description:
Gets options for del interface filters
Arguments:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR --*/ { return IpAddDelIfFilter(ppwcArguments, dwCurrentIndex, dwArgCount, FALSE); }
DWORD IpAddSetDelRtmRoute( PWCHAR *ppwcArguments, DWORD dwCurrentIndex, DWORD dwArgCount, DWORD dwCommand )
/*++
Routine Description:
Gets options for add/del routes over interfaces. These operations are performed directly to RTM and do not involve the registry. As persistence is not involved, we need the router to be running.
Arguments: ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg dwCommand - To add, set, or delete
Return Value:
NO_ERROR --*/
{ INTERFACE_ROUTE_INFO route; DWORD dwNumParsed, dwErr, dwRes; DWORD dwNumOpt, dwStatus = (DWORD) -1; DWORD dwNumArg, i; WCHAR wszIfName[MAX_INTERFACE_NAME_LEN + 1] = L"\0"; TAG_TYPE pttTags[] = {{TOKEN_DEST,TRUE,FALSE}, {TOKEN_MASK,FALSE,FALSE}, {TOKEN_NAMEINDEX,FALSE,FALSE}, {TOKEN_NHOP,FALSE,FALSE}, {TOKEN_PREFERENCE,FALSE,FALSE}, {TOKEN_METRIC,FALSE,FALSE}, {TOKEN_VIEW,FALSE,FALSE}}; enum idx {DEST, MASK, NAMEINDEX, NHOP, PREFERENCE, METRIC, VIEW}; DWORD pdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; DWORD dwMaxArgs; DWORD dwIfClass; DWORD dwFlags; PINTERFACE_ROUTE_INFO pTable = NULL;
//
// We can add non persistent routes only if router is running
//
CHECK_ROUTER_RUNNING();
ZeroMemory(&route, sizeof(route));
route.dwRtInfoProto = PROTO_IP_NETMGMT; // default proto
route.dwRtInfoPreference = 0; // default preference = protocol default
route.dwRtInfoMetric1 = 1; // default metric
route.dwRtInfoMetric2 = MIB_IPROUTE_METRIC_UNUSED; route.dwRtInfoMetric3 = MIB_IPROUTE_METRIC_UNUSED; route.dwRtInfoViewSet = RTM_VIEW_MASK_UCAST | RTM_VIEW_MASK_MCAST;
// Do generic processing
dwErr = PreHandleCommand( ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 1, sizeof(pttTags)/sizeof(TAG_TYPE), pdwTagType );
if (dwErr) { return dwErr; }
dwNumArg = dwArgCount - dwCurrentIndex;
//
// At this point, the arg array contains only values (either because
// the tags werent present, or because that info has now been split out)
// So we go through each of the each of the arguments, look up its tag
// type in the tag array, switch on the type of tag it is and then
// process accordingly.
//
for (i = 0; i < dwNumArg; i++) { switch (pdwTagType[i]) { case DEST: // DEST
{ dwErr = GetIpPrefix(ppwcArguments[i + dwCurrentIndex], &route.dwRtInfoDest, &route.dwRtInfoMask); break; }
case MASK: // MASK
{ dwErr = GetIpMask(ppwcArguments[i + dwCurrentIndex], &route.dwRtInfoMask); break; }
case NAMEINDEX : // INDEX or NAME
{ PWCHAR endptr = NULL; DWORD BufLen;
//
// Initially consider the user input to be the friendly name of the
// interface
// If we fail to get the interface name from this friendly name
// then we shall try considering the user as an index
//
route.dwRtInfoIfIndex = 0; BufLen = sizeof(wszIfName); dwErr = GetInterfaceName(ppwcArguments[i + dwCurrentIndex], wszIfName, BufLen, &dwNumParsed);
if (dwErr != NO_ERROR) { // If it starts with '0x', this is a hex index
// else if it starts with 0, this is an 0ctal index
// else it is decimal or an interface name
//
if ((ppwcArguments[i + dwCurrentIndex][0] == L'0') && (ppwcArguments[i + dwCurrentIndex][1] == L'x')) { route.dwRtInfoIfIndex = wcstoul(ppwcArguments[i + dwCurrentIndex], &endptr, 16); } else if ( ppwcArguments[i + dwCurrentIndex][0] == L'0') { route.dwRtInfoIfIndex = wcstoul(ppwcArguments[i + dwCurrentIndex], &endptr, 8); } else { route.dwRtInfoIfIndex = wcstoul(ppwcArguments[i + dwCurrentIndex], &endptr, 10); }
//
// If all the characters in the field were not used while doing the
// conversion, then we know that the input was not purely
/// numeric, and is thus invalid as an index value
//
if (*endptr != L'\0') { DisplayMessage(g_hModule, EMSG_CANT_MATCH_NAME); return ERROR_INVALID_PARAMETER; } }
break; }
case NHOP: // NHOP
{ dwErr = GetIpAddress(ppwcArguments[i + dwCurrentIndex], &route.dwRtInfoNextHop); break; }
case PREFERENCE: { route.dwRtInfoPreference = wcstoul(ppwcArguments[i + dwCurrentIndex], NULL, 10); break; }
case METRIC: // METRIC
{ route.dwRtInfoMetric1 = wcstoul(ppwcArguments[i + dwCurrentIndex], NULL, 10); break; }
case VIEW: { TOKEN_VALUE rgMaskEnums[] = { { TOKEN_VALUE_UNICAST, RTM_VIEW_MASK_UCAST }, { TOKEN_VALUE_MULTICAST, RTM_VIEW_MASK_MCAST }, { TOKEN_VALUE_BOTH, RTM_VIEW_MASK_UCAST |RTM_VIEW_MASK_MCAST } };
dwErr = MatchEnumTag( g_hModule, ppwcArguments[i + dwCurrentIndex], sizeof(rgMaskEnums)/sizeof(TOKEN_VALUE), rgMaskEnums, &route.dwRtInfoViewSet);
if (dwErr isnot NO_ERROR) { DispTokenErrMsg( g_hModule, MSG_IP_BAD_OPTION_VALUE, pttTags[pdwTagType[i]].pwszTag, ppwcArguments[i + dwCurrentIndex] );
i = dwArgCount;
return ERROR_INVALID_PARAMETER; }
break; } } }
if (dwErr) { return dwErr; }
if (route.dwRtInfoDest & ~route.dwRtInfoMask) { // Mask contains bits not in address
DisplayMessage(g_hModule, EMSG_PREFIX_ERROR); return ERROR_INVALID_PARAMETER; }
if (!pttTags[NAMEINDEX].bPresent) { //
// Neither NAME nor INDEX - adding with a nexthop
//
PMIB_IPADDRTABLE AddrTable; PMIB_IPADDRROW AddrEntry; MIB_OPAQUE_QUERY Query; PMIB_OPAQUE_INFO Info; DWORD dwQuerySize; DWORD dwEntrySize; INT iFirstMatch; UINT Count;
if (!pttTags[NHOP].bPresent) { DisplayMessage(g_hModule, EMSG_CANT_FIND_NAME_OR_NHOP); return ERROR_INVALID_SYNTAX; }
//
// Search for the interface that matches nexthop
//
dwQuerySize = sizeof(MIB_OPAQUE_QUERY) - sizeof(DWORD);
Query.dwVarId = IP_ADDRTABLE;
dwErr = MibGet(PID_IP, IPRTRMGR_PID, (PVOID) &Query, dwQuerySize, (PVOID *) &Info, &dwEntrySize);
if (dwErr != NO_ERROR) { DisplayMessage(g_hModule, MSG_IP_DIM_ERROR, dwErr); return ERROR_SUPPRESS_OUTPUT; } if (Info is NULL) { DisplayMessage(g_hModule, EMSG_CANT_FIND_INDEX); return ERROR_INVALID_PARAMETER; } AddrTable = (PMIB_IPADDRTABLE)Info->rgbyData;
iFirstMatch = -1;
for (Count = 0; Count < AddrTable->dwNumEntries; Count++) { AddrEntry = &AddrTable->table[Count];
if ((route.dwRtInfoNextHop & AddrEntry->dwMask) == (AddrEntry->dwAddr & AddrEntry->dwMask)) { if (iFirstMatch != -1) { //
// We already matched an interface
// [Ambiguous next hop description]
//
MprAdminMIBBufferFree((PVOID)Info); DisplayMessage(g_hModule, EMSG_AMBIGUOUS_INDEX_FROM_NHOP); return ERROR_INVALID_PARAMETER; }
iFirstMatch = Count; } } if (iFirstMatch == -1) { //
// Could not find the direct nexthop
//
MprAdminMIBBufferFree((PVOID)Info); DisplayMessage(g_hModule, EMSG_CANT_FIND_INDEX); return ERROR_INVALID_PARAMETER; }
//
// Found the interface used to reach nexthop
//
route.dwRtInfoIfIndex = AddrTable->table[iFirstMatch].dwIndex;
MprAdminMIBBufferFree((PVOID)Info); }
if (route.dwRtInfoIfIndex) { //
// Check if this index has a public exported name
//
dwErr = GetGuidFromIfIndex(g_hMIBServer, route.dwRtInfoIfIndex, wszIfName, MAX_INTERFACE_NAME_LEN); if ( dwErr != NO_ERROR ) { DisplayMessage(g_hModule, EMSG_CANT_FIND_INDEX); return ERROR_INVALID_PARAMETER; } } if (wszIfName[0] != L'\0') { //
// NAME specified, or derived from INDEX above
//
dwErr = GetInterfaceClass(wszIfName, &dwIfClass);
//
// If we get an error, we will skip remaining
// checks which will be performed by iprtrmgr
//
if (dwErr == NO_ERROR) { if (dwIfClass is IFCLASS_LOOPBACK) { return ERROR_INVALID_SYNTAX; }
if (!pttTags[NHOP].bPresent) { // Make sure interface is p2p
if (dwIfClass isnot IFCLASS_P2P) { DisplayMessage(g_hModule, EMSG_NEED_NHOP); return ERROR_INVALID_PARAMETER; } } } } else { DisplayMessage(g_hModule, EMSG_CANT_MATCH_NAME); return ERROR_INVALID_PARAMETER; }
//
// If it is a set, we should not overwrite things not specified
//
dwFlags = ALL_FIELDS_SPECIFIED;
if (dwCommand == SET_COMMAND) { if (!pttTags[PREFERENCE].bPresent) dwFlags |= PREF_NOT_SPECIFIED; if (!pttTags[METRIC].bPresent) dwFlags |= METRIC_NOT_SPECIFIED; if (!pttTags[VIEW].bPresent) dwFlags |= VIEW_NOT_SPECIFIED; }
return AddSetDelRtmRouteInfo(&route, wszIfName, dwCommand, dwFlags); }
DWORD HandleIpAddRtmRoute( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { return IpAddSetDelRtmRoute(ppwcArguments, dwCurrentIndex, dwArgCount, ADD_COMMAND); }
DWORD HandleIpDelRtmRoute( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { return IpAddSetDelRtmRoute(ppwcArguments, dwCurrentIndex, dwArgCount, DELETE_COMMAND); }
DWORD HandleIpSetRtmRoute( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { return IpAddSetDelRtmRoute(ppwcArguments, dwCurrentIndex, dwArgCount, SET_COMMAND); }
DWORD IpAddSetDelPersistentRoute( PWCHAR *ppwcArguments, DWORD dwCurrentIndex, DWORD dwArgCount, DWORD dwCommand )
/*++
Routine Description:
Gets options for add/del routes over interfaces. These operations are performed directly to the registry and so these routes are persistent. If the router is running, they go into the RTM too.
Arguments: ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg dwCommand - To add, set, or delete
Return Value:
NO_ERROR --*/
{ INTERFACE_ROUTE_INFO route; DWORD dwNumParsed, dwErr, dwRes; DWORD dwNumOpt, dwStatus = (DWORD) -1; DWORD dwNumArg, i; WCHAR wszIfName[MAX_INTERFACE_NAME_LEN + 1] = L"\0"; WCHAR *pwszIfNameOnCmdLine = NULL; TAG_TYPE pttTags[] = {{TOKEN_DEST,TRUE,FALSE}, {TOKEN_MASK,FALSE,FALSE}, {TOKEN_NAME,FALSE,FALSE}, {TOKEN_NHOP,FALSE,FALSE}, {TOKEN_PROTOCOL,FALSE,FALSE}, {TOKEN_PREFERENCE,FALSE,FALSE}, {TOKEN_METRIC,FALSE,FALSE}, {TOKEN_VIEW,FALSE,FALSE}}; enum idx {DEST, MASK, NAME, NHOP, PROTO, PREFERENCE, METRIC, VIEW}; DWORD pdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; DWORD dwMaxArgs; DWORD dwIfClass; DWORD dwFlags; PINTERFACE_ROUTE_INFO pTable = NULL;
ZeroMemory(&route, sizeof(route));
route.dwRtInfoProto = PROTO_IP_NT_STATIC_NON_DOD; // default proto
route.dwRtInfoPreference = 0; // default preference = protocol default
route.dwRtInfoMetric1 = 1; // default metric
route.dwRtInfoMetric2 = MIB_IPROUTE_METRIC_UNUSED; route.dwRtInfoMetric3 = MIB_IPROUTE_METRIC_UNUSED; route.dwRtInfoViewSet = RTM_VIEW_MASK_UCAST | RTM_VIEW_MASK_MCAST;
// Do generic processing
dwErr = PreHandleCommand( ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 1, sizeof(pttTags)/sizeof(TAG_TYPE), pdwTagType );
if (dwErr) { return dwErr; }
dwNumArg = dwArgCount - dwCurrentIndex;
//
// At this point, the arg array contains only values (either because
// the tags werent present, or because that info has now been split out)
// So we go through each of the each of the arguments, look up its tag
// type in the tag array, switch on the type of tag it is and then
// process accordingly.
//
for (i = 0; i < dwNumArg; i++) { switch (pdwTagType[i]) { case DEST: // DEST
{ dwErr = GetIpPrefix(ppwcArguments[i + dwCurrentIndex], &route.dwRtInfoDest, &route.dwRtInfoMask); break; }
case MASK: // MASK
{ dwErr = GetIpMask(ppwcArguments[i + dwCurrentIndex], &route.dwRtInfoMask); break; }
case NAME : // NAME
{ DWORD BufLen = sizeof(wszIfName); pwszIfNameOnCmdLine = ppwcArguments[i + dwCurrentIndex]; GetInterfaceName(ppwcArguments[i + dwCurrentIndex], wszIfName, BufLen, &dwNumParsed); break; }
case NHOP: // NHOP
{ dwErr = GetIpAddress(ppwcArguments[i + dwCurrentIndex], &route.dwRtInfoNextHop); break; }
case PROTO : // PROTO
{ TOKEN_VALUE rgEnums[] = {/*{TOKEN_VALUE_AUTOSTATIC, PROTO_IP_NT_AUTOSTATIC},*/ {TOKEN_VALUE_STATIC, PROTO_IP_NT_STATIC}, {TOKEN_VALUE_NONDOD, PROTO_IP_NT_STATIC_NON_DOD}};
dwErr = MatchEnumTag(g_hModule, ppwcArguments[i + dwCurrentIndex], sizeof(rgEnums)/sizeof(TOKEN_VALUE), rgEnums, &dwRes);
if (dwErr != NO_ERROR) { DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE, pttTags[pdwTagType[i]].pwszTag, ppwcArguments[i + dwCurrentIndex]);
DisplayMessage( g_hModule, MSG_IP_BAD_OPTION_ENUMERATION, pttTags[pdwTagType[i]].pwszTag ); for (i=0; i<sizeof(rgEnums)/sizeof(TOKEN_VALUE); i++) { DisplayMessageT( L" %1!s!\n", rgEnums[i].pwszToken ); }
return ERROR_SUPPRESS_OUTPUT; }
route.dwRtInfoProto = dwRes; break; }
case PREFERENCE: { route.dwRtInfoPreference = wcstoul(ppwcArguments[i + dwCurrentIndex], NULL, 10); break; }
case METRIC: { route.dwRtInfoMetric1 = wcstoul(ppwcArguments[i + dwCurrentIndex], NULL, 10); break; }
case VIEW: { TOKEN_VALUE rgMaskEnums[] = { { TOKEN_VALUE_UNICAST, RTM_VIEW_MASK_UCAST }, { TOKEN_VALUE_MULTICAST, RTM_VIEW_MASK_MCAST }, { TOKEN_VALUE_BOTH, RTM_VIEW_MASK_UCAST |RTM_VIEW_MASK_MCAST } };
dwErr = MatchEnumTag( g_hModule, ppwcArguments[i + dwCurrentIndex], sizeof(rgMaskEnums)/sizeof(TOKEN_VALUE), rgMaskEnums, &route.dwRtInfoViewSet);
if (dwErr isnot NO_ERROR) { DispTokenErrMsg( g_hModule, MSG_IP_BAD_OPTION_VALUE, pttTags[pdwTagType[i]].pwszTag, ppwcArguments[i + dwCurrentIndex] );
i = dwArgCount;
return ERROR_SUPPRESS_OUTPUT; }
break; } } }
if (dwErr) { return dwErr; }
if (route.dwRtInfoDest & ~route.dwRtInfoMask) { // Mask contains bits not in address
DisplayMessage(g_hModule, EMSG_PREFIX_ERROR); return ERROR_SUPPRESS_OUTPUT; }
if (!pttTags[NAME].bPresent) { // Need if name to add persistent route
DisplayMessage(g_hModule, EMSG_CANT_FIND_NAME); return ERROR_SUPPRESS_OUTPUT; } dwErr = GetInterfaceClass(wszIfName, &dwIfClass);
if (dwErr) { DisplayMessage(g_hModule, EMSG_CANT_GET_IF_INFO, pwszIfNameOnCmdLine, dwErr);
return ERROR_SUPPRESS_OUTPUT; } if (dwIfClass is IFCLASS_LOOPBACK) { return ERROR_INVALID_SYNTAX; }
if (!pttTags[NHOP].bPresent) { // Make sure interface is p2p
if (dwIfClass isnot IFCLASS_P2P) { DisplayMessage(g_hModule, EMSG_NEED_NHOP); return ERROR_SUPPRESS_OUTPUT; } }
if (dwIfClass is IFCLASS_P2P) { if (!pttTags[PROTO].bPresent) { // if not explicitly specified, change protocol to static
route.dwRtInfoProto = PROTO_IP_NT_STATIC; // default proto
}
// Make sure nhop is not specified.
if (pttTags[NHOP].bPresent) { // if class is p2p, then nhop specification is not allowed
DisplayMessage(g_hModule, EMSG_P2P_WITH_NHOP, pwszIfNameOnCmdLine); return ERROR_SUPPRESS_OUTPUT; } } else { // make sure we didn't try to set static on a non-P2P interface
if (route.dwRtInfoProto is PROTO_IP_NT_STATIC) { return ERROR_INVALID_PARAMETER; } }
//
// If it is a set, we should not overwrite things not specified
//
dwFlags = ALL_FIELDS_SPECIFIED;
if (dwCommand == SET_COMMAND) { if (!pttTags[PREFERENCE].bPresent) dwFlags |= PREF_NOT_SPECIFIED; if (!pttTags[METRIC].bPresent) dwFlags |= METRIC_NOT_SPECIFIED; if (!pttTags[VIEW].bPresent) dwFlags |= VIEW_NOT_SPECIFIED; }
return AddSetDelPersistentRouteInfo(&route, wszIfName, dwCommand, dwFlags); }
DWORD HandleIpAddPersistentRoute( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { return IpAddSetDelPersistentRoute(ppwcArguments, dwCurrentIndex, dwArgCount, ADD_COMMAND); }
DWORD HandleIpDelPersistentRoute( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { return IpAddSetDelPersistentRoute(ppwcArguments, dwCurrentIndex, dwArgCount, DELETE_COMMAND); }
DWORD HandleIpSetPersistentRoute( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { return IpAddSetDelPersistentRoute(ppwcArguments, dwCurrentIndex, dwArgCount, SET_COMMAND); }
DWORD HandleIpAddRoutePref( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone )
/*++
Routine Description:
Gets options for adding route preferences
Arguments:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR --*/
{
PPROTOCOL_METRIC ppm; DWORD dwBitVector = 0, dwNumPref,dwPrefIndex; DWORD dwErr = NO_ERROR,dwRes; PDWORD pdwTagType; DWORD dwNumTags = 2, dwNumArg, i, dwAddr; TAG_TYPE pttTags[] = {{TOKEN_PROTOCOL, TRUE,FALSE}, {TOKEN_PREF_LEVEL, TRUE,FALSE}};
if (dwCurrentIndex >= dwArgCount) { //
// No arguments specified
//
return ERROR_SHOW_USAGE; } dwNumArg = dwArgCount - dwCurrentIndex;
pdwTagType = HeapAlloc(GetProcessHeap(), 0, dwNumArg * sizeof(DWORD));
if (pdwTagType is NULL) { DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY); return ERROR_NOT_ENOUGH_MEMORY; }
dwErr = MatchTagsInCmdLine(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, dwNumTags, pdwTagType);
if (dwErr isnot NO_ERROR) { HeapFree(GetProcessHeap(),0,pdwTagType);
if (dwErr is ERROR_INVALID_OPTION_TAG) { dwErr = ERROR_INVALID_SYNTAX; // show usage
}
return dwErr; }
dwNumPref = dwNumArg / 2 + dwNumArg % 2;
ppm = HeapAlloc(GetProcessHeap(), 0, dwNumPref * sizeof(PROTOCOL_METRIC));
if (ppm is NULL) { HeapFree(GetProcessHeap(),0,pdwTagType);
DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY); return ERROR_SUPPRESS_OUTPUT; }
for ( i = 0, dwPrefIndex = 0; i < dwNumArg; i++) { switch (pdwTagType[i]) { case 0: { //
// TAG = PROTOCOL
//
dwRes = MatchRoutingProtoTag(ppwcArguments[i + dwCurrentIndex]);
if (dwRes == (DWORD) -1) { DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE, pttTags[pdwTagType[i]].pwszTag, ppwcArguments[i + dwCurrentIndex]); i = dwNumArg; dwErr = ERROR_SUPPRESS_OUTPUT; break; }
ppm[dwPrefIndex].dwProtocolId = dwRes;
//
// Get the metric too
//
if (pdwTagType[i+1] == 1) { ppm[dwPrefIndex].dwMetric = wcstoul(ppwcArguments[i + 1 +dwCurrentIndex],NULL,10);
if (ppm[dwPrefIndex].dwMetric==0 && wcscmp(ppwcArguments[i + 1 +dwCurrentIndex], L"0")!=0) { dwErr = ERROR_INVALID_SYNTAX; i = dwNumArg; break; }
i++; dwPrefIndex++; } else { //
// the range is not an addr mask pair.
// So ignore the addr (i.e. don't increment dwRangeIndex)
//
dwErr = ERROR_INVALID_SYNTAX; i = dwNumArg; break; }
break; }
default : { i = dwNumArg; dwErr = ERROR_INVALID_SYNTAX; break; } } }
HeapFree(GetProcessHeap(), 0, pdwTagType);
switch(dwErr) { case NO_ERROR : break;
default: return dwErr; }
if (dwPrefIndex) { //
// Add route pref
//
dwRes = AddDeleteRoutePrefLevel(ppm, dwPrefIndex, TRUE); }
HeapFree(GetProcessHeap(), 0, ppm);
return dwErr; }
DWORD HandleIpDelRoutePref( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) /*++
Routine Description:
Gets options for deleting route preferences
Arguments:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR --*/ { PPROTOCOL_METRIC ppm; DWORD dwBitVector = 0, dwNumPref,dwPrefIndex; DWORD dwErr = NO_ERROR,dwRes; TAG_TYPE pttTags[] = {{TOKEN_PROTOCOL,TRUE,FALSE}};
PDWORD pdwTagType; DWORD dwNumTags = 1, dwNumArg, i, dwAddr;
if (dwCurrentIndex >= dwArgCount) { //
// No arguments specified
//
return ERROR_SHOW_USAGE; }
dwNumArg = dwArgCount - dwCurrentIndex;
pdwTagType = HeapAlloc(GetProcessHeap(), 0, dwNumArg * sizeof(DWORD));
if (pdwTagType is NULL) { DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY); return ERROR_SUPPRESS_OUTPUT; }
dwErr = MatchTagsInCmdLine(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, dwNumTags, pdwTagType);
if (dwErr isnot NO_ERROR) { HeapFree(GetProcessHeap(),0,pdwTagType); if (dwErr is ERROR_INVALID_OPTION_TAG) { dwErr = ERROR_INVALID_SYNTAX; // show usage
} return dwErr; }
dwNumPref = dwNumArg;
ppm = HeapAlloc(GetProcessHeap(), 0, dwNumPref * sizeof(PROTOCOL_METRIC));
if (ppm is NULL) { HeapFree(GetProcessHeap(),0,pdwTagType);
DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY); return ERROR_SUPPRESS_OUTPUT; }
for ( i = 0, dwPrefIndex = 0; i < dwNumArg; i++) { switch (pdwTagType[i]) { case 0: {
//
// TAG = PROTOCOL
//
dwRes = MatchRoutingProtoTag(ppwcArguments[i + dwCurrentIndex]);
if (dwRes == (DWORD) -1) { DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE, pttTags[pdwTagType[i]].pwszTag, ppwcArguments[i + dwCurrentIndex]); i = dwNumArg; dwErr = ERROR_SUPPRESS_OUTPUT; break; }
ppm[dwPrefIndex++].dwProtocolId = dwRes;
break; }
default : { i = dwNumArg;
dwErr = ERROR_INVALID_SYNTAX;
break; } } }
HeapFree(GetProcessHeap(), 0, pdwTagType);
switch(dwErr) { case NO_ERROR : break;
default: return dwErr; }
if (dwPrefIndex) { //
// Add route pref
//
dwRes = AddDeleteRoutePrefLevel(ppm, dwPrefIndex, FALSE); }
HeapFree(GetProcessHeap(), 0, ppm);
return dwErr; }
DWORD HandleIpSetRoutePref( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) /*++
Routine Description:
Gets options for setting route preferences
Arguments:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR --*/ { PROTOCOL_METRIC pm; DWORD dwBitVector = 0, dwNumPref,dwPrefIndex; DWORD dwErr = NO_ERROR,dwRes; TAG_TYPE pttTags[] = {{TOKEN_PROTOCOL, TRUE,FALSE}, {TOKEN_PREF_LEVEL, TRUE,FALSE}}; PDWORD pdwTagType; DWORD dwNumTags = 2, dwNumArg, i, dwAddr;
if (dwCurrentIndex >= dwArgCount) { //
// No arguments specified
//
return ERROR_SHOW_USAGE; }
dwNumArg = dwArgCount - dwCurrentIndex;
pdwTagType = HeapAlloc(GetProcessHeap(), 0, dwNumArg * sizeof(DWORD));
if (pdwTagType is NULL) { DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY); return ERROR_NOT_ENOUGH_MEMORY; }
dwErr = MatchTagsInCmdLine(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, dwNumTags, pdwTagType);
if (dwErr isnot NO_ERROR) { HeapFree(GetProcessHeap(),0,pdwTagType); if (dwErr is ERROR_INVALID_OPTION_TAG) { return ERROR_INVALID_SYNTAX; // show usage
} return dwErr; }
for ( i = 0, dwPrefIndex = 0; i < dwNumArg; i++) { switch (pdwTagType[i]) { case 0: // PROTOCOL
dwRes = MatchRoutingProtoTag(ppwcArguments[i + dwCurrentIndex]);
if (dwRes == (DWORD) -1) { DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE, pttTags[pdwTagType[i]].pwszTag, ppwcArguments[i + dwCurrentIndex]); i = dwNumArg; dwErr = ERROR_SUPPRESS_OUTPUT; break; }
pm.dwProtocolId = dwRes;
//
// Get the metric too
//
if (pdwTagType[i+1] == 1) { pm.dwMetric = wcstoul(ppwcArguments[i + 1 +dwCurrentIndex],NULL,10);
if (pm.dwMetric==0 && wcscmp(ppwcArguments[i + 1 +dwCurrentIndex], L"0")!=0) { dwErr = ERROR_INVALID_SYNTAX; i = dwNumArg; break; }
i++; dwPrefIndex++; } else { dwErr = ERROR_INVALID_SYNTAX; i = dwNumArg; break; }
break;
default : i = dwNumArg; dwErr = ERROR_INVALID_SYNTAX; break; } }
HeapFree(GetProcessHeap(), 0, pdwTagType);
switch(dwErr) { case NO_ERROR : break;
default: return dwErr; }
dwErr = SetRoutePrefLevel(pm);
return dwErr; }
DWORD HandleIpSetLogLevel( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) /*++
Routine Description:
Gets options for setting global parameter namely logging level
Arguments:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR --*/ { DWORD dwErr = NO_ERROR; TAG_TYPE pttTags[] = {{TOKEN_LOG_LEVEL,TRUE,FALSE}}; PDWORD pdwTagType; DWORD dwNumTags = 1, dwNumArg, i, dwAddr; DWORD dwLoggingLevel = (DWORD) -1; BOOL bOkay = TRUE; if (dwCurrentIndex >= dwArgCount) { //
// No arguments specified
//
return ERROR_SHOW_USAGE; }
dwNumArg = dwArgCount - dwCurrentIndex;
pdwTagType = HeapAlloc(GetProcessHeap(), 0, dwNumArg * sizeof(DWORD));
if (pdwTagType is NULL) { DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY); return ERROR_SUPPRESS_OUTPUT; }
dwErr = MatchTagsInCmdLine(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, dwNumTags, pdwTagType);
if (dwErr isnot NO_ERROR) { HeapFree(GetProcessHeap(),0,pdwTagType); if (dwErr is ERROR_INVALID_OPTION_TAG) { return ERROR_INVALID_SYNTAX; } return dwErr; }
for ( i = 0; i < dwNumArg; i++) { switch (pdwTagType[i]) { case 0: // LOGLEVEL
{ TOKEN_VALUE rgEnums[] = {{TOKEN_VALUE_NONE, IPRTR_LOGGING_NONE}, {TOKEN_VALUE_ERROR, IPRTR_LOGGING_ERROR}, {TOKEN_VALUE_WARN, IPRTR_LOGGING_WARN}, {TOKEN_VALUE_INFO, IPRTR_LOGGING_INFO}};
dwErr = MatchEnumTag(g_hModule, ppwcArguments[i + dwCurrentIndex], sizeof(rgEnums)/sizeof(TOKEN_VALUE), rgEnums, &dwLoggingLevel);
if (dwErr != NO_ERROR) { DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE, pttTags[pdwTagType[i]].pwszTag, ppwcArguments[i + dwCurrentIndex]);
DisplayMessage( g_hModule, MSG_IP_BAD_OPTION_ENUMERATION, pttTags[pdwTagType[i]].pwszTag ); for (i=0; i<4; i++) { DisplayMessageT( L" %1!s!\n", rgEnums[i].pwszToken ); }
i = dwNumArg;
dwErr = ERROR_SUPPRESS_OUTPUT; bOkay = FALSE;
break; }
break; }
default : { i = dwNumArg;
dwErr = ERROR_INVALID_SYNTAX;
break; } } }
HeapFree(GetProcessHeap(), 0, pdwTagType);
switch(dwErr) { case NO_ERROR : break;
default: return dwErr; }
if (!bOkay) { return NO_ERROR; }
dwErr = SetGlobalConfigInfo(dwLoggingLevel);
return dwErr; }
DWORD HandleIpSetIfFilter( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone )
/*++
Routine Description:
Gets options for setting interface filter parameters
Arguments:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR --*/ { DWORD dwNumParsed = 0; DWORD dwErr = NO_ERROR,dwRes; TAG_TYPE pttTags[] = {{TOKEN_NAME,TRUE,FALSE}, {TOKEN_FILTER_TYPE,FALSE,FALSE}, {TOKEN_ACTION,FALSE,FALSE}, {TOKEN_FRAGCHECK,FALSE,FALSE}}; PDWORD pdwTagType; DWORD dwNumOpt; DWORD dwNumTags = 4, dwNumArg, i, j; WCHAR wszIfName[MAX_INTERFACE_NAME_LEN + 1] = L"\0"; DWORD dwFilterType, dwAction; BOOL bFragCheck, bOkay = TRUE; if (dwCurrentIndex >= dwArgCount) { //
// No arguments specified
//
return ERROR_SHOW_USAGE; }
dwNumArg = dwArgCount - dwCurrentIndex;
pdwTagType = HeapAlloc(GetProcessHeap(), 0, dwNumArg * sizeof(DWORD));
if (pdwTagType is NULL) { DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY);
return ERROR_SUPPRESS_OUTPUT; }
dwErr = MatchTagsInCmdLine(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, dwNumTags, pdwTagType);
if (dwErr isnot NO_ERROR) { HeapFree(GetProcessHeap(),0,pdwTagType); if (dwErr is ERROR_INVALID_OPTION_TAG) { return ERROR_INVALID_SYNTAX; // show usage
} return dwErr; }
for ( i = 0; i < dwNumArg; i++) { switch (pdwTagType[i]) { case 0 : { DWORD BufLen = sizeof(wszIfName); GetInterfaceName(ppwcArguments[i + dwCurrentIndex], wszIfName, BufLen, &dwNumParsed); // no filters allowed on INTERNAL/LOOPBACK interfaces
if (!_wcsicmp(wszIfName, L"internal") or !_wcsicmp(wszIfName, L"loopback")) { DisplayMessage(g_hModule, MSG_IP_BAD_INTERFACE_TYPE, wszIfName); dwErr = ERROR_SUPPRESS_OUTPUT; i = dwNumArg; } break; }
case 1: { TOKEN_VALUE rgEnums[] = {{TOKEN_VALUE_INPUT, IP_IN_FILTER_INFO}, {TOKEN_VALUE_OUTPUT, IP_OUT_FILTER_INFO}, {TOKEN_VALUE_DIAL, IP_DEMAND_DIAL_FILTER_INFO}};
//
// Tag TYPE
//
dwErr = MatchEnumTag(g_hModule, ppwcArguments[i + dwCurrentIndex], sizeof(rgEnums)/sizeof(TOKEN_VALUE), rgEnums, &dwFilterType);
if (dwErr != NO_ERROR) { DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE, pttTags[pdwTagType[i]].pwszTag, ppwcArguments[i + dwCurrentIndex]);
DisplayMessage( g_hModule, MSG_IP_BAD_OPTION_ENUMERATION, pttTags[pdwTagType[i]].pwszTag ); for (i=0; i<sizeof(rgEnums)/sizeof(TOKEN_VALUE); i++) { DisplayMessageT( L" %1!s!\n", rgEnums[i].pwszToken ); }
i = dwNumArg; bOkay = FALSE; dwErr = ERROR_SUPPRESS_OUTPUT; break; }
break; }
case 2: { TOKEN_VALUE rgEnums[] = {{TOKEN_VALUE_DROP, PF_ACTION_DROP}, {TOKEN_VALUE_FORWARD, PF_ACTION_FORWARD}};
//
// Tag ACTION
//
dwErr = MatchEnumTag(g_hModule, ppwcArguments[i + dwCurrentIndex], sizeof(rgEnums)/sizeof(TOKEN_VALUE), rgEnums, &dwAction);
if (dwErr != NO_ERROR) { DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE, pttTags[pdwTagType[i]].pwszTag, ppwcArguments[i + dwCurrentIndex]);
DisplayMessage( g_hModule, MSG_IP_BAD_OPTION_ENUMERATION, pttTags[pdwTagType[i]].pwszTag ); for (i=0; i<sizeof(rgEnums)/sizeof(TOKEN_VALUE); i++) { DisplayMessageT( L" %1!s!\n", rgEnums[i].pwszToken ); }
i = dwNumArg;
dwErr = ERROR_SUPPRESS_OUTPUT; bOkay = FALSE;
break; }
break; }
case 3: { TOKEN_VALUE rgEnums[] = {{TOKEN_VALUE_ENABLE, TRUE}, {TOKEN_VALUE_DISABLE, FALSE}};
//
// TAG = FRAGCHK
//
dwErr = MatchEnumTag(g_hModule, ppwcArguments[i + dwCurrentIndex], sizeof(rgEnums)/sizeof(TOKEN_VALUE), rgEnums, &dwRes);
if (dwErr != NO_ERROR) { DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE, pttTags[pdwTagType[i]].pwszTag, ppwcArguments[i + dwCurrentIndex]);
DisplayMessage( g_hModule, MSG_IP_BAD_OPTION_ENUMERATION, pttTags[pdwTagType[i]].pwszTag ); for (i=0; i<sizeof(rgEnums)/sizeof(TOKEN_VALUE); i++) { DisplayMessageT( L" %1!s!\n", rgEnums[i].pwszToken ); }
i = dwNumArg;
dwErr = ERROR_SUPPRESS_OUTPUT; bOkay = FALSE;
break; }
bFragCheck = (dwRes) ? TRUE : FALSE; break; }
default: { i = dwNumArg;
dwErr = ERROR_INVALID_SYNTAX;
break; } } }
HeapFree(GetProcessHeap(), 0, pdwTagType);
switch(dwErr) { case NO_ERROR : break;
default: return dwErr; }
if (!bOkay) { return NO_ERROR; }
if (!pttTags[0].bPresent || (pttTags[1].bPresent && !pttTags[2].bPresent) || (!pttTags[1].bPresent && pttTags[2].bPresent)) { return ERROR_INVALID_SYNTAX; // show usage
}
if (pttTags[3].bPresent) { dwErr = SetFragCheckInfo(wszIfName, bFragCheck); }
if (dwErr isnot NO_ERROR) { return dwErr; } if (pttTags[1].bPresent) { dwErr = SetFilterInfo(wszIfName, dwFilterType, dwAction); }
return dwErr; }
DWORD IpAddSetDelInterface( PWCHAR *ppwcArguments, DWORD dwCurrentIndex, DWORD dwArgCount, DWORD dwAction )
/*++
Routine Description:
Gets options for setting interface parameters
Arguments:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR --*/
{ DWORD dwBitVector = 0, dwNumParsed = 0; DWORD dwErr = NO_ERROR, dwRes; TAG_TYPE pttTags[] = { {TOKEN_NAME, TRUE, FALSE}, {TOKEN_STATUS, FALSE,FALSE}}; BOOL bOkay = TRUE; DWORD pdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; DWORD dwNumOpt; DWORD dwStatus = IF_ADMIN_STATUS_UP; DWORD dwNumTags = 2, dwNumArg, i, j; WCHAR wszIfName[MAX_INTERFACE_NAME_LEN + 1] = L"\0"; DWORD dwMaxArgs = (dwAction is DELETE_COMMAND)? 1 : sizeof(pttTags)/sizeof(TAG_TYPE);
// Do generic processing
dwErr = PreHandleCommand( ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 1, dwMaxArgs, pdwTagType );
if (dwErr) { return dwErr; }
dwNumArg = dwArgCount - dwCurrentIndex;
for (i=0; i<dwNumArg; i++) { switch (pdwTagType[i]) { case 0: // NAME
{ DWORD BufLen = sizeof(wszIfName); GetInterfaceName(ppwcArguments[i + dwCurrentIndex], wszIfName, BufLen, &dwNumParsed); break; }
case 1: // STATE
{ TOKEN_VALUE rgEnums[] = {{TOKEN_VALUE_ENABLE, IF_ADMIN_STATUS_UP}, {TOKEN_VALUE_DISABLE, IF_ADMIN_STATUS_DOWN}};
dwErr = MatchEnumTag(g_hModule, ppwcArguments[i + dwCurrentIndex], sizeof(rgEnums)/sizeof(TOKEN_VALUE), rgEnums, &dwStatus);
if (dwErr isnot NO_ERROR) { DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE, pttTags[pdwTagType[i]].pwszTag, ppwcArguments[i + dwCurrentIndex]);
DisplayMessage( g_hModule, MSG_IP_BAD_OPTION_ENUMERATION, pttTags[pdwTagType[i]].pwszTag ); for (i=0; i<sizeof(rgEnums)/sizeof(TOKEN_VALUE); i++) { DisplayMessageT( L" %1!s!\n", rgEnums[i].pwszToken ); }
i = dwNumArg;
dwErr = ERROR_SUPPRESS_OUTPUT; bOkay = FALSE;
break; }
break; } } }
if (!bOkay) { return NO_ERROR; }
if (dwAction is DELETE_COMMAND) { dwErr = DeleteInterfaceInfo(wszIfName); if (dwErr isnot NO_ERROR) { return dwErr; } return ERROR_OKAY; }
if (dwStatus is IF_ADMIN_STATUS_DOWN) { DWORD dwIfType;
// Make sure we support disabling this interface
dwErr = GetInterfaceInfo(wszIfName, NULL, NULL, &dwIfType);
if (dwErr == NO_ERROR) { if (dwIfType isnot ROUTER_IF_TYPE_DEDICATED) { DisplayMessage( g_hModule, MSG_IP_CANT_DISABLE_INTERFACE ); return ERROR_SUPPRESS_OUTPUT; } } }
if (dwAction is ADD_COMMAND) { dwErr = AddInterfaceInfo(wszIfName); }
dwErr = UpdateInterfaceStatusInfo(dwAction, wszIfName, dwStatus); if (dwErr isnot NO_ERROR) { return dwErr; }
return ERROR_OKAY; }
DWORD HandleIpAddInterface( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone )
{ return IpAddSetDelInterface( ppwcArguments, dwCurrentIndex, dwArgCount, ADD_COMMAND); }
DWORD HandleIpSetInterface( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone )
{ return IpAddSetDelInterface( ppwcArguments, dwCurrentIndex, dwArgCount, SET_COMMAND ); }
DWORD HandleIpDelInterface( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone )
{ return IpAddSetDelInterface( ppwcArguments, dwCurrentIndex, dwArgCount, DELETE_COMMAND); }
DWORD HandleIpShowRoutePref( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone )
/*++
Routine Description:
Arguments:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR --*/ { //
// No options expected
//
return ShowRoutePref(NULL); }
DWORD HandleIpShowLogLevel( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone )
/*++
Routine Description:
Arguments:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR --*/ { //
// No options expected
//
if (dwCurrentIndex != dwArgCount) { return ERROR_SHOW_USAGE; } return ShowIpGlobal(NULL); }
DWORD HandleIpShowProtocol( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone )
/*++
Routine Description:
Arguments:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR --*/ { //
// No options expected
//
return ShowIpProtocol(); }
DWORD IpShowSingleInterfaceInfo( IN LPCWSTR pwszInterfaceName, IN DWORD dwInfoType, IN DWORD dwFormat, IN OUT PDWORD pdwNumRows ) { switch(dwInfoType) { case SHOW_IF_FILTER: { return ShowIpIfFilter(NULL, dwFormat, pwszInterfaceName, pdwNumRows); }
case SHOW_INTERFACE: { return ShowIpInterface(dwFormat, pwszInterfaceName, pdwNumRows); }
case SHOW_PERSISTENTROUTE: { return ShowIpPersistentRoute(NULL, pwszInterfaceName, pdwNumRows); }
default: { return ERROR_INVALID_PARAMETER; } } }
DWORD IpShowInterfaceInfo( PWCHAR *ppwcArguments, DWORD dwCurrentIndex, DWORD dwArgCount, DWORD dwInfoType ) /*++
Routine Description:
Gets options for showing various interface information Arguments:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg dwInfoType - The type of info to display
Return Value:
NO_ERROR --*/ { DWORD dwErr, dwTotal; TAG_TYPE pttTags[] = {{TOKEN_NAME,FALSE,FALSE}}; WCHAR wszInterfaceName[MAX_INTERFACE_NAME_LEN + 1] = L"\0"; DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)]; DWORD dwCount, i, j, dwNumOpt; DWORD dwNumTags = 1, dwNumArg, dwNumParsed; DWORD dwSize, dwRes, dwNumRows = 0; PMPR_INTERFACE_0 pmi0;
// Do generic processing
dwErr = PreHandleCommand( ppwcArguments, dwCurrentIndex, dwArgCount, pttTags, sizeof(pttTags)/sizeof(TAG_TYPE), 0, 1, rgdwTagType ); if (dwErr isnot NO_ERROR) { return dwErr; }
// If interface specified, show info for specified interface only.
for (i=0; i<dwArgCount-dwCurrentIndex; i++) { switch (rgdwTagType[i]) { case 0: // NAME
{ DWORD BufLen = sizeof(wszInterfaceName); GetInterfaceName( ppwcArguments[i + dwCurrentIndex], wszInterfaceName, BufLen, &dwNumParsed);
dwErr = IpShowSingleInterfaceInfo(wszInterfaceName, dwInfoType, FORMAT_VERBOSE, &dwNumRows);
if (!dwNumRows) { DisplayMessage( g_hModule, MSG_IP_NO_ENTRIES ); dwErr = ERROR_SUPPRESS_OUTPUT; }
return dwErr; } } }
// No Interface specified. Enumerate interfaces and show
// info for each interface.
dwErr = IpmontrInterfaceEnum((PBYTE *) &pmi0, &dwCount, &dwTotal); if (dwErr isnot NO_ERROR) { return dwErr; }
for (i=0; i<dwCount && dwErr is NO_ERROR; i++) { dwErr = IpShowSingleInterfaceInfo( pmi0[i].wszInterfaceName, dwInfoType, FORMAT_TABLE, &dwNumRows ); if (dwErr is ERROR_NO_SUCH_INTERFACE) { dwErr = NO_ERROR; } }
if (!dwNumRows) { DisplayMessage( g_hModule, MSG_IP_NO_ENTRIES ); }
return dwErr; }
DWORD HandleIpShowIfFilter( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone )
/*++
Routine Description:
Arguments:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR --*/
{ return IpShowInterfaceInfo(ppwcArguments, dwCurrentIndex, dwArgCount, SHOW_IF_FILTER); }
DWORD HandleIpShowInterface( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone )
/*++
Routine Description:
Arguments:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR --*/
{ return IpShowInterfaceInfo(ppwcArguments, dwCurrentIndex, dwArgCount, SHOW_INTERFACE); }
DWORD HandleIpShowPersistentRoute( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone )
/*++
Routine Description:
Handler for show ip route. We just call the main interface info display handler
Arguments:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR
--*/
{ DisplayMessage(g_hModule, MSG_IP_PERSISTENT_CONFIG);
return IpShowInterfaceInfo(ppwcArguments, dwCurrentIndex, dwArgCount, SHOW_PERSISTENTROUTE); }
#ifdef KSL_IPINIP
DWORD HandleIpAddIpIpTunnel( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone )
/*++
Routine Description:
Arguments:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR
--*/
{ return IpAddSetIpIpTunnel(ppwcArguments, dwCurrentIndex, dwArgCount, TRUE); }
DWORD HandleIpSetIpIpTunnel( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone )
/*++
Routine Description:
Arguments:
ppwcArguments - Argument array dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR
--*/
{ return IpAddSetIpIpTunnel(ppwcArguments, dwCurrentIndex, dwArgCount, FALSE); }
DWORD IpAddSetIpIpTunnel( PWCHAR *ppwcArguments, DWORD dwCurrentIndex, DWORD dwArgCount, BOOL bAdd )
{ DWORD dwNumArgs, dwErr, dwNumParsed;
TAG_TYPE rgTags[] = {{TOKEN_NAME, TRUE, FALSE}, {TOKEN_LOCALADDR, TRUE, FALSE}, {TOKEN_REMADDR, TRUE, FALSE}, {TOKEN_TTL, FALSE,FALSE}};
WCHAR rgwcIfName[MAX_INTERFACE_NAME_LEN + 1]; DWORD rgdwTagType[sizeof(rgTags)/sizeof(TAG_TYPE)]; ULONG i; PWCHAR pwszIfName;
IPINIP_CONFIG_INFO ConfigInfo;
dwNumArgs = dwArgCount - dwCurrentIndex;
if((dwCurrentIndex > dwArgCount) or (dwNumArgs isnot 4)) { //
// No arguments specified
//
return ERROR_SHOW_USAGE; }
dwErr = MatchTagsInCmdLine(g_hModule, ppwcArguments, dwCurrentIndex, dwArgCount, rgTags, sizeof(rgTags)/sizeof(TAG_TYPE), rgdwTagType);
if (dwErr isnot NO_ERROR) { if (dwErr is ERROR_INVALID_OPTION_TAG) { return ERROR_INVALID_SYNTAX; }
return dwErr; }
for(i = 0; i < dwNumArgs; i ++) { switch (rgdwTagType[i]) { case 0 : // NAME
{ DWORD BufLen = sizeof(rgwcIfName); dwErr = GetInterfaceName(ppwcArguments[i + dwCurrentIndex], rgwcIfName, BufLen, &dwNumParsed);
if(bAdd) { if(dwErr is NO_ERROR) { return ERROR_OBJECT_ALREADY_EXISTS; } pwszIfName = ppwcArguments[i + dwCurrentIndex]; } else { if(dwErr isnot NO_ERROR) { return dwErr; }
pwszIfName = rgwcIfName; }
break; }
case 1: { //
// Tag for localaddr
//
dwErr = GetIpAddress(ppwcArguments[i + dwCurrentIndex], &ConfigInfo.dwLocalAddress);
break; }
case 2: { //
// Tag for remoteaddr
//
dwErr = GetIpAddress(ppwcArguments[i + dwCurrentIndex], &ConfigInfo.dwRemoteAddress);
break; }
case 3: { //
// Tag for ttl
//
ConfigInfo.byTtl = LOBYTE(LOWORD(wcstoul(ppwcArguments[i + dwCurrentIndex], NULL, 10)));
break; }
default: { i = dwNumArgs;
dwErr = ERROR_INVALID_SYNTAX;
break; } } }
switch(dwErr) { case NO_ERROR: { break; }
default: { return dwErr; } }
for(i = 0; i < dwNumArgs; i++) { if(!rgTags[i].bPresent) { DisplayMessage(g_hModule, MSG_CANT_FIND_EOPT);
return ERROR_INVALID_SYNTAX; } }
dwErr = AddSetIpIpTunnelInfo(pwszIfName, &ConfigInfo);
return dwErr; } #endif //KSL_IPINIP
DWORD IpDump( IN LPCWSTR pwszRouter, IN LPWSTR *ppwcArguments, IN DWORD dwArgCount, IN LPCVOID pvData ) { DumpIpInformation((HANDLE)-1);
return NO_ERROR; }
#if 0
DWORD HandleIpInstall( PWCHAR pwszMachine, PWCHAR *ppwcArguments, DWORD dwCurrentIndex, DWORD dwArgCount, DWORD dwFlags, PVOID pvData, BOOL *pbDone ) { // XXX DLLPath, ProtocolId
// XXX set default info here
// global info block (what is this?)
// protocol priority block (no need?)
// multicast boundaries block (no need)
return NO_ERROR; }
DWORD HandleIpUninstall( PWCHAR pwszMachine, PWCHAR *ppwcArguments, DWORD dwCurrentIndex, DWORD dwArgCount, DWORD dwFlags, PVOID pvData, BOOL *pbDone ) { PMPR_INTERFACE_0 pmi0; DWORD dwCount, dwTotal, i, dwErr;
// Remove global info
// XXX
// Remove interface info
dwErr = IpmontrInterfaceEnum((PBYTE *) &pmi0, &dwCount, &dwTotal); if (dwErr is NO_ERROR) { for (i=0; i<dwCount; i++) { DeleteInterfaceInfo(pmi0[i].wszInterfaceName); } }
return NO_ERROR; } #endif
DWORD HandleIpReset( IN LPCWSTR pwszMachine, IN OUT LPWSTR *ppwcArguments, IN DWORD dwCurrentIndex, IN DWORD dwArgCount, IN DWORD dwFlags, IN LPCVOID pvData, OUT BOOL *pbDone ) { PMPR_INTERFACE_0 pmi0; DWORD dwCount, dwTotal, i, dwErr, dwSize, dwBlkSize; DWORD dwNumProtocols; GLOBAL_INFO gi; PPRIORITY_INFO pPriInfo; PPROTOCOL_METRIC pProtocolMetrics; RTR_INFO_BLOCK_HEADER *pInfoHdr; RTR_INFO_BLOCK_HEADER *pLocalInfoHdr;
PROTOCOL_METRIC defaultProtocolMetrics[] = { {PROTO_IP_LOCAL, 1}, {PROTO_IP_NT_STATIC, 3}, {PROTO_IP_NT_STATIC_NON_DOD, 5}, {PROTO_IP_NT_AUTOSTATIC, 7}, {PROTO_IP_NETMGMT, 10}, {PROTO_IP_OSPF, 110}, {PROTO_IP_RIP, 120} };
PROTOCOL_METRIC defaultProtocolMetricsNT4[] = { {PROTO_IP_LOCAL, 1}, {PROTO_IP_NETMGMT, 2}, {PROTO_IP_OSPF, 3}, {PROTO_IP_RIP, 4}, {PROTO_IP_IGMP, 5} };
// delete all blocks except the IP_GLOBAL_INFO
dwErr = ValidateGlobalInfo(&pInfoHdr); if (dwErr is NO_ERROR) { // Copy to a local buffer just in case the APIs modify it as we go
dwSize = sizeof(RTR_INFO_BLOCK_HEADER) * pInfoHdr->TocEntriesCount; pLocalInfoHdr = MALLOC(dwSize); if (pLocalInfoHdr is NULL) { return ERROR_NOT_ENOUGH_MEMORY; }
memcpy(pLocalInfoHdr, pInfoHdr, dwSize);
// Set Global and RoutePref info
{ dwBlkSize = sizeof(GLOBAL_INFO); dwCount = 1; gi.bFilteringOn = FALSE; gi.dwLoggingLevel = IPRTR_LOGGING_ERROR; dwErr = IpmontrSetInfoBlockInGlobalInfo(IP_GLOBAL_INFO, (PBYTE) &gi, dwBlkSize, dwCount); }
{ // Based on the router version, calculate the number
// of protocols etc.
// TODO: currently assuming >=NT5. Should find out the router
// version somehow
dwNumProtocols = sizeof(defaultProtocolMetrics)/sizeof(PROTOCOL_METRIC); pProtocolMetrics = defaultProtocolMetrics;
dwBlkSize = SIZEOF_PRIORITY_INFO(dwNumProtocols); dwCount = 1;
// Allocate buffer to hold the Priority Information
pPriInfo = MALLOC(dwBlkSize); if (pPriInfo is NULL) { return ERROR_NOT_ENOUGH_MEMORY; }
pPriInfo->dwNumProtocols = dwNumProtocols; memcpy( pPriInfo->ppmProtocolMetric, pProtocolMetrics, dwNumProtocols * sizeof(PROTOCOL_METRIC));
dwErr = IpmontrSetInfoBlockInGlobalInfo(IP_PROT_PRIORITY_INFO, (PBYTE) pPriInfo, dwBlkSize, dwCount);
FREE(pPriInfo); }
for (i=0; i<pLocalInfoHdr->TocEntriesCount; i++) { switch (pLocalInfoHdr->TocEntry[i].InfoType) { case IP_GLOBAL_INFO: case IP_PROT_PRIORITY_INFO: // already done
break;
default: IpmontrDeleteInfoBlockFromGlobalInfo( pLocalInfoHdr->TocEntry[i].InfoType ); break; } }
FREE(pLocalInfoHdr); }
// Delete all interface info
dwErr = IpmontrInterfaceEnum((PBYTE *) &pmi0, &dwCount, &dwTotal); if (dwErr is NO_ERROR) { for (i=0; i<dwCount; i++) { DeleteInterfaceInfo(pmi0[i].wszInterfaceName); } }
return NO_ERROR; }
|