fix cidr issue

This commit is contained in:
Emo-Damage
2023-05-28 02:00:47 +08:00
parent 3b9737b7ba
commit d759583c80
2 changed files with 50 additions and 63 deletions

View File

@@ -460,7 +460,7 @@ async function isCloudFlareIP(addressType, addressRemote) {
if(addressType === 2) if(addressType === 2)
{ {
const domainIP = await doh(addressRemote); const domainIP = await doh(addressRemote);
// console.log(' domainIP ', domainIP); console.log(' domainIP ', domainIP);
return isIPv4InCFCIDR(domainIP); return isIPv4InCFCIDR(domainIP);
} }
return false; return false;
@@ -554,7 +554,7 @@ function isIPv4InCFCIDR(ip) {
// 134866689: 1000000010011110011100000001 // 134866689: 1000000010011110011100000001
// -256: 11111111111111111111100000000000 // -256: 11111111111111111111100000000000
// 134866688 1000000010011110011100000000 // 134866688 1000000010011110011100000000
return cidrNumberList.some(({ipNumber, ipMask}) => (currentIPNum & ipMask) === ipNumber); return cidrNumberList.some(({ipNumber, ipMask}) => (currentIPNum & ipMask) === (ipNumber & ipMask));
} }
/** /**

View File

@@ -1,3 +1,36 @@
function isIPv4InCFCIDR(ip) {
const currentIPNum = convertIp2Num(ip);
// if not valid number, return false
if(!currentIPNum){
return false;
}
// 134866688 / -256
// 134866689: 1000000010011110011100000001
// -256: 11111111111111111111100000000000
// 134866688 1000000010011110011100000000
return cidrNumberList.some(({ipNumber, ipMask}) => (currentIPNum & ipMask) === (ipNumber & ipMask));
}
/**
*
* @param {string} ip
*/
function convertIp2Num(ip){
const ipParts = ip.split('.');
if(ipParts.length !== 4){
return 0;
}
let ipNumber = 0;
for (const ipPart of ipParts) {
ipNumber = (ipNumber << 8) + parseInt(ipPart, 10); // 8.9.231.0 --> 134866688// 134866688 --> 1000000010011110011100000000
}
return ipNumber >>> 0; // unsgined int
}
const cidrList = [ const cidrList = [
"1.0.0.0/24", "1.0.0.0/24",
"1.1.1.0/24", "1.1.1.0/24",
@@ -6535,71 +6568,25 @@ const cidrList = [
"199.27.134.0/24", "199.27.134.0/24",
"199.27.135.0/24" "199.27.135.0/24"
]; ];
const cidrToRangeMask = (cidr) => {
const [ipRange, maskLength] = cidr.split('/');
const ipInt = ipRange.split('.').reduce((acc, val) => (acc << 8) + parseInt(val, 10), 0);
const ipMask = -1 << (32 - parseInt(maskLength, 10));
return [ipInt, ipMask];
};
console.log(cidrList.map(cidrToRangeMask)); /** @type { {ipNumber: number, ipMask: number}[]} */
const cidrNumberList= []
const ipInt = "142.250.204.68".split('.').reduce((acc, val) => (acc << 8) + parseInt(val, 10), 0) >>> 0; for (const cidr of cidrList) {
console.log(ipInt); // 8.9.231.0/24
/**
* Checks if an IPv4 address is within a CIDR range.
*
* @param {string} address The IPv4 address to check.
* @param {string} cidr The CIDR range to check against.
* @returns {boolean} `true` if the address is within the CIDR range, `false` otherwise.
*/
function isIPv4InRange(address, cidr) {
// Parse the address and CIDR range
const addressParts = address.split('.').map(part => parseInt(part, 10));
const [rangeAddress, rangePrefix] = cidr.split('/'); const [rangeAddress, rangePrefix] = cidr.split('/');
const rangeParts = rangeAddress.split('.').map(part => parseInt(part, 10)); const prefix = parseInt(rangePrefix, 10); // 24
const prefix = parseInt(rangePrefix, 10); const ipMask = -1 << (32 - prefix); // -256
// const ipMask = ~(2 ** (32 - prefix) - 1);
// Convert the address and range to binary format const ipNumber = convertIp2Num(rangeAddress);
const addressBinary = addressParts.reduce((acc, part) => acc + part.toString(2).padStart(8, '0'), ''); cidrNumberList.push(
const rangeBinary = rangeParts.reduce((acc, part) => acc + part.toString(2).padStart(8, '0'), ''); {
ipNumber, // 8.9.231.0 --> 134866688
// Compare the bits up to the prefix length ipMask // -256
for (let i = 0; i < prefix; i++) {
if (addressBinary[i] !== rangeBinary[i]) {
return false;
} }
} )
return true;
} }
/** console.log(convertIp2Num('162.159.137.0'));
* Checks if an IPv6 address is within a CIDR range.
*
* @param {string} address The IPv6 address to check.
* @param {string} cidr The CIDR range to check against.
* @returns {boolean} `true` if the address is within the CIDR range, `false` otherwise.
*/
function isIPv6InRange(address, cidr) {
// Parse the address and CIDR range
const addressParts = address.split(':').map(part => parseInt(part, 16));
const [rangeAddress, rangePrefix] = cidr.split('/');
const rangeParts = rangeAddress.split(':').map(part => parseInt(part, 16));
const prefix = parseInt(rangePrefix, 10);
// Convert the address and range to binary format console.log(isIPv4InCFCIDR('162.159.137.0'));
const addressBinary = addressParts.reduce((acc, part) => acc + part.toString(2).padStart(16, '0'), '');
const rangeBinary = rangeParts.reduce((acc, part) => acc + part.toString(2).padStart(16, '0'), '');
// Compare the bits up to the prefix length
for (let i = 0; i < prefix; i++) {
if (addressBinary[i] !== rangeBinary[i]) {
return false;
}
}
return true;
}