Logo Search packages:      
Sourcecode: airport-utils version File versions  Download package

PortInspector.java

/*
 * AirPort Port Inspector
 *
 * Copyright (C) 2003, Jonathan Sevy <jsevy@mcs.drexel.edu>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */




import java.util.*;
import java.net.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import java.awt.event.*;
import java.io.*;
import java.math.*;
import snmp.*;




public class PortInspector extends JFrame
                                          implements ActionListener, Runnable
{     
      
      
      JButton newPreferencesButton, discoverDevicesButton;
      JRadioButton simpleDisplayButton, detailedDisplayButton;
      JTextField airportInternalIPField;
      JTextField airportExternalIPField, airportNameField, airportLocationField;
      JPanel hostPanel;
      
      MenuBar theMenubar;
      Menu fileMenu;
      MenuItem quitItem, aboutItem, savePreferencesItem;
      
      JTextArea messagesArea;
      JTextAreaWriter messagesAreaWriter;
      
      PortMapTable portMapTable;
      
      Thread inspectionThread;
      
      Preferences preferences;
      boolean preferencesSaved = true;
      
      SNMPv1CommunicationInterface communicationInterface;
      String portMapBaseID = "1.3.6.1.4.1.731.100.3.1.1";
      String arpInfoTableOID = "1.3.6.1.2.1.4.22.1";
      private Vector changeListeners;
      
      PortInfoTreeMap currentInfo;
      
      
      
      // WindowCloseAdapter to catch window close-box closings
      private class WindowCloseAdapter extends WindowAdapter
      { 
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
      }
            
            
      
      public PortInspector()
      {
                  
      // read any settings that have previously been saved
            readSettings();
            
            
            changeListeners = new Vector();
      currentInfo = new PortInfoTreeMap();
      
      // create thread, but don't start it
      inspectionThread = new Thread(this);
        
        setUpDisplay();
      
      // create Writer interface into messages area for use by change listeners
      messagesAreaWriter = new JTextAreaWriter(messagesArea);
      
      this.pack();
                  
        // tweak app size to make it a little larger than necessary, to address the
        // "shrunken textfields" problem arising from the layout manager packing stuff
        // a little too tightly.
        Dimension dim = this.getSize();
        dim.height += 20;
        dim.width += 20;
        this.setSize(dim);

        this.show();
        
            // put up dialog to solicit new settings
            if (getPreferences() == false)
            {
                messagesArea.setText("Problem with supplied information; set options again");
            }
             
      
            
            
      }
      
      
      
      public void addChangeListener(PortInfoChangeListener changeListener)
      {
          if (!changeListeners.contains(changeListener))
              changeListeners.add(changeListener);
      }
      
      
      
      public void removeChangeListener(PortInfoChangeListener changeListener)
      {
          if (changeListeners.contains(changeListener))
              changeListeners.remove(changeListener);
      }
      
      
      
      private void setUpDisplay()
      {
            
            
            
            // set fonts to smaller-than-normal size, for compaction!
            UIManager manager = new UIManager();
            FontUIResource appFont = new FontUIResource("SansSerif", Font.PLAIN, 10);
            UIDefaults defaults = manager.getLookAndFeelDefaults();
            Enumeration keys = defaults.keys();
            
            while (keys.hasMoreElements())
            {
                  String nextKey = (String)(keys.nextElement());
                  if ((nextKey.indexOf("font") > -1) || (nextKey.indexOf("Font") > -1))
                  {
                        manager.put(nextKey, appFont);
                  }
            }
            
            
            
            // add WindowCloseAdapter to catch window close-box closings
            addWindowListener(new WindowCloseAdapter());

            
            
            this.setTitle("Port Inspector");
            
            this.getRootPane().setBorder(new BevelBorder(BevelBorder.RAISED));
            
            theMenubar = new MenuBar();
            this.setMenuBar(theMenubar);
            fileMenu = new Menu("File");
            
            
            aboutItem = new MenuItem("About...");
            aboutItem.setActionCommand("about");
            aboutItem.addActionListener(this);
            fileMenu.add(aboutItem);
            
            savePreferencesItem = new MenuItem("Save settings");
            savePreferencesItem.setActionCommand("save preferences");
            savePreferencesItem.addActionListener(this);
            fileMenu.add(savePreferencesItem);
                        
            fileMenu.addSeparator();

            quitItem = new MenuItem("Quit");
            quitItem.setShortcut(new MenuShortcut('q'));
            quitItem.setActionCommand("quit");
            quitItem.addActionListener(this);
            fileMenu.add(quitItem);
            
            theMenubar.add(fileMenu);
            
            
            JLabel airportInternalIPLabel = new JLabel("Base station LAN address:");
            airportInternalIPField = new JTextField(10);
            airportInternalIPField.setText("10.0.1.1");
            airportInternalIPField.setEditable(false);
                        
            JLabel airportExternalIPLabel = new JLabel("Base station WAN address:");
            airportExternalIPField = new JTextField(10);
            airportExternalIPField.setEditable(false);
            
            JLabel airportNameLabel = new JLabel("Base station name:");
            airportNameField = new JTextField(20);
            airportNameField.setEditable(false);

            JLabel airportLocationLabel = new JLabel("Base station location:");
            airportLocationField = new JTextField(20);
            airportLocationField.setEditable(false);
            
            
        simpleDisplayButton = new JRadioButton("Simple display");
            simpleDisplayButton.setActionCommand("simple display");
            simpleDisplayButton.addActionListener(this);
            
            detailedDisplayButton = new JRadioButton("Detailed display");
            detailedDisplayButton.setActionCommand("detailed display");
            detailedDisplayButton.addActionListener(this);
            
            ButtonGroup displayButtonGroup = new ButtonGroup();
            displayButtonGroup.add(simpleDisplayButton);
            displayButtonGroup.add(detailedDisplayButton);
            
            if (preferences.displayType == PortMapTable.DETAILED)
                detailedDisplayButton.setSelected(true);
            else
                simpleDisplayButton.setSelected(true);
                
            
            newPreferencesButton = new JButton("Change base station");
            newPreferencesButton.setActionCommand("new preferences");
            newPreferencesButton.addActionListener(this);
            
            discoverDevicesButton = new JButton("Discover devices");
            discoverDevicesButton.setActionCommand("discover devices");
            discoverDevicesButton.addActionListener(this);
            
            
            
            portMapTable = new PortMapTable(currentInfo, preferences.displayType);
      
            
            
            // set params for layout manager
            GridBagLayout  theLayout = new GridBagLayout();
            GridBagConstraints c = new GridBagConstraints();
            
            c.gridwidth = 1;
            c.gridheight = 1;
            c.fill = GridBagConstraints.NONE;
            c.ipadx = 0;
            c.ipady = 0;
            Insets theMargin = new Insets(2,2,2,2);
            c.insets = theMargin;
            c.anchor = GridBagConstraints.CENTER;
            c.weightx = .5;
            c.weighty = .5;
            
            
            
            // layout buttons in panel
            JPanel buttonPanel = new JPanel();
            buttonPanel.setLayout(theLayout);
            
            c.gridwidth = 2;
            
            c.gridx = 1;
            c.gridy = 1;
            theLayout.setConstraints(newPreferencesButton, c);
            buttonPanel.add(newPreferencesButton);
            
            /*
            c.gridx = 2;
            c.gridy = 1;
            theLayout.setConstraints(discoverDevicesButton, c);
            buttonPanel.add(discoverDevicesButton);
            */
            
            c.gridwidth = 1;
            
            c.gridx = 1;
            c.gridy = 2;
            theLayout.setConstraints(simpleDisplayButton, c);
            buttonPanel.add(simpleDisplayButton);
            
            c.gridx = 2;
            c.gridy = 2;
            theLayout.setConstraints(detailedDisplayButton, c);
            buttonPanel.add(detailedDisplayButton);
            
            
            
            // layout host info in panel
            hostPanel = new JPanel();
            hostPanel.setLayout(theLayout);
            
            c.anchor = GridBagConstraints.EAST;
            c.gridx = 1;
            c.gridy = 1;
            theLayout.setConstraints(airportInternalIPLabel, c);
            hostPanel.add(airportInternalIPLabel);
            
            c.anchor = GridBagConstraints.WEST;
            c.gridx = 2;
            c.gridy = 1;
            theLayout.setConstraints(airportInternalIPField, c);
            hostPanel.add(airportInternalIPField);
            
            c.anchor = GridBagConstraints.EAST;
            c.gridx = 1;
            c.gridy = 2;
            theLayout.setConstraints(airportExternalIPLabel, c);
            hostPanel.add(airportExternalIPLabel);
            
            c.anchor = GridBagConstraints.WEST;
            c.gridx = 2;
            c.gridy = 2;
            theLayout.setConstraints(airportExternalIPField, c);
            hostPanel.add(airportExternalIPField);
            
            c.anchor = GridBagConstraints.EAST;
            c.gridx = 1;
            c.gridy = 3;
            theLayout.setConstraints(airportNameLabel, c);
            hostPanel.add(airportNameLabel);
            
            c.anchor = GridBagConstraints.WEST;
            c.gridx = 2;
            c.gridy = 3;
            theLayout.setConstraints(airportNameField, c);
            hostPanel.add(airportNameField);
            
            c.anchor = GridBagConstraints.EAST;
            c.gridx = 1;
            c.gridy = 4;
            theLayout.setConstraints(airportLocationLabel, c);
            hostPanel.add(airportLocationLabel);
            
            c.anchor = GridBagConstraints.WEST;
            c.gridx = 2;
            c.gridy = 4;
            theLayout.setConstraints(airportLocationField, c);
            hostPanel.add(airportLocationField);
            
            
            
            c.anchor = GridBagConstraints.CENTER;
            
            
            
            JPanel messagesPanel = new JPanel();
            messagesPanel.setLayout(theLayout);
            
            messagesArea = new JTextArea(6,40);
            JScrollPane messagesScroll = new JScrollPane(messagesArea);
            
            c.fill = GridBagConstraints.NONE;
            c.weightx = 0;
            c.weighty = 0;
            c.gridx = 1;
            c.gridy = 1;
            JLabel messagesLabel = new JLabel("Messages:");
            theLayout.setConstraints(messagesLabel, c);
            messagesPanel.add(messagesLabel);
            
            c.fill = GridBagConstraints.BOTH;
            c.weightx = .5;
            c.weighty = .5;
            c.gridx = 1;
            c.gridy = 2;
            theLayout.setConstraints(messagesScroll, c);
            messagesPanel.add(messagesScroll);
            
            
            
            
            this.getContentPane().setLayout(theLayout);
            
            c.fill = GridBagConstraints.NONE;
            c.weightx = 0;
            c.weighty = 0;
            c.gridx = 1;
            c.gridy = 1;
            theLayout.setConstraints(hostPanel, c);
            this.getContentPane().add(hostPanel);
            
            c.gridx = 1;
            c.gridy = 2;
            theLayout.setConstraints(buttonPanel, c);
            this.getContentPane().add(buttonPanel);
            
            c.fill = GridBagConstraints.BOTH;
            c.weightx = .5;
            c.weighty = .5;
            c.gridx = 1;
            c.gridy = 3;
            theLayout.setConstraints(portMapTable, c);
            this.getContentPane().add(portMapTable);
            
            c.fill = GridBagConstraints.HORIZONTAL;
            c.weightx = .5;
            c.weighty = .5;
            c.gridx = 1;
            c.gridy = 4;
            theLayout.setConstraints(messagesPanel, c);
            this.getContentPane().add(messagesPanel);
            
            c.fill = GridBagConstraints.NONE;
            c.weightx = 0;
            c.weighty = 0;
            c.gridx = 1;
            c.gridy = 5;
            JLabel authorLabel = new JLabel(" Version 1.0        J. Sevy, January 2003 ");
            authorLabel.setFont(new Font("SansSerif", Font.ITALIC, 8));
            theLayout.setConstraints(authorLabel, c);
            this.getContentPane().add(authorLabel);
            
            
            
      }
      
      
      
      
      public void actionPerformed(ActionEvent theEvent)
      // respond to button pushes, menu selections
      {
            String command = theEvent.getActionCommand();
            
      
            if (command.equals("quit"))
            {
                  if (preferencesSaved == false)
                  {
                      // put up dialog to ask if settings should be saved
                      if (JOptionPane.showConfirmDialog(this, "Save current settings?","Save settings?",JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
                      {
                          saveSettings();
                      }
                  }
                  
                  System.exit(0);
            }
            
            
            
            if (command == "about")
            {
                  AboutDialog aboutDialog = new AboutDialog(this);
            }
            
            
            
            if (command.equals("discover devices"))
            {
                  AirportDiscoverer discoverer = new AirportDiscoverer();
            }
            
            
            
            if (command.equals("simple display"))
            {
                  portMapTable.setDisplayType(PortMapTable.SIMPLE);
            }
            
            
            if (command.equals("detailed display"))
            {
                  portMapTable.setDisplayType(PortMapTable.DETAILED);
            }     
            
            
            
            if (command == "new preferences")
            {
                  getPreferences();
            }
            
            
            if (command.equals("save preferences"))
            {
                  saveSettings();
            }
            
      }
      
      
      
      private boolean getPreferences()
      {
          
          PreferencesDialog theDialog = new PreferencesDialog(this, preferences);
                  
        if (!theDialog.isCancelled())
        {
            
            // stop thread if needed
            if (inspectionThread.isAlive())
            {
                inspectionThread.interrupt();
            }
            
            // get preferences
            Preferences newPreferences = theDialog.getPreferences();
            
            
            try
            {
                  
                  if (!newPreferences.equals(preferences))
                    preferencesSaved = false;
                    
                InetAddress airportInternalIPAddress = InetAddress.getByName(newPreferences.ipAddress);
                  airportInternalIPField.setText(newPreferences.ipAddress);
                  
                  // create new SNMP communication interface
                  communicationInterface = new SNMPv1CommunicationInterface(0, airportInternalIPAddress, newPreferences.password);
                  
                  // remove current action object
                //this.removeChangeListener(changeEmailer);
                
                // create and add new action object
                //changeEmailer = new AirportInfoChangeEmailer(newPreferences.emailAddress, newPreferences.smtpHost, messagesAreaWriter);
              //changeListeners.add(changeEmailer);
              
                  preferences = newPreferences;
                  
                  inspectionThread = new Thread(this);
                inspectionThread.start();
                
                return true;
            
            }
            catch(UnknownHostException e)
            {
                  JOptionPane.showMessageDialog(this, "Unknown host name supplied.");
            }
            catch(Exception e)
            {
                  JOptionPane.showMessageDialog(this, "Error setting new preferences: " + e);
            }
              
        }
        
        return false;
      }
      
      
      
      
      private PortInfoTreeMap getInfo()
          throws IllegalArgumentException, SocketException, IOException, SNMPGetException, SNMPBadValueException
      {
          
          SNMPVarBindList varBindList;
            String valueString;
            
          varBindList = communicationInterface.getMIBEntry("1.3.6.1.2.1.1.5.0");
            valueString = ((SNMPSequence)varBindList.getSNMPObjectAt(0)).getSNMPObjectAt(1).toString();
            airportNameField.setText(valueString);
            
            varBindList = communicationInterface.getMIBEntry("1.3.6.1.2.1.1.6.0");
            valueString = ((SNMPSequence)varBindList.getSNMPObjectAt(0)).getSNMPObjectAt(1).toString();
            airportLocationField.setText(valueString);
            
            
            // get WAN IP address (corresponding to interface 3)
            varBindList = communicationInterface.retrieveMIBTable("1.3.6.1.2.1.4.20.1");
            valueString = getInterfaceAddress(varBindList, 3);
            airportExternalIPField.setText(valueString);
            
            
            // now fetch portmap table
            SNMPVarBindList snmpPortMapInfo = communicationInterface.retrieveMIBTable(portMapBaseID);
            PortInfoTreeMap portInfoHashtable = new PortInfoTreeMap(snmpPortMapInfo);     
        
            //System.out.println("SNMP table:");
            //System.out.println(snmpPortMapInfo.toString());
            
            // now fetch arp info table, to get MAC addresses
            SNMPVarBindList snmpArpInfo = communicationInterface.retrieveMIBTable(arpInfoTableOID);
            ArpInfoTreeMap ArpInfoTreeMap = new ArpInfoTreeMap(snmpArpInfo);  
        portInfoHashtable.setMACAddresses(ArpInfoTreeMap);
            
            return portInfoHashtable;
      }
      
      
      
      
      public String getInterfaceAddress(SNMPVarBindList varBindList, int interfaceIndex)
      {
          class InterfaceInfo
          {
              String ipAddress;
              int interfaceIndex;
          }
          
          TreeMap interfaceInfoMap = new TreeMap();
          
          
          
          
          // make list of interface index / IP address pairs;
          // find entry corresponding to interface 2, and return its IP address
          if (varBindList.size() > 0)
        {
            int i = 0;
            SNMPSequence variablePair = (SNMPSequence)varBindList.getSNMPObjectAt(i);
            SNMPObjectIdentifier snmpOID = (SNMPObjectIdentifier)variablePair.getSNMPObjectAt(0);
            String oid = snmpOID.toString();
                
            String oidBase = "1.3.6.1.2.1.4.20.1.1";
            while(oid.startsWith(oidBase))
            {
                // get index
                String tableIndex = oid.substring(oidBase.length() + 1);
                    
                // add a new InterfaceInfo object to hashtable, hashed by index
                interfaceInfoMap.put(tableIndex, new InterfaceInfo());
                
                // this entry also gives IP address
                InterfaceInfo interfaceInfo = (InterfaceInfo)interfaceInfoMap.get(tableIndex);
                SNMPIPAddress ipAddress = (SNMPIPAddress)variablePair.getSNMPObjectAt(1);
                interfaceInfo.ipAddress = ipAddress.toString();
                i++;

                if (i >= varBindList.size())
                    break;
                
                variablePair = (SNMPSequence)varBindList.getSNMPObjectAt(i);
                snmpOID = (SNMPObjectIdentifier)variablePair.getSNMPObjectAt(0);
                oid = snmpOID.toString();
                
                
            }
            
            oidBase = "1.3.6.1.2.1.4.20.1.2";
            while(oid.startsWith(oidBase))
            {
                // get index
                String tableIndex = oid.substring(oidBase.length() + 1);
                    
                // modify PortInfo in hashtable
                InterfaceInfo interfaceInfo = (InterfaceInfo)interfaceInfoMap.get(tableIndex);
                SNMPInteger snmpInterfaceIndex = (SNMPInteger)variablePair.getSNMPObjectAt(1);
                interfaceInfo.interfaceIndex = ((BigInteger)snmpInterfaceIndex.getValue()).intValue();
                
                // see if have entry for desired interface index
                if (interfaceInfo.interfaceIndex == interfaceIndex)
                {
                    return interfaceInfo.ipAddress;
                }
                
                i++;

                if (i >= varBindList.size())
                    break;
                
                variablePair = (SNMPSequence)varBindList.getSNMPObjectAt(i);
                snmpOID = (SNMPObjectIdentifier)variablePair.getSNMPObjectAt(0);
                oid = snmpOID.toString();
            }
            
        }
        
        // if get here, didn't find it...
          return "";
      }
      
      
      
      
      private void refreshInfoDisplay(PortInfoTreeMap newInfo)
      {
            // update displayed info
            //messagesArea.append(newInfo.toString());
            portMapTable.setInfo(newInfo);
            
      }
      
      
      
      /*
      private String hexByte(byte b)
      {
            int pos = b;
            if (pos < 0)
                  pos += 256;
            String returnString = new String();
            returnString += Integer.toHexString(pos/16);
            returnString += Integer.toHexString(pos%16);
            return returnString;
      }
      
      
      
      private String printHexBytes(byte[] bytes)
      {
            String returnString = new String();
            
            for(int i = 0; i < bytes.length; i++)
            {
                  returnString += hexByte(bytes[i]) + " ";
                  
                  if (((i+1)%16) == 0)
                        returnString += "\n";
                        
            }
            
            return returnString;
            
      }
      
      
      private static boolean arraysEqual(byte[] a, byte[] b)
      {
            if (a.length != b.length)
            {
                  return false;
            }
            else
            {
                  for (int i = 0; i < a.length; i++)
                  {
                        if (a[i] != b[i])
                              return false;
                  }
            }
            
            return true;
      }
      
      
      
      private static byte[] maskBytes(byte[] inBytes, byte[] mask)
      {
            byte[] maskedBytes = new byte[inBytes.length];
            
            for (int i = 0; i < inBytes.length; i++)
            {
                  maskedBytes[i] = (byte)(inBytes[i] & mask[i % inBytes.length]);
            }
            
            return maskedBytes;
      }
      */
      
      
      
      private void invokeChangeListeners(PortInfoTreeMap oldInfo, PortInfoTreeMap newInfo)
      {
          // just call the processPortInfoChange method of each listener
          for (int i = 0; i < changeListeners.size(); i++)
          {
              ((PortInfoChangeListener)changeListeners.elementAt(i)).processPortInfoChange(oldInfo, newInfo);
          }
      }
      
      
      
      
      
      
      public void run()
      {
            
            
            while(!Thread.currentThread().isInterrupted())
            {
                
                try
                {
                // retrieve current info from base station
                  PortInfoTreeMap newInfo = getInfo();
                  
                  messagesArea.setText("Information retrieved " + (new Date()).toString() + ".\n");
                      
                  // now refresh display
                  refreshInfoDisplay(newInfo);
                  
                  // see if info has changed; if so, take action
                  invokeChangeListeners(currentInfo, newInfo);
                  
                  currentInfo = newInfo;
                  }
                  catch(IllegalArgumentException ex)
                  {
                        // thrown by PortInfoTreeMap constructor if no data retrieved
                        messagesArea.setText("Error retrieving information (check password)\n");
                  }
                  catch(SocketException e)
            {
                  messagesArea.setText("Error retrieving information: " + e + "\n");
            }
            catch(IOException e)
            {
                  messagesArea.setText("Error retrieving information: timed out waiting for response.\n");
            }
            catch (Exception e)
            {
                  messagesArea.setText("Error retrieving information: " + e.getMessage() + "\n");
            }
            
            
                  try
                  {
                        // sleep for inspection interval seconds
                        Thread.currentThread().sleep(1000 * preferences.queryInterval);
                  }
                  catch(InterruptedException e)
                  {
                        // don't bother informing of interruption
                        Thread.currentThread().interrupt();
                  }
                  
            
            }
            
            
      }
      
      
      
      private void saveSettings()
      {
          // save into file PortInspector.ini
          ObjectOutputStream outStream;
          
          try
          {
          outStream = new ObjectOutputStream(new FileOutputStream("PortInspector.ini"));
          outStream.writeObject(preferences);
          outStream.close();
          preferencesSaved = true;
          }
          catch (Exception e)
          {
              // oh well...
              messagesArea.setText("Couldn't write settings: " + e.toString());
              preferencesSaved = false;
          }
          
      }
      
      
      
      private void readSettings()
      {
          // read from file PortInspector.ini
          
          try
          {
              ObjectInputStream inStream = new ObjectInputStream(new FileInputStream("PortInspector.ini"));
              preferences = (Preferences)inStream.readObject();
              inStream.close();
              preferencesSaved = true;
          }
          catch (Exception e)
          {
              // couldn't read; just return empty settings
              //messagesArea.setText("Couldn't read settings: " + e.toString());
              preferences = new Preferences();
              preferencesSaved = false;
          }
          
      }
      
      
      
      public static void main(String args[]) 
      {
            try
            {
                  
                  PortInspector theApp = new PortInspector();
                  
            }
            catch (Exception e)
            {}
      }
      

}

Generated by  Doxygen 1.6.0   Back to index