windows-nt/Source/XPSP1/NT/net/config/netcfg/tcpipcfg/tcperror.cpp
2020-09-26 16:20:57 +08:00

370 lines
10 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997.
//
// File: T C P E R R O R . C P P
//
// Contents:
//
// Notes:
//
// Author: tongl
//
//----------------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
#include "tcperror.h"
#include "tcputil.h"
#include "tcpconst.h"
#include "resource.h"
IP_VALIDATION_ERR IsValidIpandSubnet(PCWSTR szIp, PCWSTR szSubnet)
{
IP_VALIDATION_ERR ret = ERR_NONE;
DWORD dwAddr = IPStringToDword(szIp);
DWORD dwMask = IPStringToDword(szSubnet);
//The host ID cannot contain all 1's
if ((dwMask | dwAddr) == 0xFFFFFFFF)
{
return ERR_HOST_ALL1;
}
if (((~dwMask) & dwAddr) == 0)
{
return ERR_HOST_ALL0;
}
if ((dwMask & dwAddr) == 0)
{
return ERR_SUBNET_ALL0;
}
DWORD ardwNetID[4];
DWORD ardwIp[4];
DWORD ardwMask[4];
GetNodeNum(szIp, ardwIp);
GetNodeNum(szSubnet, ardwMask);
INT nFirstByte = ardwIp[0] & 0xFF ;
// setup Net ID
ardwNetID[0] = ardwIp[0] & ardwMask[0] & 0xFF;
ardwNetID[1] = ardwIp[1] & ardwMask[1] & 0xFF;
ardwNetID[2] = ardwIp[2] & ardwMask[2] & 0xFF;
ardwNetID[3] = ardwIp[3] & ardwMask[3] & 0xFF;
// setup Host ID
DWORD ardwHostID[4];
ardwHostID[0] = ardwIp[0] & (~(ardwMask[0]) & 0xFF);
ardwHostID[1] = ardwIp[1] & (~(ardwMask[1]) & 0xFF);
ardwHostID[2] = ardwIp[2] & (~(ardwMask[2]) & 0xFF);
ardwHostID[3] = ardwIp[3] & (~(ardwMask[3]) & 0xFF);
// check each case
if( ((nFirstByte & 0xF0) == 0xE0) || // Class D
((nFirstByte & 0xF0) == 0xF0) || // Class E
(ardwNetID[0] == 127) || // NetID cannot be 127...
((ardwNetID[0] == 0) && // netid cannot be 0.0.0.0
(ardwNetID[1] == 0) &&
(ardwNetID[2] == 0) &&
(ardwNetID[3] == 0)) ||
// netid cannot be equal to sub-net mask
((ardwNetID[0] == ardwMask[0]) &&
(ardwNetID[1] == ardwMask[1]) &&
(ardwNetID[2] == ardwMask[2]) &&
(ardwNetID[3] == ardwMask[3])) ||
// hostid cannot be 255.255.255.255
((ardwHostID[0] == 0xFF) &&
(ardwHostID[1] == 0xFF) &&
(ardwHostID[2] == 0xFF) &&
(ardwHostID[3] == 0xFF)) ||
// test for all 255
((ardwIp[0] == 0xFF) &&
(ardwIp[1] == 0xFF) &&
(ardwIp[2] == 0xFF) &&
(ardwIp[3] == 0xFF)))
{
ret = ERR_INCORRECT_IP;
}
return ret;
}
// return IP_VALIDATION_ERR
IP_VALIDATION_ERR ValidateIp(ADAPTER_INFO * const pAdapterInfo)
{
IP_VALIDATION_ERR result = ERR_NONE;
IP_VALIDATION_ERR tmp = ERR_NONE;
Assert(pAdapterInfo != NULL);
// if enable DHCP is false;
if (!pAdapterInfo->m_fEnableDhcp)
{
// check the first pair of IP and subnet
VSTR_ITER iterIpBegin = pAdapterInfo->m_vstrIpAddresses.begin();
VSTR_ITER iterIpEnd = pAdapterInfo->m_vstrIpAddresses.end();
VSTR_ITER iterIp = iterIpBegin;
VSTR_ITER iterSubnetMaskBegin = pAdapterInfo->m_vstrSubnetMask.begin();
VSTR_ITER iterSubnetMaskEnd = pAdapterInfo->m_vstrSubnetMask.end();
VSTR_ITER iterSubnetMask = iterSubnetMaskBegin;
BOOL fSwap = FALSE;
// If ip address and subnet are both empty
if((iterIp == iterIpEnd) && (iterSubnetMask == iterSubnetMaskEnd))
{
result = ERR_NO_IP;
}
else
{
for( ;
iterIp != iterIpEnd || iterSubnetMask != iterSubnetMaskEnd ;
++iterIp, ++iterSubnetMask)
{
if((iterIp == iterIpEnd || **iterIp == L"") && !fSwap)
{
result = ERR_NO_IP;
fSwap = TRUE;
}
else if((iterSubnetMask == iterSubnetMaskEnd || **iterSubnetMask == L"") && !fSwap)
{
result = ERR_NO_SUBNET;
fSwap = TRUE;
}
else if(!IsContiguousSubnet((*iterSubnetMask)->c_str()))
{
result = ERR_UNCONTIGUOUS_SUBNET;
fSwap = TRUE;
}
else if(ERR_NONE != (tmp = IsValidIpandSubnet((*iterIp)->c_str(), (*iterSubnetMask)->c_str())) && !fSwap)
{
result = tmp;
fSwap = TRUE;
}
if(fSwap)
{
tstring * pstrTmp;
pstrTmp = *iterIp;
*iterIp = *iterIpBegin;
*iterIpBegin = pstrTmp;
pstrTmp = *iterSubnetMask;
*iterSubnetMask = *iterSubnetMaskBegin;
*iterSubnetMaskBegin = pstrTmp;
break;
}
}
}
}
return result;
}
// return >=0 : the adapter that has the duplicate address
// return -1 : all is ok
// Check from duplicate IP address between the adapter in pAdapterInfo and
// any different, enabled, LAN adapters in the pvcardAdapterInfo list
int CheckForDuplicates(const VCARD * pvcardAdapterInfo,
ADAPTER_INFO * pAdapterInfo,
tstring& strIp)
{
int nResult = -1;
Assert(pvcardAdapterInfo != NULL);
Assert(pAdapterInfo != NULL);
Assert(!pAdapterInfo->m_fEnableDhcp);
for(size_t i = 0; ((i < pvcardAdapterInfo->size()) && (nResult == -1)) ; ++i)
{
VSTR_ITER iterCompareIpBegin;
VSTR_ITER iterCompareIpEnd;
if ((*pvcardAdapterInfo)[i]->m_guidInstanceId ==
pAdapterInfo->m_guidInstanceId)
{
// same adapter
continue;
}
else
{
// different adapter
// Skip the following:
// 1) disabled adapter
// 2) ndiswan adapter
// 3) Dhcp enabled adapter
// 4) RAS Fake adapters
if(((*pvcardAdapterInfo)[i]->m_BindingState != BINDING_ENABLE) ||
((*pvcardAdapterInfo)[i]->m_fIsWanAdapter) ||
((*pvcardAdapterInfo)[i]->m_fEnableDhcp) ||
((*pvcardAdapterInfo)[i]->m_fIsRasFakeAdapter))
continue;
iterCompareIpBegin = (*pvcardAdapterInfo)[i]->m_vstrIpAddresses.begin();
iterCompareIpEnd = (*pvcardAdapterInfo)[i]->m_vstrIpAddresses.end();
}
VSTR_ITER iterCompareIp = iterCompareIpBegin;
for ( ; iterCompareIp != iterCompareIpEnd; ++iterCompareIp)
{
if(**iterCompareIp == strIp) // if duplicate IP address found
{
nResult = i;
break;
/*
nCompareCount++;
if (nCompareCount >= 1)
{
nResult = i;
tstring * pstrTmp;
// swap the Current Compared IP and Subnet Mask with the
// first IP and first subnetmask that are duplicates
pstrTmp = *iterIp;
*iterIp = *iterIpBegin;
*iterIpBegin = pstrTmp;
pstrTmp = *iterSubnetMask;
*iterSubnetMask = *iterSubnetMaskBegin;
*iterSubnetMaskBegin = pstrTmp;
break;
}
*/
}
}
}
return nResult;
}
BOOL FHasDuplicateIp(ADAPTER_INFO * pAdapterInfo)
{
Assert(pAdapterInfo);
Assert(!pAdapterInfo->m_fEnableDhcp);
BOOL fDup = FALSE;
VSTR_ITER iterIpBegin = pAdapterInfo->m_vstrIpAddresses.begin();
VSTR_ITER iterIpEnd = pAdapterInfo->m_vstrIpAddresses.end();
VSTR_ITER iterIp = iterIpBegin;
for( ; ((iterIp != iterIpEnd) && (!fDup)) ; ++iterIp)
{
// check only IP addresses one by one
VSTR_ITER iterCompareIpBegin = iterIp+1;
VSTR_ITER iterCompareIpEnd = pAdapterInfo->m_vstrIpAddresses.end();
VSTR_ITER iterCompareIp = iterCompareIpBegin;
for ( ; iterCompareIp != iterCompareIpEnd; ++iterCompareIp)
{
if(**iterCompareIp == **iterIp) // if duplicate IP address found
{
fDup = TRUE;
break;
}
}
}
return fDup;
}
//Check if all the fields of the IP address are valid
//Arguments: szIp the IP address
// fIsIpAddr whether the szIp is IP address (otherwise, it should be subnet mask)
// if szIp is IP address, it's first field should be between 1 and 223,
// and cannot be 127 (loopback address)
BOOL FIsValidIpFields(PCWSTR szIp, BOOL fIsIpAddr)
{
BOOL fRet = TRUE;
DWORD ardwIp[4];
GetNodeNum(szIp, ardwIp);
// if the address is IP, there are some special rules for its first field
if (fIsIpAddr && (ardwIp[0] < c_iIPADDR_FIELD_1_LOW || ardwIp[0] > c_iIPADDR_FIELD_1_HIGH ||
ardwIp[0] == c_iIPADDR_FIELD_1_LOOPBACK))
{
fRet = FALSE;
}
else
{
//if the address is IP, then we have already validate the first field. Otherwise, we need
// valid the first field here.
for (INT i = (fIsIpAddr) ? 1 : 0; i < 4; i++)
{
#pragma warning(push)
#pragma warning(disable:4296)
if (ardwIp[i] < (DWORD)c_iIpLow || ardwIp[i] > c_iIpHigh)
{
fRet = FALSE;
break;
}
#pragma warning(pop)
}
}
return fRet;
}
//Get the resource ID of the error message based on the IP validation err
UINT GetIPValidationErrorMessageID(IP_VALIDATION_ERR err)
{
UINT uID = 0;
switch(err)
{
case ERR_NONE:
uID = 0;
break;
case ERR_HOST_ALL0:
uID = IDS_INVALID_HOST_ALL_0;
break;
case ERR_HOST_ALL1:
uID = IDS_INVALID_HOST_ALL_1;
break;
case ERR_SUBNET_ALL0:
uID = IDS_INVALID_SUBNET_ALL_0;
break;
case ERR_INCORRECT_IP:
uID = IDS_INCORRECT_IPADDRESS;
break;
case ERR_NO_IP:
uID = IDS_INVALID_NO_IP;
break;
case ERR_NO_SUBNET:
uID = IDS_INVALID_NOSUBNET;
break;
case ERR_UNCONTIGUOUS_SUBNET:
uID = IDS_ERROR_UNCONTIGUOUS_SUBNET;
break;
default:
uID = IDS_INCORRECT_IPADDRESS;
break;
}
return uID;
}