package es.tid.tedb; import java.net.Inet4Address; import java.util.Iterator; import java.util.LinkedList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import es.tid.rsvp.objects.subobjects.EROSubobject; import es.tid.rsvp.objects.subobjects.IPv4prefixEROSubobject; import es.tid.rsvp.objects.subobjects.SubObjectValues; /** * Class that maintains a table with Reachability entries. * It has a method to add a reachability entry * It has a method to query the domain of an IPv4 endpoint * It has a method to query if an address begins to a given IP range * KNOWN BUGS: * * When a reachability entry is added, it is not checked if * it is already there or not. * * Reachability entries cannot be removed * * @author ogondio * */ public class ReachabilityManager { /** * Table with IP address/prefix --> domain */ LinkedList<ReachabilityEntry> reachability; /** * The logger */ private Logger log; /** * ReachabilityManager constructor */ public ReachabilityManager(){ log=LoggerFactory.getLogger("PCEServer"); reachability=new LinkedList<ReachabilityEntry>(); } /** * gets the domain of an IPv4 EndpointAddress * @param endpointAddress the address to query * @return The domain id if the endpointAddress belongs to a domain, null otherwise. */ public Inet4Address getDomain(Inet4Address endpointAddress) { //String domain="0.0.0.1"; Iterator<ReachabilityEntry> it=reachability.iterator(); while (it.hasNext()){ ReachabilityEntry ra=it.next(); //log.info("reachability entry "+ra.aggregatedIPRange+" mask "+(ra.mask[0]&0xFF)+"."+(ra.mask[1]&0xFF)+"."+(ra.mask[2]&0xFF)+"."+(ra.mask[3]&0xFF)); if (belongsToDomain(endpointAddress, ra.mask, ra.aggregatedIPRange)){ return ra.domainId; } } return null; } /** * Method to determine if the address 'nodeAdrress' belongs to the aggregated IP address range given by the mask and the addresss 'aggregatedIPRange' * @param nodeAddress The address to query * @param mask The 32 bit network mask * @param aggregatedIPRange The aggregated IP address * @return true if it belongs to the range, false if it does not belong to the range */ public boolean belongsToDomain(Inet4Address nodeAddress, byte []mask, Inet4Address aggregatedIPRange){ int i; //byte [] networkAddress=new byte[4]; byte [] bytesAggregatedIPRange=aggregatedIPRange.getAddress(); byte [] bytesNodeAddress=nodeAddress.getAddress(); boolean found=true; for (i=0;i<4;++i){ //networkAddress[i]= (byte) ((bytesNodeAddress[i]&mask[i])&0xFF) ; //log.info("network Node Address[i]: "+(networkAddress[i]&0xFF)); //log.info("bytesAggregatedIPRange["+i+"]: "+((bytesAggregatedIPRange[i]&mask[i])&0xFF)); //log.info("bytesNodeAddress["+i+"]: "+((bytesNodeAddress[i]&mask[i])&0xFF)); if ((byte)((bytesAggregatedIPRange[i]&mask[i])&0xFF)!=(byte)((bytesNodeAddress[i]&mask[i])&0xFF)){ found=false; return found; } } return found; } /** * Adds a ERO Subobject associated with a given domainId to the reachability table * @param domainId Domain ID * @param eroso ERO Subobject */ public void addEROSubobject(Inet4Address domainId, EROSubobject eroso ){ if (eroso.getType()==SubObjectValues.ERO_SUBOBJECT_IPV4PREFIX){ log.info("Adding IPv4 ERO Subobject to the Reachability Database"); IPv4prefixEROSubobject ipv4eroso=(IPv4prefixEROSubobject)eroso; //long mask=(long)0xFFFFFFFF-(long)Math.pow(2, 32-ipv4eroso.getPrefix())-1; log.info("prefix "+ipv4eroso.getPrefix()); long resta=((long)0x1<<ipv4eroso.getPrefix())-1; long maskLong=resta<<(32-ipv4eroso.getPrefix()); byte[] mask=new byte[4]; mask[0]=(byte)(maskLong>>>24 & 0xFF); mask[1]=(byte)(maskLong>>>16 & 0xFF); mask[2]=(byte)(maskLong>>>8 & 0xFF); mask[3]=(byte)(maskLong& 0xFF); log.info("mask: "+(mask[0]&0xFF)+"."+(mask[1]&0xFF)+"."+(mask[2]&0xFF)+"."+(mask[3]&0xFF)); log.info("Domain ID: "+domainId+" mask "+mask+" IPv4 Address: "+ipv4eroso.getIpv4address());//Pasar a FINE addIPv4Entry(domainId,mask,ipv4eroso.getIpv4address(),ipv4eroso.getPrefix()); } } private void addIPv4Entry(Inet4Address domainId,byte [] mask,Inet4Address aggregatedIPRange,int prefix){ ReachabilityEntry ra=new ReachabilityEntry(); ra.aggregatedIPRange=aggregatedIPRange; ra.mask=mask; ra.domainId=domainId; ra.prefix=prefix; if (!(reachability.contains(ra))){ reachability.add(ra); } return; } /** * Print the reachability table * @return String with the reachability information */ public String printReachability(){ String reachabilityString; Iterator <ReachabilityEntry> reachabIterator=reachability.iterator(); reachabilityString="Reachability entries: \r\n"; while (reachabIterator.hasNext()){ ReachabilityEntry entry= reachabIterator.next(); reachabilityString=reachabilityString+"\t"+entry.toString()+"\r\n"; } return reachabilityString; } public LinkedList<ReachabilityEntry> getReachability() { return reachability; } }