2009-02-23 3 views

risposta

19

Jakarta Commons Net ha org.apache.commons.net.util.SubnetUtils che sembra soddisfare le vostre esigenze. Sembra che si fa qualcosa di simile:

SubnetInfo subnet = (new SubnetUtils("10.10.10.0", "255.255.255.128")).getInfo(); 
boolean test = subnet.isInRange("10.10.10.10"); 

nota, come carson sottolinea, che Jakarta Commons Net ha a bug che gli impedisce di dare la risposta corretta in alcuni casi. Carson suggerisce di usare la versione SVN per evitare questo bug.

+4

Fare attenzione a questo. C'è un bug che impedirà il corretto funzionamento. Potresti voler estrarlo da SVN. http://mail-archives.apache.org/mod_mbox/commons-issues/200902.mbox/%[email protected]%3E – carson

+0

@carson: Grazie per l'avvertimento. Ho modificato la mia risposta per includere questa informazione. – Eddie

9

Si può anche provare

boolean inSubnet = (ip & netmask) == (subnet & netmask); 

o meno lungo

boolean inSubnet = (ip^subnet) & netmask == 0; 
+0

Sono ip o netmask inte o long? – simgineer

+0

Gli indirizzi a 32 bit, IPv4, sono ints. Ho il sospetto che IPv6 sia un valore a 64 bit, ma non ho usato me stesso –

3

Usa Primavera IpAddressMatcher. A differenza di Apache Commons Net, supporta sia ipv4 che ipv6.

import org.springframework.security.web.util.matcher.IpAddressMatcher; 
... 

private void checkIpMatch() { 
    matches("192.168.2.1", "192.168.2.1"); // true 
    matches("192.168.2.1", "192.168.2.0/32"); // false 
    matches("192.168.2.5", "192.168.2.0/24"); // true 
    matches("92.168.2.1", "fe80:0:0:0:0:0:c0a8:1/120"); // false 
    matches("fe80:0:0:0:0:0:c0a8:11", "fe80:0:0:0:0:0:c0a8:1/120"); // true 
    matches("fe80:0:0:0:0:0:c0a8:11", "fe80:0:0:0:0:0:c0a8:1/128"); // false 
    matches("fe80:0:0:0:0:0:c0a8:11", "192.168.2.0/32"); // false 
} 

private boolean matches(String ip, String subnet) { 
    IpAddressMatcher ipAddressMatcher = new IpAddressMatcher(subnet); 
    return ipAddressMatcher.matches(ip); 
} 

Fonte: here

0

Per controllare un IP in una sottorete, ho usato il metodo isInRange in classe SubnetUtils. Ma questo metodo ha un bug che se la tua sottorete era X, ogni indirizzo IP inferiore a X, isInRange restituisce true. Ad esempio se la tua sottorete era 10.10.30.0/24 e vuoi controllare 10.10.20.5, questo metodo restituisce true. Per far fronte a questo bug ho usato il codice qui sotto.

public static void main(String[] args){ 
    String list = "10.10.20.0/24"; 
    String IP1 = "10.10.20.5"; 
    String IP2 = "10.10.30.5"; 
    SubnetUtils subnet = new SubnetUtils(list); 
    SubnetUtils.SubnetInfo subnetInfo = subnet.getInfo(); 
    if(MyisInRange(subnetInfo , IP1) == true) 
     System.out.println("True"); 
    else 
     System.out.println("False"); 
    if(MyisInRange(subnetInfo , IP2) == true) 
     System.out.println("True"); 
    else 
     System.out.println("False"); 
} 

private boolean MyisInRange(SubnetUtils.SubnetInfo info, String Addr) 
{ 
    int address = info.asInteger(Addr); 
    int low = info.asInteger(info.getLowAddress()); 
    int high = info.asInteger(info.getHighAddress()); 
    return low <= address && address <= high; 
}