在我在开放式嵌入式Linux上运行的应用程序(用MVC3编写的管理Web界面)中,我必须列出所有TCP / IP设置.这包括IP-Adresse,Gateway和子网掩码.以下代码在MS .Net下运行良好,但Mono 2.10为“IPv4Mask”属性抛出NotImplem...
在我在开放式嵌入式Linux上运行的应用程序(用MVC3编写的管理Web界面)中,我必须列出所有TCP / IP设置.这包括IP-Adresse,Gateway和子网掩码.
以下代码在MS .Net下运行良好,但Mono 2.10为“IPv4Mask”属性抛出NotImplemntedException:
var ipProperties = networkIntf.GetIPProperties();
var unicastIpInfo = ipProperties.UnicastAddresses.FirstOrDefault();
var subnetMask = unicastAddress != null ? unicastAddress.IPv4Mask.ToString() : "";
有人知道如何使用Mono获得IPv4子网掩码吗?
我发现这个问题已在2009年问过,但未找到任何答案.
解决方法:
我看了一些Mono源代码并提取了一些代码片段来构建一个帮助器,它返回给定网络接口的IPv4子网掩码.代码不是绝对的美,但它的工作原理.
[StructLayout(LayoutKind.Explicit)]
struct ifa_ifu
{
[FieldOffset(0)]
public IntPtr ifu_broadaddr;
[FieldOffset(0)]
public IntPtr ifu_dstaddr;
}
[StructLayout(LayoutKind.Sequential)]
struct ifaddrs
{
public IntPtr ifa_next;
public string ifa_name;
public uint ifa_flags;
public IntPtr ifa_addr;
public IntPtr ifa_netmask;
public ifa_ifu ifa_ifu;
public IntPtr ifa_data;
}
[StructLayout(LayoutKind.Sequential)]
struct sockaddr_in
{
public ushort sin_family;
public ushort sin_port;
public uint sin_addr;
}
[StructLayout(LayoutKind.Sequential)]
struct sockaddr_in6
{
public ushort sin6_family; /* AF_INET6 */
public ushort sin6_port; /* Transport layer port # */
public uint sin6_flowinfo; /* IPv6 flow information */
public in6_addr sin6_addr; /* IPv6 address */
public uint sin6_scope_id; /* scope id (new in RFC2553) */
}
[StructLayout(LayoutKind.Sequential)]
struct in6_addr
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] u6_addr8;
}
[StructLayout(LayoutKind.Sequential)]
struct sockaddr_ll
{
public ushort sll_family;
public ushort sll_protocol;
public int sll_ifindex;
public ushort sll_hatype;
public byte sll_pkttype;
public byte sll_halen;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] sll_addr;
}
internal class IPInfoTools
{
const int AF_INET = 2;
const int AF_INET6 = 10;
const int AF_PACKET = 17;
[DllImport("libc")]
static extern int getifaddrs (out IntPtr ifap);
[DllImport ("libc")]
static extern void freeifaddrs (IntPtr ifap);
internal static string GetIPv4Mask(string networkInterfaceName)
{
IntPtr ifap;
if (getifaddrs(out ifap) != 0)
{
throw new SystemException("getifaddrs() failed");
}
try
{
var next = ifap;
while (next != IntPtr.Zero)
{
var addr = (ifaddrs)Marshal.PtrToStructure(next, typeof(ifaddrs));
var name = addr.ifa_name;
if (addr.ifa_addr != IntPtr.Zero)
{
var sockaddr = (sockaddr_in)Marshal.PtrToStructure(addr.ifa_addr, typeof(sockaddr_in));
switch (sockaddr.sin_family)
{
case AF_INET6:
//sockaddr_in6 sockaddr6 = (sockaddr_in6)Marshal.PtrToStructure(addr.ifa_addr, typeof(sockaddr_in6));
break;
case AF_INET:
if (name == networkInterfaceName)
{
var netmask = (sockaddr_in)Marshal.PtrToStructure(addr.ifa_netmask, typeof(sockaddr_in));
var ipAddr = new IPAddress(netmask.sin_addr); // IPAddress to format into default string notation
return ipAddr.ToString();
}
break;
case AF_PACKET:
{
var sockaddrll = (sockaddr_ll)Marshal.PtrToStructure(addr.ifa_addr, typeof(sockaddr_ll));
if (sockaddrll.sll_halen > sockaddrll.sll_addr.Length)
{
Console.Error.WriteLine("Got a bad hardware address length for an AF_PACKET {0} {1}",
sockaddrll.sll_halen, sockaddrll.sll_addr.Length);
next = addr.ifa_next;
continue;
}
}
break;
}
}
next = addr.ifa_next;
}
}
finally
{
freeifaddrs(ifap);
}
return null;
}
}
上面帮手的用法是这样的:
String subnetMask = IPInfoTools.GetIPv4Mask("etc0");
我还没有设法在Mono源代码中解决这个问题,因为需要在Mono中更改一些文件,以便从查询它的位置(LinuxNetworkInterface)获取上述信息到它所使用的位置(LinuxUnicastIPAddressInfo).但我会将我的代码发布到Mono错误报告中,所以也许Mono开发人员可以看一下.
本文标题为:c# – 如何在Linux上使用Mono查询子网掩码?
- C# 使用Aspose.Cells 导出Excel的步骤及问题记录 2023-05-16
- WPF使用DrawingContext实现绘制刻度条 2023-07-04
- Unity3D实现渐变颜色效果 2023-01-16
- Oracle中for循环的使用方法 2023-07-04
- 如何使用C# 捕获进程输出 2023-03-10
- c# 模拟线性回归的示例 2023-03-14
- Unity Shader实现模糊效果 2023-04-27
- user32.dll 函数说明小结 2022-12-26
- .NET CORE DI 依赖注入 2023-09-27
- 在C# 8中如何使用默认接口方法详解 2023-03-29