我写一个简单的实用程序,为特定的接口添加一个路由。
using System;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Text;
cl Program
{
static void Main(string[] args)
{
const string firstConnection = "x.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 inteceId = GetInteceId(firstConnection);
string routeAdd = string.Format(routeAddMask, inteceId);
StartProcess("route", routeAdd);
}
private static int GetInteceId(string name)
{
NetworkIntece[] adapters = NetworkIntece.GetAllNetworkInteces();
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)
{
UseSExecute = 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
工作正常,我得到接口号,但是当我运行route
时,我得到一个错误:
无效的 MASK 会生成错误,即当 (DEST & amp;MASK)!= DEST 时。
我认为问题是进程启动参数没有通过,因为我在发送null
而不是routeAdd
参数时得到相同的错误,同时这个命令工作正常,当我在 cmd 中提示它。
可执行文件正在以管理员身份运行。
我试图用 winapi 创建它,但它也失败了
const string firstConnection = "someconnect";
StartProcess("rasdial", firstConnection);
var inteceIndex = GetInteceIndex(firstConnection); //Everything is fine
var route = new MIB_IPFORWARDROW
{
dwForwardDest = BitConverter.ToUInt32(IPAddress.P("XX.XX.XX.XX").GetAddressBytes(), 0),
dwForwardMask = BitConverter.ToUInt32(IPAddress.P("255.255.255.255").GetAddressBytes(), 0),
dwForwardNextHop = BitConverter.ToUInt32(IPAddress.P("XXX.XXX.XXX.XXX").GetAddressBytes(), 0),
dwForwardMetric1 = 99,
dwForwardIfIndex = inteceIndex
};
var ipForwardEntry = RouteInterop.CreateIpForwardEntry(ref route);
Console.WriteLine(ipForwardEntry);
returnsERROR_INVALID_PARAMETER
我知道这个问题不是很复杂,但我没有在互联网上遇到任何解释,这就是为什么我认为这个答案会有帮助,这就是为什么我写它,而不是删除我最初的问题。
您只需要指定更多的参数,使其工作
var route = new MIB_IPFORWARDROW
{
dwForwardDest = BitConverter.ToUInt32(IPAddress.P("XX.XX.XX.XX").GetAddressBytes(), 0),
dwForwardMask = BitConverter.ToUInt32(IPAddress.P("255.255.255.255").GetAddressBytes(), 0),
dwForwardNextHop = BitConverter.ToUInt32(IPAddress.P("XXX.XXX.XXX.XXX").GetAddressBytes(), 0),
dwForwardMetric1 = 99,
dwForwardType = ForwardType.Indirect,
dwForwardProto = ForwardProtocol.NetMT,
dwForwardAge = 0,
dwForwardIfIndex = inteceIndex
};
var ipForwardEntry = RouteInterop.CreateIpForwardEntry(ref route);
详细阐述了 Alex Zhukovskiy 的答案,因为我将他的答案与一堆 MSDN 文章结合在一起。下面的代码使用Win32 API,特别是“iphlpapi.h”模块,可以在managing routing上的1结构中找到。
模仿“route print”、“route add”和“route delete”命令的主要方法是
GetIpForwardTable-获取网络路由表“route PRINT”
CreateIpForwardEntry-添加路由,如“路由 ADD”
DeleteIpFowardEntry-删除路由,如“路由删除”
SetIpForwardEntry-修改现有路由,如“路由更改”
使用 C # 的全面代码可以在这个 github 存储库中找到(Ip4RouteTable)-https://github.com/CodeCowboyOrg/Ip4RouteTable
在 C# 中设置 Win32 API 调用
internal static cl NativeMetds
{
[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(ref /*PMIB_IPFORWARDROW*/ Ip4RouteTable.PMIB_IPFORWARDROW pRoute); Can do by reference or by Pointer
public extern static int CreateIpForwardEntry(IntPtr /*PMIB_IPFORWARDROW*/ pRoute);
[DllImport("iphlpapi", CharSet = CharSet.Auto)]
public extern static int DeleteIpForwardEntry(IntPtr /*PMIB_IPFORWARDROW*/ pRoute);
}
public cl Ip4RouteTable
{
[ComVisible(false), StructLayout(LayoutKind.Sequential)]
internal struct IPForwardTable
{
public uint Size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public PMIB_IPFORWARDROW[] Table;
};
[ComVisible(false), StructLayout(LayoutKind.Sequential)]
internal struct PMIB_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));
PMIB_IPFORWARDROW[] table = new PMIB_IPFORWARDROW[result.Size];
IntPtr p = new IntPtr(tablePtr.ToInt64() + Marshal.SizeOf(result.Size));
for (int i = 0; i < result.Size; ++i)
{
table[i] = (PMIB_IPFORWARDROW)Marshal.PtrToStructure(p, typeof(PMIB_IPFORWARDROW));
p = new IntPtr(p.ToInt64() + Marshal.SizeOf(typeof(PMIB_IPFORWARDROW)));
}
result.Table = table;
return result;
}
public static void RoutePrint(bool testing)
{
var fwdTable = IntPtr.Zero;
int size = 0;
var result = NativeMetds.GetIpForwardTable(fwdTable, ref size, true);
fwdTable = Marshal.AllocHGlobal(size);
result = NativeMetds.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)
{
Console.Write("\n\tRoute[{0}] Dest IP: {1}\n", i, new IPAddress((long)forwardTable.Table[i].dwForwardDest).ToString());
Console.Write("\tRoute[{0}] Subnet Mask: {1}\n", i, new IPAddress((long)forwardTable.Table[i].dwForwardMask).ToString());
Console.Write("\tRoute[{0}] Next Hop: {1}\n", i, new IPAddress((long)forwardTable.Table[i].dwForwardNextHop).ToString());
Console.Write("\tRoute[{0}] If Index: {1}\n", i, forwardTable.Table[i].dwForwardIfIndex);
Console.Write("\tRoute[{0}] Type: {1}\n", i, forwardTable.Table[i].dwForwardType);
Console.Write("\tRoute[{0}] Proto: {1}\n", i, forwardTable.Table[i].dwForwardProto);
Console.Write("\tRoute[{0}] Age: {1}\n", i, forwardTable.Table[i].dwForwardAge);
Console.Write("\tRoute[{0}] Metric1: {1}\n", i, forwardTable.Table[i].dwForwardMetric1);
}
}
public static void RoutePrint()
{
List<Ip4RouteEntry> routeTable = GetRouteTable();
RoutePrint(routeTable);
}
public static void RoutePrint(List<Ip4RouteEntry> routeTable)
{
Console.WriteLine("Route Count: {0}", routeTable.Count);
Console.WriteLine("{0,18} {1,18} {2,18} {3,5} {4,8} ", "DestinationIP", "NetMask", "Gateway", "IF", "Metric");
foreach (Ip4RouteEntry entry in routeTable)
{
Console.WriteLine("{0,18} {1,18} {2,18} {3,5} {4,8} ", entry.DestinationIP, entry.SubnetMask, entry.GatewayIP, entry.InteceIndex, entry.Metric);
}
}
public static List<Ip4RouteEntry> GetRouteTable()
{
var fwdTable = IntPtr.Zero;
int size = 0;
var result = NativeMetds.GetIpForwardTable(fwdTable, ref size, true);
fwdTable = Marshal.AllocHGlobal(size);
result = NativeMetds.GetIpForwardTable(fwdTable, ref size, true);
var forwardTable = ReadIPForwardTable(fwdTable);
Marshal.FreeHGlobal(fwdTable);
List<Ip4RouteEntry> routeTable = new List<Ip4RouteEntry>();
for (int i = 0; i < forwardTable.Table.Length; ++i)
{
Ip4RouteEntry entry = new Ip4RouteEntry();
entry.DestinationIP = new IPAddress((long)forwardTable.Table[i].dwForwardDest);
entry.SubnetMask = new IPAddress((long)forwardTable.Table[i].dwForwardMask);
entry.GatewayIP = new IPAddress((long)forwardTable.Table[i].dwForwardNextHop);
entry.InteceIndex = Convert.ToInt32(forwardTable.Table[i].dwForwardIfIndex);
entry.ForwardType = Convert.ToInt32(forwardTable.Table[i].dwForwardType);
entry.ForwardProtocol = Convert.ToInt32(forwardTable.Table[i].dwForwardProto);
entry.ForwardAge = Convert.ToInt32(forwardTable.Table[i].dwForwardAge);
entry.Metric = Convert.ToInt32(forwardTable.Table[i].dwForwardMetric1);
routeTable.Add(entry);
}
return routeTable;
}
C# 包装函数
public cl Ip4RouteEntry
{
public IPAddress DestinationIP { get; set; }
public IPAddress SubnetMask { get; set; }
public IPAddress GatewayIP { get; set; }
public int InteceIndex { get; set; }
public int ForwardType { get; set; }
public int ForwardProtocol { get; set; }
public int ForwardAge { get; set; }
public int Metric { get; set; }
}
public static void RoutePrint()
{
List<Ip4RouteEntry> routeTable = GetRouteTable();
RoutePrint(routeTable);
}
public static void RoutePrint(List<Ip4RouteEntry> routeTable)
{
Console.WriteLine("Route Count: {0}", routeTable.Count);
Console.WriteLine("{0,18} {1,18} {2,18} {3,5} {4,8} ", "DestinationIP", "NetMask", "Gateway", "IF", "Metric");
foreach (Ip4RouteEntry entry in routeTable)
{
Console.WriteLine("{0,18} {1,18} {2,18} {3,5} {4,8} ", entry.DestinationIP, entry.SubnetMask, entry.GatewayIP, entry.InteceIndex, entry.Metric);
}
}
public static List<Ip4RouteEntry> GetRouteTable()
{
var fwdTable = IntPtr.Zero;
int size = 0;
var result = NativeMetds.GetIpForwardTable(fwdTable, ref size, true);
fwdTable = Marshal.AllocHGlobal(size);
result = NativeMetds.GetIpForwardTable(fwdTable, ref size, true);
var forwardTable = ReadIPForwardTable(fwdTable);
Marshal.FreeHGlobal(fwdTable);
List<Ip4RouteEntry> routeTable = new List<Ip4RouteEntry>();
for (int i = 0; i < forwardTable.Table.Length; ++i)
{
Ip4RouteEntry entry = new Ip4RouteEntry();
entry.DestinationIP = new IPAddress((long)forwardTable.Table[i].dwForwardDest);
entry.SubnetMask = new IPAddress((long)forwardTable.Table[i].dwForwardMask);
entry.GatewayIP = new IPAddress((long)forwardTable.Table[i].dwForwardNextHop);
entry.InteceIndex = Convert.ToInt32(forwardTable.Table[i].dwForwardIfIndex);
entry.ForwardType = Convert.ToInt32(forwardTable.Table[i].dwForwardType);
entry.ForwardProtocol = Convert.ToInt32(forwardTable.Table[i].dwForwardProto);
entry.ForwardAge = Convert.ToInt32(forwardTable.Table[i].dwForwardAge);
entry.Metric = Convert.ToInt32(forwardTable.Table[i].dwForwardMetric1);
routeTable.Add(entry);
}
return routeTable;
}
public static bool RouteExists(string destinationIP)
{
List<Ip4RouteEntry> routeTable = Ip4RouteTable.GetRouteTable();
Ip4RouteEntry routeEntry = routeTable.Find(i => i.DestinationIP.ToString().Equals(destinationIP));
return (routeEntry != null);
}
public static List<Ip4RouteEntry> GetRouteEntry(string destinationIP)
{
List<Ip4RouteEntry> routeTable = Ip4RouteTable.GetRouteTable();
List<Ip4RouteEntry> routeMatches = routeTable.FindAll(i => i.DestinationIP.ToString().Equals(destinationIP));
return routeMatches;
}
public static List<Ip4RouteEntry> GetRouteEntry(string destinationIP, string mask)
{
List<Ip4RouteEntry> routeTable = Ip4RouteTable.GetRouteTable();
List<Ip4RouteEntry> routeMatches = routeTable.FindAll(i => i.DestinationIP.ToString().Equals(destinationIP) && i.SubnetMask.ToString().Equals(mask));
return routeMatches;
}
public static void CreateRoute(Ip4RouteEntry routeEntry)
{
var route = new PMIB_IPFORWARDROW
{
dwForwardDest = BitConverter.ToUInt32(IPAddress.P(routeEntry.DestinationIP.ToString()).GetAddressBytes(), 0),
dwForwardMask = BitConverter.ToUInt32(IPAddress.P(routeEntry.SubnetMask.ToString()).GetAddressBytes(), 0),
dwForwardNextHop = BitConverter.ToUInt32(IPAddress.P(routeEntry.GatewayIP.ToString()).GetAddressBytes(), 0),
dwForwardMetric1 = 99,
dwForwardType = Convert.ToUInt32(3), //Default to 3
dwForwardProto = Convert.ToUInt32(3), //Default to 3
dwForwardAge = 0,
dwForwardIfIndex = Convert.ToUInt32(routeEntry.InteceIndex)
};
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PMIB_IPFORWARDROW)));
try
{
Marshal.StructureToPtr(route, ptr, false);
var status = NativeMetds.CreateIpForwardEntry(ptr);
}
finally
{
Marshal.FreeHGlobal(ptr);
}
}
public static void CreateRoute(string destination, string mask, int inteceIndex, int metric)
{
NetworkAdaptor adaptor = NicIntece.GetNetworkAdaptor(inteceIndex);
var route = new PMIB_IPFORWARDROW
{
dwForwardDest = BitConverter.ToUInt32(IPAddress.P(destination).GetAddressBytes(), 0),
dwForwardMask = BitConverter.ToUInt32(IPAddress.P(mask).GetAddressBytes(), 0),
dwForwardNextHop = BitConverter.ToUInt32(IPAddress.P(adaptor.PrimaryGateway.ToString()).GetAddressBytes(), 0),
dwForwardMetric1 = Convert.ToUInt32(metric),
dwForwardType = Convert.ToUInt32(3), //Default to 3
dwForwardProto = Convert.ToUInt32(3), //Default to 3
dwForwardAge = 0,
dwForwardIfIndex = Convert.ToUInt32(inteceIndex)
};
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PMIB_IPFORWARDROW)));
try
{
Marshal.StructureToPtr(route, ptr, false);
var status = NativeMetds.CreateIpForwardEntry(ptr);
}
finally
{
Marshal.FreeHGlobal(ptr);
}
}
public static void DeleteRoute(Ip4RouteEntry routeEntry)
{
var route = new PMIB_IPFORWARDROW
{
dwForwardDest = BitConverter.ToUInt32(IPAddress.P(routeEntry.DestinationIP.ToString()).GetAddressBytes(), 0),
dwForwardMask = BitConverter.ToUInt32(IPAddress.P(routeEntry.SubnetMask.ToString()).GetAddressBytes(), 0),
dwForwardNextHop = BitConverter.ToUInt32(IPAddress.P(routeEntry.GatewayIP.ToString()).GetAddressBytes(), 0),
dwForwardMetric1 = 99,
dwForwardType = Convert.ToUInt32(3), //Default to 3
dwForwardProto = Convert.ToUInt32(3), //Default to 3
dwForwardAge = 0,
dwForwardIfIndex = Convert.ToUInt32(routeEntry.InteceIndex)
};
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PMIB_IPFORWARDROW)));
try
{
Marshal.StructureToPtr(route, ptr, false);
var status = NativeMetds.DeleteIpForwardEntry(ptr);
}
finally
{
Marshal.FreeHGlobal(ptr);
}
}
public static void DeleteRoute(string destinationIP)
{
List<Ip4RouteEntry> routeMatches = Ip4RouteTable.GetRouteEntry(destinationIP);
if (routeMatches == null) return;
foreach (Ip4RouteEntry routeEntry in routeMatches)
{
DeleteRoute(routeEntry);
}
}
public static void DeleteRoute(string destinationIP, string mask)
{
List<Ip4RouteEntry> routeMatches = Ip4RouteTable.GetRouteEntry(destinationIP, mask);
if (routeMatches == null) return;
foreach (Ip4RouteEntry routeEntry in routeMatches)
{
DeleteRoute(routeEntry);
}
}
public static void DeleteRoute(int inteceIndex)
{
var fwdTable = IntPtr.Zero;
int size = 0;
var result = NativeMetds.GetIpForwardTable(fwdTable, ref size, true);
fwdTable = Marshal.AllocHGlobal(size);
result = NativeMetds.GetIpForwardTable(fwdTable, ref size, true);
var forwardTable = ReadIPForwardTable(fwdTable);
Marshal.FreeHGlobal(fwdTable);
List<PMIB_IPFORWARDROW> filtered = new List<PMIB_IPFORWARDROW>();
for (int i = 0; i < forwardTable.Table.Length; ++i)
{
if (Convert.ToInt32(forwardTable.Table[i].dwForwardIfIndex).Equals(inteceIndex))
{
filtered.Add(forwardTable.Table[i]);
}
}
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PMIB_IPFORWARDROW)));
try
{
foreach (PMIB_IPFORWARDROW routeEntry in filtered)
{
Marshal.StructureToPtr(routeEntry, ptr, false);
var status = NativeMetds.DeleteIpForwardEntry(ptr);
}
}
finally
{
Marshal.FreeHGlobal(ptr);
}
}
本站系公益性非盈利分享网址,本文来自用户投稿,不代表边看边学立场,如若转载,请注明出处
评论列表(14条)