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

IPInspector.java

/*
 * IPInspector
 *
 * Copyright (C) 2002, 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 airport.*;





public class IPInspector extends JFrame
                                          implements ActionListener, Runnable
{     
      
      
      JButton newPreferencesButton, discoverDevicesButton;
      JTextField airportInternalIPField;
      AirportInfoTextField airportExternalIPField, airportNameField, airportLocationField;
      JPanel hostPanel;
      
      MenuBar theMenubar;
      Menu fileMenu;
      MenuItem quitItem, aboutItem, savePreferencesItem;
      
      JTextArea messagesArea;
      JTextField statusArea;
      JTextAreaWriter messagesAreaWriter;
      
      Thread inspectionThread;
      
      IPInspectorAirportInfo airportInfo;

      Preferences preferences;
      boolean preferencesSaved = true;
      
      InetAddress airportInternalIPAddress;
      
      private Vector changeListeners;
      AirportInfoChangeEmailer changeEmailer;
      
      
      
      // WindowCloseAdapter to catch window close-box closings
      private class WindowCloseAdapter extends WindowAdapter
      { 
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
      }
            
            
      
      public IPInspector()
      {
                  
      airportInfo = new IPInspectorAirportInfo();
      changeListeners = new Vector();
      
      // create thread, but don't start it
      inspectionThread = new Thread(this);
                
      setUpDisplay();
      
      // create Writer interface into messages area for use by mailer thread
      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();
        
            // set up preferences
            // read any settings that have previously been saved
            readSettings();
            
            // put up dialog
            if (getPreferences() == false)
            {
                messagesArea.setText("Problem with supplied information; set options again");
            }
            
            
      }
      
      
      
      public void addChangeListener(AirportInfoChangeListener changeListener)
      {
          if (!changeListeners.contains(changeListener))
              changeListeners.add(changeListener);
      }
      
      
      
      public void removeChangeListener(AirportInfoChangeListener 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("AirPort IP 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 AirportInfoTextField((AirportInfoRecord)airportInfo.get("waIP"));
            airportExternalIPField.setEditable(false);
            
            JLabel airportNameLabel = new JLabel("Base station name:");
            airportNameField = new AirportInfoTextField((AirportInfoRecord)airportInfo.get("syNm"));
            airportNameField.setEditable(false);

            JLabel airportLocationLabel = new JLabel("Base station location:");
            airportLocationField = new AirportInfoTextField((AirportInfoRecord)airportInfo.get("syLo"));
            airportLocationField.setEditable(false);

            
            newPreferencesButton = new JButton("New settings");
            newPreferencesButton.setActionCommand("new preferences");
            newPreferencesButton.addActionListener(this);
            
            discoverDevicesButton = new JButton("Discover devices");
            discoverDevicesButton.setActionCommand("discover devices");
            discoverDevicesButton.addActionListener(this);
            
            
            
            
            
            // 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;
            
            
            JPanel buttonPanel = new JPanel();
            buttonPanel.setLayout(theLayout);
            
            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);
            
            
            
            hostPanel = new JPanel();
            hostPanel.setLayout(theLayout);
            
            c.gridx = 1;
            c.gridy = 1;
            theLayout.setConstraints(airportInternalIPLabel, c);
            hostPanel.add(airportInternalIPLabel);
            
            c.gridx = 2;
            c.gridy = 1;
            theLayout.setConstraints(airportInternalIPField, c);
            hostPanel.add(airportInternalIPField);
            
            c.gridx = 1;
            c.gridy = 2;
            theLayout.setConstraints(airportExternalIPLabel, c);
            hostPanel.add(airportExternalIPLabel);
            
            c.gridx = 2;
            c.gridy = 2;
            theLayout.setConstraints(airportExternalIPField, c);
            hostPanel.add(airportExternalIPField);
            
            c.gridx = 1;
            c.gridy = 3;
            theLayout.setConstraints(airportNameLabel, c);
            hostPanel.add(airportNameLabel);
            
            c.gridx = 2;
            c.gridy = 3;
            theLayout.setConstraints(airportNameField, c);
            hostPanel.add(airportNameField);
            
            c.gridx = 1;
            c.gridy = 4;
            theLayout.setConstraints(airportLocationLabel, c);
            hostPanel.add(airportLocationLabel);
            
            c.gridx = 2;
            c.gridy = 4;
            theLayout.setConstraints(airportLocationField, c);
            hostPanel.add(airportLocationField);
            
            
            
            JPanel messagesPanel = new JPanel();
            messagesPanel.setLayout(theLayout);
            
            statusArea = new JTextField(50);
            messagesArea = new JTextArea(6,50);
            JScrollPane messagesScroll = new JScrollPane(messagesArea);
            
            c.gridx = 1;
            c.gridy = 1;
            JLabel messagesLabel = new JLabel("Messages:");
            theLayout.setConstraints(messagesLabel, c);
            messagesPanel.add(messagesLabel);
            
            c.gridx = 1;
            c.gridy = 2;
            theLayout.setConstraints(statusArea, c);
            messagesPanel.add(statusArea);
            
            c.gridx = 1;
            c.gridy = 3;
            theLayout.setConstraints(messagesScroll, c);
            messagesPanel.add(messagesScroll);
            
            
            
            
            this.getContentPane().setLayout(theLayout);
            
            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.gridx = 1;
            c.gridy = 4;
            theLayout.setConstraints(messagesPanel, c);
            this.getContentPane().add(messagesPanel);
            
            c.gridx = 1;
            c.gridy = 5;
            JLabel authorLabel = new JLabel(" Version 1.0        J. Sevy, February 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 == "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;
                    
                airportInternalIPAddress = InetAddress.getByName(newPreferences.ipAddress);
                  airportInternalIPField.setText(newPreferences.ipAddress);
                  
                  // 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 IPInspectorAirportInfo getInfo()
      {
          
          try
            {
                  
                  IPInspectorAirportInfo newInfo;
          
              byte[] requestPayload = airportInfo.getRequestBytes();
                  
                  Airport2ProtocolMessage requestMessage = new Airport2ProtocolMessage(Airport2ProtocolMessage.READ, preferences.password, requestPayload, requestPayload.length);
                  
                  // open socket
                  int port = 5009;
                  
                  Socket configSocket = new Socket(airportInternalIPAddress, port);
                  
                  // set socket timeout to 5 seconds
                  configSocket.setSoTimeout(5000);
                        
                  DataInputStream inputStream = new DataInputStream(configSocket.getInputStream());
                  
                  OutputStream outputStream = configSocket.getOutputStream();
                  
                  outputStream.write(requestMessage.getBytes());
                  
                  
                  /*
                  System.out.println("Request header bytes:");
                  System.out.println(printHexBytes(requestMessage.getBytes()));
                  */
                  
                  outputStream.write(requestPayload);
                  
                  
                  // get and process response
                  byte[] responseHeader = new byte[128];
                  
                  inputStream.readFully(responseHeader);
                  //int numBytes = inputStream.read(responseHeader);
                  
                  // create temp buffer to hold retrieved config; 4k should suffice...
                  byte[] responsePayload = new byte[4096];
                  
                  // read info
                  
                  try
                  {
                        inputStream.readFully(responsePayload);
                  }
                  catch (EOFException e)
                  {
                        // this is expected; we _should_ reach the end of the stream before filling the buffer
                  }
                  
                  
                  
                  /*
                  numBytes = 0;
                  int newNumBytes = 0;
                  while(  ((newNumBytes = inputStream.read(responsePayload, numBytes, responsePayload.length - numBytes)) >= 0 )
                              &&
                              (numBytes < responsePayload.length)
                         )
                  {
                        System.out.println("Read " + newNumBytes + " bytes.");
                        numBytes += newNumBytes;
                  }
                  */
                  
                  
                  //System.out.println("done.");
                  //System.out.println("Read " + numBytes + " bytes total.");
                  
                  inputStream.close();
                  outputStream.close();
                  
                  configSocket.close();
                  
                  
                  // check to see if we retrieved valid data from the base station
                  try
                  {
                        statusArea.setText("Information retrieved (" + (new Date()).toString() + ").");
                      
                      return new IPInspectorAirportInfo(responsePayload);     
                
                  }
                  catch(IllegalArgumentException ex)
                  {
                        // thrown by AirportInfo constructor if no data retrieved
                        statusArea.setText("Error retrieving information (check password)");
                  }
                  
            }
            catch(SocketException e)
            {
                  statusArea.setText("Error retrieving information: " + e + ".");
            }
            catch(IOException e)
            {
                  statusArea.setText("Error retrieving information: timed out waiting for response.");
            }
            catch (Exception e)
            {
                  statusArea.setText("Error retrieving information: " + e.getMessage() + ".");
            }
            
            // if get here, didn't get valid stuff; return a blank structure
            return new IPInspectorAirportInfo();
            
      }
      
      
      
      
      private void refreshInfoDisplay(IPInspectorAirportInfo newInfo)
      {
            // update displayed info
            airportExternalIPField.setAirportInfoRecord(newInfo.get("waIP"));
            airportNameField.setAirportInfoRecord(newInfo.get("syNm"));
            airportLocationField.setAirportInfoRecord(newInfo.get("syLo"));
            
      }
      
      
      
      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(IPInspectorAirportInfo oldInfo, IPInspectorAirportInfo newInfo)
      {
          // just call the processInfoChange method of each listener
          for (int i = 0; i < changeListeners.size(); i++)
          {
              ((AirportInfoChangeListener)changeListeners.elementAt(i)).processInfoChange(oldInfo, newInfo);
          }
      }
      
      
      
      public void run()
      {
            
            IPInspectorAirportInfo newInfo;
            
            while(!Thread.currentThread().isInterrupted())
            {
                
                // retrieve current info from base station
                  newInfo = getInfo();
                  
                  // now refresh display
                  refreshInfoDisplay(newInfo);
                  
                  // see if info has changed; if so, take action
                  if (!newInfo.get("waIP").toString().equals(airportInfo.get("waIP").toString()))
                  {
                      invokeChangeListeners(airportInfo, newInfo);
                  }
                  
                  airportInfo = newInfo;
                  
                  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 IpInspector.ini
          ObjectOutputStream outStream;
          
          try
          {
          outStream = new ObjectOutputStream(new FileOutputStream("IPInspector.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 IpInspector.ini
          
          try
          {
              ObjectInputStream inStream = new ObjectInputStream(new FileInputStream("IPInspector.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
            {
                  
                  IPInspector theApp = new IPInspector();
                  
            }
            catch (Exception e)
            {}
      }
      

}

Generated by  Doxygen 1.6.0   Back to index