using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Windows.Forms; using System.Collections; using System.Threading; using Telerik.WinControls; using SafeMobileLib; using System.Runtime.InteropServices; using System.Net; namespace MotoTRBO_GW { public static class NativeMethods { [DllImport("iphlpapi", CharSet = CharSet.Auto)] public extern static int GetIpForwardTable(IntPtr /*PMIB_IPFORWARDTABLE*/ pIpForwardTable, ref int /*PULONG*/ pdwSize, bool bOrder); [DllImport("iphlpapi", CharSet = CharSet.Auto)] public extern static int CreateIpForwardEntry(IntPtr /*PMIB_IPFORWARDROW*/ pRoute); } class RoutingUtils { [ComVisible(false), StructLayout(LayoutKind.Sequential)] internal struct IPForwardTable { public uint Size; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public IPFORWARDROW[] Table; }; [ComVisible(false), StructLayout(LayoutKind.Sequential)] internal struct IPFORWARDROW { internal uint /*DWORD*/ dwForwardDest; internal uint /*DWORD*/ dwForwardMask; internal uint /*DWORD*/ dwForwardPolicy; internal uint /*DWORD*/ dwForwardNextHop; internal uint /*DWORD*/ dwForwardIfIndex; internal uint /*DWORD*/ dwForwardType; internal uint /*DWORD*/ dwForwardProto; internal uint /*DWORD*/ dwForwardAge; internal uint /*DWORD*/ dwForwardNextHopAS; internal uint /*DWORD*/ dwForwardMetric1; internal uint /*DWORD*/ dwForwardMetric2; internal uint /*DWORD*/ dwForwardMetric3; internal uint /*DWORD*/ dwForwardMetric4; internal uint /*DWORD*/ dwForwardMetric5; }; static IPForwardTable ReadIPForwardTable(IntPtr tablePtr) { var result = (IPForwardTable)Marshal.PtrToStructure(tablePtr, typeof(IPForwardTable)); IPFORWARDROW[] table = new IPFORWARDROW[result.Size]; IntPtr p = new IntPtr(tablePtr.ToInt64() + Marshal.SizeOf(result.Size)); for (int i = 0; i < result.Size; ++i) { table[i] = (IPFORWARDROW)Marshal.PtrToStructure(p, typeof(IPFORWARDROW)); p = new IntPtr(p.ToInt64() + Marshal.SizeOf(typeof(IPFORWARDROW))); } result.Table = table; return result; } #region Capacity plus code /// /// /// /// checks if any route is in table/ checks if an specific ip is in table /// IP if specific is set to true / else add it "" /// private static void ExecuteCommand(String command) { Process p = new Process(); p = new Process(); p.StartInfo.FileName = "cmd.exe"; String arguments = "/c " + command; p.StartInfo.Arguments = arguments; p.StartInfo.UseShellExecute = false; p.Start(); } private static void DeletePreviousTRBORoutes() { Process p = new Process(); p = new Process(); p.StartInfo.FileName = "cmd.exe"; String arguments = "/c route print"; p.StartInfo.Arguments = arguments; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.Start(); String output = p.StandardOutput.ReadToEnd(); char[] delimiters = new char[] { '\r', '\n' }; String[] lines = output.Split(delimiters, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < lines.Length; i++) { String currentLine = lines[i].Trim(); if (currentLine.StartsWith("12.") || currentLine.StartsWith("13.")) { String ip = currentLine.Split(' ')[0]; ExecuteCommand("route delete " + ip); } } } public static void UpdateRoutes(String masterRadioIP, Boolean capacityPlus) { Utils.WriteLine("START: UpdateRoutes", ConsoleColor.Yellow); List gatewayRadios = MotoTrbo_GW.RadioStuff.getAllRadiosIPs(); MotoTrbo_GW.Main.gatewayRadios = gatewayRadios; SafeMobileLib.Utils.WriteLine("__________"); SafeMobileLib.Utils.WriteLine("__________"); SafeMobileLib.Utils.WriteLine("__________"); SafeMobileLib.Utils.WriteLine("Update routes count of gateway list:" + MotoTrbo_GW.Main.gatewayRadios.Count); SafeMobileLib.Utils.WriteLine("__________"); SafeMobileLib.Utils.WriteLine("__________"); SafeMobileLib.Utils.WriteLine("__________"); if (capacityPlus) { GatewayID_IP masterRadio = new GatewayID_IP(); try { foreach (GatewayID_IP gatewayRadio in gatewayRadios) { Utils.WriteLine("Route CMD:" + "route delete " + gatewayRadio.remoteIP); if ((gatewayRadio.remoteIP != "") && (gatewayRadio.remoteIP != " ")) ExecuteCommand("route delete " + gatewayRadio.remoteIP); if (gatewayRadio.remoteIP.Equals(masterRadioIP)) { masterRadio = gatewayRadio; } } } catch (Exception ex) { Utils.WriteLine("Error on route Delete:"+ex.ToString()); } if (masterRadio.ID != null) { //adding gateway radio route SafeMobileLib.Utils.WriteLine("Adding master radio route"); String command = "route add " + masterRadio.remoteIP + " mask 255.255.255.255 " + masterRadio.localIP + " metric 40 IF " + masterRadio.ID; ExecuteCommand(command); SafeMobileLib.Utils.WriteLine("Route added, master radio ip is " + masterRadio.remoteIP); //adding 12.x.x.x route SafeMobileLib.Utils.WriteLine("updating 12.0.0.0 route"); command = "route delete 12.0.0.0"; ExecuteCommand(command); Thread.Sleep(200); command = "route add 12.0.0.0 mask 255.0.0.0 " + masterRadio.remoteIP + " metric 10 IF " + masterRadio.ID; ExecuteCommand(command); SafeMobileLib.Utils.WriteLine("12.0.0.0 route added"); // adding 225.x.x.x route SafeMobileLib.Utils.WriteLine("updating 225.0.0.0 route"); command = "route delete 225.0.0.0"; ExecuteCommand(command); Thread.Sleep(200); command = "route add 225.0.0.0 mask 255.0.0.0 " + masterRadio.remoteIP + " metric 10 IF " + masterRadio.ID; ExecuteCommand(command); SafeMobileLib.Utils.WriteLine("225.0.0.0 route added"); } else { RadMessageBox.Show("The master radio IP does not exist in the routing table.\r\n Please make sure the radio is connected and the IP is properly\r\n configured in CPS."); } } else { foreach (GatewayID_IP gatewayRadio in gatewayRadios) { String command = "route add " + gatewayRadio.remoteIP + " mask 255.255.255.255 " + gatewayRadio.localIP + " metric 50 IF " + gatewayRadio.ID; ExecuteCommand(command); } } Utils.WriteLine("END: UpdateRoutes", ConsoleColor.Yellow); } public static void UpdateRoutes_NonCapPlus(string ip, string intIP, int Netowrk_id) { Utils.WriteLine("START: UpdateRoutes_NonCapPlus", ConsoleColor.Yellow); List gatewayRadios = MotoTrbo_GW.RadioStuff.getAllRadiosIPs(); MotoTrbo_GW.Main.gatewayRadios = gatewayRadios; SafeMobileLib.Utils.WriteLine("__________"); SafeMobileLib.Utils.WriteLine("__________"); SafeMobileLib.Utils.WriteLine("__________"); SafeMobileLib.Utils.WriteLine("Update routes count of gateway list:" + MotoTrbo_GW.Main.gatewayRadios.Count); SafeMobileLib.Utils.WriteLine("__________"); SafeMobileLib.Utils.WriteLine("__________"); SafeMobileLib.Utils.WriteLine("__________"); String command = "route add " + ip + " mask 255.255.255.255 " + intIP + " metric 10 IF " + Netowrk_id; SafeMobileLib.Utils.WriteLine("**** Updating route for the new radio\n" + command); ExecuteCommand(command); //add groups list in route // MotoTrbo_GW.Main.GroupList just for temp groups /*Thread.Sleep(200); String commandGRP = "route add 225.0.0.0 mask 255.0.0.0 " + ip + " metric 80 IF " + Netowrk_id; SafeMobileLib.Utils.WriteLine("**** Add groups IP\n" + commandGRP); ExecuteCommand(commandGRP);*/ Utils.WriteLine("END: UpdateRoutes_NonCapPlus", ConsoleColor.Yellow); } #endregion #region Non-Capacity plus functions private static RouteTableInfo routeTable; /// /// /// /// /// /// public static bool checkRouteTable(string radioIP) { Utils.WriteLine("START: checkRouteTable", ConsoleColor.Yellow); bool ret = false; Process p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.Arguments = "/c route print"; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.Start(); string output = p.StandardOutput.ReadToEnd(); if (output.Contains(radioIP)) { ret = true; } Utils.WriteLine("END: checkRouteTable", ConsoleColor.Yellow); return ret; } public static bool checkRouteTableUnmanaged(string radioIP) { Console.WriteLine("START: checkRouteTableUnmanaged " + DateTime.Now.ToString("H: mm:ss.ffffff")); bool ret = false; var fwdTable = IntPtr.Zero; int size = 0; var result = NativeMethods.GetIpForwardTable(fwdTable, ref size, true); fwdTable = Marshal.AllocHGlobal(size); result = NativeMethods.GetIpForwardTable(fwdTable, ref size, true); var forwardTable = ReadIPForwardTable(fwdTable); Marshal.FreeHGlobal(fwdTable); Console.Write("\tNumber of entries: {0}\n", forwardTable.Size); for (int i = 0; i < forwardTable.Table.Length; ++i) { if (new IPAddress((long)forwardTable.Table[i].dwForwardDest).ToString() == radioIP) { Console.WriteLine("END: checkRouteTableUnmanaged " + DateTime.Now.ToString("H: mm:ss.ffffff")); return true; } } Console.WriteLine("END: checkRouteTableUnmanaged " + DateTime.Now.ToString("H: mm:ss.ffffff")); return ret; } public static bool checkIfAlreadyPresent(string radioIP, string gwip) { Utils.WriteLine("START: checkIfAlreadyPresent", ConsoleColor.Yellow); bool ret = false; Process p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.Arguments = "/c route print"; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.Start(); string output = p.StandardOutput.ReadToEnd(); routeTable = new RouteTableInfo(); routeTable.time = DateTime.Now; routeTable.routeString = output; if (output.Contains(radioIP + " 255.255.255.255 " + gwip)) { string temp1 = output.Substring(output.IndexOf(radioIP)); if (temp1.Contains(gwip)) { string temp2 = temp1.Remove(temp1.IndexOf(gwip) + gwip.Length); temp2 = temp2.Replace(radioIP, ""); temp2 = temp2.Replace(gwip, ""); temp2 = temp2.Replace("255.255.255.255", ""); temp2 = temp2.Replace(" ", ""); if(temp2.Length ==0) ret = true; } } Utils.WriteLine("END: checkIfAlreadyPresent", ConsoleColor.Yellow); return ret; } public static void displayRoutes() { Utils.WriteLine("START: displayRoutes", ConsoleColor.Yellow); bool ret = false; Process p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.Arguments = "/c route print"; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.Start(); string output = p.StandardOutput.ReadToEnd(); Utils.WriteLine("ROUTING LIST " + output, ConsoleColor.Yellow); Utils.WriteLine("END: displayRoutes", ConsoleColor.Yellow); } public static bool checkIfAlreadyPresent_withBuffer(string radioIP, string gwip) { Utils.WriteLine("START: checkIfAlreadyPresent_withBuffer", ConsoleColor.Yellow); string output = ""; bool ret = false; if (routeTable != null) { if (routeTable.time.AddMinutes(5) > DateTime.Now) { Utils.WriteLine("Getting route from buffer. buffer time:" + routeTable.time + " system time:" + DateTime.Now); output = routeTable.routeString; } else { Utils.WriteLine("Refreshing buffer. old buffer time:" + routeTable.time + " system time:" + DateTime.Now); Process p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.Arguments = "/c route print"; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.Start(); output = p.StandardOutput.ReadToEnd(); routeTable = new RouteTableInfo(); routeTable.time = DateTime.Now; routeTable.routeString = output; } } else { Utils.WriteLine("Creating route table buffer at: "+DateTime.Now); Process p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.Arguments = "/c route print"; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.Start(); output = p.StandardOutput.ReadToEnd(); routeTable = new RouteTableInfo(); routeTable.time = DateTime.Now; routeTable.routeString = output; } if (output.Contains(radioIP + " 255.255.255.255 " + gwip)) { string temp1 = output.Substring(output.IndexOf(radioIP)); if (temp1.Contains(gwip)) { string temp2 = temp1.Remove(temp1.IndexOf(gwip) + gwip.Length); temp2 = temp2.Replace(radioIP, ""); temp2 = temp2.Replace(gwip, ""); temp2 = temp2.Replace("255.255.255.255", ""); temp2 = temp2.Replace(" ", ""); if (temp2.Length == 0) ret = true; } } Utils.WriteLine("END: checkIfAlreadyPresent_withBuffer", ConsoleColor.Yellow); return ret; } public static void deleteRoute(string ip) { //SafeMobileLib.Utils.WriteLine("route delete " + ip); Utils.WriteLine("START: deleteRoute", ConsoleColor.Yellow); Process p = new Process(); p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.Arguments = "/c route delete " + ip; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.Start(); string output = p.StandardOutput.ReadToEnd(); Utils.WriteLine("END: deleteRoute", ConsoleColor.Yellow); } public static String radioID2IP(String p_radioID) { Int64 radioID = Convert.ToInt64(p_radioID); if (radioID > 255 * 255 * 255) throw new Exception("Radio ID out of range"); byte c = (byte)(radioID & 0x0000FF); byte b = (byte)((radioID & 0x00FF00) >> 8); byte a = (byte)((radioID & 0xFF0000) >> 16); string m_ip = "12." + a + "." + b + "." + c; return m_ip; } public static void addRoute(String radioID, String gatewayIP, String gatewayInterfaceID) { Utils.WriteLine("START: addRoute", ConsoleColor.Yellow); String radioIP = radioID2IP(radioID); if (checkIfAlreadyPresent(radioIP, gatewayIP)) { //SafeMobileLib.Utils.WriteLine("Route " + radioIP + " to " + gatewayIP + " already in route table!!!"); Utils.WriteLine("END: addRoute", ConsoleColor.Yellow); return; } else { //SafeMobileLib.Utils.WriteLine("Route " + radioIP + " to " + gatewayIP + " DOSEN'T exist in route table!!!"); } //SafeMobileLib.Utils.WriteLine("---------------------------------------------------------------"); if (checkRouteTableUnmanaged(radioIP)) { deleteRoute(radioIP); } Process p = new Process(); p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.Arguments = "/c route add " + radioIP + " mask 255.255.255.255 " + gatewayIP + " metric 40 IF " + gatewayInterfaceID; //SafeMobileLib.Utils.WriteLine("route adding:" + p.StartInfo.Arguments); p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.Start(); string output = p.StandardOutput.ReadToEnd(); if (checkRouteTableUnmanaged(radioIP)) { //SafeMobileLib.Utils.WriteLine("Route added for {0} to {1}", radioIP, gatewayIP); } else { Utils.WriteLine($"Route adding failed for {radioIP} to {gatewayIP}" ); } //SafeMobileLib.Utils.WriteLine("---------------------------------------------------------------"); Utils.WriteLine("END: addRoute", ConsoleColor.Yellow); } public static void addRoute_withBuffer(String radioID, String gatewayIP, String gatewayInterfaceID) { Utils.WriteLine("START: addRoute_withBuffer", ConsoleColor.Yellow); String radioIP = radioID2IP(radioID); if (checkIfAlreadyPresent_withBuffer(radioIP, gatewayIP)) { Utils.WriteLine("Route " + radioIP + " to " + gatewayIP + " already in route table!!!", ConsoleColor.Green); Utils.WriteLine("END: addRoute_withBuffer", ConsoleColor.Yellow); return; } else Utils.WriteLine("Route " + radioIP + " to " + gatewayIP + " does not exist. Recreating it...", ConsoleColor.Red); //SafeMobileLib.Utils.WriteLine("---------------------------------------------------------------"); /* if (checkRouteTable(radioIP)) { deleteRoute(radioIP); } */ Process p = new Process(); p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.Arguments = "/c route add " + radioIP + " mask 255.255.255.255 " + gatewayIP + " metric 40 IF " + gatewayInterfaceID; //SafeMobileLib.Utils.WriteLine("route adding:" + p.StartInfo.Arguments); p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.Start(); string output = p.StandardOutput.ReadToEnd(); if (checkRouteTableUnmanaged(radioIP)) { //SafeMobileLib.Utils.WriteLine("Route added for {0} to {1} ", radioIP, gatewayIP); } else { SafeMobileLib.Utils.WriteLine($"Route adding failed for {radioIP} to {gatewayIP}"); } Utils.WriteLine("END: addRoute_withBuffer", ConsoleColor.Yellow); ///SafeMobileLib.Utils.WriteLine("---------------------------------------------------------------"); } #endregion } public class RouteTableInfo { public DateTime time; public string routeString; } }