private static IntPtr GenerateIpForwardEntry(uint destIPAddress, uint destMask, uint nextHopIPAddress, uint ifIndex, int metric, uint policy, uint type, uint proto) { MIB_IPFORWARDROW row = new MIB_IPFORWARDROW { dwForwardDest = destIPAddress, dwForwardMask = destMask, dwForwardPolicy = policy, dwForwardNextHop = nextHopIPAddress, dwForwardIfIndex = ifIndex, dwForwardType = type, dwForwardProto = proto, dwForwardAge = 0, dwForwardNextHopAS = 0, dwForwardMetric1 = metric, dwForwardMetric2 = 0, dwForwardMetric3 = 0, dwForwardMetric4 = 0, dwForwardMetric5 = 0 }; var ptr = Marshal.AllocHGlobal(Marshal.SizeOf <MIB_IPFORWARDROW>()); Marshal.StructureToPtr(row, ptr, false); return(ptr); }
/// <summary> /// Modifie une route existante. /// </summary> /// <param name="entryToSet">Route à modifier.</param> /// <param name="IPInterface">Nouvelle interface.</param> /// <param name="IPDestination">Nouvelle IP de destination.</param> /// <param name="Mask">Nouveau masque.</param> /// <param name="Protocol">Protocol de routage.</param> /// <param name="NextHopAddr">Nouvelle adresse du prochain saut.</param> /// <returns>0 si réussi.</returns> public int ChangeRouteEntry(ref RouteEntry entryToSet, int IPInterface, IPAddress IPDestination, IPAddress Mask, ForwardProtocol Protocol, IPAddress NextHopAddr, int metric) { int ret = -1; try { MIB_IPFORWARDROW ipFwdSet = entryToSet._ipFwdNative; ipFwdSet.dwForwardIfIndex = IPInterface; ipFwdSet.dwForwardDest = (uint)BitConverter.ToInt32(IPDestination.GetAddressBytes(), 0); ipFwdSet.dwForwardMask = (uint)BitConverter.ToInt32(Mask.GetAddressBytes(), 0); ipFwdSet.dwForwardProto = Protocol; ipFwdSet.dwForwardNextHop = (uint)BitConverter.ToInt32(NextHopAddr.GetAddressBytes(), 0); //ipFwdSet.dwForwardMetric1 = metric; //Appel api pour modifier la route. ret = NativeMethods.SetIpForwardEntry(ref ipFwdSet); if (ret == 0) { entryToSet.Index = IPInterface; entryToSet.Destination = IPDestination; entryToSet.Mask = Mask; entryToSet.Protocol = Protocol; entryToSet.NextHop = NextHopAddr; entryToSet.Metric1 = metric; } } catch (Exception) { } return(ret); }
public static void DeleteRoute(IPAddress ipAddress, IPAddress mask, IPAddress gateway, int gatewayIndex) { if (gateway != null) { var route = new MIB_IPFORWARDROW { dwForwardDest = BitConverter.ToUInt32(ipAddress.GetAddressBytes(), 0), dwForwardMask = BitConverter.ToUInt32(mask.GetAddressBytes(), 0), dwForwardNextHop = BitConverter.ToUInt32(gateway.GetAddressBytes(), 0), dwForwardNextHopAS = 0, dwForwardPolicy = 0, dwForwardMetric1 = 9999, dwForwardType = ForwardType.Indirect, dwForwardProto = ForwardProtocol.NetMGMT, dwForwardAge = 0, dwForwardIfIndex = gatewayIndex, dwForwardMetric2 = -1, dwForwardMetric3 = -1, dwForwardMetric4 = -1, dwForwardMetric5 = -1 }; int output = DeleteIpForwardEntry(ref route); } }
public static WinApiRouteManagementResult DeleteRoute(string destinationIpAddress, string mask, string gatewayIpAddress) { WinApiRouteManagementResult result; uint destinationIpAddressWinApiFormat = ParseInternetAddress(destinationIpAddress); uint interfaceIndex; if (GetBestInterface(destinationIpAddressWinApiFormat, out interfaceIndex) == NO_ERROR) { MIB_IPFORWARDROW route = new MIB_IPFORWARDROW { dwForwardProto = ForwardProtocol.NetMGMT, dwForwardDest = destinationIpAddressWinApiFormat, dwForwardMask = ParseInternetAddress(mask), dwForwardNextHop = ParseInternetAddress(gatewayIpAddress), dwForwardIfIndex = interfaceIndex }; result = (WinApiRouteManagementResult)DeleteIpForwardEntry(ref route); } else { result = WinApiRouteManagementResult.ErrorCouldNotFindNetworkInterface; } return(result); }
public static int deleteIpForwardEntry(UInt32 destIPAddress, UInt32 destMask, UInt32 nextHopIPAddress, UInt32 ifIndex) { MIB_IPFORWARDROW mifr = new MIB_IPFORWARDROW(); mifr.dwForwardDest = destIPAddress; mifr.dwForwardMask = destMask; mifr.dwForwardNextHop = nextHopIPAddress; mifr.dwForwardIfIndex = ifIndex; mifr.dwForwardPolicy = Convert.ToUInt32(0); mifr.dwForwardType = Convert.ToUInt32(4); mifr.dwForwardProto = Convert.ToUInt32(3); mifr.dwForwardAge = Convert.ToUInt32(0); mifr.dwForwardNextHopAS = Convert.ToUInt32(0); mifr.dwForwardMetric1 = -1; mifr.dwForwardMetric2 = -1; mifr.dwForwardMetric3 = -1; mifr.dwForwardMetric4 = -1; mifr.dwForwardMetric5 = -1; return(DeleteIpForwardEntry(ref mifr)); }
/// <summary> /// Liste les routes de la table de routage. /// </summary> /// <returns></returns> public List <RouteEntry> GetRoutesTable() { List <RouteEntry> forwardEntries = new List <RouteEntry>(); IntPtr pTable = IntPtr.Zero; int iBufLen = 0; int iRet = 0; //1ier appel pour déterminer la taille de la table de routage. iRet = NativeMethods.GetIpForwardTable(IntPtr.Zero, ref iBufLen, true); try { pTable = Marshal.AllocHGlobal(iBufLen); //Lecture de la table. iRet = NativeMethods.GetIpForwardTable(pTable, ref iBufLen, true); //Retour OK. if (iRet == 0) { //Nombre d'entrées dans la table. int iEntries = Marshal.ReadInt32(pTable); //Pointeur sur 1ière entrée. IntPtr pEntry = new IntPtr(pTable.ToInt32() + 4); for (int i = 0; i < iEntries; i++) { //Lit la ligne de la table de routage. MIB_IPFORWARDROW entry = (MIB_IPFORWARDROW)Marshal.PtrToStructure(pEntry, typeof(MIB_IPFORWARDROW)); RouteEntry rteEntry = new RouteEntry( entry.dwForwardDest, entry.dwForwardMask, entry.dwForwardPolicy, entry.dwForwardNextHop, _adapters.GetAdapter(entry.dwForwardIfIndex), entry.dwForwardType, entry.dwForwardProto, entry.dwForwardAge, entry.dwForwardNextHopAS, entry.dwForwardMetric1, entry.dwForwardMetric2, entry.dwForwardMetric3, entry.dwForwardMetric4, entry.dwForwardMetric5, entry.dwForwardIfIndex); rteEntry._ipFwdNative = entry; //Extrait les infos. forwardEntries.Add(rteEntry); //Pointeur sur entrée suivante. pEntry = new IntPtr(pEntry.ToInt32() + Marshal.SizeOf(typeof(MIB_IPFORWARDROW))); } } } catch (Exception) { } finally { Marshal.FreeHGlobal(pTable); } return(forwardEntries); }
/// <summary>Creates or deletes a route in the local computer's IPv4 routing table.</summary> /// <param name="add"></param> /// <param name="destination"></param> /// <param name="mask"></param> /// <param name="gateway"></param> /// <param name="index"></param> /// <param name="metric"></param> /// <param name="message"></param> /// <returns></returns> public static bool ModifyIpForwardEntry(bool add, string destination, string mask, string gateway, uint index, uint metric, out string message) { var route = new MIB_IPFORWARDROW(); if (index == 0) { message = "Network interface index not found."; return(false); } if (metric == 1) { message = "Metric value not found."; return(false); } route.dwForwardDest = GetIPFromString(destination); route.dwForwardMask = GetIPFromString(mask); route.dwForwardNextHop = GetIPFromString(gateway); route.dwForwardIfIndex = index; route.dwForwardMetric1 = metric; route.dwForwardProto = ForwardProtocol.NetMGMT; int result = add ? CreateIpForwardEntry(ref route) : DeleteIpForwardEntry(ref route); message = string.Empty; if (result == ERROR_SUCCESS) { return(true); } if (result == ERROR_INVALID_PARAMETER) { route.dwForwardNextHop = 0; result = add ? CreateIpForwardEntry(ref route) : DeleteIpForwardEntry(ref route); } if (result == ERROR_SUCCESS) { return(true); } if (result == ERROR_OBJECT_ALREADY_EXISTS) { message = "Route already exist."; return(true); } if (result == ERROR_NOT_FOUND) { message = "Cannot delete or modify a route that does not exist."; return(true); } message = new System.ComponentModel.Win32Exception(result).Message; return(false); }
public static IPForwardTable ReadIPForwardTable(IntPtr tablePtr) { var result = (IPForwardTable)Marshal.PtrToStructure(tablePtr, typeof(IPForwardTable)); MIB_IPFORWARDROW[] table = new MIB_IPFORWARDROW[result.Size]; IntPtr p = new IntPtr(tablePtr.ToInt64() + Marshal.SizeOf(result.Size)); for (int i = 0; i < result.Size; ++i) { table[i] = (MIB_IPFORWARDROW)Marshal.PtrToStructure(p, typeof(MIB_IPFORWARDROW)); p = new IntPtr(p.ToInt64() + Marshal.SizeOf(typeof(MIB_IPFORWARDROW))); } result.Table = table; return(result); }
private int CreateIpForwardEntry(string nextHopIPAddress, int ifIndex, int matric, string Mask) { MIB_IPFORWARDROW mifr = new MIB_IPFORWARDROW(); mifr.dwForwardDest = BitConverter.ToUInt32(IPAddress.Parse(AppConfiguration.ZERO_IP_KEY).GetAddressBytes(), 0); mifr.dwForwardMask = BitConverter.ToUInt32(IPAddress.Parse(Mask).GetAddressBytes(), 0); mifr.dwForwardPolicy = Convert.ToUInt32(0); mifr.dwForwardNextHop = BitConverter.ToUInt32(IPAddress.Parse(nextHopIPAddress).GetAddressBytes(), 0); mifr.dwForwardIfIndex = Convert.ToUInt32(ifIndex); mifr.dwForwardType = Convert.ToUInt32(4); mifr.dwForwardProto = Convert.ToUInt32(3); mifr.dwForwardAge = Convert.ToUInt32(0); mifr.dwForwardNextHopAS = Convert.ToUInt32(0); mifr.dwForwardMetric1 = Convert.ToUInt32(matric); mifr.dwForwardMetric2 = Convert.ToUInt32(matric); mifr.dwForwardMetric3 = Convert.ToUInt32(matric); mifr.dwForwardMetric4 = Convert.ToUInt32(matric); mifr.dwForwardMetric5 = Convert.ToUInt32(matric); return(CreateIpForwardEntry(ref mifr)); }
public static MIB_IPFORWARDROW[] GetCurrentForwardTable() { var fwdTable = IntPtr.Zero; var size = 0; var result = GetIpForwardTable(fwdTable, ref size, true); fwdTable = Marshal.AllocHGlobal(size); result = GetIpForwardTable(fwdTable, ref size, true); var fib = Marshal.PtrToStructure <MIB_IPFORWARDTABLE>(fwdTable); var rows = new MIB_IPFORWARDROW[fib.dwNumEntries]; var p = fwdTable + Marshal.SizeOf(fib.dwNumEntries); for (var i = 0; i < fib.dwNumEntries; i++) { rows[i] = Marshal.PtrToStructure <MIB_IPFORWARDROW>(p); p += Marshal.SizeOf <MIB_IPFORWARDROW>(); } Marshal.FreeHGlobal(fwdTable); return(rows); }
public void CreateSetDeleteIpForwardEntryTest() { Assert.That(() => { MIB_IPFORWARDROW row = default; foreach (var rrow in GetIpForwardTable(true).Where(r => r.dwForwardDest == 0)) { if (row.dwForwardType == 0) { row = rrow; } DeleteIpForwardEntry(rrow).ThrowIfFailed(); } row.dwForwardNextHop = 0xDDBBCCAA; CreateIpForwardEntry(row).ThrowIfFailed(); //row.dwForwardProto = MIB_IPFORWARD_PROTO.MIB_IPPROTO_DHCP; SetIpForwardEntry(row).ThrowIfFailed(); DeleteIpForwardEntry(row).ThrowIfFailed(); }, Throws.Nothing); }
private static extern int GetBestRoute(uint dwDestAddr, uint dwSourceAddr, out MIB_IPFORWARDROW pBestRoute);
private static extern int SetIpForwardEntry(MIB_IPFORWARDROW pRoute);
/// <summary> /// XP - IPv4 only /// </summary> /// <param name="destination"></param> /// <param name="prefix"></param> /// <param name="gateway"></param> /// <param name="interfaceIndex"></param> public static void DeleteRoute(string destination, string prefix, string gateway, string interfaceIndex) { if (Environment.OSVersion.Version.CompareTo(new Version("6.0")) < 0) { MIB_IPFORWARDROW route = new MIB_IPFORWARDROW(); route.dwForwardDest = BitConverter.ToUInt32(IPAddress.Parse(destination).GetAddressBytes().ToArray(), 0); route.dwForwardMask = BitConverter.ToUInt32(IPAddress.Parse(prefix).GetAddressBytes().ToArray(), 0); route.dwForwardNextHop = BitConverter.ToUInt32(IPAddress.Parse(gateway).GetAddressBytes().ToArray(), 0); route.dwForwardIfIndex = uint.Parse(interfaceIndex); route.dwForwardProto = NL_ROUTE_PROTOCOL.MIB_IPPROTO_NETMGMT; IntPtr pRoute = Marshal.AllocHGlobal(Marshal.SizeOf(route)); Marshal.StructureToPtr(route, pRoute, false); DeleteIpForwardEntry(pRoute); Marshal.DestroyStructure(pRoute, typeof(MIB_IPFORWARDROW)); Marshal.FreeHGlobal(pRoute); } else { MIB_IPFORWARD_ROW2 route2 = new MIB_IPFORWARD_ROW2(); uint prefixLength = 0; if (IPAddress.Parse(destination).AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { SOCKADDR_IN address = new SOCKADDR_IN(); address.sin_family = FAMILY.AF_INET; address.sin_addr.S_addr = BitConverter.ToUInt32(IPAddress.Parse(destination).GetAddressBytes().ToArray(), 0); route2.DestinationPrefix.Prefix.Ipv4 = address; uint ipMask = BitConverter.ToUInt32(IPAddress.Parse(prefix).GetAddressBytes().Reverse().ToArray(), 0); while (ipMask > 0) { prefixLength++; ipMask <<= 1; } address.sin_addr.S_addr = BitConverter.ToUInt32(IPAddress.Parse(gateway).GetAddressBytes().ToArray(), 0); route2.NextHop.Ipv4 = address; } else { SOCKADDR_IN6 address = new SOCKADDR_IN6(); address.sin6_family = FAMILY.AF_INET6; address.sin6_addr.Byte = IPAddress.Parse(destination).GetAddressBytes().ToArray(); route2.DestinationPrefix.Prefix.Ipv6 = address; prefixLength = uint.Parse(prefix); address.sin6_addr.Byte = IPAddress.Parse(gateway).GetAddressBytes().ToArray(); route2.NextHop.Ipv6 = address; } route2.DestinationPrefix.PrefixLength = prefixLength; route2.InterfaceIndex = uint.Parse(interfaceIndex); IntPtr pRoute = Marshal.AllocHGlobal(Marshal.SizeOf(route2)); Marshal.StructureToPtr(route2, pRoute, false); DeleteIpForwardEntry2(pRoute); Marshal.DestroyStructure(pRoute, typeof(MIB_IPFORWARD_ROW2)); Marshal.FreeHGlobal(pRoute); } }
private static extern int DeleteIpForwardEntry(ref MIB_IPFORWARDROW pRoute);
static extern int CreateIpForwardEntry(ref MIB_IPFORWARDROW pRoute);
public static extern int GetBestRoute(uint dwDestAddr, int dwSourceAddr, out MIB_IPFORWARDROW pRoute);
// Searches the system's routing table for the best route to the // specified IP address *that does not route through the TAP device*. // // That last requirement - ignoring the TAP device - is what prevents us // from simply calling GetBestRoute: other than that, it does all the // work of finding the lowest-weighted gateway to the destination IP. // // NOTE: This function does not *always* find the best gateway: it // currently only considers "default" gateways (0.0.0.0) which may not // work in some rare cases. Several re-implementations of the Windows // API illustrate how we could more closely match GetBestRoute: // - https://github.com/wine-mirror/wine/blob/master/dlls/iphlpapi/iphlpapi_main.c // - https://github.com/reactos/reactos/blob/master/dll/win32/iphlpapi/iphlpapi_main.c private void GetSystemIpv4Gateway(string proxyIp) { gatewayIp = null; gatewayInterfaceIndex = -1; int tapInterfaceIndex; try { tapInterfaceIndex = NetworkInterface.GetAllNetworkInterfaces() .Where(i => i.Name == TAP_DEVICE_NAME) .FirstOrDefault() .GetIPProperties() .GetIPv4Properties().Index; } catch (Exception) { throw new Exception("TAP device not found"); } // Some marshalling craziness follows: we have to first ask // GetIpForwardTable how much memory is required to hold the routing // table before calling it again to actually return us the table; // once we have the table, we have to iterate over the rows // (thankfully, MIB_IPFORWARDROW marshalls easily). int bufferSize = 0; if (GetIpForwardTable(IntPtr.Zero, ref bufferSize, true) != ERROR_INSUFFICIENT_BUFFER) { throw new Exception("could not fetch routing table"); } var buffer = Marshal.AllocHGlobal(bufferSize); if (GetIpForwardTable(buffer, ref bufferSize, true) != 0) { Marshal.FreeHGlobal(buffer); throw new Exception("could not fetch routing table"); } // NOTE: We deliberately *do not marshal the entire // MIB_IPFORWARDTABLE* owing to unexplained crashes following // suspend/resume. Fortunately, since that structure is // logically just a DWORD followed by an array, this entails // little extra work. var numEntries = Marshal.ReadInt32(buffer); MIB_IPFORWARDROW bestRow = null; var rowPtr = buffer + Marshal.SizeOf(numEntries); for (int i = 0; i < numEntries; i++) { MIB_IPFORWARDROW row = (MIB_IPFORWARDROW)Marshal.PtrToStructure(rowPtr, typeof(MIB_IPFORWARDROW)); // Must be a gateway (see note above on how we can improve this). if (row.dwForwardDest != 0) { continue; } // Must not be the TAP device. if (row.dwForwardIfIndex == tapInterfaceIndex) { continue; } if (bestRow == null || row.dwForwardMetric1 < bestRow.dwForwardMetric1) { bestRow = row; } rowPtr += Marshal.SizeOf(typeof(MIB_IPFORWARDROW)); } Marshal.FreeHGlobal(buffer); if (bestRow == null) { throw new Exception("no gateway found"); } gatewayIp = new IPAddress(BitConverter.GetBytes(bestRow.dwForwardNextHop)).ToString(); gatewayInterfaceIndex = bestRow.dwForwardIfIndex; }
public DataTable GetRoutesTableInTable() { List <RouteEntry> forwardEntries = new List <RouteEntry>(); DataTable tmp = new DataTable(); tmp.Columns.Add("DestIP", System.Type.GetType("System.String")); tmp.Columns.Add("SubnetMask", System.Type.GetType("System.String")); tmp.Columns.Add("NextHop", System.Type.GetType("System.String")); tmp.Columns.Add("IfIndex", System.Type.GetType("System.Int32")); tmp.Columns.Add("Type", System.Type.GetType("System.Int32")); tmp.Columns.Add("TypeText", System.Type.GetType("System.String")); tmp.Columns.Add("Proto", System.Type.GetType("System.Int32")); tmp.Columns.Add("ProtoText", System.Type.GetType("System.String")); tmp.Columns.Add("Age", System.Type.GetType("System.Int32")); tmp.Columns.Add("Metric1", System.Type.GetType("System.Int32")); tmp.Columns.Add("Type_Text", System.Type.GetType("System.Int32")); tmp.Columns.Add("IFText", System.Type.GetType("System.String")); tmp.Columns.Add("AgeText", System.Type.GetType("System.String")); IntPtr pTable = IntPtr.Zero; int iBufLen = 0; int iRet = 0; iRet = NativeMethods.GetIpForwardTable(IntPtr.Zero, ref iBufLen, true); try { pTable = Marshal.AllocHGlobal(iBufLen); iRet = NativeMethods.GetIpForwardTable(pTable, ref iBufLen, true); if (iRet == 0) { int iEntries = Marshal.ReadInt32(pTable); IntPtr pEntry = new IntPtr(pTable.ToInt32() + 4); for (int i = 0; i < iEntries; i++) { MIB_IPFORWARDROW entry = (MIB_IPFORWARDROW)Marshal.PtrToStructure(pEntry, typeof(MIB_IPFORWARDROW)); RouteEntry rteEntry = new RouteEntry( entry.dwForwardDest, entry.dwForwardMask, entry.dwForwardPolicy, entry.dwForwardNextHop, _adapters.GetAdapter(entry.dwForwardIfIndex), entry.dwForwardType, entry.dwForwardProto, entry.dwForwardAge, entry.dwForwardNextHopAS, entry.dwForwardMetric1, entry.dwForwardMetric2, entry.dwForwardMetric3, entry.dwForwardMetric4, entry.dwForwardMetric5, entry.dwForwardIfIndex); tmp.Rows.Add(); tmp.Rows[tmp.Rows.Count - 1][0] = rteEntry.Destination; tmp.Rows[tmp.Rows.Count - 1][1] = rteEntry.Mask; tmp.Rows[tmp.Rows.Count - 1][2] = rteEntry.NextHop; tmp.Rows[tmp.Rows.Count - 1][3] = entry.dwForwardIfIndex; tmp.Rows[tmp.Rows.Count - 1][4] = rteEntry.ForwardType; tmp.Rows[tmp.Rows.Count - 1][5] = rteEntry.ForwardType; tmp.Rows[tmp.Rows.Count - 1][6] = rteEntry.Protocol; tmp.Rows[tmp.Rows.Count - 1][7] = rteEntry.Protocol; tmp.Rows[tmp.Rows.Count - 1][8] = rteEntry.Age; tmp.Rows[tmp.Rows.Count - 1][9] = rteEntry.Metric1; pEntry = new IntPtr(pEntry.ToInt32() + Marshal.SizeOf(typeof(MIB_IPFORWARDROW))); } } } catch (Exception) { } finally { Marshal.FreeHGlobal(pTable); } return(tmp); }
public extern static int SetIpForwardEntry(ref MIB_IPFORWARDROW pRoute);
internal extern static Int32 GetBestRoute( UInt32 dwDestAddr, UInt32 dwSourceAddr, out MIB_IPFORWARDROW pBestRoute);
public extern static int GetBestRoute(uint dwDestAddr, int dwSourceAddr, out MIB_IPFORWARDROW pRoute); //dwSourceAddr = 0 for the caller