2009-09-30 7 views
26

के भीतर है या नहीं, मेरे पास 10.132.0.0/20 प्रारूप में एक सबनेट है और ASP.Net अनुरोध ऑब्जेक्ट से एक आईपी पता है।यह जांचने के लिए कि कोई आईपी पता किसी विशेष सबनेट

क्या यह देखने के लिए कोई .NET फ्रेमवर्क फ़ंक्शन है कि आईपी पता दिए गए सबनेट के भीतर है या नहीं?

यदि नहीं, तो यह कैसे किया जा सकता है? बिट मैनिपुलेशन, मुझे लगता है?

उत्तर

23

MSDN ब्लॉग पर IP Address Calculations with C# पर एक नजर डालें। इसमें एक विस्तार विधि (IsInSameSubnet) शामिल है जो आपकी आवश्यकताओं को पूरा करने के साथ-साथ कुछ अन्य उपहारों को पूरा कर लेती है।

public static class IPAddressExtensions 
{ 
    public static IPAddress GetBroadcastAddress(this IPAddress address, IPAddress subnetMask) 
    { 
     byte[] ipAdressBytes = address.GetAddressBytes(); 
     byte[] subnetMaskBytes = subnetMask.GetAddressBytes(); 

     if (ipAdressBytes.Length != subnetMaskBytes.Length) 
      throw new ArgumentException("Lengths of IP address and subnet mask do not match."); 

     byte[] broadcastAddress = new byte[ipAdressBytes.Length]; 
     for (int i = 0; i < broadcastAddress.Length; i++) 
     { 
      broadcastAddress[i] = (byte)(ipAdressBytes[i] | (subnetMaskBytes[i]^255)); 
     } 
     return new IPAddress(broadcastAddress); 
    } 

    public static IPAddress GetNetworkAddress(this IPAddress address, IPAddress subnetMask) 
    { 
     byte[] ipAdressBytes = address.GetAddressBytes(); 
     byte[] subnetMaskBytes = subnetMask.GetAddressBytes(); 

     if (ipAdressBytes.Length != subnetMaskBytes.Length) 
      throw new ArgumentException("Lengths of IP address and subnet mask do not match."); 

     byte[] broadcastAddress = new byte[ipAdressBytes.Length]; 
     for (int i = 0; i < broadcastAddress.Length; i++) 
     { 
      broadcastAddress[i] = (byte)(ipAdressBytes[i] & (subnetMaskBytes[i])); 
     } 
     return new IPAddress(broadcastAddress); 
    } 

    public static bool IsInSameSubnet(this IPAddress address2, IPAddress address, IPAddress subnetMask) 
    { 
     IPAddress network1 = address.GetNetworkAddress(subnetMask); 
     IPAddress network2 = address2.GetNetworkAddress(subnetMask); 

     return network1.Equals(network2); 
    } 
} 
+0

में पार्स करने के लिए सहायक पाया गया आईपीवी 6 पते के बारे में क्या? – ageroh

+0

@ageroh गिटहब में कुछ सी # पुस्तकालय हैं जो आईपीवी 6 पते को संभाल सकते हैं। आईपीनेटवर्क, उदाहरण के लिए https://github.com/lduchosal/ipnetwork –

10

बिट मैनिपुलेशन काम करता है। सामग्री एक 32-बिट अहस्ताक्षरित पूर्णांक में आईपी, 0xFFFFFFFF << (32-20) साथ सबनेट के पते, & दोनों -mask साथ भी ऐसा ही और तुलना करें:

unsigned int net = ..., ip = ...; 
int network_bits = 20; 
unsigned int mask = 0xFFFFFFFF << (32 - network_bits); 
if ((net & mask) == (ip & mask)) { 
    // ... 
} 
+0

या, के रूप में आम है, सबनेट 255.255.240.0 की तरह एक संख्या के रूप में दिया जाता है, केवल वही जानकारी शिफ्ट के बजाय 32-बिट पूर्णांक में मुखौटा। – erikkallen

+3

मुझे सिस्टम.Net.IPAddress क्लास पाइपिंग और आईपी पतों को बाइट्स –

0

समाधान System.Net.IPAddress का उपयोग कर बाइट्स में आईपी पता बदलने और पता, सबनेट, और मुखौटा ओक्टेट्स पर बिटवाइज़ तुलना प्रदर्शन करने के लिए है।

बाइनरी और ऑपरेटर & दोनों ऑपरेटरों में मौजूद होने पर परिणाम के लिए थोड़ा सा प्रतिलिपि बनाता है।

कोड:

using System.Net; // Used to access IPAddress 

bool IsAddressOnSubnet(string address, string subnet, string mask) 
{ 
    try 
    { 
     IPAddress Address = IPAddress.Parse(address); 
     IPAddress Subnet = IPAddress.Parse(subnet); 
     IPAddress Mask = IPAddress.Parse(mask);    

     Byte[] addressOctets = Address.GetAddressBytes(); 
     Byte[] subnetOctets = Mask.GetAddressBytes(); 
     Byte[] networkOctets = Subnet.GetAddressBytes(); 

     return 
      ((networkOctets[0] & subnetOctets[0]) == (addressOctets[0] & subnetOctets[0])) && 
      ((networkOctets[1] & subnetOctets[1]) == (addressOctets[1] & subnetOctets[1])) && 
      ((networkOctets[2] & subnetOctets[2]) == (addressOctets[2] & subnetOctets[2])) && 
      ((networkOctets[3] & subnetOctets[3]) == (addressOctets[3] & subnetOctets[3])); 
    } 
    catch (System.Exception ex) 
    { 
     return false;     
    } 
} 

Спасибо के लिए विशेष धन्यवाद! Прекрасное решение! Reference

+1

बस जागरूक रहें यदि आईपीवी 6 पते के साथ प्रस्तुत किया गया तो यह टूट जाएगा – Fowl

2

चूंकि एमएसडीएन ब्लॉग कोड प्रसारण पर निर्भर करता है और आईपीवी 6 में कोई नहीं है, मुझे नहीं पता कि यह आईपीवी 6 के साथ काम करता है या नहीं।

मैं इन विधियों के साथ समाप्त हुआ (एनयू ईवेस्ट के लिए धन्यवाद)। आप एक सीआईडीआर नोटेशन ("1.2.3.4/5") से सबनेट और मास्क प्राप्त कर सकते हैं और जांच सकते हैं कि कोई एड्रेस इस नेटवर्क के भीतर है या नहीं।

यह IPv4 और IPv6 के लिए काम करता है:

public static class IpAddresses 
{ 
    public static Tuple<IPAddress, IPAddress> GetSubnetAndMaskFromCidr(string cidr) 
    { 
     var delimiterIndex = cidr.IndexOf('/'); 
     string ipSubnet = cidr.Substring(0, delimiterIndex); 
     string mask = cidr.Substring(delimiterIndex + 1); 

     var subnetAddress = IPAddress.Parse(ipSubnet); 

     if (subnetAddress.AddressFamily == AddressFamily.InterNetworkV6) 
     { 
      // ipv6 
      var ip = BigInteger.Parse("00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", NumberStyles.HexNumber) << (128 - int.Parse(mask)); 

      var maskBytes = new[] 
      { 
       (byte)((ip & BigInteger.Parse("00FF000000000000000000000000000000", NumberStyles.HexNumber)) >> 120), 
       (byte)((ip & BigInteger.Parse("0000FF0000000000000000000000000000", NumberStyles.HexNumber)) >> 112), 
       (byte)((ip & BigInteger.Parse("000000FF00000000000000000000000000", NumberStyles.HexNumber)) >> 104), 
       (byte)((ip & BigInteger.Parse("00000000FF000000000000000000000000", NumberStyles.HexNumber)) >> 96), 
       (byte)((ip & BigInteger.Parse("0000000000FF0000000000000000000000", NumberStyles.HexNumber)) >> 88), 
       (byte)((ip & BigInteger.Parse("000000000000FF00000000000000000000", NumberStyles.HexNumber)) >> 80), 
       (byte)((ip & BigInteger.Parse("00000000000000FF000000000000000000", NumberStyles.HexNumber)) >> 72), 
       (byte)((ip & BigInteger.Parse("0000000000000000FF0000000000000000", NumberStyles.HexNumber)) >> 64), 
       (byte)((ip & BigInteger.Parse("000000000000000000FF00000000000000", NumberStyles.HexNumber)) >> 56), 
       (byte)((ip & BigInteger.Parse("00000000000000000000FF000000000000", NumberStyles.HexNumber)) >> 48), 
       (byte)((ip & BigInteger.Parse("0000000000000000000000FF0000000000", NumberStyles.HexNumber)) >> 40), 
       (byte)((ip & BigInteger.Parse("000000000000000000000000FF00000000", NumberStyles.HexNumber)) >> 32), 
       (byte)((ip & BigInteger.Parse("00000000000000000000000000FF000000", NumberStyles.HexNumber)) >> 24), 
       (byte)((ip & BigInteger.Parse("0000000000000000000000000000FF0000", NumberStyles.HexNumber)) >> 16), 
       (byte)((ip & BigInteger.Parse("000000000000000000000000000000FF00", NumberStyles.HexNumber)) >> 8), 
       (byte)((ip & BigInteger.Parse("00000000000000000000000000000000FF", NumberStyles.HexNumber)) >> 0), 
      }; 

      return Tuple.Create(subnetAddress, new IPAddress(maskBytes)); 
     } 
     else 
     { 
      // ipv4 
      uint ip = 0xFFFFFFFF << (32 - int.Parse(mask)); 

      var maskBytes = new[] 
      { 
       (byte)((ip & 0xFF000000) >> 24), 
       (byte)((ip & 0x00FF0000) >> 16), 
       (byte)((ip & 0x0000FF00) >> 8), 
       (byte)((ip & 0x000000FF) >> 0), 
      }; 

      return Tuple.Create(subnetAddress, new IPAddress(maskBytes)); 
     } 
    } 

    public static bool IsAddressOnSubnet(IPAddress address, IPAddress subnet, IPAddress mask) 
    { 
     byte[] addressOctets = address.GetAddressBytes(); 
     byte[] subnetOctets = mask.GetAddressBytes(); 
     byte[] networkOctets = subnet.GetAddressBytes(); 

     // ensure that IPv4 isn't mixed with IPv6 
     if (addressOctets.Length != subnetOctets.Length 
      || addressOctets.Length != networkOctets.Length) 
     { 
      return false; 
     } 

     for (int i = 0; i < addressOctets.Length; i += 1) 
     { 
      var addressOctet = addressOctets[i]; 
      var subnetOctet = subnetOctets[i]; 
      var networkOctet = networkOctets[i]; 

      if (networkOctet != (addressOctet & subnetOctet)) 
      { 
       return false; 
      } 
     } 
     return true; 
    } 
} 

उदाहरण उपयोग:

var subnetAndMask = IpAddresses.GetSubnetAndMaskFromCidr("10.132.0.0/20"); 
bool result = IpAddresses.IsAddressOnSubnet(
    IPAddress.Parse("10.132.12.34"), 
    subnetAndMask.Item1, 
    subnetAndMask.Item2); 
0

मैं देर से पार्टी के लिए यहाँ हूँ, लेकिन एक ऐसी ही जरूरत थी, और के लिए एक साथ एक त्वरित पैकेज डाल ठीक है यह करो।

https://www.nuget.org/packages/IpMatcher/

और स्रोत:

https://github.com/jchristn/IpMatcher

सरल उपयोग:

using IpMatcher; 

Matcher matcher = new Matcher(); 
matcher.Add("192.168.1.0", "255.255.255.0"); 
matcher.Add("192.168.2.0", "255.255.255.0"); 
matcher.Remove("192.168.2.0"); 
matcher.Exists("192.168.1.0", "255.255.255.0"); // true 
matcher.Match("192.168.1.34"); // true 
matcher.Match("10.10.10.10"); // false 
संबंधित मुद्दे