Skip to content

Commit fac06e8

Browse files
Manuel-Polpgallino
andauthored
fix: handles cases where the NetworkDevice.getForwardingData return undefined (#259)
Co-authored-by: Pedro Gallino <[email protected]>
1 parent a0e3c19 commit fac06e8

File tree

9 files changed

+95
-62
lines changed

9 files changed

+95
-62
lines changed

src/graphics/renderables/program_info.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,12 @@ export class ProgramInfo implements Renderable {
1515
this.name = name;
1616
}
1717

18-
withDestinationDropdown(
19-
viewgraph: ViewGraph,
20-
srcId: DeviceId,
21-
layer?: Layer,
22-
) {
18+
withDestinationDropdown(viewgraph: ViewGraph, srcId: DeviceId, layer: Layer) {
2319
let devices = otherDevices(viewgraph, srcId);
24-
if (layer) {
25-
devices = devices.filter((device) => {
26-
const deviceLayer = viewgraph.getDevice(device.id)?.getLayer();
27-
return layerIncluded(deviceLayer, layer);
28-
});
29-
}
20+
devices = devices.filter((device) => {
21+
const deviceLayer = viewgraph.getDevice(device.id)?.getLayer();
22+
return layerIncluded(deviceLayer, layer);
23+
});
3024
this.withDropdown(TOOLTIP_KEYS.DESTINATION, devices);
3125
}
3226

src/programs/echo_sender.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import { ProgramBase } from "./program_base";
55
import { ViewGraph } from "../types/graphs/viewgraph";
66
import { ProgramInfo } from "../graphics/renderables/device_info";
77
import { EchoRequest } from "../packets/icmp";
8-
import { IPv4Packet } from "../packets/ip";
8+
import { IpAddress, IPv4Packet } from "../packets/ip";
99
import { ViewNetworkDevice } from "../types/view-devices/vNetworkDevice";
10-
import { EthernetFrame } from "../packets/ethernet";
10+
import { EthernetFrame, MacAddress } from "../packets/ethernet";
1111
import { TOOLTIP_KEYS } from "../utils/constants/tooltips_constants";
12+
import { Layer } from "../types/layer";
1213

1314
export class SingleEcho extends ProgramBase {
1415
static readonly PROGRAM_NAME = TOOLTIP_KEYS.SEND_ICMP_ECHO;
@@ -50,19 +51,39 @@ export class SingleEcho extends ProgramBase {
5051
);
5152
return;
5253
}
53-
const { src, dst, sendingIface } = ViewNetworkDevice.getForwardingData(
54+
55+
const forwardingData = ViewNetworkDevice.getForwardingData(
5456
this.srcId,
5557
this.dstId,
5658
this.viewgraph,
5759
);
60+
let src: { ip: IpAddress; mac: MacAddress },
61+
dst: { ip: IpAddress; mac: MacAddress },
62+
sendingIface: number;
63+
if (!forwardingData) {
64+
console.warn(
65+
`Device ${this.srcId} could not send ping to device ${this.dstId}`,
66+
);
67+
src = {
68+
mac: srcDevice.interfaces[0].mac,
69+
ip: srcDevice.interfaces[0].ip,
70+
};
71+
dst = {
72+
mac: dstDevice.interfaces[0].mac,
73+
ip: dstDevice.interfaces[0].ip,
74+
};
75+
sendingIface = 0;
76+
} else {
77+
({ src, dst, sendingIface } = forwardingData);
78+
}
5879
const echoRequest = new EchoRequest(0);
5980
// Wrap in IP datagram
6081
const ipPacket = new IPv4Packet(src.ip, dst.ip, echoRequest);
6182

6283
// Resolve destination MAC address
6384
const dstMac = srcDevice.resolveAddress(dst.ip);
6485
if (!dstMac) {
65-
console.warn(
86+
console.debug(
6687
`Device ${this.srcId} couldn't resolve MAC address for device with IP ${dst.ip.toString()}. Program cancelled`,
6788
);
6889
return;
@@ -75,7 +96,7 @@ export class SingleEcho extends ProgramBase {
7596

7697
static getProgramInfo(viewgraph: ViewGraph, srcId: DeviceId): ProgramInfo {
7798
const programInfo = new ProgramInfo(this.PROGRAM_NAME);
78-
programInfo.withDestinationDropdown(viewgraph, srcId);
99+
programInfo.withDestinationDropdown(viewgraph, srcId, Layer.Network);
79100
return programInfo;
80101
}
81102
}
@@ -135,7 +156,7 @@ export class EchoServer extends ProgramBase {
135156
];
136157

137158
const programInfo = new ProgramInfo(this.PROGRAM_NAME);
138-
programInfo.withDestinationDropdown(viewgraph, srcId);
159+
programInfo.withDestinationDropdown(viewgraph, srcId, Layer.Network);
139160
programInfo.withDropdown("Time between pings", delayOptions);
140161
return programInfo;
141162
}

src/types/edge.ts

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -288,15 +288,35 @@ export class Edge extends Graphics {
288288
this.on("mouseover", () => {
289289
const group = this.viewgraph.findConnectedEdges(this);
290290
group.forEach((edge) => {
291-
edge.setupConnectedDevicesTooltips();
291+
edge.handleConnectedDevicesTooltips(
292+
(device: ViewDevice, iface: number) => {
293+
if (!device) {
294+
console.error(
295+
`Device ${device.id} not found in viewgraph, cannot set device tooltip`,
296+
);
297+
return;
298+
}
299+
if (device.isVisible()) {
300+
device.setupToolTip(iface);
301+
}
302+
},
303+
);
292304
edge.showTooltips();
293305
edge.fixTooltipPositions();
294306
});
295307
});
296308
this.on("mouseout", () => {
297309
const group = this.viewgraph.findConnectedEdges(this);
298310
group.forEach((edge) => {
299-
edge.hideConnectedDevicesTooltips();
311+
edge.handleConnectedDevicesTooltips((device: ViewDevice) => {
312+
if (!device) {
313+
console.error(
314+
`Device ${device.id} not found in viewgraph, cannot set device tooltip`,
315+
);
316+
return;
317+
}
318+
device.hideToolTip();
319+
});
300320
edge.hideTooltips();
301321
});
302322
});
@@ -326,46 +346,28 @@ export class Edge extends Graphics {
326346
);
327347
}
328348

329-
private setupConnectedDevicesTooltips() {
349+
handleConnectedDevicesTooltips(
350+
handleTooltip: (device: ViewDevice, iface?: number) => void,
351+
) {
330352
const [startId, startIface] = [this.data.from.id, this.data.from.iface];
331353
const [endId, endIface] = [this.data.to.id, this.data.to.iface];
332354
const startDevice = this.viewgraph.getDevice(startId);
333355
const endDevice = this.viewgraph.getDevice(endId);
334356

335-
const setTooltip = (device: ViewDevice, iface: number) => {
357+
const deviceFound = (device: ViewDevice, id: DeviceId) => {
336358
if (!device) {
337359
console.error(
338-
`Device ${device.id} not found in viewgraph, cannot set device tooltip`,
360+
`Device ${id} not found in viewgraph, cannot set device tooltip`,
339361
);
340-
return;
341-
}
342-
if (device.isVisible()) {
343-
device.setupTooltip(iface);
362+
return false;
344363
}
364+
return true;
345365
};
346366

347-
setTooltip(startDevice, startIface);
348-
setTooltip(endDevice, endIface);
349-
}
367+
if (deviceFound(startDevice, startId))
368+
handleTooltip(startDevice, startIface);
350369

351-
private hideConnectedDevicesTooltips() {
352-
const startId = this.data.from.id;
353-
const endId = this.data.to.id;
354-
const startDevice = this.viewgraph.getDevice(startId);
355-
const endDevice = this.viewgraph.getDevice(endId);
356-
357-
const hideTooltip = (device: ViewDevice) => {
358-
if (!device) {
359-
console.error(
360-
`Device ${device.id} not found in viewgraph, cannot set device tooltip`,
361-
);
362-
return;
363-
}
364-
device.hideToolTip();
365-
};
366-
367-
hideTooltip(startDevice);
368-
hideTooltip(endDevice);
370+
if (deviceFound(endDevice, endId)) handleTooltip(endDevice, endIface);
369371
}
370372

371373
private fixTooltipPositions() {
@@ -411,6 +413,9 @@ export class Edge extends Graphics {
411413
}
412414

413415
private removeTooltips() {
416+
this.handleConnectedDevicesTooltips((device: ViewDevice) =>
417+
device.hideToolTip(),
418+
);
414419
this.startTooltip = removeTooltip(this, this.startTooltip);
415420
this.endTooltip = removeTooltip(this, this.endTooltip);
416421
}

src/types/graphs/datagraph.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -532,8 +532,7 @@ export class DataGraph {
532532
parents.forEach((currentId, childId) => {
533533
const dstId = childId;
534534
if (dstId === id) return;
535-
// Get edge connection both devices
536-
console.debug(`currentId: ${currentId}, childId: ${childId}`);
535+
// Get edge connecting both devices
537536
const edge = this.getConnection(currentId, childId);
538537
// Get childId interface involved in connection
539538
const receivingIfaceNum =

src/types/graphs/viewgraph.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,10 +366,10 @@ export class ViewGraph {
366366
console.warn(`Edge ${n1Id},${n2Id} is not in the datagraph`);
367367
return null;
368368
}
369+
this._removeEdge(n1Id, n2Id);
370+
369371
// Remove connection in DataGraph
370372
this.datagraph.removeConnection(n1Id, n2Id);
371-
372-
this._removeEdge(n1Id, n2Id);
373373
return datagraphEdge;
374374
}
375375

src/types/network-modules/tcp/tcpState.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ function sendIpPacket(
5353
dst.id,
5454
viewgraph,
5555
);
56+
if (!forwardingData) {
57+
console.warn(`Device ${dst.id} is not reachable from device ${src.id}`);
58+
return false;
59+
}
5660
const [srcData, dstData, sendingIface] = [
5761
forwardingData.src,
5862
forwardingData.dst,

src/types/view-devices/vDevice.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ export abstract class ViewDevice extends Container {
150150
// Do nothing
151151
}
152152

153-
setupTooltip(iface: number) {
153+
setupToolTip(iface: number) {
154154
const currentLayer = this.ctx.getCurrentLayer();
155155
const tooltipMessage = this.getTooltipDetails(currentLayer, iface);
156156
this.tooltip = showTooltip(
@@ -166,6 +166,10 @@ export abstract class ViewDevice extends Container {
166166
hideTooltip(this.tooltip);
167167
}
168168

169+
removeToolTip() {
170+
removeTooltip(this, this.tooltip);
171+
}
172+
169173
setCircleColor(color: number) {
170174
if (!this.isDragCircle) return;
171175
if (this.circleGraphic) {

src/types/view-devices/vNetworkDevice.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ import { ViewGraph } from "../graphs/viewgraph";
1111
import { Position } from "../common";
1212
import { EthernetFrame, MacAddress } from "../../packets/ethernet";
1313
import { sendViewPacket, dropPacket } from "../packet";
14-
import { EchoReply, EchoRequest } from "../../packets/icmp";
14+
import {
15+
EchoReply,
16+
EchoRequest,
17+
ICMP_REQUEST_TYPE_NUMBER,
18+
} from "../../packets/icmp";
1519
import { GlobalContext } from "../../context";
1620
import {
1721
ARP_REPLY_CODE,
@@ -82,11 +86,7 @@ export abstract class ViewNetworkDevice extends ViewDevice {
8286
// Get dstMac
8387
let dstMac: MacAddress = dstIface.mac;
8488
for (const idx of path.slice(1).keys()) {
85-
console.debug(`Iterando en indice: ${idx}`);
8689
const [sendingId, receivingId] = [path[idx], path[idx + 1]];
87-
console.debug(
88-
`Se obtienen los devices con ids ${sendingId} y ${receivingId}`,
89-
);
9090
const receivingDevice = viewgraph.getDevice(receivingId);
9191
if (receivingDevice instanceof ViewNetworkDevice) {
9292
const edge = viewgraph.getEdge(sendingId, receivingId);
@@ -169,12 +169,15 @@ export abstract class ViewNetworkDevice extends ViewDevice {
169169
console.debug("Packet has reach its destination!");
170170
const dstDevice = this.viewgraph.getDeviceByIP(datagram.sourceAddress);
171171
if (!(dstDevice instanceof ViewNetworkDevice)) {
172+
console.warn(
173+
`Device with IP ${datagram.sourceAddress.toString} was not found or was not a Network Device`,
174+
);
172175
return;
173176
}
174177
switch (datagram.payload.protocol()) {
175178
case ICMP_PROTOCOL_NUMBER: {
176179
const request: EchoRequest = datagram.payload as EchoRequest;
177-
if (dstDevice && request.type) {
180+
if (dstDevice && request.type === ICMP_REQUEST_TYPE_NUMBER) {
178181
const { src, dst } = ViewNetworkDevice.getForwardingData(
179182
this.id,
180183
dstDevice.id,

src/types/view-devices/vRouter.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,14 +200,17 @@ export class ViewRouter extends ViewNetworkDevice {
200200

201201
const dstDevice = this.viewgraph.getDeviceByIP(datagram.destinationAddress);
202202
// TODO: use arp table here?
203-
const { src, dst } = ViewNetworkDevice.getForwardingData(
203+
const forwardingData = ViewNetworkDevice.getForwardingData(
204204
this.id,
205-
dstDevice.id,
205+
dstDevice?.id,
206206
this.viewgraph,
207207
);
208+
if (forwardingData && forwardingData.sendingIface === iface) {
209+
const { src, dst } = forwardingData;
208210

209-
const newFrame = new EthernetFrame(src.mac, dst.mac, datagram);
210-
sendViewPacket(this.viewgraph, this.id, newFrame, iface);
211+
const newFrame = new EthernetFrame(src.mac, dst.mac, datagram);
212+
sendViewPacket(this.viewgraph, this.id, newFrame, iface);
213+
} else console.debug(`Router ${this.id} could not forward packet.`);
211214

212215
if (this.packetQueue.isEmpty()) {
213216
this.stopPacketProcessor();

0 commit comments

Comments
 (0)