SafeDispatch/MotoTrbo_GW/RoutingUtils.cs
2024-02-22 18:43:59 +02:00

511 lines
22 KiB
C#

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
/// <summary>
///
/// </summary>
/// <param name="specific">checks if any route is in table/ checks if an specific ip is in table</param>
/// <param name="ip">IP if specific is set to true / else add it ""</param>
/// <returns></returns>
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<GatewayID_IP> 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<GatewayID_IP> 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;
/// <summary>
///
/// </summary>
/// <param name="specific"></param>
/// <param name="ip"></param>
/// <returns></returns>
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;
}
}