package jnetman.network; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import jnetman.session.SessionPref; import jnetman.snmp.MIB; import jnetman.snmp.SnmpErrorException; import jnetman.snmp.SnmpSyntaxException; import jnetman.snmp.Table; import jnetman.snmp.TimeoutException; import org.snmp4j.smi.OID; import org.snmp4j.smi.SMIConstants; public class NodeAgent extends Agent { private Node node; public NodeAgent(Node node) throws AddressException { super(node); this.node = node; } /** * Update the list of InterfaceCards declared for the node based on the data * retrieved from SNMP. * * @param ifDescrFilter * Update or add only interface cards whose name start with this * filter (e.g. 'eth' to update or add eth1, eth2, etc.). 'Null' * to not filter. * @param ifTypeFilter * update or add only interface cards with this MIB-II ifType * value (e.g '6' to update or add only ethernet interfaces). * '-1' to not filter. For a list of other possible ifType values * refer to RFC1213-MIB. * @return True if changes are made, false elsewhere */ public boolean updateIfCards(String ifDescrFilter, int ifTypeFilter) { logger.debug("Update of interface cards started..."); boolean changes = false; Table ifTable = snmpHelper.getTable(MIB.IfTable); Table ipAddrTable = snmpHelper.getTable(MIB.IpAddrTable); IfCard ifCard = null; String name; int ifType; int ifIndex; InetAddress address; short prefixLength; for (Table.Row ifRow : ifTable.getMap().values()) { name = ifRow.getVariable(MIB.IfDescr).toString(); ifType = ifRow.getVariable(MIB.IfType).toInt(); ifIndex = ifRow.getVariable(MIB.IfIndex).toInt(); logger.debug("Interface found >> name = " + name + ", ifType = " + ifType + ", ifIndex = " + ifIndex); // filter and create or get if (ifDescrFilter == null || name.startsWith(ifDescrFilter)) if (ifTypeFilter == -1 || ifType == ifTypeFilter) try { ifCard = node.createInterfaceCard(name); logger.debug("New interface created >> " + name); changes = true; } catch (DuplicateElementException e) { logger.debug("Interface already existing >> " + name); ifCard = node.getInterfaceCard(name); } else continue; else continue; try { ifCard.getAgent().ifIndex = ifIndex; } catch (AddressException e) { // we don't care } // now we look at the ipaddrTable to find the ip address of this // interface for (Table.Row ipRow : ipAddrTable.getMap().values()) if (ipRow.getVariable(MIB.IpAdEntIfIndex).toInt() == ifIndex) { try { address = InetAddress.getByName(ipRow.getVariable( MIB.IpAdEntAddr).toString()); prefixLength = InetAddressUtils.toPrefixLenght(ipRow .getVariable(MIB.IpAdEntNetMask).toString()); logger.debug("IP address found for interface " + name + " >> " + address.getHostAddress() + "/" + prefixLength); if (ifCard.getAddress() == null || !ifCard.getAddress().equals(address)) { ifCard.setAddress(address); logger.debug("IP address updated for interface " + name + " >> " + ifCard.getAddress().getHostAddress()); changes = true; } if (ifCard.getAddrPrefixLenght() != prefixLength) { ifCard.setAddrPrefixLenght(prefixLength); logger.debug("Network prefix length updated for interface " + name + " >> " + ifCard.getAddrPrefixLenght()); changes = true; } } catch (UnknownHostException e) { // no way to be here because we setted address in ip // format, not host name format e.printStackTrace(); } } } return changes; } public long getIpOutNoRoutes() throws TimeoutException, SnmpErrorException, SnmpSyntaxException { return snmpHelper.getLong(MIB.IpOutNoRoutes); } public Map<IfCard, Integer> getOspfCosts(int tos) throws TimeoutException, SnmpErrorException, SnmpSyntaxException { return getOspfCosts(new HashSet<IfCard>(node.getIfCards()), tos); } public Map<IfCard, Integer> getOspfCosts(Set<IfCard> ifCards, int tos) throws TimeoutException, SnmpErrorException, SnmpSyntaxException { // FIXME probably buggy, we are assuming that the ip address for the // interface is always declared, so we don't need to use the // ospfIfMetricAddressLessIf index. Check the indexes of // OSPF-MIB::ospfIfMetricTable for further informations IfCard[] ifCardsArr = new IfCard[ifCards.size()]; OID[] oids = new OID[ifCards.size()]; int i = 0; for (IfCard ifCard : ifCards) { ifCardsArr[i] = ifCard; oids[i] = MIB.getOspfIfMetricEntryOID(MIB.ospfIfMetricValue, ifCard.getAddress(), 0, tos); i++; } int[] metrics = snmpHelper.getInt(oids); HashMap<IfCard, Integer> costs = new HashMap<IfCard, Integer>(); for (i = 0; i < ifCardsArr.length; i++) { costs.put(ifCardsArr[i], metrics[i]); } return costs; } public Map<IfCard, Boolean> setOspfCosts(Map<IfCard, Integer> map, int tos) throws TimeoutException, SnmpErrorException, SnmpSyntaxException { // FIXME probably buggy, we are assuming that the ip address for the // interface is always declared, so we don't need to use the // ospfIfMetricAddressLessIf index. Check the indexes of // OSPF-MIB::ospfIfMetricTable for further informations IfCard[] ifCardsArr = new IfCard[map.size()]; OID[] oids = new OID[map.size()]; int[] values = new int[map.size()]; int[] smiSyntaxs = new int[map.size()]; int i = 0; for (IfCard ifCard : map.keySet()) { ifCardsArr[i] = ifCard; oids[i] = MIB.getOspfIfMetricEntryOID(MIB.ospfIfMetricValue, ifCard.getAddress(), 0, tos); values[i] = map.get(ifCard); i++; } Arrays.fill(smiSyntaxs, SMIConstants.SYNTAX_INTEGER32); HashMap<IfCard, Boolean> resMap = new HashMap<IfCard, Boolean>(); if (SessionPref.isCumulativeSetRequestsAllowed()) { boolean[] res = snmpHelper.setInt(oids, values, smiSyntaxs); for (i = 0; i < ifCardsArr.length; i++) { resMap.put(ifCardsArr[i], res[i]); } } else { for (i = 0; i < ifCardsArr.length; i++) { resMap.put(ifCardsArr[i], snmpHelper.setInt(oids[i], values[i], SMIConstants.SYNTAX_INTEGER32)); if (SessionPref.getOspfCostSetRequestMillisInterval() > 0) try { Thread.sleep(SessionPref .getOspfCostSetRequestMillisInterval()); } catch (InterruptedException e) { } } } return resMap; } }