diff --git a/api/src/routes/ipv4.py b/api/src/routes/ipv4.py index a23d589..dfa9faf 100644 --- a/api/src/routes/ipv4.py +++ b/api/src/routes/ipv4.py @@ -102,4 +102,4 @@ async def get_mask(ipv4: str) -> dict: async def get_vlsm(baseip: str, subnet: str) -> dict: """Implement the VLSM (Variable Length Subnet Mask) technique.""" res = vlsm(baseip, subnet) - return {"ipv4": res} + return {"subnet": res} diff --git a/front-js/src/app/modules/vlsm/Cours.tsx b/front-js/src/app/modules/vlsm/Cours.tsx new file mode 100644 index 0000000..a7818f6 --- /dev/null +++ b/front-js/src/app/modules/vlsm/Cours.tsx @@ -0,0 +1,124 @@ +import Title from "@/components/Title"; +import Text from "@/components/Text"; +import React from "react"; +import Space from "@/components/Space"; +import { Emoji, EmojiProvider } from "react-apple-emojis"; +import emojiData from "react-apple-emojis/src/data.json"; +import { Alert, CircularProgress } from "@mui/material"; +import axios from "@/axiosConfig"; +import Cookies from "js-cookie"; +import { Code, solarizedLight } from "react-code-blocks"; +import Box from "@/components/Box"; +import Button from "@/components/Button"; +import Input from "@/components/Input"; +import { AxiosError } from "axios"; + +const Cours: React.FC = () => { + const [addrRestante, setAddrRestante] = React.useState(""); + const [res, setRes] = React.useState(""); + const [isLoading, setIsLoading] = React.useState(false); + + const handleAddrRestante = async (e: { preventDefault: () => void }) => { + setIsLoading(true); + setRes(""); + e.preventDefault(); + try { + const response = await axios.get("/ipv4/vlsm/192.168.1.0/15,30,50", { + headers: { + Authorization: `Bearer ${Cookies.get("access_token")}`, + }, + }); + const data = response.data; + if (response.status === 200) { + let lastRange = data.subnet[data.subnet.length - 1].range; + lastRange = lastRange.split(" - ")[1]; + const listLastRange = lastRange.split("."); + const newLastDigit = + parseInt(listLastRange[listLastRange.length - 1]) + 1; + listLastRange.pop(); + listLastRange.push(newLastDigit.toString()); + const ok = listLastRange.join(".") + " - 192.168.1.254"; + if (addrRestante == ok) { + setRes("Bravo !"); + } else { + setRes("Mauvaise réponse !"); + } + } + } catch (error: unknown) { + const axiosError = error as AxiosError; + if (axiosError.response?.status === 400) { + setRes("Erreur interne"); + } else { + setRes("Erreur interne"); + } + } + setIsLoading(false); + }; + + return ( + <> + + + Introduction + + VLSM (Variable Length Subnet Masking) est une technique de + sous-réseautage qui permet de créer des sous-réseaux de différentes + tailles. Cette technique est utilisée pour optimiser + l’utilisation des adresses IP. + + + Fonctionnement VLSM + + + VLSM permet de diviser un réseau en sous-réseaux de différentes + tailles. Chaque sous-réseau peut accueillir un nombre minimisé de + machine. Cela permet d’optimiser l’utilisation des + adresses IP. + + + Attention il ne faut pas oublier de réserver une adresse pour le + réseau et une pour le broadcast. + + + Essayez ! + + + Notre réseau{" "} + {" "} + contient des sous-réseaux avec 15 machines, 30 machines et 50 + machines. Qu’elle est la plage d’adresses IP restante ? + + + setAddrRestante(e.target.value)} + value={addrRestante} + type="text" + placeholder="192.168.1.xxx - 192.168.1.xxx" + margin={{ bottom: "20px" }} + required + label="Plage restante" + /> + + + + {res ? ( + + {res} + + ) : isLoading ? ( + + + + ) : null} + + + + > + ); +}; + +export default Cours; diff --git a/front-js/src/app/modules/vlsm/VlsmSandbox.tsx b/front-js/src/app/modules/vlsm/VlsmSandbox.tsx new file mode 100644 index 0000000..0331cc4 --- /dev/null +++ b/front-js/src/app/modules/vlsm/VlsmSandbox.tsx @@ -0,0 +1,176 @@ +import Title from "@/components/Title"; +import Button from "@/components/Button"; +import Input from "@/components/Input"; +import Space from "@/components/Space"; +import React from "react"; +import { useState } from "react"; +import axios from "@/axiosConfig"; +import Cookies from "js-cookie"; +import { + Alert, + CircularProgress, + Paper, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, +} from "@mui/material"; +import Box from "@/components/Box"; +import { AxiosError } from "axios"; + +interface Subnet { + network: string; + mask: string; + broadcast: string; + range: string; +} + +const VlsmSandbox: React.FC = () => { + const [baseIp, setBaseIp] = useState(""); + const [nombreAddr, setNombreAddr] = useState(""); + const [subnets, setSubnets] = useState< + Array<{ network: string; mask: string; broadcast: string; range: string }> + >([]); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(""); + + const handleSubnets = async (e: { preventDefault: () => void }) => { + setIsLoading(true); + setError(""); + setSubnets([]); + e.preventDefault(); + try { + const response = await axios.get( + "/ipv4/vlsm/" + baseIp + "/" + nombreAddr, + { + headers: { + Authorization: `Bearer ${Cookies.get("access_token")}`, + }, + } + ); + const data = response.data; + if (response.status === 200) { + const formattedSubnets = data.subnet.map((subnet: Subnet) => ({ + network: subnet.network, + mask: subnet.mask, + broadcast: subnet.broadcast, + range: subnet.range, + })); + setSubnets(formattedSubnets); + } + } catch (error: unknown) { + const axiosError = error as AxiosError; + if (axiosError.response?.status === 400) { + setError("Erreur interne"); + } else { + setError("Erreur interne inconnue"); + } + } + setIsLoading(false); + }; + + return ( + <> + + + Création d’un sous réseau + + setBaseIp(e.target.value)} + required + label="Adresse IP de base" + /> + setNombreAddr(e.target.value)} + required + label="Nombre d’adresses à attribuer (séparées par des virgules)" + /> + { + handleSubnets(e); + }} + /> + {subnets.length > 0 ? ( + + + Sous-réseaux créés avec succès ! + + + + + + + Network + + + Mask + + + Broadcast + + + Range + + + + + {subnets.map((subnet, index) => ( + + {subnet.network} + {subnet.mask} + {subnet.broadcast} + {subnet.range} + + ))} + + + + + ) : isLoading ? ( + + + + ) : error ? ( + + + {error} + + + ) : null} + + + > + ); +}; + +export default VlsmSandbox; diff --git a/front-js/src/app/modules/vlsm/page.tsx b/front-js/src/app/modules/vlsm/page.tsx index 92e0288..9a00f24 100644 --- a/front-js/src/app/modules/vlsm/page.tsx +++ b/front-js/src/app/modules/vlsm/page.tsx @@ -4,140 +4,87 @@ import Layout from "@/components/Layout"; import Header from "@/components/Header"; import Title from "@/components/Title"; import Box from "@/components/Box"; -import Text from "@/components/Text"; import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; import Cookies from "js-cookie"; -import { Spacer } from "@nextui-org/spacer"; -import Space from "@/components/Space"; import axios from "@/axiosConfig"; -import Button from "@/components/Button"; -import Input from "@/components/Input"; +import { Tabs, Tab } from "@mui/material"; +import Cours from "./Cours"; +import VlsmSandbox from "./VlsmSandbox"; export default function VLSM() { - const router = useRouter(); - - const [, setHasAccessToken] = useState(false); + const router = useRouter(); - useEffect(() => { - const checkTokens = async () => { - const token = Cookies.get("access_token"); - const refresh = Cookies.get("refresh_token"); - if (!token && refresh) { - try { - const response = await axios.post("/auth/refresh", { - refresh_token: refresh, - }); - const data = response.data; - if (response.status === 200) { - Cookies.set("access_token", data.access_token); - Cookies.set("refresh_token", refresh); - } - } catch { - Cookies.remove("access_token"); - Cookies.remove("refresh_token"); - } - } - setHasAccessToken(!!token); - - if (!token && !refresh) { - router.push("/"); - } - }; + const [, setHasAccessToken] = useState(false); - checkTokens(); - }, [router]); - - const [ipv4, setIPv4] = useState(""); - const [subnet, setSubnet] = useState(""); - const [res, setRes] = useState(""); - - const handleVLSM = async (e: { preventDefault: () => void }) => { - e.preventDefault(); + useEffect(() => { + const checkTokens = async () => { + const token = Cookies.get("access_token"); + const refresh = Cookies.get("refresh_token"); + if (!token && refresh) { try { - const response = await axios.get("/ipv4/vlsm/" + ipv4 + "/" + subnet, { - headers: { - Authorization: `Bearer ${Cookies.get("access_token")}`, - }, + const response = await axios.post("/auth/refresh", { + refresh_token: refresh, }); const data = response.data; if (response.status === 200) { - console.log(data); - setRes(data.ipv6); + Cookies.set("access_token", data.access_token); + Cookies.set("refresh_token", refresh); } - } catch (error: unknown) { + } catch { + Cookies.remove("access_token"); + Cookies.remove("refresh_token"); } - }; + } + setHasAccessToken(!!token); + + if (!token && !refresh) { + router.push("/"); + } + }; + + checkTokens(); + }, [router]); + + const [activeTab, setActiveTab] = useState("cours"); + + const handleTabChange = (tab: string) => { + setActiveTab(tab); + }; + + return ( + + + router.push(`/${tab.toLowerCase()}`)} + onClickLogout={() => router.push("/auth/logout")} + onClickLogo={() => router.push("/")} + /> + + + + VLSM + + + + handleTabChange(tab)} + centered + > + + + - return ( - - - router.push(`/${tab.toLowerCase()}`)} - onClickLogout={() => router.push("/auth/logout")} - onClickLogo={() => router.push("/")} - /> - - - - VLSM - - - - Introduction - - - ... - - - - Exercices - - ??? - - - setIPv4(e.target.value)} - required - label="Adresse IPv4" - /> - setSubnet(e.target.value)} - required - label="Sous-réseau" - /> - { - handleVLSM(e); - }} - /> - - {res ? - <> - Résultat : {res} - > - : null} - + + {activeTab === "cours" ? : } + - ); - } - + ); +}