我找到了用于管理ip相关信息的IP Helper接口,但我找不到使用Windows XP支持的接口获取和/或更改给定适配器的网关地址的方法。有什么想法吗?
答案 0 :(得分:2)
如果你可以使用WMI,那就是Win32_NetworkAdapterConfiguration类。如果您需要普通的旧C API,我发现this(靠近底部的“设置默认网关地址”)。
答案 1 :(得分:1)
GetAdaptersInfo()
和GetAdaptersAddresses()
函数都返回每个适配器的网关信息。
答案 2 :(得分:0)
注意:Win32_NetworkAdapterConfiguration :: SetGateways()将在参数中设置指定的网关,其中将覆盖exisitng网关。
但是: 正在删除 网关 似乎无法正常工作 当使用SetGateways()WMI调用时 - 在我的情况下,调用返回成功,但网关仍然存在。似乎有很多人看过这个(在StringArray中设置NULL字符串或者为StringArray传递NULL没有帮助)。
在我的情况下,我开始使用WMI方式(很可能是因为EnableDHCP()),但也需要实现Luke建议的WINAPI方式来摆脱网关的灾难。非常感谢Luke !!
答案 3 :(得分:-1)
public enum ForwardType
{
Other = 1,
Invalid = 2,
Direct = 3,
Indirect = 4
}
public enum ForwardProtocol
{
Other = 1,
Local = 2,
NetMGMT = 3,
ICMP = 4,
EGP = 5,
GGP = 6,
Hello = 7,
RIP = 8,
IS_IS = 9,
ES_IS = 10,
CISCO = 11,
BBN = 12,
OSPF = 13,
BGP = 14,
NT_AUTOSTATIC = 10002,
NT_STATIC = 10006,
NT_STATIC_NON_DOD = 10007
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_IPFORWARDROW
{
public uint dwForwardDest;
public uint dwForwardMask;
public int dwForwardPolicy;
public uint dwForwardNextHop;
public int dwForwardIfIndex;
public ForwardType dwForwardType;
public ForwardProtocol dwForwardProto;
public int dwForwardAge;
public int dwForwardNextHopAS;
public int dwForwardMetric1;
public int dwForwardMetric2;
public int dwForwardMetric3;
public int dwForwardMetric4;
public int dwForwardMetric5;
public static List<MIB_IPFORWARDROW> FromByteArray(byte[] buffer)
{
List<MIB_IPFORWARDROW> ret = new List<MIB_IPFORWARDROW>();
int n =
(buffer[3] << 24) +
(buffer[2] << 16) +
(buffer[1] << 8) +
(buffer[0] << 0);
int offset = sizeof(int);
for (int i = 0; i < n; i++)
{
MIB_IPFORWARDROW map = new MIB_IPFORWARDROW();
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(map));
Marshal.StructureToPtr(map, ptr, false);
Marshal.Copy(buffer, offset, ptr, Marshal.SizeOf(map));
map = (MIB_IPFORWARDROW)Marshal.PtrToStructure(ptr, typeof(MIB_IPFORWARDROW));
Marshal.FreeHGlobal(ptr);
ret.Add(map);
offset += Marshal.SizeOf(map);
}
return ret;
}
}
[DllImport("Iphlpapi.dll", CharSet = CharSet.Auto)]
public static extern int GetIpForwardTable(byte[] pIpForwardTable, ref ulong pdwSize, bool bOrder);
[DllImport("Iphlpapi.dll", CharSet = CharSet.Auto)]
public static extern int DeleteIpForwardEntry(ref MIB_IPFORWARDROW pRoute);
[DllImport("Iphlpapi.dll", CharSet = CharSet.Auto)]
public static extern int SetIpForwardEntry(ref MIB_IPFORWARDROW pRoute);
private static uint IPToUIntR(IPAddress ip)
{
uint ret = 0;
byte[] ipBytes = ip.GetAddressBytes();
ret += (uint)ipBytes[0] << 24;
ret += (uint)ipBytes[1] << 16;
ret += (uint)ipBytes[2] << 8;
ret += (uint)ipBytes[3];
return ret;
}
public static List<MIB_IPFORWARDROW> GetIPForwardTable(int index)
{
List<MIB_IPFORWARDROW> ret = new List<MIB_IPFORWARDROW>();
ulong size = 0;
int err = GetIpForwardTable(null, ref size, false);
byte[] buffer = new byte[size];
err = GetIpForwardTable(buffer, ref size, false);
if (err != 0)
{
throw new System.ComponentModel.Win32Exception(err, $"GetIPForwardTable return with error code {err}");
}
foreach (MIB_IPFORWARDROW mipr in MIB_IPFORWARDROW.FromByteArray(buffer))
{
if (mipr.dwForwardIfIndex != index)
{
continue;
}
ret.Add(mipr);
}
return ret;
}
public static void SetDefaultGateway(int index, string gateway)
{
int err;
int i;
List<MIB_IPFORWARDROW> l = GetIPForwardTable(index);
MIB_IPFORWARDROW mipr = new MIB_IPFORWARDROW();
for (i = 0; i < l.Count; ++i)
{
// 0.0.0.0 default gateway
if (l[i].dwForwardDest != 0)
{
continue;
}
mipr = l[i];
err = DeleteIpForwardEntry(ref mipr);
if (err != 0)
{
throw new System.ComponentModel.Win32Exception(err, $"DeleteIpForwardEntry return with error code {err}");
}
break;
}
mipr.dwForwardNextHop = IPToUIntR(IPAddress.Parse(gateway));
err = SetIpForwardEntry(ref mipr);
if (err != 0)
{
throw new System.ComponentModel.Win32Exception(err, $"DeleteIpForwardEntry return with error code {err}");
}
}
上面的代码使用pinvokes在.net中使用iphelper函数,所以只需忘记pinvokes并使用代码作为win32应用程序的参考。
https://msdn.microsoft.com/en-us/library/windows/desktop/aa366363(v=vs.85).aspx
编辑: 您可以使用以下代码获取适配器信息。并在需要使用SetDefaultGateway时使用Index字段。
const int MAX_ADAPTER_ADDRESS_LENGTH = 8;
const int MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
const int MAX_ADAPTER_NAME_LENGTH = 256;
const int MAX_ADAPTER_NAME = 128;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct IP_ADDRESS_STRING
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string Address;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct IP_ADDR_STRING
{
public IntPtr Next;
public IP_ADDRESS_STRING IpAddress;
public IP_ADDRESS_STRING IpMask;
public ulong Context;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct IP_ADAPTER_INFO
{
public IntPtr Next;
public Int32 ComboIndex;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_ADAPTER_NAME_LENGTH + 4)]
public string AdapterName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_ADAPTER_DESCRIPTION_LENGTH + 4)]
public string AdapterDescription;
public UInt32 AddressLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_ADAPTER_ADDRESS_LENGTH)]
public byte[] Address;
public Int32 Index;
public UInt32 Type;
public UInt32 DhcpEnabled;
public IntPtr CurrentIpAddress;
public IP_ADDR_STRING IpAddressList;
public IP_ADDR_STRING GatewayList;
public IP_ADDR_STRING DhcpServer;
public bool HaveWins;
public IP_ADDR_STRING PrimaryWinsServer;
public IP_ADDR_STRING SecondaryWinsServer;
public Int32 LeaseObtained;
public Int32 LeaseExpires;
}
[DllImport("iphlpapi.dll", CharSet = CharSet.Ansi)]
static extern int GetAdaptersInfo(byte[] pAdapterInfo, ref ulong pBufOutLen);
public static List<IP_ADAPTER_INFO> GetAllAdapters()
{
List<IP_ADAPTER_INFO> ret = new List<IP_ADAPTER_INFO>();
ulong size = 0;
int err = GetAdaptersInfo(null, ref size);
byte[] buffer = new byte[size];
err = GetAdaptersInfo(buffer, ref size);
if (err != 0)
{
throw new System.ComponentModel.Win32Exception(err, $"GetInterfaceInfo return with error code {err}");
}
GCHandle gc = GCHandle.Alloc(buffer, GCHandleType.Pinned);
IntPtr pEntry = gc.AddrOfPinnedObject();
do
{
IP_ADAPTER_INFO entry = (IP_ADAPTER_INFO)Marshal.PtrToStructure(pEntry, typeof(IP_ADAPTER_INFO));
ret.Add(entry);
pEntry = entry.Next;
}
while (pEntry != IntPtr.Zero);
gc.Free();
return ret;
}