import React, { useEffect, useRef, useState } from "react"; import { useTranslation, Trans } from "react-i18next"; import * as styles from "./IPv4SubnettingTool.module.scss" import { Helmet } from "react-helmet"; const intToIPv4String = (ip: number): string => { let out = "" for (let group = 0; group < 4; group++) { let groupBin = ip & 0xff out = groupBin.toString()+"."+out ip >>= 8; } return out.substring(0, out.length-1) } const IPv4SubnettingTool = () => { const { t } = useTranslation(); let [ipPart1, setIPPart1] = useState(""); let [ipPart2, setIPPart2] = useState(""); let [ipPart3, setIPPart3] = useState(""); let [ipPart4, setIPPart4] = useState(""); let [subnet, setSubnet] = useState(""); let ipInput1 = useRef(null) let ipInput2 = useRef(null) let ipInput3 = useRef(null) let ipInput4 = useRef(null) let subnetInput = useRef(null) let [ipBinary, setIpBinary] = useState(undefined); let [subnetNumber, setSubnetMaskNumber] = useState(undefined); let [subnetMask, setSubnetMask] = useState(undefined); let [firstAddr, setFirstAddr] = useState(undefined); let [lastAddr, setLastAddr] = useState(undefined); let [isPeerNet, setIsPeerNet] = useState(false); useEffect(() => { let myIpPart1 = ipPart1; let myIpPart2 = ipPart2; let myIpPart3 = ipPart3; let myIpPart4 = ipPart4; let mySubnet = subnet; if(myIpPart1.indexOf(".") !== -1) { let split = myIpPart1.split(".") myIpPart1 = split.shift()! myIpPart2 = split.join(".") ipInput2.current?.focus() } if(myIpPart2.indexOf(".") !== -1) { let split = myIpPart2.split(".") myIpPart2 = split.shift()! myIpPart3 = split.join(".") ipInput3.current?.focus() } if(myIpPart3.indexOf(".") !== -1) { let split = myIpPart3.split(".") myIpPart3 = split.shift()! myIpPart4 = split.join(".") ipInput4.current?.focus() } if(myIpPart4.indexOf("/") !== -1) { let split = myIpPart4.split("/") myIpPart4 = split.shift()! mySubnet = split.join("/") subnetInput.current?.focus() } if(myIpPart4.indexOf(".") !== -1) { let split = myIpPart4.split(".") myIpPart4 = split.shift()! mySubnet = split.join(".") subnetInput.current?.focus() } let ipPart1Num = parseInt(myIpPart1); let ipPart2Num = parseInt(myIpPart2); let ipPart3Num = parseInt(myIpPart3); let ipPart4Num = parseInt(myIpPart4); let subnetNum = parseInt(mySubnet); if(!isNaN(ipPart1Num)) setIPPart1(ipPart1Num.toString()); if(!isNaN(ipPart2Num)) setIPPart2(ipPart2Num.toString()); if(!isNaN(ipPart3Num)) setIPPart3(ipPart3Num.toString()); if(!isNaN(ipPart4Num)) setIPPart4(ipPart4Num.toString()); if(!isNaN(subnetNum)) setSubnet(subnetNum.toString()); let invalid = false; [ipInput1, ipInput2, ipInput3, ipInput4].forEach((field) => { if(!field.current) return const val = field.current.value; if (val === "") { field.current.setCustomValidity(""); return } const valInt = parseInt(val); if(isNaN(valInt)) { field.current.setCustomValidity(t("tools.networking.ipv4subnetting.error.isNaN")); field.current.reportValidity(); invalid = true; return } if(valInt < 0) { field.current.setCustomValidity(t("tools.networking.ipv4subnetting.error.tooSmall")); field.current.reportValidity(); invalid = true; return } if(valInt > 255) { field.current.setCustomValidity(t("tools.networking.ipv4subnetting.error.tooBig")); field.current.reportValidity(); invalid = true; return } field.current.setCustomValidity(""); }); ((field: React.RefObject) => { if(!field.current) return const val = field.current.value; if (val === "") { field.current.setCustomValidity(""); return } const valInt = parseInt(val); if(isNaN(valInt)) { field.current.setCustomValidity(t("tools.networking.ipv4subnetting.error.isNaN")); field.current.reportValidity(); invalid = true; return } if(valInt < 0) { field.current.setCustomValidity(t("tools.networking.ipv4subnetting.error.tooSmall")); field.current.reportValidity(); invalid = true; return } if(valInt > 32) { field.current.setCustomValidity(t("tools.networking.ipv4subnetting.error.tooBigSubnet")); field.current.reportValidity(); invalid = true; return } field.current.setCustomValidity(""); })(subnetInput) setIpBinary(undefined); setFirstAddr(undefined); setLastAddr(undefined); setSubnetMaskNumber(undefined); setSubnetMask(undefined); setIsPeerNet(false); if(invalid) return; if(!isNaN(ipPart1Num) && !isNaN(ipPart2Num) && !isNaN(ipPart3Num) && !isNaN(ipPart4Num)) { let ipBinary = ipPart1Num * Math.pow(2, 24) + ipPart2Num * Math.pow(2, 16) + ipPart3Num * Math.pow(2, 8) + ipPart4Num; setIpBinary(ipBinary); if (!isNaN(subnetNum)) { setSubnetMaskNumber(subnetNum); let peerNet = false; if (subnetNum > 30) { setIsPeerNet(true); peerNet = true; } let subnetMaskBinary = new Uint32Array(1); for (let index = 0; index < 32 - subnetNum; index++) { subnetMaskBinary[0] = (subnetMaskBinary[0] << 1) | 0b1; } subnetMaskBinary[0] ^= 0xffffffff //setSubnetMaskBinaryString(subnetMaskBinary[0].toString(2)) setSubnetMask(subnetMaskBinary[0]) if(!peerNet) { setFirstAddr((ipBinary & subnetMaskBinary[0])+1) setLastAddr((ipBinary | (subnetMaskBinary[0] ^ 0xffffffff)) - 1) } if(peerNet) { setFirstAddr((ipBinary & subnetMaskBinary[0])) setLastAddr((ipBinary | (subnetMaskBinary[0] ^ 0xffffffff))) } } } }, [ipPart1, ipPart2, ipPart3, ipPart4, subnet, t]) return (
{t("tools.networking.ipv4subnetting.title")} | {t("site.title")}

{t("tools.networking.ipv4subnetting.title")}

{setIPPart1(e.currentTarget.value); if((e.currentTarget.value.length >= 3 && e.currentTarget.value.length > ipPart1.length) || e.currentTarget.value[e.currentTarget.value.length - 1] === ".") ipInput2.current?.focus()}} value={ipPart1} /> . {setIPPart2(e.currentTarget.value); if((e.currentTarget.value.length >= 3 && e.currentTarget.value.length > ipPart2.length) || e.currentTarget.value[e.currentTarget.value.length - 1] === ".") ipInput3.current?.focus()}} value={ipPart2} /> . {setIPPart3(e.currentTarget.value); if((e.currentTarget.value.length >= 3 && e.currentTarget.value.length > ipPart3.length) || e.currentTarget.value[e.currentTarget.value.length - 1] === ".") ipInput4.current?.focus()}} value={ipPart3} /> . {setIPPart4(e.currentTarget.value); if((e.currentTarget.value.length >= 3 && e.currentTarget.value.length > ipPart4.length) || e.currentTarget.value[e.currentTarget.value.length - 1] === "/" || e.currentTarget.value[e.currentTarget.value.length - 1] === ".") subnetInput.current?.focus()}} value={ipPart4} /> / {setSubnet(e.currentTarget.value);}} value={subnet} />
{t("tools.networking.common.subnetMask")} {subnetMask || subnetMask === 0 ? intToIPv4String(subnetMask) : "???"}
{t("tools.networking.common.firstAddr")} {firstAddr ? intToIPv4String(firstAddr) : "???"}
{t("tools.networking.common.lastAddr")} {lastAddr ? intToIPv4String(lastAddr) : "???"}
{t("tools.networking.common.netAddr")} {isPeerNet ? "n/a" : (firstAddr ? intToIPv4String(firstAddr - 1) : "???")}
{t("tools.networking.common.broadcastAddr")} {isPeerNet ? "n/a" : (lastAddr ? intToIPv4String(lastAddr + 1) : "???")}
{t("tools.networking.common.ipv4addr")} ({t("tools.networking.common.binary")}) {ipBinary || ipBinary === 0 ? ipBinary.toString(2).padStart(32, "0").split("").map((bit, index) => { return = (subnetNumber||32) ? "red" : undefined}} key={"bit"+index}>{bit} }) : "???"}
{t("tools.networking.common.subnetMask")} ({t("tools.networking.common.binary")}) {subnetMask || subnetMask === 0 ? subnetMask.toString(2).padStart(32, "0").split("").map((bit, index) => { return {bit} }) : "???"}
) } export default IPv4SubnettingTool;