Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions front-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"js-cookie": "^3.0.5",
"next": "15.1.0",
"react": "^19.0.0",
"react-code-blocks": "^0.1.6",
"react-apple-emojis": "^2.2.2",
"react-code-blocks": "^0.1.6",
"react-dom": "^19.0.0",
Expand Down
13 changes: 7 additions & 6 deletions front-js/src/app/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,15 @@ export default function Dashboard() {
<Grid2 size={4}>
<Card
title="IPv6"
description="Simplifiez ou étendez une adresse IPv6 avec ce module."
description="Simplifiez ou étendez une adresse IPv6."
image="/modules_assets/ipv6.svg"
onClick={() => router.push("/modules/ipv6")}
/>
</Grid2>
<Grid2 size={4}>
<Card
title="Calcul IPv4"
description="..."
description="Faîtes le calcul d'une adresse IPv4."
image="/modules_assets/ipv4.svg"
/>
</Grid2>
Expand All @@ -135,16 +135,17 @@ export default function Dashboard() {
<Grid2 size={4}>
<Card
title="VLSM"
description="..."
description="Décomposez votre réseau avec VLSM"
image="/modules_assets/ipv4.svg"
onClick={() => router.push("/modules/vlsm")}
/>
</Grid2>
<Grid2 size={4}>
<Card
title="Ethernet"
description="..."
description="Établissez une trame ethernet"
image="/modules_assets/scapy.svg"
onClick={() => router.push("/modules/ethernet")}
/>
</Grid2>
<Grid2 size={4}>
Expand All @@ -158,14 +159,14 @@ export default function Dashboard() {
<Grid2 size={4}>
<Card
title="TCP"
description="..."
description="Testez une connexion TCP"
image="/modules_assets/scapy.svg"
/>
</Grid2>
<Grid2 size={4}>
<Card
title="Interface réseau"
description="..."
description="Affichez l'interface réseau du client"
image="/modules_assets/scapy.svg"
onClick={() => router.push("/modules/interface_reseau")}
/>
Expand Down
54 changes: 54 additions & 0 deletions front-js/src/app/modules/ethernet/Cours.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import Space from "@/components/Space"
import Title from "@/components/Title"
import { EmojiProvider } from "react-apple-emojis"
import Text from "@/components/Text"
import emojiData from "react-apple-emojis/src/data.json";
import { Code, CodeBlock, solarizedLight } from "react-code-blocks";
import { text } from "stream/consumers";


const CoursEthernet: React.FC = () => {

const example = `{
"frame": {
"dst_mac": "FF:FF:FF:FF:FF:FF",
"src_mac": "00:11:22:33:44:55",
"eth_type": "0x0800",
"frame_hex": "FFFFFFFFFFFF0011223344550800"
}
}`;

return (
<EmojiProvider data={emojiData}>

<Space space="1rem">
<Title level={1} margin={{ top: "2rem" }}>Ethernet</Title>
<Text>
Bienvenue sur le module Ethernet. Ce module génère une trame Ethernet basée sur les paramètres fournis.
Elle utilise les informations sur les adresses MAC source et destination ainsi que le type Ethernet (exprimé en hexadécimal).
La trame générée est renvoyée au format JSON.
</Text>

<Title level={2} margin={{ top: "2rem" }}>Entrées : </Title>
<Text>・Adresse MAC de destination, (par exemple, FF:FF:FF:FF:FF:FF).</Text>
<Text>・Adresse MAC source, (par exemple, 00:11:22:33:44:55).</Text>
<Text>・Type de trame ethernet, (cf Types de trames).</Text>

<Title level={2} margin={{ top: "2rem" }}>Types de trames Ethernet :</Title>
<Text>・0x0800 pour IPv4</Text>
<Text>・0x0806 pour ARP</Text>
<Text>・0x86DD pour IPv6</Text>
<Text>・0x8100 pour VLAN</Text>

<Title level={2} margin={{ top: "2rem" }}>Exemple de réponse 200 OK</Title>
<CodeBlock
text={(example)}
language="JSON"
theme={solarizedLight}
/>
</Space>
</EmojiProvider>
)
}

export default CoursEthernet
113 changes: 113 additions & 0 deletions front-js/src/app/modules/ethernet/EthernetSandbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
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 { Alert } from "@mui/material";
import Box from "@/components/Box";
import Cookies from "js-cookie";
import axios from "@/axiosConfig";
import { AxiosError } from "axios";
import { CodeBlock, solarizedLight } from "react-code-blocks";

const EthernetSandbox: React.FC = () => {
const [masdst, setMacdst] = useState("");
const [macsrc, setMacsrc] = useState("");
const [typetrame, setTypetrame] = useState("");
const [simpleRes, setSimpleRes] = useState("");

const handleEthernet = async (e: { preventDefault: () => void }) => {
e.preventDefault();
try {
const response = await axios.get(
`/scapy/ethernet-frame/${masdst}/${macsrc}/${typetrame}`,
{
headers: {
Authorization: `Bearer ${Cookies.get("access_token")}`,
},
}
);
const data = response.data;
if (response.status === 200) {
setSimpleRes(data.frame);
}
} catch (error: unknown) {
const axiosError = error as AxiosError;
if (axiosError.response?.status === 400) {
const data = axiosError.response.data as { detail: string };
setSimpleRes(data.detail || "Erreur lors de la création de la trame Ethernet");
} else {
setSimpleRes("Erreur inattendue lors de l'appel API");
}
}
};


return (
<>
<Space space="50px" direction="vertical" margin={{ bottom: "100px" }}>
<form onSubmit={handleEthernet}>
<Title level={2}>Rédiger votre trame Ethernet :</Title>

<Input
type="text"
placeholder="FF:FF:FF:FF:FF:FF"
value={masdst}
margin={{ bottom: "20px" }}
onChange={(e) => setMacdst(e.target.value)}
required
label="Adresse mac destination"
/>
<Input
type="text"
placeholder="00:11:22:33:44:55"
value={macsrc}
margin={{ bottom: "20px" }}
onChange={(e) => setMacsrc(e.target.value)}
required
label="Adresse mac source"
/>
<Input
type="text"
placeholder="0x0800"
value={typetrame}
margin={{ bottom: "20px" }}
onChange={(e) => setTypetrame(e.target.value)}
required
label="Type de trame Ethernet"
/>
<Button
text="Envoyer"
primary
form="submit"
type="input"
margin={{ top: "20px" }}
disabled={!masdst || !macsrc || !typetrame}
onClick={(e) => {
handleEthernet(e);
}}
/>
{simpleRes ? (
<Box margin={{ top: "20px", bottom: "20px" }}>
<Alert
severity={simpleRes.includes("Erreur") ? "error" : "success"}
variant="outlined"
style={{ borderRadius: "10px" }}
>
Résultat :
<CodeBlock
text={simpleRes}
language="JSON"
theme={solarizedLight}
/>
</Alert>
</Box>
) : null}
</form>
</Space>
</>
);
};

export default EthernetSandbox;
14 changes: 14 additions & 0 deletions front-js/src/app/modules/ethernet/Layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { Metadata } from "next";

export const metadata: Metadata = {
title: "Ethernet",
description: "Networkers",
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return <body>{children}</body>;
}
114 changes: 114 additions & 0 deletions front-js/src/app/modules/ethernet/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
"use client";

import Box from "@/components/Box";
import Layout from "@/components/Layout";
import Header from "@/components/Header";
import { useRouter } from "next/navigation";
import Cookies from "js-cookie";
import axios from "@/axiosConfig";
import { useEffect, useState } from "react";
import { Tab, Tabs } from "@mui/material";
import Title from "@/components/Title";
import CoursEthernet from "./Cours";
import EthernetSandbox from "./EthernetSandbox";

export default function Ethernet() {
const router = useRouter();
const [hasAccessToken, setHasAccessToken] = useState(false);

const [isLoading, setIsLoading] = useState(true);

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("/");
}
};

checkTokens();
}, [router]);

const [username, setUsername] = useState("");

useEffect(() => {
const getUser = async () => {
setIsLoading(true);
try {
const response = await axios.get("/users/me", {
headers: {
Authorization: `Bearer ${Cookies.get("access_token")}`,
},
});
setUsername(response.data.username);
} catch {
Cookies.remove("access_token");
Cookies.remove("refresh_token");
router.push("/");
}
setIsLoading(false);
};

getUser();
}, [router]);

const [activeTab, setActiveTab] = useState("cours");

const handleTabChange = (tab: string) => {
setActiveTab(tab);
};

return (
<Layout type="logged">
<Box align="center" margin={{ top: "50px", bottom: "50px" }}>
<Header
tabs={{
dashboard: "Tableau de bord",
modules: "Mes modules",
profile: "Mon profil",
}}
activeTab="modules"
onClick={(tab) => router.push(`/${tab.toLowerCase()}`)}
onClickLogout={() => router.push("/auth/logout")}
onClickLogo={() => router.push("/")}
/>
</Box>
<Box align="center" margin={{ top: "50px", bottom: "50px" }}>
<Title level={1} align="center">
IPv6
</Title>
</Box>

<Tabs
value={activeTab}
onChange={(_, tab) => handleTabChange(tab)}
centered
>
<Tab label="Cours & exercice" value="cours" />
<Tab label="Bac à sable" value="sandbox" />
</Tabs>

<Box margin={{ top: "50px", bottom: "50px", left: "20%", right: "20%" }}>
{activeTab === "cours" ? <CoursEthernet /> : <EthernetSandbox />}
</Box>
</Layout>
);
}