Skip to content

Commit 1c0711a

Browse files
authored
Ipv4 header data (#80)
This pull request introduces new functionality to display detailed information about packets in the right sidebar. The changes include adding a toggle button to show/hide packet details, creating a new function to generate the toggle information, and updating the styles to support the new feature. Key changes: **Functionality enhancements:** * [`src/graphics/right_bar.ts`](diffhunk://#diff-2ffc3b298d27be79ce1fc85f908ca77f488f67ee59e05d3d17b8a9e1aad6d696R77-R90): Added `addToggleButton` method to `RightBar` class to append a toggle button for displaying packet details. * [`src/graphics/right_bar.ts`](diffhunk://#diff-2ffc3b298d27be79ce1fc85f908ca77f488f67ee59e05d3d17b8a9e1aad6d696R161-R218): Added `createToggleInfo` function to create a container with a toggle button and detailed information list. * [`src/types/packet.ts`](diffhunk://#diff-e546d6337dcb4e908b738659b527f00387c07ab30674ab0dfbd61edab3d03ff4R86-R134): Added `getPacketDetails` method to `Packet` class to generate a dictionary of packet details. * [`src/types/packet.ts`](diffhunk://#diff-e546d6337dcb4e908b738659b527f00387c07ab30674ab0dfbd61edab3d03ff4R155-R170): Updated `showInfo` method in `Packet` class to include the toggle button for packet details. **Styling updates:** * [`src/styles/index.ts`](diffhunk://#diff-701113bd02bdc9f8c671df93b0a5a0d2dadb520ae378674c8cfa956d1eb2daffR8): Imported new stylesheet `info.css` for the toggle info container. * [`src/styles/info.css`](diffhunk://#diff-491a767362663fa382b6668f53918a33594c6cff6f34f616a22ae85b4dfbac53R1-R41): Added styles for the toggle info container and its elements, including transitions for a smoother user experience.
1 parent e5615bd commit 1c0711a

File tree

4 files changed

+172
-1
lines changed

4 files changed

+172
-1
lines changed

src/graphics/right_bar.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,20 @@ export class RightBar {
7474
}
7575
}
7676

77+
addToggleButton(
78+
title: string,
79+
details: Record<string, string | number | object>,
80+
buttonClass = "right-bar-toggle-button",
81+
infoClass = "right-bar-info",
82+
) {
83+
const container = createToggleInfo(title, details, buttonClass, infoClass);
84+
const infoContent = document.getElementById("info-content");
85+
86+
if (infoContent) {
87+
infoContent.appendChild(container);
88+
}
89+
}
90+
7791
// Adds a select dropdown to the right-bar
7892
addDropdown(
7993
label: string,
@@ -144,6 +158,64 @@ export function createToggleTable(
144158
return container;
145159
}
146160

161+
export function createToggleInfo(
162+
title: string,
163+
details: Record<string, string | number | object>,
164+
buttonClass = "right-bar-toggle-button",
165+
infoClass = "right-bar-info",
166+
) {
167+
const container = document.createElement("div");
168+
container.classList.add("toggle-info-container");
169+
170+
// Create toggle button
171+
const button = document.createElement("button");
172+
button.classList.add(buttonClass);
173+
button.textContent = "Show Details";
174+
175+
// Create Packet Details title
176+
const header = document.createElement("h3");
177+
header.classList.toggle("hidden", true);
178+
header.textContent = title;
179+
180+
// Create info list
181+
const list = document.createElement("ul");
182+
list.classList.add(infoClass, "hidden");
183+
184+
// Add details to the list
185+
Object.entries(details).forEach(([key, value]) => {
186+
const listItem = document.createElement("li");
187+
if (key === "Payload") {
188+
// Format the payload as JSON
189+
const pre = document.createElement("pre");
190+
pre.textContent = JSON.stringify(value, null, 2); // Pretty-print JSON
191+
listItem.innerHTML = `<strong>${key}:</strong>`;
192+
listItem.appendChild(pre);
193+
} else {
194+
listItem.innerHTML = `<strong>${key}:</strong> ${value}`;
195+
}
196+
list.appendChild(listItem);
197+
});
198+
199+
// Toggle when clicking on button
200+
button.onclick = () => {
201+
const isHidden = list.classList.contains("hidden");
202+
list.classList.toggle("hidden", !isHidden);
203+
list.classList.toggle("open", isHidden);
204+
container.classList.toggle("hidden", !isHidden);
205+
container.classList.toggle("open", isHidden);
206+
button.classList.toggle("open", isHidden);
207+
header.classList.toggle("hidden", !isHidden);
208+
button.textContent = isHidden ? "Hide Details" : "Show Details";
209+
};
210+
211+
// Add elements to container
212+
container.appendChild(button);
213+
container.appendChild(header);
214+
container.appendChild(list);
215+
216+
return container;
217+
}
218+
147219
export function createRightBarButton(
148220
text: string,
149221
onClick: () => void,

src/styles/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ import "./canvas.css";
55
import "./right-bar.css";
66
import "./right-bar-buttons.css";
77
import "./table.css";
8+
import "./info.css";
89
import "./buttons.css";

src/styles/info.css

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/* Estilos base para el contenedor */
2+
.toggle-info-container {
3+
overflow: hidden;
4+
text-align: left;
5+
margin: 0;
6+
padding: 0;
7+
}
8+
9+
/* Ajustes para el texto de la lista */
10+
.toggle-info-container .right-bar-info {
11+
margin: 0;
12+
padding: 0;
13+
list-style: none;
14+
}
15+
16+
.toggle-info-container .right-bar-info li {
17+
margin: 20px 0px;
18+
padding: 0;
19+
text-align: flex;
20+
}
21+
22+
/* Estilo para el pre que contiene el payload */
23+
.toggle-info-container .right-bar-info li pre {
24+
background-color: #000;
25+
color: #fff;
26+
padding: 10px;
27+
border-radius: 4px;
28+
font-family: monospace;
29+
white-space: pre-wrap;
30+
overflow-x: auto;
31+
}
32+
33+
/* Elementos abiertos */
34+
.toggle-info-container .right-bar-info.open {
35+
display: block;
36+
}
37+
38+
/* Transiciones para una experiencia más fluida */
39+
.toggle-info-container .hidden {
40+
display: none;
41+
}

src/types/packet.ts

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { RightBar, StyledInfo } from "../graphics/right_bar";
1111
import { Position } from "./common";
1212
import { ViewGraph } from "./graphs/viewgraph";
1313
import { EmptyPayload, IpAddress, IPv4Packet } from "../packets/ip";
14-
import { EchoRequest } from "../packets/icmp";
14+
import { EchoRequest, EchoReply } from "../packets/icmp";
1515
import { DeviceId, isRouter } from "./graphs/datagraph";
1616

1717
const contextPerPacketType: Record<string, GraphicsContext> = {
@@ -31,6 +31,7 @@ export class Packet extends Graphics {
3131
type: string;
3232
sourceId: number;
3333
destinationId: number;
34+
private detailsVisible = false;
3435

3536
rawPacket: IPv4Packet;
3637

@@ -82,8 +83,55 @@ export class Packet extends Graphics {
8283
this.removeHighlight();
8384
}
8485

86+
private getPacketDetails(packet: IPv4Packet) {
87+
// Creates a dictionary with the data of the packet
88+
const packetDetails: Record<string, string | number | object> = {
89+
Version: packet.version,
90+
"Internet Header Length": packet.internetHeaderLength,
91+
"Type of Service": packet.typeOfService,
92+
"Total Length": packet.totalLength,
93+
Identification: packet.identification,
94+
Flags: packet.flags,
95+
"Fragment Offset": packet.fragmentOffset,
96+
"Time to Live": packet.timeToLive,
97+
Protocol: packet.protocol,
98+
"Header Checksum": packet.headerChecksum,
99+
};
100+
101+
// Add payload details if available
102+
if (packet.payload instanceof EchoRequest) {
103+
const echoRequest = packet.payload as EchoRequest;
104+
packetDetails.Payload = {
105+
type: "EchoRequest",
106+
identifier: echoRequest.identifier,
107+
sequenceNumber: echoRequest.sequenceNumber,
108+
data: Array.from(echoRequest.data),
109+
};
110+
} else if (packet.payload instanceof EchoReply) {
111+
const echoReply = packet.payload as EchoReply;
112+
packetDetails.Payload = {
113+
type: "EchoReply",
114+
identifier: echoReply.identifier,
115+
sequenceNumber: echoReply.sequenceNumber,
116+
data: Array.from(echoReply.data),
117+
};
118+
} else {
119+
packetDetails.Payload = {
120+
type: "Unknown",
121+
protocol: packet.payload.protocol(),
122+
};
123+
}
124+
125+
return packetDetails;
126+
}
127+
85128
showInfo() {
86129
const rightbar = RightBar.getInstance();
130+
if (!rightbar) {
131+
console.error("RightBar instance not found.");
132+
return;
133+
}
134+
87135
const info = new StyledInfo("Packet Information");
88136
info.addField("Type", this.type);
89137
info.addField("Source ID", this.sourceId.toString());
@@ -104,13 +152,22 @@ export class Packet extends Graphics {
104152
},
105153
"right-bar-delete-button",
106154
);
155+
156+
// Add a toggle info section for packet details
157+
const packetDetails = this.getPacketDetails(this.rawPacket);
158+
159+
rightbar.addToggleButton("Packet Details", packetDetails);
107160
}
108161

109162
highlight() {
110163
this.context = highlightedPacketContext;
111164
}
112165

113166
removeHighlight() {
167+
if (!this.context || !contextPerPacketType[this.type]) {
168+
console.warn("Context or packet type context is null");
169+
return;
170+
}
114171
this.context = contextPerPacketType[this.type];
115172
}
116173

0 commit comments

Comments
 (0)