/// <summary> /// Removes an entry from the route forwarding table. /// </summary> /// <param name="remoteNetworkAddr">Address of the route to delete</param> /// <param name="remoteNetworkMask">Mask of the route to delete</param> /// <returns>0 if successful, or error code if not.</returns> public static int DeleteRoute(string remoteNetworkAddr, string remoteNetworkMask) { IPAddress addr, mask; try { addr = IPAddress.Parse(remoteNetworkAddr); } catch (Exception ex) { throw new ArgumentException("remoteNetworkAddr", ex); } try { mask = IPAddress.Parse(remoteNetworkMask); } catch (Exception ex) { throw new ArgumentException("remoteNetworkMask", ex); } addr = ApplyMask(addr, mask); // make sure zero bits of the mask are zero in the address. // Load the existing route table NativeMethods.IpForwardRow[] rows = NativeMethods.GetIpForwardTable(); if (rows == null) { return((int)NativeMethods.IPErrorCodes.ERROR_FAILURE); // should never happen } // Find the address in the route table foreach (NativeMethods.IpForwardRow row in rows) { if ((IPAddressAsUint(addr) == row.dwForwardDest) && (IPAddressAsUint(mask) == row.dwForwardMask)) { // found, so delete it. NativeMethods.IpForwardRow foundRow = row; return(NativeMethods.DeleteIpForwardEntry(ref foundRow)); } } // if we got this far, the specified route was not in the table. return((int)(NativeMethods.IPErrorCodes.ERROR_NOT_FOUND)); }
/// <summary> /// Adds the specified route to the routine table /// </summary> /// <param name="remoteNetworkAddr"></param> /// <param name="remoteNetworkMask"></param> /// <param name="remoteNetworkGateway"></param> /// <exception cref="ArgumentException">Thrown if arguments are not valid Internet address strings</exception> /// <returns>0 if success, or error code if failed.</returns> public static int AddRoute(string remoteNetworkAddr, string remoteNetworkMask, string remoteNetworkGateway) { int result; IPAddress addr, mask, gate; try { addr = IPAddress.Parse(remoteNetworkAddr); } catch (Exception ex) { throw new ArgumentException("remoteNetworkAddr", ex); } try { mask = IPAddress.Parse(remoteNetworkMask); } catch (Exception ex) { throw new ArgumentException("remoteNetworkMask", ex); } try { gate = IPAddress.Parse(remoteNetworkGateway); } catch (Exception ex) { throw new ArgumentException("remoteNetworkGateway", ex); } addr = ApplyMask(addr, mask); // make sure zero bits of the mask are zero in the address. // figure out which adapter out of the list is the best to use uint bestAdapterIndex = 0; result = NativeMethods.GetBestInterface(IPAddressAsUint(gate), out bestAdapterIndex); if (result != 0) { return(result); } // Load the existing route table NativeMethods.IpForwardRow[] rows = NativeMethods.GetIpForwardTable(); if (rows == null) { return((int)NativeMethods.IPErrorCodes.ERROR_FAILURE); // should never happen } // Make sure the address isn't already covered in the route table foreach (NativeMethods.IpForwardRow row in rows) { if ((row.dwForwardMask != 0) && ((IPAddressAsUint(addr) & row.dwForwardMask) == row.dwForwardDest)) { return((int)NativeMethods.IPErrorCodes.ERROR_ALREADY_EXISTS); } } // for some versions of Windows, the value of Metric1 must be greater than or equal to // the value of the adapter metric. Unfortunately, it is somewhat difficult to get this value. // We will work around this by duplicating the metric of any other route that uses this adapter, // or, if none exist, use the maximum value of any route in the table. If the table is empty, we // will use a fixed value of 255, and hope it works ok. uint dwMetric = 0; foreach (NativeMethods.IpForwardRow row in rows) { uint rowIndex = row.dwForwardIfIndex; uint rowMetric = row.dwForwardMetric1; if (rowIndex == bestAdapterIndex) { dwMetric = rowMetric; break; } else if (rowMetric > dwMetric) { dwMetric = rowMetric; } } // if we didn't find anything relevant, use 255 - this should be OK dwMetric = (dwMetric == 0) ? 255 : dwMetric; // Everything looks good - create the route. NativeMethods.IpForwardRow newRoute = new NativeMethods.IpForwardRow(); newRoute.dwForwardDest = IPAddressAsUint(addr); newRoute.dwForwardMask = IPAddressAsUint(mask); newRoute.dwForwardPolicy = 0; // policy - always ; newRoute.dwForwardNextHop = IPAddressAsUint(gate); newRoute.dwForwardIfIndex = bestAdapterIndex; newRoute.ForwardType = NativeMethods.IpForwardType.MIB_IPROUTE_TYPE_INDIRECT; newRoute.ForwardProto = NativeMethods.IpForwardProto.MIB_IPPROTO_NETMGMT; newRoute.dwForwardAge = 0; newRoute.dwForwardNextHopAS = 0; newRoute.dwForwardMetric1 = dwMetric; newRoute.dwForwardMetric2 = 0; newRoute.dwForwardMetric3 = 0; newRoute.dwForwardMetric4 = 0; newRoute.dwForwardMetric5 = 0; return(NativeMethods.CreateIpForwardEntry(ref newRoute)); }