2011-11-14 14 views
5

ओपन-एम्बेडेड लिनक्स पर चल रहे मेरे एप्लिकेशन (एमवीसी 3 में लिखित एडमिन वेब इंटरफ़ेस) में मुझे सभी टीसीपी/आईपी सेटिंग्स सूचीबद्ध करना है। इसमें आईपी एड्रेस, गेटवे और सबनेट मास्क शामिल हैं।लिनक्स पर मोनो का उपयोग करके सबनेट मास्क से पूछताछ कैसे करें?

निम्नलिखित कोड एमएस नेट के तहत अच्छी तरह से चलता है, लेकिन मोनो 2.10 "IPv4Mask" संपत्ति के लिए एक NotImplemntedException फेंकता है:

var ipProperties = networkIntf.GetIPProperties(); 
var unicastIpInfo = ipProperties.UnicastAddresses.FirstOrDefault(); 
var subnetMask = unicastAddress != null ? unicastAddress.IPv4Mask.ToString() : ""; 

किसी को भी पता है कि कैसे एक मोनो का उपयोग कर आईपीवी 4 सबनेट मास्क मिल सकता है?

मुझे पता चला कि यह प्रश्न 200 9 में पहले से ही पूछा गया था लेकिन इसका कोई जवाब नहीं मिला।

+0

या तो उन्हें लागू करने के लिए कहें, या इसे स्वयं लागू करें! – leppie

+0

पहले से ही मोनो-लिस्ट में पूछे गए लेकिन मुझे कोई प्रतिक्रिया नहीं मिली। सोचो कि मेरे पास लिनक्स नहीं है-इसे स्वयं कैसे कार्यान्वित करना है। तो हो सकता है कि कोई और कामकाज जानता हो। – Marc

+1

आप हमेशा 'ifconfig' को कॉल कर सकते हैं और इसे मैन्युअल रूप से पार्स कर सकते हैं। – leppie

उत्तर

5

मैंने कुछ मोनो स्रोत कोड पर एक नज़र डाली और कुछ सहायक-स्निपेट निकाले जो एक सहायक बनाने के लिए निकाले गए जो नेटवर्क नेटवर्क इंटरफ़ेस का आईपीवी 4 सबनेट मास्क देता है। कोड एक पूर्ण सौंदर्य नहीं है लेकिन यह काम करता है। ऊपर सहायक की

[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"); 

मैं अभी तक एक मोनो में काफी कुछ फ़ाइलों को बदलने के लिए उपरोक्त होने की जरूरत है के रूप में मोनो sourcecode में इसे ठीक करने के प्रबंधन नहीं किया उस जगह से जानकारी जहां यह पूछताछ की जाती है (LinuxNetworkInterface) जहां इसका उपयोग किया जाता है (LinuxUnicastIPAddressInfo)। लेकिन मैं अपना कोड मोनो बग-रिपोर्ट में पोस्ट करूंगा ताकि शायद मोनो डेवलपर्स में से एक एक नज़र डालें।

1

मार्क, सिर्फ इतना कहना है आप इस कोड के लिए बहुत धन्यवाद करना चाहता था। मैं इसे अपने आवेदन में बहुत आसानी से काम करने में सक्षम था और यह मोनो 2.10.6 पर उबंटू 10.10 पर बहुत अच्छा काम करता है। काश मैं इसे एक से अधिक बार बढ़ा सकता हूं।

मैं मोनो के लिए एप्लिकेशन का एक विशेष संस्करण का निर्माण के बाद से Win32 संस्करण System.Deployment जो मोनो पर उपलब्ध नहीं है का उपयोग करता है; इसलिए संदर्भ के लिए, यहाँ कोड मैं प्रयोग किया जाता है:

UnicastIPAddressInformation addr = GetUnicastAddrFromNic(nic.GetIPProperties().UnicastAddresses); 

#if BUILD4MONO 
string mask = null; 
try { 
    mask = IPInfoTools.GetIPv4Mask(nic.Name); // Marc's function - nic.Name is eth0 or wlan1 etc. 
} catch (Exception ex) { // getifaddrs failed 
    Console.WriteLine("GetIPRangeInfoFromNetworkInterface failed: {0}", ex.Message); 
} 

if (mask == null || IPAddress.TryParse(mask, out rangeInfo.SubnetMask) == false) { 
    rangeInfo.SubnetMask = IPAddress.Parse("255.255.255.0"); // default to this 
} 
#else 
rangeInfo.SubnetMask = addr.IPv4Mask; // Win32 
#endif 

नोट: nic सिर्फ एक NetworkInterface वस्तु है और GetUnicastAddrFromNic() एक समारोह मुझे लगता है कि सिर्फ nic के लिए सभी UnicastAddresses पर लग रहा है बना दिया है और पहले एक जिसका AddressFamily रिटर्न InterNetwork है।

उम्मीद है कि मोनो टीम का कोई भी व्यक्ति आगामी समाधान में आपका समाधान लागू करेगा।

+0

अच्छा वृद्धि - धन्यवाद! मोनो: मैंने सभी को मोनो को सबमिट किया लेकिन उनसे कुछ भी नहीं सुना। निराशाजनक लेकिन अच्छी तरह से ... – Marc

+1

हाँ नेटवर्किंग कोड के रूप में कुछ सामान्य के लिए हाँ, मैं इसे एएसएपी शामिल करना चाहता हूं, लेकिन मुझे लगता है कि यह एम $ के साथ बनाए रखने और सीएलआर के साथ अपने कामकाजी कोड को अद्यतित रखने के लिए पर्याप्त कठिन है। .. कम से कम अब मैं अपने फॉर्म पर .NET और मोनो रेंडरिंग तत्वों के बीच असंगतताओं को ठीक करने के लिए आगे बढ़ सकता हूं जो विंडोज बी पर ठीक काम करता है लिनक्स पर गलत तरीके से दिखाएं। एक बार फिर धन्यवाद। – drew010

संबंधित मुद्दे