Example #1
0
        /// <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));
        }
Example #2
0
        /// <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));
        }