From 9e33a6f39213b56c88c144f0f80e17d87cbf6462 Mon Sep 17 00:00:00 2001 From: Tim Young Date: Mon, 13 Mar 2017 14:04:02 +0300 Subject: [PATCH] traceroute works, at least rudimentarily --- EduNetworkBuilder/IPAddress.cs | 1 + EduNetworkBuilder/Network.cs | 11 +++- EduNetworkBuilder/NetworkBuilder.cs | 6 +- EduNetworkBuilder/NetworkDevice.cs | 63 +++++++++++++++++-- EduNetworkBuilder/Packet.cs | 9 ++- .../Resources/languages/edustrings.resx | 8 +++ 6 files changed, 88 insertions(+), 10 deletions(-) diff --git a/EduNetworkBuilder/IPAddress.cs b/EduNetworkBuilder/IPAddress.cs index 38dc9e5..aa2a11f 100644 --- a/EduNetworkBuilder/IPAddress.cs +++ b/EduNetworkBuilder/IPAddress.cs @@ -252,6 +252,7 @@ namespace EduNetworkBuilder public static UInt32 ParseIp(this string ipAddress) { + if (ipAddress == null) ipAddress = ""; var gw = ipAddress.Split('/'); //Pull off any cdr var mySplitVal = gw[0].Split('.'); if (mySplitVal.Count() != 4) diff --git a/EduNetworkBuilder/Network.cs b/EduNetworkBuilder/Network.cs index 0fb1742..dc04940 100644 --- a/EduNetworkBuilder/Network.cs +++ b/EduNetworkBuilder/Network.cs @@ -1053,6 +1053,15 @@ namespace EduNetworkBuilder return; //exit early. Rest is done in tick } + public void ResetPacketTimeout() + { + //We should only do this when we know we are starting new packets. + //Traceroute does this when resetting + AlreadyChosenTimeout = false; //we do this at the beginning of processing + NumberOfSecondsForTimeout = DefaultTimeout; + NetworkStartTime = DateTime.Now; + } + public void Tick() { EraseOldPackets(); @@ -1069,7 +1078,7 @@ namespace EduNetworkBuilder ProcessPacketsOnce(); if(!ProcessingShouldContinue()) { - //We it has all been taken care of + //It has all been taken care of } DrawPackets(); //myPBox.Refresh(); diff --git a/EduNetworkBuilder/NetworkBuilder.cs b/EduNetworkBuilder/NetworkBuilder.cs index 78b9cb8..7e56ac0 100644 --- a/EduNetworkBuilder/NetworkBuilder.cs +++ b/EduNetworkBuilder/NetworkBuilder.cs @@ -823,9 +823,9 @@ namespace EduNetworkBuilder todo = destination.Edit(ItemClickedOn, this, NB.Translate("_Traceroute")); if (todo) { - //ItemClickedOn.PingFromHere(destination); - //myNetwork.ProcessPackets(); - //UpdateMessages(); + ItemClickedOn.TracerouteFromHere(destination); + myNetwork.ProcessPackets(); + UpdateMessages(); } } diff --git a/EduNetworkBuilder/NetworkDevice.cs b/EduNetworkBuilder/NetworkDevice.cs index faade45..7922f78 100644 --- a/EduNetworkBuilder/NetworkDevice.cs +++ b/EduNetworkBuilder/NetworkDevice.cs @@ -1279,11 +1279,10 @@ namespace EduNetworkBuilder public void TracerouteFromHere(IPAddress Destination) { - //We need to create a packet - Packet TracertPacket = new Packet(this, Destination, NB.Translate("_Traceroute"), PacketType.tracert_request, -1, 1); + //We need to create a traceroute packet - start with 1 TTL + //We pass it the destination as the payload string, so we have that for all traceroutes. + Packet TracertPacket = new Packet(this, Destination, Destination.GetIPString, PacketType.tracert_request, -1, 1); Network myNet = NB.GetNetwork(); - //string dHost = myNet.ReverseDNSLookup(this, Destination); - //myNet.RegisterPingTest(hostname, dHost); myNet.addPacket(TracertPacket); } @@ -1821,7 +1820,29 @@ namespace EduNetworkBuilder } return; } - if(tPacket.MyType == PacketType.arp_request) + //Tracert_request is processed on the link arrivak + if (tPacket.MyType == PacketType.tracert_reply) + { + //The reply got here. This packet is done + tPacket.AddMessage(DebugLevel.info, NB.Translate("ND_ProcessArrival_TracertReply") + " " + tPacket.sourceIP.GetIPString); + tPacket.Tracking.Status = NB.LeftPad(hostname) + " " + string.Format(NB.Translate("ND_ProcessArrival_TracertReply") + " " + tPacket.sourceIP.GetIPString); + tPacket.MyStatus = PacketStatus.finished_ok; + + IPAddress origStart = new IPAddress(tPacket.payloadData); + int ttl = tPacket.OrigTTL + 1; + + Console.WriteLine("Tracert: " + tPacket.OrigTTL + " " + tPacket.sourceIP.GetIPString); + Console.WriteLine("Tracert: -- " + tPacket.sourceIP.GetIPString + " " + origStart.GetIPString); + //If we had not landed on the actual dest... + if (tPacket.sourceIP.GetIPString != origStart.GetIPString && ttl < 10) + { + Packet trPacket = new Packet(this, origStart, origStart.GetIPString, PacketType.tracert_request, -1, ttl); + myNet.addPacket(trPacket); + myNet.ResetPacketTimeout(); + } + return; + } + if (tPacket.MyType == PacketType.arp_request) { //The arp request may not be asking for this IP. if(HasIPAddress(tPacket.destIP)) @@ -2478,6 +2499,38 @@ namespace EduNetworkBuilder if (!ForwardsPackets()) { + //Traceroute bounce-back + if(tPacket.MyType == PacketType.tracert_request) + { + tPacket.TTL--; + //If it is a router, or this is the destination + if(tPacket.TTL < 1 && (RoutesPackets() || HasMac(tPacket.destMAC))) + { + //The packet reached the end of its ttl. Bounce back. + //this packet ends, another begins. + Network myNet = NB.GetNetwork(); + + //We create a new packet + Packet nPacket = new Packet(this, tPacket.sourceIP, tPacket.payloadData, PacketType.tracert_reply, tPacket.packetID); + nPacket.OrigTTL = tPacket.OrigTTL; + nPacket.OriginalDestIP = tPacket.destIP; + nPacket.isFresh = true; //So it starts from here + nPacket.Tracking = new PacketMessage(); + + //The original packet stops here + tPacket.AddMessage(DebugLevel.info, NB.Translate("ND_ProcessArrival_TracerouteArrived") + " " + hostname); + tPacket.Tracking.Status = NB.LeftPad(hostname) + " Traceroute: " + NB.Translate("ND_ProcessArrival_TracerouteArrived") + " "+ hostname; + tPacket.MyStatus = PacketStatus.finished_ok; + Console.WriteLine(" Tracert bounce: " + tPacket.OrigTTL + " " + hostname + " " + tPacket.payloadData); + + //Finish setting up the new packet - sending it back + nPacket.sourceIP = new IPAddress(NB.ZeroIPString); + nPacket.TsourceIP = new IPAddress(NB.ZeroIPString); + myNet.addPacket(nPacket); + Console.WriteLine(" Tracert bounce pkt:" + nPacket.OrigTTL + nPacket.payloadData); + } + } + if (tPacket.MyType == PacketType.dhcp_request && !isDHCPServer) { tPacket.AddMessage(DebugLevel.debug, NB.LeftPad(hostname) + " " +string.Format(NB.Translate("ND_DoInFromLnkDeaf"))); diff --git a/EduNetworkBuilder/Packet.cs b/EduNetworkBuilder/Packet.cs index 99bd944..945f174 100644 --- a/EduNetworkBuilder/Packet.cs +++ b/EduNetworkBuilder/Packet.cs @@ -38,6 +38,7 @@ namespace EduNetworkBuilder public int packetID; public int VLANID = NB.UntaggedVLAN; //starts on the management vlan public int TTL = 20; + public int OrigTTL = 20; //The original TTL. We need to know what we started with so we can pass it back on a traceroute public int TickTTL = 50; public int health = 100; public IPAddress sourceIP; @@ -95,6 +96,7 @@ namespace EduNetworkBuilder { MyType = copyfrom.MyType; TTL = copyfrom.TTL; + OrigTTL = copyfrom.OrigTTL; sourceIP = copyfrom.sourceIP; TsourceIP = copyfrom.TsourceIP; destIP = copyfrom.destIP; @@ -126,6 +128,7 @@ namespace EduNetworkBuilder packetID = NewPacketID; } if (startTTL != -1) this.TTL = startTTL; + OrigTTL = TTL; WhereAmI = start; payloadData = payload; MyType = theType; @@ -170,7 +173,7 @@ namespace EduNetworkBuilder } if (startTTL != -1) this.TTL = startTTL; - + OrigTTL = TTL; if (theType != PacketType.arp_answer && theType != PacketType.arp_request) { @@ -228,6 +231,10 @@ namespace EduNetworkBuilder case PacketType.ping_request: pencolor = Color.Blue; break; + case PacketType.tracert_reply: + case PacketType.tracert_request: + pencolor = Color.LightBlue; + break; case PacketType.tun_packet: pencolor = Color.White; break; diff --git a/EduNetworkBuilder/Resources/languages/edustrings.resx b/EduNetworkBuilder/Resources/languages/edustrings.resx index ab54ba3..70ee178 100644 --- a/EduNetworkBuilder/Resources/languages/edustrings.resx +++ b/EduNetworkBuilder/Resources/languages/edustrings.resx @@ -1657,6 +1657,14 @@ Device cannot respond - Packet Failed ND_DoInputFromLink_PowerOff = Device cannot respond - Packet Failed + + TTL reached. + ND_ProcessArrival_TracerouteArrived = TTL reached. + + + Traceroute Destination Reached + ND_ProcessArrival_TracertReply = Traceroute Destination Reached + Traceroute _Traceroute = Traceroute