<%+header%>
<script>
// 将IP地址转换为32位二进制字符串
function ipToBinary(ip) {
    return ip.split('.').map(octet => parseInt(octet, 10).toString(2).padStart(8, '0')).join('');
}

// 将32位二进制字符串转换为IP地址
function binaryToIp(binary) {
    let ip = [];
    for (let i = 0; i < 4; i++) {
        ip.push(parseInt(binary.substring(i * 8, (i + 1) * 8), 2));
    }
    return ip.join('.');
}

// 计算网络地址
function calculateNetworkAddress(ipBinary, maskBinary) {
    return ipBinary.split('').map((bit, index) => bit & maskBinary[index]).join('');
}

// 计算广播地址
function calculateBroadcastAddress(networkBinary, maskBinary) {
    let invertedMask = maskBinary.split('').map(bit => bit === '0' ? '1' : '0').join('');
    return networkBinary.split('').map((bit, index) => bit | invertedMask[index]).join('');
}

// 生成网络地址和广播地址之间的所有IP地址
function generateIpAddresses(networkBinary, broadcastBinary) {
    let networkDecimal = parseInt(networkBinary, 2);
    let broadcastDecimal = parseInt(broadcastBinary, 2);
    let ipAddresses = [];
    for (let i = networkDecimal + 1; i < broadcastDecimal; i++) {
        ipAddresses.push(binaryToIp(i.toString(2).padStart(32, '0')));
    }
    return ipAddresses;
}

// 计算地址总数
function calculateTotalAddresses(maskBinary) {
    let hostBits = maskBinary.split('').filter(bit => bit === '0').length;
    return Math.pow(2, hostBits) - 2; // Subtract 2 for network and broadcast addresses
}

// 主函数，调用上述函数并返回结果
function getIpAddresses(ip, mask) {
    let ipBinary = ipToBinary(ip);
    let maskBinary = ipToBinary(mask);
    let networkBinary = calculateNetworkAddress(ipBinary, maskBinary);
    let broadcastBinary = calculateBroadcastAddress(networkBinary, maskBinary);
    let ipAddresses = generateIpAddresses(networkBinary, broadcastBinary);
    let totalAddresses = calculateTotalAddresses(maskBinary);

    if (ipAddresses.length == 0) {
        ipAddresses = [ip]; totalAddresses = 1;
    }

    return ipAddresses;
}

// 示例使用
// let ip = "192.168.1.1";
// let mask = "255.255.255.0";
// let result = getIpAddresses(ip, mask);
// console.log("IP Addresses:", result.ipAddresses);
// console.log("Total Addresses:", result.totalAddresses);

function runscript(url) {
	var script = document.createElement('script');  
	script.setAttribute('src', url);
	document.getElementsByTagName('head')[0].appendChild(script);  
}
function showResult(s) {
	document.getElementById('dvMsg').style.display = '';
	if(s.result == "error") {
		document.getElementById('dvMsg').innerHTML = "<font color=red>"+ s.msg +"</font>";
	} else if(s.result == "ok") {
        var ip1 = s.ip1;
        var mask1 = s.mask1;
        var ip2 = s.ip2;
        var mask2 = s.mask2;

        var h = "";
        if (ip1 == "") {
            h = "<font color=red>"+ document.getElementById('if1').value + " <%: No IP address detected %> </font>";
            document.getElementById('dvMsg').innerHTML = h;
            return;
        }
        if (ip2 == "") {
            h = "<font color=red>"+ document.getElementById('if2').value + " <%: No IP address detected %> </font>";
            document.getElementById('dvMsg').innerHTML = h;
            return;
        }

        var ips1 = getIpAddresses(ip1, mask1);
        var ip1start = ips1[0];
        var ip1last = ips1[ ips1.length - 1 ];

        var ips2 = getIpAddresses(ip2, mask2);
        var ip2start = ips2[0];
        var ip2last = ips2[ ips2.length - 1 ];

        if (ips1.indexOf(ip2) != -1 || ips2.indexOf(ip1) != -1) {
            h = "<font color=red><b><%: IP range conflict detected ! Please check your network configuration. %></b></font><br><br>";
        } else {
            h = "<font color='#008800'><b><%:It is OK, no conflict. %></b></font><br><br>";
        }

		h += "<table style='height:100px; width:100%; max-width:800px; border: 1px solid #888;'><tr align='center'><td><%: Interface %></td><td>IP</td><td><%: Mask %></td><td><%: Net Address %></td><td><%: IP Range %></td></tr>" +
            "<tr align='center'><td>"+ document.getElementById('if1').value +"</td><td>"+ s.ip1 +"</td><td>"+ s.mask1 +"</td><td>"+ s.net1 +"</td><td>"+ ip1start +" ~ "+ ip1last +"</td></tr>" +
            "<tr align='center'><td>"+ document.getElementById('if2').value +"</td><td>"+ s.ip2 +"</td><td>"+ s.mask2 +"</td><td>"+ s.net2 +"</td><td>"+ ip2start +" ~ "+ ip2last +"</td></tr>" +
            "</table>";
		document.getElementById('dvMsg').innerHTML = h;

	} else {
		document.getElementById('dvMsg').innerHTML = '<%:Unknown error %>';
	}
}

function doCheck() {
	runscript( '/cgi-bin/luci/admin/oplus/ipcheck_check/?_r='+ Math.random() +
		"&if1="+ encodeURIComponent(document.getElementById('if1').value) +
        "&if2="+ encodeURIComponent(document.getElementById('if2').value)
    );
}
</script>

<br><br>
<b><%:This tool detects IP range conflicts between network interfaces %></b>
<br><br>
<%:IP address or address range conflicts are a major cause of network connection interruptions or latency issues. %><br>
<%:It is recommended to use this tool to detect any conflicts after network is configured. %>
<br><br>
<center>
<div id="dvMsg" style="color: #0000a0; display: none; font-weight: bold;"></div>
<br>
<table>
    <tr><td colspan="2"> <%:Input Network Interface Names to check %> : </td></tr>
	<tr>
		<td> <%:Network Interface 1 %> : </td>
		<td> <input type="text" id="if1" value="lan" /> </td>
	</tr>
	<tr>
		<td> <%:Network Interface 2 %> : </td>
		<td> <input type="text" id="if2" value="wan" /> </td>
	</tr>
</table>

<br>
<input type="button" style="background-color: #0055ff; color: #fff; width:100px; height: 40px;" value="<%:Check %>" onclick="doCheck();" />

<br><br>
<a href="http://www.wiwiz.com/pinpinwifi/oplus/help.htm" target="_blank"><%:Docs %></a>
<br><br>
Copyright &copy; 2025-<script>document.write(new Date().getFullYear());</script> <a href="http://www.wiwiz.com/pinpinwifi" target='_blank'>www.PinPinWiFi.com</a>. All rights reserved.
<br>
<%: We reserve the right to pursue legal responsibility for any unauthorized copying, distribution, cracking, reverse engineering, unauthorized use, etc. %>
<br>
</center>

<%+footer%>