Files
wireguard-ui/src/functions/backend/setup/check-private-ip-availability.ts
T

81 lines
2.0 KiB
TypeScript

import type { APIResponseObject } from "@moduletrace/bunext/types";
import { execSync } from "node:child_process";
type Params = {
ip_address: string;
};
/**
* Function to check the availability of a private
* IP address (like 10.1.0.1)
* @param param0
*/
export default async function checkPrivateIPAvailability({
ip_address,
}: Params): Promise<APIResponseObject> {
const ip_pattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
const matches = ip_address.match(ip_pattern);
if (!matches) {
return {
success: false,
msg: `Invalid IP address: ${ip_address}`,
};
}
const octets = matches.slice(1).map(Number);
if (octets.some((o) => o < 0 || o > 255)) {
return {
success: false,
msg: `Invalid IP address: ${ip_address}`,
};
}
if (octets[3] !== 1) {
return {
success: false,
msg: `IP address must end with 1: ${ip_address}`,
};
}
const [octet1, octet2, octet3] = octets;
try {
const addr_output = execSync(`ip -4 addr show`, {
encoding: "utf-8",
});
for (const match of addr_output.matchAll(
/inet\s+(\d+\.\d+\.\d+\.\d+)\/\d+/g,
)) {
if (!match[1]) continue;
const [existing1, existing2, existing3] = match[1]
.split(".")
.map(Number);
if (
existing1 === octet1 &&
existing2 === octet2 &&
existing3 === octet3
) {
return {
success: false,
msg: `IP address ${ip_address} is already in use`,
};
}
}
return {
success: true,
msg: `IP address ${ip_address} is available`,
};
} catch (error: any) {
return {
success: false,
msg: error.message,
};
}
}