Programmatically add route

2019-05-06 10:18发布

I write a simple utility that adds a route for specific interface. Code is very simple:

using System;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Text;

class Program
{
    static void Main(string[] args)
    {
        const string firstConnection = "xxxx.yyyyy";
        const string routeAddMask = "route add XX.XX.XX.XX mask 255.255.255.255 XXX.XXX.XXX.XXX METRIC 99 IF {0}";
        StartProcess("rasdial", firstConnection);
        var interfaceId = GetInterfaceId(firstConnection);
        string routeAdd = string.Format(routeAddMask, interfaceId);
        StartProcess("route", routeAdd);
    }

    private static int GetInterfaceId(string name)
    {
        NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
        var adapter = Array.Find(adapters, ni => ni.Name == name);
        var props = adapter.GetIPProperties().GetIPv4Properties();
        return props.Index;
    }

    private static void StartProcess(string name, string args)
    {
        var process = new Process
                   {
                       StartInfo = new ProcessStartInfo(name, args)
                                   {
                                       UseShellExecute = false,
                                       RedirectStandardOutput = true,
                                       StandardOutputEncoding = Encoding.ASCII
                                   }
                   };
        process.Start();
        while (!process.HasExited)
        {
            Console.WriteLine(process.StandardOutput.ReadToEnd());
        }
        process.WaitForExit();
        Console.WriteLine("Process {0} finished, exit code = {1}", name, process.ExitCode);
    }
}

rasdial works fine and I get interface number, but when I'm running route I get an error:

Invalid MASK generates an error, that is when (DEST & MASK) != DEST.

I think problem is that process start args are not passed because I get the same error while sending null instead of routeAdd parameter meanwhile this command works fine when i'm prompting it in cmd.

Executable is running as Administrator.

I'm trying to create it with winapi, but it fails too

const string firstConnection = "someconnect";
StartProcess("rasdial", firstConnection);
var interfaceIndex = GetInterfaceIndex(firstConnection); //Everything is fine

var route = new MIB_IPFORWARDROW
            {
                dwForwardDest = BitConverter.ToUInt32(IPAddress.Parse("XX.XX.XX.XX").GetAddressBytes(), 0),
                dwForwardMask = BitConverter.ToUInt32(IPAddress.Parse("255.255.255.255").GetAddressBytes(), 0),
                dwForwardNextHop = BitConverter.ToUInt32(IPAddress.Parse("XXX.XXX.XXX.XXX").GetAddressBytes(), 0),
                dwForwardMetric1 = 99,
                dwForwardIfIndex = interfaceIndex
            };
var ipForwardEntry = RouteInterop.CreateIpForwardEntry(ref route);
Console.WriteLine(ipForwardEntry);

returns ERROR_INVALID_PARAMETER

1条回答
乱世女痞
2楼-- · 2019-05-06 10:40

I know that question is not very complex, but I didn't encounter any explanation in the internet, this is why I think this answer would be helpful and this is why I'm writing it instead of deleting my initial question.

You just should specify more parameters to make it work

    var route = new MIB_IPFORWARDROW
                {
                    dwForwardDest = BitConverter.ToUInt32(IPAddress.Parse("XX.XX.XX.XX").GetAddressBytes(), 0),
                    dwForwardMask = BitConverter.ToUInt32(IPAddress.Parse("255.255.255.255").GetAddressBytes(), 0),
                    dwForwardNextHop = BitConverter.ToUInt32(IPAddress.Parse("XXX.XXX.XXX.XXX").GetAddressBytes(), 0),
                    dwForwardMetric1 = 99,
                    dwForwardType =  ForwardType.Indirect,
                    dwForwardProto =  ForwardProtocol.NetMGMT,
                    dwForwardAge = 0,
                    dwForwardIfIndex = interfaceIndex
                };
    var ipForwardEntry = RouteInterop.CreateIpForwardEntry(ref route);
查看更多
登录 后发表回答