airportconfig-1.5.2/0000755000175000017500000000000007521635727013741 5ustar julienjulienairportconfig-1.5.2/AUTHORS0000444000175000017500000000041407503646614015003 0ustar julienjulienAirportBaseStationConfigurator http://gicl.mcs.drexel.edu/sevy/airport Jon Sevy Geometric and Intelligent Computing Laboratory Department of Mathematics and Computer Science Drexel University http://gicl.mcs.drexel.edu/sevy airportconfig-1.5.2/AirportBaseStationConfigurator.java0000644000175000017500000011104207503646614022740 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 byteblock.*; import snmp.*; import airport.*; public class AirportBaseStationConfigurator extends JFrame implements ActionListener { public static final String encryptionKeySizeString = "05"; public static final int encryptionKeySize = 5; public static final String aboutString = "Airport Base Station Configurator "; JButton discoverDevicesButton, retrieveItemButton, updateBaseStationButton; JTextField hostIDField; JTextField communityField; GridBagLayout mainLayout = new GridBagLayout(); MenuBar theMenubar; Menu fileMenu; MenuItem quitItem, openItem, saveItem, aboutItem, uploadFirmwareItem; private final int baseBlockSize = 68*16*16; private ByteBlock baseBlock = new ByteBlock(68*16, 16); private final int configurationSize = 17336; // total number of significant bytes, including checksum AirportInfo airportInfo; AirportInfoTabbedPane infoPane; JTextArea messagesArea; SNMPv1CommunicationInterface comInterface; SNMPVarBindList retrievedVars; // WindowCloseAdapter to catch window close-box closings private class WindowCloseAdapter extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } }; public AirportBaseStationConfigurator() { airportInfo = new AirportInfo(baseBlock); setUpDisplay(); retrievedVars = new SNMPVarBindList(); } 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 // thanks to Jer for this one! addWindowListener(new WindowCloseAdapter()); this.setTitle("AirPort Base Station Configurator"); this.getRootPane().setBorder(new BevelBorder(BevelBorder.RAISED)); theMenubar = new MenuBar(); this.setMenuBar(theMenubar); fileMenu = new Menu("File"); openItem = new MenuItem("Open saved settings..."); openItem.setShortcut(new MenuShortcut('o')); openItem.setActionCommand("open settings"); openItem.addActionListener(this); fileMenu.add(openItem); saveItem = new MenuItem("Save settings..."); saveItem.setShortcut(new MenuShortcut('s')); saveItem.setActionCommand("save settings"); saveItem.addActionListener(this); fileMenu.add(saveItem); fileMenu.addSeparator(); uploadFirmwareItem = new MenuItem("Upload new base station firmware..."); uploadFirmwareItem.setActionCommand("upload firmware"); uploadFirmwareItem.addActionListener(this); fileMenu.add(uploadFirmwareItem); fileMenu.addSeparator(); aboutItem = new MenuItem("About..."); aboutItem.setActionCommand("about"); aboutItem.addActionListener(this); fileMenu.add(aboutItem); quitItem = new MenuItem("Quit"); quitItem.setShortcut(new MenuShortcut('q')); quitItem.setActionCommand("quit"); quitItem.addActionListener(this); fileMenu.add(quitItem); theMenubar.add(fileMenu); JLabel hostIDLabel = new JLabel("Device address:"); hostIDField = new JTextField(10); hostIDField.setText("10.0.1.1"); JLabel communityLabel = new JLabel("Community name (password):"); communityField = new JPasswordField(10); //communityField = new JTextField(10); //communityField.setText("public"); discoverDevicesButton = new JButton("Discover Devices"); discoverDevicesButton.setActionCommand("discover devices"); discoverDevicesButton.addActionListener(this); retrieveItemButton = new JButton("Retrieve Settings"); retrieveItemButton.setActionCommand("retrieve data"); retrieveItemButton.addActionListener(this); updateBaseStationButton = new JButton("Update Base Station"); updateBaseStationButton.setActionCommand("update base station"); updateBaseStationButton.addActionListener(this); updateBaseStationButton.setEnabled(false); //initially disabled until read in or open settings // 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(discoverDevicesButton, c); buttonPanel.add(discoverDevicesButton); c.gridx = 2; c.gridy = 1; theLayout.setConstraints(retrieveItemButton, c); buttonPanel.add(retrieveItemButton); c.gridx = 3; c.gridy = 1; theLayout.setConstraints(updateBaseStationButton, c); buttonPanel.add(updateBaseStationButton); JPanel hostPanel = new JPanel(); hostPanel.setLayout(theLayout); c.gridx = 1; c.gridy = 1; theLayout.setConstraints(hostIDLabel, c); hostPanel.add(hostIDLabel); c.gridx = 2; c.gridy = 1; theLayout.setConstraints(hostIDField, c); hostPanel.add(hostIDField); c.gridx = 3; c.gridy = 1; theLayout.setConstraints(communityLabel, c); hostPanel.add(communityLabel); c.gridx = 4; c.gridy = 1; theLayout.setConstraints(communityField, c); hostPanel.add(communityField); infoPane = new AirportInfoTabbedPane(airportInfo); JPanel messagesPanel = new JPanel(); messagesPanel.setLayout(theLayout); messagesArea = new JTextArea(4,60); 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(messagesScroll, c); messagesPanel.add(messagesScroll); this.getContentPane().setLayout(mainLayout); c.gridx = 1; c.gridy = 1; mainLayout.setConstraints(hostPanel, c); this.getContentPane().add(hostPanel); c.gridx = 1; c.gridy = 2; mainLayout.setConstraints(buttonPanel, c); this.getContentPane().add(buttonPanel); c.gridx = 1; c.gridy = 3; mainLayout.setConstraints(infoPane, c); this.getContentPane().add(infoPane); c.gridx = 1; c.gridy = 4; mainLayout.setConstraints(messagesPanel, c); this.getContentPane().add(messagesPanel); c.gridx = 1; c.gridy = 5; JLabel authorLabel = new JLabel(" Version 1.5.2 J. Sevy, November 2001 "); authorLabel.setFont(new Font("SansSerif", Font.ITALIC, 8)); mainLayout.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")) { System.exit(0); } if (command == "about") { AboutDialog aboutDialog = new AboutDialog(this); } if (command.equals("discover devices")) { AirportDiscoverer discoverer = new AirportDiscoverer(); } if (command.equals("retrieve data")) { try { if (comInterface != null) comInterface.closeConnection(); String community = communityField.getText(); InetAddress hostAddress = InetAddress.getByName(hostIDField.getText()); int version = 0; // SNMPv1 messagesArea.append("Retrieving settings from base station " + hostAddress + "......\n"); comInterface = new SNMPv1CommunicationInterface(version, hostAddress, community); for (int k = 1; k <= 68; k++) { String itemID = "1.3.6.1.4.1.762.2.2.1.1." + k; SNMPVarBindList newVars = comInterface.getMIBEntry(itemID); SNMPSequence pair = (SNMPSequence)(newVars.getSNMPObjectAt(0)); SNMPOctetString value = (SNMPOctetString)(pair.getSNMPObjectAt(1)); // get the 256 bytes byte[] bytes = (byte[])value.getValue(); // create a window to write bytes into int startIndex = (k-1)*256; int rows = 16; int cols = 16; ByteBlockRectangularWindow currentBlock = new ByteBlockRectangularWindow(startIndex, rows, cols, baseBlock); // write the bytes currentBlock.writeBytes(bytes); } // would like to check checksum to make sure retrieved block is valid, at least... // however, base station doesn't return valid checksum when data retrieved - // it's just a partial echo of the last checksum sent to it :-( messagesArea.append("Settings retrieved.\n"); // now refresh display this.refreshInfoPane(); // enable updating updateBaseStationButton.setEnabled(true); } catch(UnknownHostException e) { messagesArea.append("Error retrieving settings: unknown host.\n"); } catch(SocketException e) { messagesArea.append("Error retrieving settings: " + e + "\n"); } catch(IOException e) { messagesArea.append("Error retrieving settings: timed out waiting for response.\n"); } catch (SNMPBadValueException e) { // will never occur! messagesArea.append("Error retrieving settings: bad SNMP value received.\n"); } catch (SNMPGetException e) { messagesArea.append("Error retrieving settings: incorrect community name (password).\n"); } catch (Exception e) { messagesArea.append("Error retrieving settings: " + e.getMessage() + "\n"); } } if (command.equals("save settings")) { try { infoPane.writeData(); setDependentData(); setStaticData(); setChecksum(baseBlock, configurationSize - 2); FileDialog fd = new FileDialog(this, "Save current settings as...", FileDialog.SAVE); fd.show(); if (fd.getFile() != null) { File newFile = new File(fd.getDirectory(), fd.getFile()); FileOutputStream fStream = new FileOutputStream(newFile); fStream.write(baseBlock.bytes, 0, configurationSize); fStream.flush(); fStream.close(); } } catch (ValueFormatException ve) { messagesArea.append("Problem with supplied value: " + ve.getMessage() + "\n"); } catch (Exception e) { messagesArea.append("Error saving settings: " + e.getMessage() + "\n"); } } if (command.equals("update base station")) { try { infoPane.writeData(); setDependentData(); setStaticData(); setChecksum(baseBlock, configurationSize - 2); // second checksum set in transmitBlocks() // configurationSize = 17336 indicates number of bytes to burn to prom: // includes first checksum (but not second, which is "transmission" // checksum - added by transmitBlocks method) transmitBlocks(baseBlock, configurationSize); } catch (ValueFormatException ve) { messagesArea.append("Problem with supplied value: " + ve.getMessage() + "\n"); } } if (command.equals("open settings")) { try { FileDialog fd = new FileDialog(this, "Open settings file...", FileDialog.LOAD); fd.show(); if (fd.getFile() != null) { File newFile = new File(fd.getDirectory(), fd.getFile()); FileInputStream fStream = new FileInputStream(newFile); byte[] newBytes = new byte[17408]; fStream.read(newBytes); fStream.close(); // check checksum to make sure block is valid, at least... // save current bytes in case new ones invalid byte[] currentBytes = baseBlock.bytes; baseBlock.bytes = newBytes; // see if shift key held down while open selected; if so, don't check checksum boolean shiftKeyDown = ((theEvent.getModifiers() & ActionEvent.SHIFT_MASK) > 0); // make sure checksum is valid, to verify this is a valid settings file // first make sure file big enough to even check checksum! if ( (newFile.length() < configurationSize) || (!shiftKeyDown && !checksumValid()) ) { // reset base block to current bytes baseBlock.bytes = currentBytes; throw new Exception("invalid settings file."); } // now refresh display of data this.refreshInfoPane(); // enable updating updateBaseStationButton.setEnabled(true); } } catch (Exception e) { messagesArea.append("Error opening settings: " + e.getMessage() + "\n"); } } if (command.equals("upload firmware")) { try { FileDialog fd = new FileDialog(this, "Select firmware file...", FileDialog.LOAD); fd.show(); if (fd.getFile() != null) { File firmwareFile = new File(fd.getDirectory(), fd.getFile()); FileInputStream fStream = new FileInputStream(firmwareFile); int fileLength = (int)firmwareFile.length(); // determine number of 256-byte blocks that need to be sent int numBlocks = (int)Math.ceil((double)fileLength/256); // create underlying ByteBlock with appropriate number of sub-blocks ByteBlock firmwareBlock = new ByteBlock(numBlocks*16, 16); fStream.read(firmwareBlock.bytes); fStream.close(); // verify this is a valid firmware file; can unfortunately only verify the embedded // configuration checksum.... AND apparently the Apple-supplied formware files computed the // checksum before the community name default passwords (4 "public" and one count of 06) // were inserted. Thus the checksum computation differs by 0xA02 for these files, // so the checksum check is a little weird.... // see if shift key held down while open selected; if so, don't validate file boolean shiftKeyDown = ((theEvent.getModifiers() & ActionEvent.SHIFT_MASK) > 0); if (!shiftKeyDown) { // first make sure file big enough to even check checksum! if (fileLength < configurationSize) { throw new Exception("invalid firmware file."); } else if ( (!appleFirmwareChecksumValid(firmwareBlock)) && (!checksumValid(firmwareBlock)) ) { throw new Exception("invalid firmware file."); } } // put up a dialog permitting the user to select uploading the current settings, if // they're valid... String messageString = "Upload firmware to base station " + hostIDField.getText() + "?"; String response = new String("Cancel"); // see if current settings are valid; if so, these become upload option if (updateBaseStationButton.isEnabled()) { String[] possibleValues = { "Upload firmware with current settings", "Upload firmware with default settings", "Cancel" }; int selectedValue = JOptionPane.showOptionDialog(null, messageString, "Firmware Upload", JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, null, possibleValues, possibleValues[0]); if ( !(selectedValue == JOptionPane.CLOSED_OPTION) ) response = possibleValues[selectedValue]; } else { String[] possibleValues = { "Upload firmware with default settings", "Cancel" }; int selectedValue = JOptionPane.showOptionDialog(null, messageString, "Firmware Upload", JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, null, possibleValues, possibleValues[0]); if ( !(selectedValue == JOptionPane.CLOSED_OPTION) ) response = possibleValues[selectedValue]; } // if current settings selected, upload these to base station with firmware; // if not, leave default settings alone in firmware bytes if (response.equals("Upload firmware with current settings")) { // note that current settings could throw ValueFormatException! infoPane.writeData(); setDependentData(); setStaticData(); setCommunityNames(); // so base station will know what to use after reset!! setChecksum(baseBlock, configurationSize - 2); // copy current setting bytes into firmware bytes for (int i = 0; i < configurationSize; i++) firmwareBlock.bytes[i] = baseBlock.bytes[i]; // now transmit info transmitBlocks(firmwareBlock, fileLength); } else if (response.equals("Upload firmware with default settings")) { // just transmit firmware info with default settings transmitBlocks(firmwareBlock, fileLength); } } } catch (ValueFormatException ve) { messagesArea.append("Problem with supplied value: " + ve.getMessage() + "\n"); } catch (Exception e) { messagesArea.append("Error updating firmware: " + e.getMessage() + "\n"); } } } 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 void refreshInfoPane() { // first, remove current infoPane this.remove(infoPane); //now create new tabbed pane to hold info infoPane = new AirportInfoTabbedPane(airportInfo); // set params for layout manager 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; // then add pane to frame c.gridx = 1; c.gridy = 3; mainLayout.setConstraints(infoPane, c); this.getContentPane().add(infoPane); // call validate to update display this.validate(); } private void setDependentData() throws ValueFormatException { /* * Write values for DHCP/NAT-delivered base station IP address, router * IP address, mask; do here since requires "cross-reference" between data * in separate panels. */ boolean ethernetConnection = false, modemConnection = false; // flags specifying base station connection and boolean dhcpConfig = false, manualConfig = false; // configuration style boolean natEnabled = false, dhcpEnabled = false; // flags indicating address delivery services of base station boolean portMappingEnabled = false; // set flags for Ethernet/Modem mode AirportInfoRecord ethernetModemSwitch1Record = airportInfo.get("Ethernet/Modem switch 1"); String ethernetModemSwitch1Setting = ethernetModemSwitch1Record.toString(); AirportInfoRecord ethernetModemSwitch2Record = airportInfo.get("Configuration interface"); String ethernetModemSwitch2Setting = ethernetModemSwitch2Record.toString(); if (ethernetModemSwitch1Setting.equals("60") || ethernetModemSwitch2Setting.equals("00")) ethernetConnection = true; if (ethernetModemSwitch1Setting.equals("62") || ethernetModemSwitch2Setting.equals("03")) modemConnection = true; //set flags for base station configuration mode AirportInfoRecord baseConfigModeRecord = airportInfo.get("Base station configuration mode switch"); String baseConfigModeSetting = baseConfigModeRecord.toString(); if (baseConfigModeSetting.equals("00")) manualConfig = true; if (baseConfigModeSetting.equals("20")) dhcpConfig = true; // set flags for NAT/DHCP mode AirportInfoRecord dhcpSwitchRecord = airportInfo.get("DHCP switch"); String dhcpSetting = dhcpSwitchRecord.toString(); if (dhcpSetting.equals("80")) dhcpEnabled = true; AirportInfoRecord natSwitchRecord = airportInfo.get("NAT switch"); String natSetting = natSwitchRecord.toString(); if (natSetting.equals("02")) natEnabled = true; // set flag for port mapping AirportInfoRecord portMappingSwitchRecord = airportInfo.get("Port mapping switch"); String portMappingSwitchSetting = portMappingSwitchRecord.toString(); if (portMappingSwitchSetting.equals("04")) portMappingEnabled = true; // get records for setting dependent data AirportInfoRecord natInboundPrivateIPAddressRecord = airportInfo.get("NAT inbound private IP address"); AirportInfoRecord natInboundPrivateSubnetMaskRecord = airportInfo.get("NAT inbound private subnet mask"); AirportInfoRecord natOutboundPrivateIPAddressRecord = airportInfo.get("NAT outbound private IP address"); AirportInfoRecord natOutboundPrivateSubnetMaskRecord = airportInfo.get("NAT outbound private subnet mask"); AirportInfoRecord natOutboundPublicIPAddressRecord = airportInfo.get("NAT outbound public IP address"); AirportInfoRecord natOutboundPublicSubnetMaskRecord = airportInfo.get("NAT outbound public subnet mask"); AirportInfoRecord dhcpServerRouterIPAddressRecord = airportInfo.get("DHCP server router address"); AirportInfoRecord dhcpServerSubnetMaskRecord = airportInfo.get("DHCP server subnet mask"); AirportInfoRecord baseStationIPAddressRecord = airportInfo.get("Base station IP address"); AirportInfoRecord subnetMaskRecord = airportInfo.get("Subnet mask"); AirportInfoRecord routerIPAddressRecord = airportInfo.get("Router IP address"); // when NAT enabled, set data that depends on settings from other panels if (natEnabled) { // set NAT outbound IP address and mask if (modemConnection) { natOutboundPublicIPAddressRecord.setBytesFromString("0.0.0.0"); natOutboundPublicSubnetMaskRecord.setBytesFromString("255.255.255.0"); } if (ethernetConnection) { natOutboundPublicIPAddressRecord.setBytesFromString(baseStationIPAddressRecord.toString()); natOutboundPublicSubnetMaskRecord.setBytesFromString(subnetMaskRecord.toString()); /* if (manualConfig) { natOutboundPublicIPAddressRecord.setBytesFromString(baseStationIPAddressRecord.toString()); natOutboundPublicSubnetMaskRecord.setBytesFromString(subnetMaskRecord.toString()); } else if (dhcpConfig) { natOutboundPublicIPAddressRecord.setBytesFromString("0.0.0.0"); natOutboundPublicSubnetMaskRecord.setBytesFromString("255.255.255.0"); } */ } } // if serving DHCP, set router and subnet mask if (dhcpEnabled) { if (natEnabled) { // use private network parameters dhcpServerRouterIPAddressRecord.setBytesFromString(natInboundPrivateIPAddressRecord.toString()); dhcpServerSubnetMaskRecord.setBytesFromString(natInboundPrivateSubnetMaskRecord.toString()); } else { // use global base station parameters dhcpServerRouterIPAddressRecord.setBytesFromString(routerIPAddressRecord.toString()); dhcpServerSubnetMaskRecord.setBytesFromString(subnetMaskRecord.toString()); } } // if port mapping, and using manual Ethernet config, need to put in base station IP address // as the public IP address in the port maps if (portMappingEnabled && ethernetConnection && manualConfig) { // get count of port maps AirportInfoRecord portMappingCountRecord = airportInfo.get("Count of port mappings"); int portMapCount = Integer.parseInt(portMappingCountRecord.toString()); // get starting indices and other parameters for the byte block multi-windows // that will hold the public IP address for port mapping, which is just the // manually configured base station IP address int publicIPStartIndex = 0xD72; int publicIPBeginningNumRows = 1; int publicIPBeginningNumCols = 2; int publicIPEndingIndex = 0xD9A; int publicIPEndingNumRows = 1; int publicIPEndingNumCols = 2; int publicIPDataType = AirportInfoRecord.IP_ADDRESS; //set the public IP address for each port map for (int i = 0; i < portMapCount; i++) { // need to use a multi-window, since the first two and last two octets are separated ByteBlockMultiWindow publicIPWindow = new ByteBlockMultiWindow(); ByteBlockWindow publicIPBeginningWindow = new ByteBlockRectangularWindow(publicIPStartIndex, publicIPBeginningNumRows, publicIPBeginningNumCols, baseBlock); publicIPWindow.addWindow(publicIPBeginningWindow); ByteBlockWindow publicIPEndingWindow = new ByteBlockRectangularWindow(publicIPEndingIndex, publicIPEndingNumRows, publicIPEndingNumCols, baseBlock); publicIPWindow.addWindow(publicIPEndingWindow); AirportInfoRecord publicIPRecord = new AirportInfoRecord(publicIPDataType, publicIPWindow); publicIPRecord.setBytesFromString(baseStationIPAddressRecord.toString()); // augment addresses publicIPStartIndex += 2; publicIPEndingIndex += 2; } } } private void setStaticData() throws ValueFormatException { // set read community password field AirportInfoRecord readCommunityRecord = airportInfo.get("Read community"); readCommunityRecord.setBytesFromString("public"); /* // set miscellaneous switches that are sometimes zero in "plain vanilla" config files String miscellaneousSetting; AirportInfoRecord miscellaneousRecord1 = airportInfo.get("Miscellaneous switch 1"); miscellaneousSetting = miscellaneousRecord1.toString(); if (miscellaneousSetting.equals("00")) miscellaneousRecord1.setBytesFromString("01"); AirportInfoRecord miscellaneousRecord2 = airportInfo.get("Miscellaneous switch 2"); miscellaneousSetting = miscellaneousRecord2.toString(); if (miscellaneousSetting.equals("00")) miscellaneousRecord2.setBytesFromString("01"); */ } private void setCommunityNames() throws ValueFormatException { // Set community name into password field so base station will know what to use after reboot! // Find out if there's an entry in the main panel; if so, use this, otherwise use // current community name field AirportInfoRecord communityNameRecord = airportInfo.get("Read/write community"); String communityName = communityNameRecord.toString(); if (communityName.equals("")) communityName = communityField.getText(); communityNameRecord.setBytesFromString(communityName); //System.out.println("Community name: " + communityName); // set trap community password field AirportInfoRecord trapCommunityRecord = airportInfo.get("Trap community"); trapCommunityRecord.setBytesFromString("public"); // set remaining community password field (and count field) AirportInfoRecord remainingCommunityCountRecord = airportInfo.get("Remaining community count"); remainingCommunityCountRecord.setBytesFromString("06"); AirportInfoRecord remainingCommunityRecord = airportInfo.get("Remaining community"); remainingCommunityRecord.setBytesFromString("public"); } private void transmitBlocks(ByteBlock byteBlock, int numBytes) { try { String community = communityField.getText(); InetAddress hostAddress = InetAddress.getByName(hostIDField.getText()); messagesArea.append("Sending data to base station " + hostAddress + "......\n"); if (comInterface == null) { int version = 0; // SNMPv1 comInterface = new SNMPv1CommunicationInterface(version, hostAddress, community); } comInterface.requestID = 1; byte[] bytes = byteBlock.bytes; // determine number of 256-byte blocks that need to be sent int numBlocks = (int)Math.ceil((double)(numBytes + 2)/256); // +2 leaves room for transmission checksum // send all but last block for (int k = 1; k < numBlocks; k++) { String itemID = "1.3.6.1.4.1.762.2.3.1.1." + k; // create new 256 byte array byte[] newBytes = new byte[256]; // copy block of 256 bytes from given bytes to new array for (int j = 0; j < 256; j++) { newBytes[j] = bytes[256*(k-1) + j]; } // create SNMP octet string from these bytes SNMPOctetString theObject = new SNMPOctetString(newBytes); // send the bytes SNMPVarBindList newVars = comInterface.setMIBEntry(itemID, theObject); } // now send last block String itemID = "1.3.6.1.4.1.762.2.3.1.1." + numBlocks; // create new 256 byte array byte[] newBytes = new byte[256]; // copy remaining bytes from given bytes to new array int endPosition = numBytes - (numBlocks-1)*256; for (int j = 0; j < endPosition; j++) { newBytes[j] = bytes[256*(numBlocks-1) + j]; } // now set transmission checksum as 2 bytes following last (legitimate) bytes; // note that number of blocks was chosen to be (numBytes+2)/256, ensuring room ByteBlock lastBlock = new ByteBlock(16, 16, newBytes); short checksum = computeChecksum(byteBlock.bytes, numBytes); setChecksum(checksum, lastBlock, endPosition); // create SNMP octet string from these bytes SNMPOctetString theObject = new SNMPOctetString(lastBlock.bytes); // send the bytes SNMPVarBindList newVars = comInterface.setMIBEntry(itemID, theObject); // now send reset signal: indicates number of bytes to burn to prom. // also indicates location of checksum SNMPInteger numBytesWritten = new SNMPInteger(numBytes); //System.out.println("Number of bytes to burn in: " + numBytesWritten); itemID = "1.3.6.1.4.1.762.2.1.2.0"; newVars = comInterface.setMIBEntry(itemID, numBytesWritten); itemID = "1.3.6.1.4.1.762.2.1.3.0"; newVars = comInterface.setMIBEntry(itemID, numBytesWritten); messagesArea.append("Data transmitted; base station restarting.\n"); } catch(UnknownHostException e) { messagesArea.append("Error transmitting data: unknown host.\n"); } catch(SocketException e) { messagesArea.append("Error transmitting data: " + e.getMessage() + "\n"); } catch(IOException e) { messagesArea.append("Error transmitting data: timed out waiting for response.\n"); } catch (SNMPSetException e) { messagesArea.append("Error transmitting data: " + e.getMessage() + "\n"); } catch (SNMPBadValueException e) { // will never occur! messagesArea.append("Error transmitting data: bad SNMP value.\n"); } } /* * Compute the 2-byte checksum for the bytes up to (but not including) the indicated position */ private short computeChecksum(byte[] bytes, int position) { short sum = 0; for (int i = 0; i < position; i++) { sum += bytes[i]; if(bytes[i] < 0) sum += 256; } return sum; } private void setChecksum(short sum, ByteBlock byteBlock, int position) { String checksumString = littleEndianHexString(sum); // create info record to write into int numRows = 1; int numCols = 2; int baseStartIndex = position; ByteBlockWindow checksumWindow = new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, byteBlock); int dataType = AirportInfoRecord.BYTE_STRING; AirportInfoRecord checksumRecord = new AirportInfoRecord(dataType, checksumWindow); checksumRecord.byteBlockWindow.clearBytes(); // write in new checksum try { checksumRecord.setBytesFromString(checksumString); } catch (ValueFormatException ve) { // won't occur! messagesArea.append("Problem writing checksum with value " + checksumString + ".\n"); } } /* * Convenience method for writing checksum value into same block it's computed from. This * is the usual case for config files; however, the more general routine is used to set * the transmission checksum immediately following the transmitted data bytes. */ private void setChecksum(ByteBlock byteBlock, int position) { short sum = computeChecksum(byteBlock.bytes, position); setChecksum(sum, byteBlock, position); } /** * Return little-endian hex string */ private String littleEndianHexString(short value) { int intValue = value; intValue = intValue & 0xFFFF; int switched = ((intValue << 8) | (intValue >>> 8)) & 0xFFFF; String returnString = Integer.toHexString(switched); // add leading zeros if needed while (returnString.length() < 4) returnString = "0" + returnString; return returnString; } /** * Used to validate checksum in stored settings, to ensure file is legitimate! Verify just * first checksum, for compatibility with Apple configurator's stored settings. */ private boolean checksumValid(ByteBlock byteBlock) { short sum = computeChecksum(byteBlock.bytes, configurationSize - 2); String computedChecksumString = littleEndianHexString(sum); //System.out.println("Computed checksum: " + computedChecksumString); // get configuration checksum from block int baseStartIndex = 0x43B6; int numRows = 1; int numCols = 2; int dataType = AirportInfoRecord.BYTE_STRING; AirportInfoRecord checksumRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, byteBlock); String existingChecksumString = checksumRecord.toString(); //System.out.println("Existing checksum: " + existingChecksumString); if (computedChecksumString.equals(existingChecksumString)) return true; else return false; } private boolean checksumValid() { return checksumValid(baseBlock); } // Apparently the Apple-supplied firmware files computed the // checksum before the community name default passwords (4 "public" and one count of 06) // were inserted. Thus the checksum computation should differ by 0xA02 for these files. // Thus the need for this "hacked" checksum validation.... private boolean appleFirmwareChecksumValid(ByteBlock byteBlock) { short sum = computeChecksum(byteBlock.bytes, configurationSize - 2); sum -= 0xA02; String computedChecksumString = littleEndianHexString(sum); //System.out.println("Computed checksum: " + computedChecksumString); // get configuration checksum from block int baseStartIndex = 0x43B6; int numRows = 1; int numCols = 2; int dataType = AirportInfoRecord.BYTE_STRING; AirportInfoRecord checksumRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, byteBlock); String existingChecksumString = checksumRecord.toString(); //System.out.println("Existing checksum: " + existingChecksumString); if (computedChecksumString.equals(existingChecksumString)) return true; else return false; } public static void main(String args[]) { try { AirportBaseStationConfigurator theApp = new AirportBaseStationConfigurator(); theApp.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 = theApp.getSize(); dim.height += 20; dim.width += 20; theApp.setSize(dim); theApp.show(); } catch (Exception e) {} } }airportconfig-1.5.2/COPYING0000444000175000017500000004363107503646614014776 0ustar julienjulien GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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 Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. airportconfig-1.5.2/airport/0000755000175000017500000000000007521635741015415 5ustar julienjulienairportconfig-1.5.2/airport/AirportAccessControlTable.java0000644000175000017500000002334407503646614023342 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; import byteblock.*; /** * Handles display and updating of MAC addresses and host names used for access control on the * wireless LAN. */ public class AirportAccessControlTable extends AirportInfoPanel { private AirportInfo airportInfo; private Vector addressVector; private JTable table; private AbstractTableModel tableModel; /** * Table model which maintains list of MAC addresses and host names. */ private class AccessAddressTableModel extends AbstractTableModel { public int getColumnCount() { return 2; } public int getRowCount() { return AirportInfo.MAX_NUM_MAC_ADDRESSES; } public boolean isCellEditable(int row, int col) { if (row <= addressVector.size()) return true; else return false; } public String getColumnName(int col) { if (col == 0) return "MAC address"; else return "Host name (opt)"; } public Object getValueAt(int row, int col) { if (row < addressVector.size()) return ((String[])addressVector.elementAt(row))[col]; else return ""; } public void setValueAt(Object newValue, int row, int col) { if (newValue instanceof String) { if (row < addressVector.size()) { String[] addressEntry = (String[])addressVector.elementAt(row); addressEntry[col] = (String)newValue; } else { String[] addressEntry = {"",""}; addressEntry[col] = (String)newValue; addressVector.insertElementAt(addressEntry, addressVector.size()); } } } } /** * Create new table based on data in airportInfo. */ public AirportAccessControlTable(AirportInfo airportInfo) { this.airportInfo = airportInfo; setUpDisplay(); } private void setUpDisplay() { refreshDisplay(); } /** * Write the MAC addresses and hostnames in the list into the appropriate locations * in the byte block referenced by the AirportInfo object supplied in the constructor. * @throws ValueFormatException Thrown if either a MAC address is malformed, or hostname * is too long. Also sets editting focus to the offending cell. */ public void writeValue() throws ValueFormatException { int dataType, namedataType, addressdataType; int baseStartIndex, numRows, numCols; int addressStartIndex, addressnumRows, addressnumCols; int nameStartIndex, namenumRows, namenumCols; // first, record changes if cell currently being edited TableCellEditor editor = table.getCellEditor(); if(editor != null) editor.stopCellEditing(); ByteBlock baseBlock = airportInfo.baseBlock; // erase entire blocks of info addressStartIndex = 0xF8A; addressnumRows = 1; addressnumCols = 6 * AirportInfo.MAX_NUM_MAC_ADDRESSES; addressdataType = AirportInfoRecord.BYTE_STRING; AirportInfoRecord addressBlockRecord = new AirportInfoRecord(addressStartIndex, addressnumRows, addressnumCols, addressdataType, baseBlock); addressBlockRecord.clearWindow(); nameStartIndex = 0x1CC8; namenumRows = 1; namenumCols = 20 * AirportInfo.MAX_NUM_MAC_ADDRESSES; namedataType = AirportInfoRecord.CHAR_STRING; AirportInfoRecord nameBlockRecord = new AirportInfoRecord(nameStartIndex, namenumRows, namenumCols, namedataType, baseBlock); nameBlockRecord.clearWindow(); //create new info records /** * Mac addresses for access control * count: byte 8*16 + 9 (maybe 8, with 2 digits) * addresses: byte 8*16 + 11, in 6-byte blocks * continue on from here. * NOTE!! Apple claims can have up to 497 MAC addresses; this would require 497*6 = 2982 bytes = 11.65 (16x16) blocks * In fact: * Mac addresses start at byte 15*256 + 8*16 + 11 = 3979 * Names start at byte 28*256 + 12*16 + 9 = 7369 * Difference is 3390 = 565 6-byte addresses (or 13.24 blocks) */ int numMacAddresses = 0; addressStartIndex = 0xF8A; addressnumRows = 1; addressnumCols = 6; addressdataType = AirportInfoRecord.BYTE_STRING; nameStartIndex = 0x1CC8; namenumRows = 1; namenumCols = 20; namedataType = AirportInfoRecord.CHAR_STRING; for (int i = 0; i < addressVector.size(); i++) { try { // these only get augmented if address is OK (and non-null) if (! ((String[])addressVector.elementAt(i))[0].equals("")) { AirportInfoRecord addressRecord = new AirportInfoRecord(addressStartIndex, addressnumRows, addressnumCols, addressdataType, baseBlock); addressRecord.setBytesFromString(((String[])addressVector.elementAt(i))[0]); addressStartIndex += 6; numMacAddresses++; } } catch (ValueFormatException e) { table.editCellAt(i,0); throw e; } try { AirportInfoRecord nameRecord = new AirportInfoRecord(nameStartIndex, namenumRows, namenumCols, namedataType, baseBlock); nameRecord.setBytesFromString(((String[])addressVector.elementAt(i))[1]); nameStartIndex += 20; } catch (ValueFormatException e) { table.editCellAt(i,1); throw e; } } // finally, write the number of addresses written baseStartIndex = 0xF87; numRows = 1; numCols = 2; dataType = AirportInfoRecord.UNSIGNED_INTEGER; AirportInfoRecord macCountRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); String addressCountString = new String(); addressCountString += numMacAddresses; macCountRecord.setBytesFromString(addressCountString); // also, set access control switch: on if any Mac entries, off otherwise /** * Access control switch: byte 4*16 + 9 * 00 = no access control * 80 = access control used */ String accessSwitchValue = new String(); if (numMacAddresses > 0) accessSwitchValue = "80"; else accessSwitchValue = "00"; AirportInfoRecord accessControlSwitchRecord = airportInfo.get("Access control switch"); accessControlSwitchRecord.setBytesFromString(accessSwitchValue); } /** * Refresh the display based on the current data in the underlying byte block. */ public void refreshDisplay() { int addressStartIndex, addressnumRows, addressnumCols, addressdataType; int nameStartIndex, namenumRows, namenumCols, namedataType; int baseStartIndex, numRows, numCols, dataType; ByteBlock baseBlock = airportInfo.baseBlock; /** * Mac addresses for access control * count: byte 8*16 + 9 (maybe 8, with 2 digits) * addresses: byte 8*16 + 11, in 6-byte blocks * continue on from here. * NOTE!! Apple claims can have up to 497 MAC addresses; this would require 497*6 = 2982 bytes = 11.65 (16x16) blocks * In fact: * Mac addresses start at byte 15*256 + 8*16 + 11 = 3979 * Names start at byte 28*256 + 12*16 + 9 = 7369 * Difference is 3390 = 565 6-byte addresses (or 13.24 blocks) */ baseStartIndex = 0xF87; numRows = 1; numCols = 2; dataType = AirportInfoRecord.UNSIGNED_INTEGER; AirportInfoRecord macCountRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); // Read in appropriate number of Mac addresses String countString = macCountRecord.toString(); int numMacAddresses = 0; try { numMacAddresses = Integer.parseInt(countString); } catch(NumberFormatException e) { System.out.println("Problem with number of Mac addresses"); } // create new addressVector, with appropriate size addressVector = new Vector(); addressStartIndex = 0xF8A; addressnumRows = 1; addressnumCols = 6; addressdataType = AirportInfoRecord.BYTE_STRING; nameStartIndex = 0x1CC8; namenumRows = 1; namenumCols = 20; namedataType = AirportInfoRecord.CHAR_STRING; for (int i = 0; i < numMacAddresses; i++) { AirportInfoRecord addressRecord = new AirportInfoRecord(addressStartIndex, addressnumRows, addressnumCols, addressdataType, baseBlock); AirportInfoRecord nameRecord = new AirportInfoRecord(nameStartIndex, namenumRows, namenumCols, namedataType, baseBlock); String[] addressEntry = new String[2]; addressEntry[0] = addressRecord.toString(); addressEntry[1] = nameRecord.toString(); addressVector.insertElementAt(addressEntry, addressVector.size()); addressStartIndex += 6; nameStartIndex += 20; } this.removeAll(); tableModel = new AccessAddressTableModel(); table = new JTable(tableModel); table.setCellSelectionEnabled(true); table.setPreferredScrollableViewportSize(new Dimension(350,200)); JScrollPane scrollPane = new JScrollPane(table); this.add(scrollPane); } }airportconfig-1.5.2/airport/AirportBridgingPanel.java0000644000175000017500000001442507503646614022335 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; /** * Panel which maintains data relevant to bridging (plus address allocation via DHCP and NAT). */ public class AirportBridgingPanel extends AirportInfoPanel { private AirportInfoRadioButton transparentBridgeButton, natButton; private ButtonGroup radioButtonGroup; private AirportInfoPanel natInfoPanel; private AirportInfoCheckBox natOnEthernetCheckbox, disableBridgingCheckbox; private AirportInfoLabelledTextField natInboundPrivateAddressBase, natInboundPrivateAddressMask; private AirportInfoTextField natOutboundPrivateAddressBase, natOutboundPrivateAddressMask; private AirportInfo theInfo; /** * Create new panel based on data referenced through the supplied AirportInfo object. */ public AirportBridgingPanel(AirportInfo theInfo) { this.theInfo = theInfo; /** * Transparent bridge/NAT switch: 0x449 * 00 = act as transparent bridge * 02 = NAT on, using specified range of IP addresses as LAN subnet */ transparentBridgeButton = new AirportInfoRadioButton("Act as transparent bridge (no NAT)"); transparentBridgeButton.addInfoRecord(theInfo.get("NAT switch"), "00"); // make sure bridging is enabled transparentBridgeButton.addInfoRecord(theInfo.get("Bridging switch"), "01"); natButton = new AirportInfoRadioButton("Provide network address translation (NAT)"); natButton.addInfoRecord(theInfo.get("NAT switch"), "02"); radioButtonGroup = new ButtonGroup(); radioButtonGroup.add(transparentBridgeButton); radioButtonGroup.add(natButton); natInboundPrivateAddressBase = new AirportInfoLabelledTextField("Private LAN base station address", theInfo.get("NAT inbound private IP address")); natInboundPrivateAddressMask = new AirportInfoLabelledTextField("Private LAN subnet mask", theInfo.get("NAT inbound private subnet mask")); // these two won't appear, but will instead be set from above two when value is written natOutboundPrivateAddressBase = new AirportInfoTextField(theInfo.get("NAT outbound private IP address")); natOutboundPrivateAddressMask = new AirportInfoTextField(theInfo.get("NAT outbound private subnet mask")); //*****natOnEthernetCheckbox = new AirportInfoCheckBox("Provide NAT on Ethernet port, too",theInfo.get("Ethernet DHCP switch"), "40", "00"); disableBridgingCheckbox = new AirportInfoCheckBox("Disable bridging between Ethernet port and wireless LAN",theInfo.get("Bridging switch"), "00", "01"); // create panel to hold NAT info to be disabled when in transparent bridge mode natInfoPanel = new AirportInfoPanel(); setUpDisplay(); } private void setUpDisplay() { //this.setOpaque(true); //this.setBackground(Color.white); // 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 = 0; c.weighty = 0; JLabel theLabel; // add stuff to NAT panel natInfoPanel.setLayout(theLayout); c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 1; theLayout.setConstraints(natInboundPrivateAddressBase, c); natInfoPanel.add(natInboundPrivateAddressBase); c.gridx = 1; c.gridy = 2; theLayout.setConstraints(natInboundPrivateAddressMask, c); natInfoPanel.add(natInboundPrivateAddressMask); c.anchor = GridBagConstraints.WEST; c.gridx = 1; c.gridy = 3; theLayout.setConstraints(disableBridgingCheckbox, c); natInfoPanel.add(disableBridgingCheckbox); // add stuff to this this.setLayout(theLayout); c.anchor = GridBagConstraints.WEST; c.gridx = 1; c.gridy = 1; theLayout.setConstraints(transparentBridgeButton, c); this.add(transparentBridgeButton); c.gridx = 1; c.gridy = 2; theLayout.setConstraints(natButton, c); this.add(natButton); c.gridx = 1; c.gridy = 3; theLayout.setConstraints(natInfoPanel, c); this.add(natInfoPanel); // make natInfoPanel enabled status dependent on button status natButton.addItemListener(natInfoPanel); natInfoPanel.setEnabled(natButton.isSelected()); } public void writeValue() throws ValueFormatException { super.writeValue(); if (natInfoPanel.isEnabled()) { // sanity-check the private IP address to make sure it's not 0.0.0.0, // to correct an issue with the RG-1000; write and read the value to // eliminate spaces, etc. natInboundPrivateAddressBase.writeValue(); String privateIP = theInfo.get("NAT inbound private IP address").toString(); if (privateIP.equals("0.0.0.0")) { // select text in panel natInboundPrivateAddressBase.theField.selectAll(); natInboundPrivateAddressBase.theField.requestFocus(); // throw exception throw new ValueFormatException("Private LAN IP address in Bridging panel can't be 0.0.0.0"); } // write private address base and subnet mask into outgoing NAT fields; // incoming fields are attached to the info text fields natOutboundPrivateAddressBase.writeValue(natInboundPrivateAddressBase.getText()); natOutboundPrivateAddressMask.writeValue(natInboundPrivateAddressMask.getText()); } } }airportconfig-1.5.2/airport/AirportLoginInfoPanel.java0000644000175000017500000001073007503646614022467 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; /** * Panel which maintains data pertaining to modem connection login, with settings for * username, password and login string. */ public class AirportLoginInfoPanel extends AirportInfoPanel { private AirportUsernamePanel usernamePanel; private AirportLoginStringTable loginStringTable; private AirportInfoPanel loginStringErasePanel; //private AirportInfoCheckBox loginStringCheckbox; private AirportInfoRadioButton userPassButton, loginStringButton; private ButtonGroup loginSelectGroup; public AirportLoginInfoPanel(AirportInfo theInfo) { /* loginStringCheckbox = new AirportInfoCheckBox("Use login script:"); loginStringCheckbox.addInfoRecord(theInfo.get("Login string switch"), "03", "01"); */ loginStringButton = new AirportInfoRadioButton("Use login script:"); loginStringButton.addInfoRecord(theInfo.get("Login string switch"), "03"); // this one won't show; just erases login script area when selected userPassButton = new AirportInfoRadioButton("Use username and password"); userPassButton.addInfoRecord(theInfo.get("Login string switch"), "01"); loginSelectGroup = new ButtonGroup(); loginSelectGroup.add(loginStringButton); loginSelectGroup.add(userPassButton); // panel holding dial-up username / password usernamePanel = new AirportUsernamePanel(theInfo); // table maintaining login string info loginStringTable = new AirportLoginStringTable(theInfo); // panel used to erase login info if not selected loginStringErasePanel = new AirportInfoPanel(); AirportInfoTextField eraseTextField = new AirportInfoTextField(theInfo.get("Login information string")); // set text in textfield to empty string so will erase login string if selected eraseTextField.setText(""); loginStringErasePanel.add(eraseTextField); setUpDisplay(); } public void setUpDisplay() { // 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; c.insets = new Insets(2,2,2,2); c.anchor = GridBagConstraints.CENTER; c.weightx = .5; c.weighty = .5; JLabel label; this.setLayout(theLayout); // add components c.insets = new Insets(8,2,2,2); c.gridx = 1; c.gridy = 1; theLayout.setConstraints(usernamePanel, c); this.add(usernamePanel); c.anchor = GridBagConstraints.WEST; c.insets = new Insets(8,2,2,2); c.gridx = 1; c.gridy = 2; theLayout.setConstraints(userPassButton, c); this.add(userPassButton); c.insets = new Insets(2,2,2,2); c.gridx = 1; c.gridy = 3; theLayout.setConstraints(loginStringButton, c); this.add(loginStringButton); c.anchor = GridBagConstraints.CENTER; c.insets = new Insets(8,2,2,2); c.gridx = 1; c.gridy = 4; theLayout.setConstraints(loginStringTable, c); this.add(loginStringTable); // now add invisible components for erasing login string if not selected c.gridx = 1; c.gridy = 5; theLayout.setConstraints(loginStringErasePanel, c); this.add(loginStringErasePanel); loginStringErasePanel.setVisible(false); // make login string table enabling dependent on button settings loginStringButton.addItemListener(loginStringTable); loginStringTable.setEnabled(loginStringButton.isSelected()); userPassButton.addItemListener(loginStringErasePanel); loginStringErasePanel.setEnabled(userPassButton.isSelected()); } }airportconfig-1.5.2/airport/AirportDHCPRangePanel.java0000644000175000017500000000652607503646614022306 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; /** * Sub-panel of bridging panel which maintains range of addresses served by base station when * acting as DHCP or NAT server. */ public class AirportDHCPRangePanel extends AirportInfoPanel { private AirportInfoTextField dhcpStartField, dhcpEndField; /** * Create new panel with start and end address for range taken from byte block referenced * in supplied AirportInfo object. */ public AirportDHCPRangePanel(AirportInfo theInfo) { dhcpStartField = new AirportInfoTextField(theInfo.get("DHCP address range start")); dhcpEndField = new AirportInfoTextField(theInfo.get("DHCP address range end")); setUpDisplay(); } /** * Create new panel with specified start and end address for range. Used to set default values * when required (e.g., range for NAT). */ public AirportDHCPRangePanel(AirportInfo theInfo, String defaultStartAddress, String defaultEndAddress) // use supplied default values, unless empty string supplied, whence use retrieved value { dhcpStartField = new AirportInfoTextField(theInfo.get("DHCP address range start")); dhcpStartField.setText(defaultStartAddress); dhcpEndField = new AirportInfoTextField(theInfo.get("DHCP address range end")); dhcpEndField.setText(defaultEndAddress); setUpDisplay(); } private void setUpDisplay() { // 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; JLabel theLabel; // textfields; put in panel this.setLayout(theLayout); c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 1; theLabel = new JLabel("Address range start"); theLayout.setConstraints(theLabel, c); this.add(theLabel); c.gridx = 1; c.gridy = 2; theLabel = new JLabel("Address range end"); theLayout.setConstraints(theLabel, c); this.add(theLabel); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 1; theLayout.setConstraints(dhcpStartField, c); this.add(dhcpStartField); c.gridx = 2; c.gridy = 2; theLayout.setConstraints(dhcpEndField, c); this.add(dhcpEndField); } }airportconfig-1.5.2/airport/AirportDiscoverer.java0000644000175000017500000001763407503646614021742 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.util.*; import java.net.*; import java.awt.*; import java.awt.event.*; import java.io.*; import javax.swing.*; import snmp.*; import byteblock.*; /** * Broadcasts discovery packet, waits for responses. Displays responding devices' IP addresses, * names, and device-type identifying strings. */ public class AirportDiscoverer extends JFrame implements ActionListener, Runnable { JButton stopDiscoveryButton, closeButton; JTextArea theArea; SNMPv1CommunicationInterface comInterface; Thread discoveryThread; public AirportDiscoverer() { setUpDisplay(); this.pack(); this.show(); discoveryThread = new Thread(this); discoveryThread.start(); } private void setUpDisplay() { this.setTitle("Base Station Discovery"); stopDiscoveryButton = new JButton("Stop Discovery"); stopDiscoveryButton.setActionCommand("stop discovery"); stopDiscoveryButton.addActionListener(this); closeButton = new JButton("Close"); closeButton.setActionCommand("close"); closeButton.addActionListener(this); theArea = new JTextArea(20,70); theArea.setLineWrap(true); theArea.setFont(new Font("Monospaced", Font.PLAIN, 10)); JScrollPane messagesScroll = new JScrollPane(theArea); // 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(stopDiscoveryButton, c); buttonPanel.add(stopDiscoveryButton); c.gridx = 2; c.gridy = 1; theLayout.setConstraints(closeButton, c); buttonPanel.add(closeButton); this.getContentPane().setLayout(new BorderLayout(5,5)); this.getContentPane().add("North", buttonPanel); this.getContentPane().add("Center", messagesScroll); } public void actionPerformed(ActionEvent theEvent) // respond to button pushes, menu selections { String command = theEvent.getActionCommand(); try { if (command == "close") { discoveryThread.interrupt(); this.hide(); this.dispose(); } if (command == "stop discovery") { discoveryThread.interrupt(); } } catch (Exception e) { } } public void run() { try { DatagramSocket dSocket = new DatagramSocket(); dSocket.setSoTimeout(1000); //1 second int AIRPORT_PORT = 192; InetAddress broadcastAddress = InetAddress.getByName("255.255.255.255"); byte[] bytes = new byte[116]; // from sniffs bytes[0] = (byte)0x01; DatagramPacket outPacket = new DatagramPacket(bytes, bytes.length, broadcastAddress, AIRPORT_PORT); dSocket.send(outPacket); while(! discoveryThread.interrupted()) { //bytes = new byte[116]; // from sniffs DatagramPacket inPacket = new DatagramPacket(bytes, bytes.length); try { dSocket.receive(inPacket); bytes = inPacket.getData(); String sourceAddress = inPacket.getAddress().getHostAddress(); // parse info in response packet /* System.out.println("Returned Message bytes:"); for (int i = 0; i < bytes.length; ++i) System.out.print(hexByte(bytes[i]) + " "); */ int rows = 8; // really, 7.25 int cols = 16; ByteBlock block = new ByteBlock(rows, cols, bytes); AirportDiscoveryInfo theInfo = new AirportDiscoveryInfo(block); long upTime = Long.parseLong(theInfo.get("Base station uptime").toString()); upTime = upTime / 100; // put into seconds // change to days:hours:minutes format long days = upTime / (3600 * 24); long hours = (upTime / 3600) % 24; long minutes = (upTime / 60) % 60; long seconds = upTime % 60; String dayString = new String(); dayString += days; String hourString = new String(); hourString += hours; if (hourString.length() < 2) hourString = "0" + hourString; // make hours, minutes and seconds have 2 digits String minuteString = new String(); minuteString += minutes; if (minuteString.length() < 2) minuteString = "0" + minuteString; String secondString = new String(); secondString += seconds; if (secondString.length() < 2) secondString = "0" + secondString; String timeString = dayString + ":" + hourString + ":" + minuteString; theArea.append("Access point found:\n"); theArea.append(" Local LAN IP address: " + theInfo.get("Base station IP address").toString() + "\n"); theArea.append(" External IP address: " + sourceAddress + "\n"); theArea.append(" MAC address: " + theInfo.get("Base station Mac address").toString() + "\n"); theArea.append(" Device name: " + theInfo.get("Base station name").toString() + "\n"); theArea.append(" Device type: " + theInfo.get("Device identifying string").toString() + "\n"); theArea.append(" Uptime (days:hrs:mins): " + timeString + "\n"); /* // now send out some SNMP requests to retrieve additional info from // the responding station; would really like to ARP on the MAC address // in case the returned IP address is unhappy (e.g., 0.0.0.0).... try { String community = "public"; int version = 0; // SNMPv1 InetAddress hostAddress = InetAddress.getByName(theInfo.get("Base station IP address").toString()); SNMPv1CommunicationInterface comInterface = new SNMPv1CommunicationInterface(version, hostAddress, community); String itemID = ""; SNMPVarBindList newVars = comInterface.getMIBEntry(itemID); SNMPSequence pair = (SNMPSequence)(newVars.getSNMPObjectAt(0)); SNMPObject snmpValue = pair.getSNMPObjectAt(1); theArea.append("External IP adress: " + snmpValue.toString() + "\n"); } catch(Exception e) { // do nothing; problem getting SNMP stuff... } */ theArea.append("\n"); } catch (InterruptedIOException e) { // will get here if nothing received in 1 second; used to check if interrupted // by user! } } } catch(Exception e) { theArea.append("Exception during discovery: " + e + "\n"); } theArea.append("Discovery finished.\n"); } 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; } }airportconfig-1.5.2/airport/AirportDiscoveryInfo.java0000644000175000017500000000616407503646614022414 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.util.*; import byteblock.*; /** * Collects together information about the location of pieces of information * in the 116-byte Discovery memory block, and creates appropriate AirportInfoRecords * (with ByteBlockWindows into the underlying ByteBlock) to read and write * the information. */ public class AirportDiscoveryInfo extends Hashtable { public ByteBlock baseBlock; /** * Create new */ public AirportDiscoveryInfo(ByteBlock baseBlock) { this.baseBlock = baseBlock; int baseStartIndex; int numRows, numCols; int dataType; byte mask; String name; /** * Base station MAC address: byte 2*16 + 5 */ baseStartIndex = 0x024; numRows = 1; numCols = 6; dataType = AirportInfoRecord.BYTE_STRING; name = "Base station Mac address"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Base station IP address: byte 2*16 + 13 */ baseStartIndex = 0x02C; numRows = 1; numCols = 4; dataType = AirportInfoRecord.IP_ADDRESS; name = "Base station IP address"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Base station name: byte 3*16 + 1 */ baseStartIndex = 0x030; numRows = 1; numCols = 32; dataType = AirportInfoRecord.CHAR_STRING; name = "Base station name"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Base station uptime: byte 5*16 + 1 */ baseStartIndex = 0x050; numRows = 1; numCols = 4; dataType = AirportInfoRecord.UNSIGNED_INTEGER; name = "Base station uptime"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Device identifying string: byte 5*16 + 5 */ baseStartIndex = 0x054; numRows = 1; numCols = 32; dataType = AirportInfoRecord.CHAR_STRING; name = "Device identifying string"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); } public AirportInfoRecord get(String name) { return (AirportInfoRecord)super.get(name); } }airportconfig-1.5.2/airport/AirportEthernetConfigPanel.java0000644000175000017500000002333707503646614023516 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * Panel maintaining configuration information for Ethernet network connection. */ public class AirportEthernetConfigPanel extends AirportInfoPanel implements ItemListener { private AirportInfoRadioButton dhcpConfigButton, manualConfigButton, pppoeButton; private AirportInfoPanel manualIPConfigPanel, ethernetButtonPanel, dhcpIPConfigPanel, dhcpClientIDPanel, pppoeClientIDPanel; private AirportInfoTextField dhcpClientIDField; private ButtonGroup dhcpManualButtonGroup; /** * Create new panel with information from supplied AirportInfo object. */ public AirportEthernetConfigPanel(AirportInfo theInfo) { /** * Base station configuration mode switch: byte 1*16 + 8, MASK 20 * 00 = manual or modem station config * 20 = DHCP station config */ dhcpConfigButton = new AirportInfoRadioButton("DHCP configuration of base station"); dhcpConfigButton.addInfoRecord(theInfo.get("Base station configuration mode switch"), "20"); dhcpConfigButton.addInfoRecord(theInfo.get("Configuration interface"), "00"); dhcpConfigButton.addInfoRecord(theInfo.get("PPPoE switch 1"), "00"); dhcpConfigButton.addInfoRecord(theInfo.get("PPPoE switch 2"), "00"); dhcpConfigButton.addInfoRecord(theInfo.get("PPPoE switch 3"), "00"); //dhcpConfigButton.addInfoRecord(theInfo.get("PPPoE switch 4"), "00"); // seems switches 5 and 6 can be ignored when not using PPPoE... //dhcpConfigButton.addInfoRecord(theInfo.get("PPPoE switch 5"), "00"); //dhcpConfigButton.addInfoRecord(theInfo.get("PPPoE switch 6"), "00"); dhcpConfigButton.addInfoRecord(theInfo.get("PPPoE switch 7"), "00"); manualConfigButton = new AirportInfoRadioButton("Manual configuration of base station"); manualConfigButton.addInfoRecord(theInfo.get("Base station configuration mode switch"), "00"); manualConfigButton.addInfoRecord(theInfo.get("Configuration interface"), "00"); manualConfigButton.addInfoRecord(theInfo.get("PPPoE switch 1"), "00"); manualConfigButton.addInfoRecord(theInfo.get("PPPoE switch 2"), "00"); manualConfigButton.addInfoRecord(theInfo.get("PPPoE switch 3"), "00"); //manualConfigButton.addInfoRecord(theInfo.get("PPPoE switch 4"), "00"); // seems switches 5 and 6 can be ignored when not using PPPoE... //manualConfigButton.addInfoRecord(theInfo.get("PPPoE switch 5"), "00"); //manualConfigButton.addInfoRecord(theInfo.get("PPPoE switch 6"), "00"); manualConfigButton.addInfoRecord(theInfo.get("PPPoE switch 7"), "00"); pppoeButton = new AirportInfoRadioButton("PPPoE configuration of base station"); pppoeButton.addInfoRecord(theInfo.get("Base station configuration mode switch"), "00"); pppoeButton.addInfoRecord(theInfo.get("Configuration interface"), "01"); pppoeButton.addInfoRecord(theInfo.get("PPPoE switch 1"), "04"); pppoeButton.addInfoRecord(theInfo.get("PPPoE switch 2"), "03"); pppoeButton.addInfoRecord(theInfo.get("PPPoE switch 3"), "0a"); // note: PPPoE switch 4 handled as two separate fields dealing with // PPPoE connection maintenance in PPPoE config panel pppoeButton.addInfoRecord(theInfo.get("PPPoE switch 5"), "a0"); pppoeButton.addInfoRecord(theInfo.get("PPPoE switch 6"), "05"); pppoeButton.addInfoRecord(theInfo.get("PPPoE switch 7"), "20"); dhcpManualButtonGroup = new ButtonGroup(); dhcpManualButtonGroup.add(dhcpConfigButton); dhcpManualButtonGroup.add(manualConfigButton); dhcpManualButtonGroup.add(pppoeButton); manualIPConfigPanel = new AirportIPConfigPanel(theInfo); dhcpClientIDField = new AirportInfoTextField(theInfo.get("DHCP client ID"), 20); pppoeClientIDPanel = new AirportPPPoEConfigPanel(theInfo); /* Set base station IP address and router IP address: .1.3.6.1.4.1.762.2.3.1.1.5 Base station IP address: byte 6*16 + 11 Router IP address and mask: byte 7*16 + 1 Manual config: set values as specified DHCP config, modem config: set default IP address router is left as is */ // dhcp config panel just used to write default IP info into block when // dhcp config desired; panel not displayed! //String defaultIPAddress = "192.42.249.12"; //dhcpIPConfigPanel = new AirportIPConfigPanel(theInfo, defaultIPAddress, "", ""); // just use retrieved info for all fields dhcpIPConfigPanel = new AirportIPConfigPanel(theInfo, "", "", ""); setUpDisplay(); } private void setUpDisplay() { // 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 = 0; c.weighty = 0; JLabel theLabel; dhcpClientIDPanel = new AirportInfoPanel(); dhcpClientIDPanel.setLayout(theLayout); c.gridx = 1; c.gridy = 1; c.anchor = GridBagConstraints.EAST; theLabel = new JLabel("DHCP client ID"); theLayout.setConstraints(theLabel, c); dhcpClientIDPanel.add(theLabel); c.gridx = 2; c.gridy = 1; c.anchor = GridBagConstraints.WEST; theLayout.setConstraints(dhcpClientIDField, c); dhcpClientIDPanel.add(dhcpClientIDField); ethernetButtonPanel = new AirportInfoPanel(); ethernetButtonPanel.setLayout(theLayout); c.gridx = 1; c.gridy = 1; theLayout.setConstraints(dhcpConfigButton, c); ethernetButtonPanel.add(dhcpConfigButton); c.gridx = 1; c.gridy = 2; theLayout.setConstraints(manualConfigButton, c); ethernetButtonPanel.add(manualConfigButton); c.gridx = 1; c.gridy = 3; theLayout.setConstraints(pppoeButton, c); ethernetButtonPanel.add(pppoeButton); this.setLayout(theLayout); // add components c.anchor = GridBagConstraints.CENTER; c.gridx = 1; c.gridy = 1; theLayout.setConstraints(ethernetButtonPanel, c); this.add(ethernetButtonPanel); c.gridx = 2; c.gridy = 1; theLayout.setConstraints(manualIPConfigPanel, c); this.add(manualIPConfigPanel); c.gridx = 2; c.gridy = 1; theLayout.setConstraints(dhcpClientIDPanel, c); this.add(dhcpClientIDPanel); c.gridx = 2; c.gridy = 1; theLayout.setConstraints(pppoeClientIDPanel, c); this.add(pppoeClientIDPanel); // never visible c.gridx = 2; c.gridy = 1; theLayout.setConstraints(dhcpIPConfigPanel, c); this.add(dhcpIPConfigPanel); // panel never visible; just used to set default data when selected dhcpIPConfigPanel.setVisible(false); // make manual config panel visibility and enabling dependent on button setting manualConfigButton.addItemListener(manualIPConfigPanel); manualConfigButton.addItemListener(this); manualIPConfigPanel.setEnabled(manualConfigButton.isSelected()); manualIPConfigPanel.setVisible(manualConfigButton.isSelected()); // make dhcp config panel enabling dependent on button setting (but never visible) dhcpConfigButton.addItemListener(dhcpIPConfigPanel); pppoeButton.addItemListener(dhcpIPConfigPanel); dhcpIPConfigPanel.setEnabled(dhcpConfigButton.isSelected() || pppoeButton.isSelected()); // make DHCP client ID panel visibility and enabling dependent on button setting dhcpConfigButton.addItemListener(dhcpClientIDPanel); dhcpConfigButton.addItemListener(this); dhcpClientIDPanel.setEnabled(dhcpConfigButton.isSelected()); dhcpClientIDPanel.setVisible(dhcpConfigButton.isSelected()); // make PPPoE client ID panel visibility and enabling dependent on button setting pppoeButton.addItemListener(pppoeClientIDPanel); pppoeButton.addItemListener(this); pppoeClientIDPanel.setEnabled(pppoeButton.isSelected()); pppoeClientIDPanel.setVisible(pppoeButton.isSelected()); } public void setEnabled(boolean enabled) { super.setEnabled(enabled); // create special setting status for subpanels manualIPConfigPanel.setEnabled(enabled && manualConfigButton.isSelected()); dhcpIPConfigPanel.setEnabled(enabled && (dhcpConfigButton.isSelected() || pppoeButton.isSelected())); dhcpClientIDPanel.setEnabled(enabled && dhcpConfigButton.isSelected()); pppoeClientIDPanel.setEnabled(enabled && pppoeButton.isSelected()); } /** * Used to trigger contained panels to be visible or not; panels themselves * are responsible for enabling/disabling themselves by virtue of being registered * as ItemListeners themselves. */ public void itemStateChanged(ItemEvent e) { super.itemStateChanged(e); manualIPConfigPanel.setVisible(manualConfigButton.isSelected()); dhcpClientIDPanel.setVisible(dhcpConfigButton.isSelected()); pppoeClientIDPanel.setVisible(pppoeButton.isSelected()); } }airportconfig-1.5.2/airport/AirportIPConfigPanel.java0000644000175000017500000001054707503646614022247 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; /** * Panel which maintains data relevant to base station and router IP address, and subnet mask. * Contained as subpanel within AirportNetworkPanel. */ public class AirportIPConfigPanel extends AirportInfoPanel { private AirportInfoTextField ipAddressField, subnetMaskField, routerIPAddressField; public AirportIPConfigPanel(AirportInfo theInfo) // use retrieved values as default values { /* Base station IP address and router IP address: .1.3.6.1.4.1.762.2.3.1.1.5 Base station IP address: byte 6*16 + 11 Router IP address and mask: byte 7*16 + 1 Manual config: set values as specified DHCP config, modem config: set default IP address router is left as is */ ipAddressField = new AirportInfoTextField((AirportInfoRecord)theInfo.get("Base station IP address")); subnetMaskField = new AirportInfoTextField((AirportInfoRecord)theInfo.get("Subnet mask")); routerIPAddressField = new AirportInfoTextField((AirportInfoRecord)theInfo.get("Router IP address")); setUpDisplay(); } public AirportIPConfigPanel(AirportInfo theInfo, String defaultIPAddress, String defaultSubnetMask, String defaultRouterIPAddress) // use supplied default values, unless empty string supplied, whence use retrieved value { ipAddressField = new AirportInfoTextField((AirportInfoRecord)theInfo.get("Base station IP address")); if(!defaultIPAddress.equals("")) ipAddressField.setText(defaultIPAddress); subnetMaskField = new AirportInfoTextField((AirportInfoRecord)theInfo.get("Subnet mask")); if(!defaultSubnetMask.equals("")) subnetMaskField.setText(defaultSubnetMask); routerIPAddressField = new AirportInfoTextField((AirportInfoRecord)theInfo.get("Router IP address")); if(!defaultRouterIPAddress.equals("")) routerIPAddressField.setText(defaultRouterIPAddress); setUpDisplay(); } private void setUpDisplay() { // 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; JLabel label; this.setLayout(theLayout); // add components c.gridwidth = 1; c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 1; label = new JLabel("Base station IP address"); theLayout.setConstraints(label, c); this.add(label); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 1; theLayout.setConstraints(ipAddressField, c); this.add(ipAddressField); c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 2; label = new JLabel("Subnet mask"); theLayout.setConstraints(label, c); this.add(label); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 2; theLayout.setConstraints(subnetMaskField, c); this.add(subnetMaskField); c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 3; label = new JLabel("Router IP address"); theLayout.setConstraints(label, c); this.add(label); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 3; theLayout.setConstraints(routerIPAddressField, c); this.add(routerIPAddressField); } }airportconfig-1.5.2/airport/AirportInfo.java0000644000175000017500000013301307503646614020516 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.util.*; import byteblock.*; import AirportBaseStationConfigurator; /** * Collects together information about the location of pieces of information * in the Airport 17k memory block, and creates appropriate AirportInfoRecords * (with ByteBlockWindows into the underlying ByteBlock) to read and write * the information. */ public class AirportInfo extends Hashtable { public static final int MAX_NUM_MAC_ADDRESSES = 256; public static final int MAX_NUM_PORT_MAPS = 20; public static final int MAX_NUM_SNMP_ACCESS_ENTRIES = 5; public static final int MAX_NUM_LOGIN_CHARS = 127; public ByteBlock baseBlock; public AirportInfo(ByteBlock baseBlock) { this.baseBlock = baseBlock; int baseStartIndex; int numRows, numCols; int dataType; byte mask; String name; /* Have 17408 bytes = 17k of ROM memory, communicated as 68 256-byte blocks in 68 OID blocks */ /** * .1.3.6.1.4.1.762.2.3.1.1.1 */ /** * Trap community password: 0x056 */ baseStartIndex = 0x056; numRows = 1; numCols = 16; dataType = AirportInfoRecord.CHAR_STRING; name = "Trap community"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Read community password: 0x076 */ baseStartIndex = 0x076; numRows = 1; numCols = 16; dataType = AirportInfoRecord.CHAR_STRING; name = "Read community"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Read/write community password: 0x096 (length????) */ baseStartIndex = 0x096; numRows = 1; numCols = 16; dataType = AirportInfoRecord.CHAR_STRING; name = "Read/write community"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Remaining community password count: 0x0B6 */ baseStartIndex = 0x0B6; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; name = "Remaining community count"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Remaining community password: 0x0B7 (length????) */ baseStartIndex = 0x0B7; numRows = 1; numCols = 16; dataType = AirportInfoRecord.CHAR_STRING; name = "Remaining community"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); // .1.3.6.1.4.1.762.2.3.1.1.2 Lots o' stuff! /* * * PPPoE switch 1: 0x107 * 00 = off * 04 = on */ baseStartIndex = 0x107; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "PPPoE switch 1"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /* * * Ethernet/Modem switch 1: 0x10A * 62 = modem * 60 = Ethernet */ baseStartIndex = 0x10A; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Ethernet/Modem switch 1"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Set configuration mode for base station: * Base station configuration mode switch: 0x117, MASK 20 * 00 = manual or modem station config * 20 = DHCP station config * NOTE: masked field: DHCP station config = 20, distribute on Ethernet = 40. */ baseStartIndex = 0x117; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Base station configuration mode switch"; mask = (byte)0x20; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /** * Set delivery of addresses on Ethernet: * Ethernet DHCP switch: 0x117, MASK 40 * 00 = don't give on Ethernet * 40 = give on Ethernet * Note: transparent mode, always 00 * NOTE: masked field: DHCP station config = 20, distribute on Ethernet = 40 */ baseStartIndex = 0x117; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Ethernet DHCP switch"; mask = (byte)0x40; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /** * Encryption flag field: mask so only single bit affected * 0x158, mask 0x08 (bit 4) * 00 = no encryption * 08 = use encryption */ baseStartIndex = 0x158; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Encryption flag 1"; mask = (byte)0x08; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /** * Microwave robustness flag flag: * 0x158, mask 0x20 (bit 6) * 00 = off * 20 = on */ baseStartIndex = 0x158; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Microwave robustness flag"; mask = (byte)0x20; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /** * RTS/CTS flag: * 0x168, mask 0x20 (bit 6) * 00 = off * 20 = on */ baseStartIndex = 0x168; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "RTS/CTS flag"; mask = (byte)0x20; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /** * Closed network flag: * 0x168, mask 0x40 (bit 7) * 00 = open * 40 = closed */ baseStartIndex = 0x168; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Closed network flag"; mask = (byte)0x40; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /** * Deny unencrypted data flag: * 0x168, mask 0x80 (bit 8) * 00 = allow all packets * 80 = allow only encrypted packets */ baseStartIndex = 0x168; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Deny unencrypted data flag"; mask = (byte)0x80; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /** * Distance between access points, rate: 0x0169 * mask 0x0F (lower nibble) * * large medium small * 1 Mbps 00 01 02 * 2 Mbps 04 05 06 * 5.5 Mbps na 09 0a * 11 Mbps na na 0e */ baseStartIndex = 0x169; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Distance and rate field"; mask = (byte)0x0F; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /** * Select encryption key to use: 0x169 * mask 0xF0 (upper nibble) * 00 = use key 1 * 40 = use key 2 * 80 = use key 3 * C0 = use key 4 */ baseStartIndex = 0x169; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Encryption key selector"; mask = (byte)0xF0; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /** * Wireless channel: 0x178 */ baseStartIndex = 0x178; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; name = "Wireless channel"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Modem timeout, in 10-second chunks: 0x17A */ baseStartIndex = 0x17A; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; name = "Modem timeout"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Dialing type: 0x17B * original: 0D = tone * 04 = pulse * * new: mask 0x08 * 08 = tone * 00 = pulse */ baseStartIndex = 0x17B; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Dialing type (tone or pulse)"; mask = (byte)0x08; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /** * Dialing type: 0x17B * mask 0x02 * 00 = auto dial on * 02 = auto dial off */ baseStartIndex = 0x17B; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Automatic dial"; mask = (byte)0x02; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /** * RTS Threshold: 0x1A8 * max value 2347 * */ baseStartIndex = 0x1A8; numRows = 1; numCols = 2; dataType = AirportInfoRecord.LITTLE_ENDIAN_UNSIGNED_INTEGER; name = "RTS threshold"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Phone country code: 0x1BA * * US standard = 32 32 * Singapore = 34 37 * Switzerland = 31 35 */ baseStartIndex = 0x1BA; numRows = 1; numCols = 2; dataType = AirportInfoRecord.BYTE_STRING; name = "Phone country code"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Network name: 0x1C8 * continuation in columns 8 and 9 of subsequent rows */ baseStartIndex = 0x1C8; numRows = 16; // assumed numCols = 2; dataType = AirportInfoRecord.CHAR_STRING; name = "Network name"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * * Modem stuff: starting at row 8, column 11 * continuation in columns 10 and 11 of subsequent rows * * First three bytes: * Primary phone number count * Secondary phone number count * Modem init string count * * Modem initialization string next, * continuation in columns 11 and 12 of subsequent rows * * Phone numbers: starting immediately after init string * continuation in columns 11 and 12 of subsequent rows * uses BCD, with D for space/paren and E for dash * secondary number follows immediately * * Some subfields defined separately: * country code (above) * string counts for modem init, phone numbers * * SO * this field all of above; counts must then overwrite first * three bytes * */ baseStartIndex = 0x18A; numRows = 31; // assumed numCols = 2; dataType = AirportInfoRecord.BYTE_STRING; name = "Modem init/phone number block"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Phone number lengths: * primary: 0x18A; secondary: 0x18B * Modem init string length: 0x19A */ baseStartIndex = 0x18A; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; name = "Primary phone number length"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x18B; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; name = "Secondary phone number length"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x19A; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; name = "Modem init string length"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** .1.3.6.1.4.1.762.2.3.1.1.3 Extension of 2, plus: */ /** Encryption flag field: 0x2C8 * 00 = no encryption * 01 = use encryption */ baseStartIndex = 0x2C8; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Encryption flag 3"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** .1.3.6.1.4.1.762.2.3.1.1.4 */ /* * * PPPoE switch 2: 0x336 * 00 = off * 03 = on */ baseStartIndex = 0x336; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "PPPoE switch 2"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /* * * PPPoE switch 3: 0x337 * 00 = off * 0a = on */ baseStartIndex = 0x337; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "PPPoE switch 3"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /* * * PPPoE idle timeout, in 10-second units: 0x346 * 0 = don't disconnect * */ baseStartIndex = 0x346; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; name = "PPPoE idle timeout"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /* * * PPPoE connection maintenance: 0x347 * 00 = PPPoE off * 04 = PPPoE on, auto connect on * 06 = PPPoE on, auto connect off * 40 = PPPoE on, always stay connected * * Break into three overlapping fields, so value will be set correctly * */ baseStartIndex = 0x347; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "PPPoE switch 4"; mask = (byte)0xFF; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); baseStartIndex = 0x347; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "PPPoE auto connect"; mask = (byte)0x06; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); baseStartIndex = 0x347; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "PPPoE stay connected"; mask = (byte)0x40; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /* * * PPPoE switch 5: 0x356 * 00 = off * a0 = on */ baseStartIndex = 0x356; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "PPPoE switch 5"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /* * * PPPoE switch 6: 0x357 * 00 = off * 05 = on */ baseStartIndex = 0x357; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "PPPoE switch 6"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Encryption keys: up to 4 * which key used determined by 0x169 * number of bytes: 0x374, 0x384, 0x394, 0x3A4 * 00 for no encryption * 05 for 40-bit (64-bit) encryption * 0D for 128-bit encryption * keys: 0x376, 0x386, 0x396, 0x3A6 */ baseStartIndex = 0x374; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Encryption key 1 size"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x376; numRows = 1; numCols = AirportBaseStationConfigurator.encryptionKeySize; dataType = AirportInfoRecord.BYTE_STRING; name = "Encryption key 1"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x384; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Encryption key 2 size"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x386; numRows = 1; numCols = AirportBaseStationConfigurator.encryptionKeySize; dataType = AirportInfoRecord.BYTE_STRING; name = "Encryption key 2"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x394; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Encryption key 3 size"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x396; numRows = 1; numCols = AirportBaseStationConfigurator.encryptionKeySize; dataType = AirportInfoRecord.BYTE_STRING; name = "Encryption key 3"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x3A4; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Encryption key 4 size"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x3A6; numRows = 1; numCols = AirportBaseStationConfigurator.encryptionKeySize; dataType = AirportInfoRecord.BYTE_STRING; name = "Encryption key 4"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /* * * PPPoE switch 7: 0x43d * mask 0x20 * 00 = off * 20 = on */ baseStartIndex = 0x43d; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "PPPoE switch 7"; mask = (byte)0x20; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /* * syslog host facility(0 - 8): 0x0440 * */ baseStartIndex = 0x440; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; name = "Syslog host facility"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** .1.3.6.1.4.1.762.2.3.1.1.5 */ /** * Bridging switch: 0x448 * mask 0x01 * 01 = bridging on * 00 = bridging off */ baseStartIndex = 0x448; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Bridging switch"; mask = (byte)0x01; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /** * Access control switch: 0x448 * mask 0x80 * 00 = no access control * 80 = access control used */ baseStartIndex = 0x448; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Access control switch"; mask = (byte)0x80; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /** * DHCP switch: 0x449 * mask 0x80 * 00 = no DHCP service * 80 = DHCP on, using specified range of IP addresses */ baseStartIndex = 0x449; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "DHCP switch"; mask = (byte)0x80; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /** * NAT switch: 0x449 * mask 0x02 * 00 = NAT off * 02 = NAT on */ baseStartIndex = 0x449; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "NAT switch"; mask = (byte)0x02; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /** * Port mapping switch: 0x449 * mask = 0x04 * 00 = off * 04 = on */ baseStartIndex = 0x449; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Port mapping switch"; mask = (byte)0x04; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /* * Configuration interface: 0x460; seems to be configuration interface * 03 = modem * 00 = Ethernet * 01 = PPPoE */ baseStartIndex = 0x460; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE_STRING; name = "Configuration interface"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /* * Watchdog reboot timer switch: 0x0462 * 01 = on * 00 = off */ baseStartIndex = 0x0462; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Watchdog reboot timer switch"; mask = (byte)0x01; this.put(name, new AirportInfoRecord(dataType, new ByteBlockMaskedWindow(baseStartIndex, numRows, numCols, baseBlock, mask))); /** * Base station IP address: 0x46A */ baseStartIndex = 0x46A; numRows = 1; numCols = 4; dataType = AirportInfoRecord.IP_ADDRESS; name = "Base station IP address"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Default TTL, for use with NAT(?): 0x46E */ baseStartIndex = 0x46E; numRows = 1; numCols = 2; dataType = AirportInfoRecord.LITTLE_ENDIAN_UNSIGNED_INTEGER; name = "Default TTL"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Router IP address and mask: 0x470, 0x474 */ baseStartIndex = 0x470; numRows = 1; numCols = 4; dataType = AirportInfoRecord.IP_ADDRESS; name = "Router IP address"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x474; numRows = 1; numCols = 4; dataType = AirportInfoRecord.IP_ADDRESS; name = "Subnet mask"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * 0x0478: syslog IP address * 0x047C: trap host IP address * */ baseStartIndex = 0x478; numRows = 1; numCols = 4; dataType = AirportInfoRecord.IP_ADDRESS; name = "Syslog host IP address"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x47C; numRows = 1; numCols = 4; dataType = AirportInfoRecord.IP_ADDRESS; name = "Trap host IP address"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Names of base station, contact person * Contact person name: 0x48C * Base station name: 0x4CC */ baseStartIndex = 0x48C; numRows = 1; numCols = 64; dataType = AirportInfoRecord.CHAR_STRING; name = "Contact person name"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x4CC; numRows = 1; numCols = 64; dataType = AirportInfoRecord.CHAR_STRING; name = "Base station name"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * .1.3.6.1.4.1.762.2.3.1.1.6 */ /** * Base station location: 0x50C */ baseStartIndex = 0x50C; numRows = 1; numCols = 64; dataType = AirportInfoRecord.CHAR_STRING; name = "Base station location"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * DHCP lease time: 0x5B4 */ baseStartIndex = 0x5B4; numRows = 1; numCols =2; dataType = AirportInfoRecord.LITTLE_ENDIAN_UNSIGNED_INTEGER; name = "DHCP lease time"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * DHCP client ID: 0x5B6 */ baseStartIndex = 0x5B6; numRows = 1; numCols =32; // guess dataType = AirportInfoRecord.CHAR_STRING; name = "DHCP client ID"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * * SNMP access control list: require multi-block windows * * 0x0636: number of entries (0-5) * * 0x0638, 0x063a, 0x063c, 0x063e, 0x0640: first two octets of IP addresses * 0x0642, 0x0644, 0x0646, 0x0648, 0x064a: second two octets of IP addresses * * 0x064c, 0x064e, 0x0650, 0x0652, 0x0654: first two octets of masks * 0x0656, 0x0658, 0x065a, 0x065c, 0x065e: second two octets of masks * * 0x0660, 0x0662, 0x0664, 0x0666, 0x0668: interfaces: 2-byte little-endian (any = ff ff) */ baseStartIndex = 0x0636; numRows = 1; numCols = 2; dataType = AirportInfoRecord.LITTLE_ENDIAN_UNSIGNED_INTEGER; name = "SNMP access control list length"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); // IP addresses ByteBlockMultiWindow ipWindow = new ByteBlockMultiWindow(); baseStartIndex = 0x638; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); baseStartIndex = 0x642; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); dataType = AirportInfoRecord.IP_ADDRESS; name = "SNMP access host 1"; this.put(name, new AirportInfoRecord(dataType, ipWindow)); ipWindow = new ByteBlockMultiWindow(); baseStartIndex = 0x63a; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); baseStartIndex = 0x644; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); dataType = AirportInfoRecord.IP_ADDRESS; name = "SNMP access host 2"; this.put(name, new AirportInfoRecord(dataType, ipWindow)); ipWindow = new ByteBlockMultiWindow(); baseStartIndex = 0x63c; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); baseStartIndex = 0x646; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); dataType = AirportInfoRecord.IP_ADDRESS; name = "SNMP access host 3"; this.put(name, new AirportInfoRecord(dataType, ipWindow)); ipWindow = new ByteBlockMultiWindow(); baseStartIndex = 0x63e; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); baseStartIndex = 0x648; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); dataType = AirportInfoRecord.IP_ADDRESS; name = "SNMP access host 4"; this.put(name, new AirportInfoRecord(dataType, ipWindow)); ipWindow = new ByteBlockMultiWindow(); baseStartIndex = 0x640; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); baseStartIndex = 0x64a; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); dataType = AirportInfoRecord.IP_ADDRESS; name = "SNMP access host 5"; this.put(name, new AirportInfoRecord(dataType, ipWindow)); // masks ipWindow = new ByteBlockMultiWindow(); baseStartIndex = 0x064c; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); baseStartIndex = 0x656; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); dataType = AirportInfoRecord.IP_ADDRESS; name = "SNMP access mask 1"; this.put(name, new AirportInfoRecord(dataType, ipWindow)); ipWindow = new ByteBlockMultiWindow(); baseStartIndex = 0x64e; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); baseStartIndex = 0x658; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); dataType = AirportInfoRecord.IP_ADDRESS; name = "SNMP access mask 2"; this.put(name, new AirportInfoRecord(dataType, ipWindow)); ipWindow = new ByteBlockMultiWindow(); baseStartIndex = 0x650; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); baseStartIndex = 0x65a; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); dataType = AirportInfoRecord.IP_ADDRESS; name = "SNMP access mask 3"; this.put(name, new AirportInfoRecord(dataType, ipWindow)); ipWindow = new ByteBlockMultiWindow(); baseStartIndex = 0x652; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); baseStartIndex = 0x65c; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); dataType = AirportInfoRecord.IP_ADDRESS; name = "SNMP access mask 4"; this.put(name, new AirportInfoRecord(dataType, ipWindow)); ipWindow = new ByteBlockMultiWindow(); baseStartIndex = 0x654; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); baseStartIndex = 0x65e; numRows = 1; numCols = 2; ipWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); dataType = AirportInfoRecord.IP_ADDRESS; name = "SNMP access mask 5"; this.put(name, new AirportInfoRecord(dataType, ipWindow)); // 0x0660, 0x0662, 0x0664, 0x0666, 0x0668: interfaces: 2-byte little-endian (any = ff ff) baseStartIndex = 0x0660; numRows = 1; numCols = 2; dataType = AirportInfoRecord.LITTLE_ENDIAN_UNSIGNED_INTEGER; name = "SNMP access interface 1"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x0662; numRows = 1; numCols = 2; dataType = AirportInfoRecord.LITTLE_ENDIAN_UNSIGNED_INTEGER; name = "SNMP access interface 2"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x0664; numRows = 1; numCols = 2; dataType = AirportInfoRecord.LITTLE_ENDIAN_UNSIGNED_INTEGER; name = "SNMP access interface 3"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x0666; numRows = 1; numCols = 2; dataType = AirportInfoRecord.LITTLE_ENDIAN_UNSIGNED_INTEGER; name = "SNMP access interface 4"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x0668; numRows = 1; numCols = 2; dataType = AirportInfoRecord.LITTLE_ENDIAN_UNSIGNED_INTEGER; name = "SNMP access interface 5"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * .1.3.6.1.4.1.762.2.3.1.1.13 */ /** * DHCP address range to serve: * starting address: 0xCF2 * ending address: 0xCF6 */ baseStartIndex = 0xCF2; numRows = 1; numCols = 4; dataType = AirportInfoRecord.IP_ADDRESS; name = "DHCP address range start"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0xCF6; numRows = 1; numCols = 4; dataType = AirportInfoRecord.IP_ADDRESS; name = "DHCP address range end"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * DNS servers: require multi-block windows * * .1.3.6.1.4.1.762.2.3.1.1.13 * First two octets of primary and secondary DNS server * primary: 0xCFA * secondary: 0xCFC * * .1.3.6.1.4.1.762.2.3.1.1.14 * Second two octets of primary and secondary DNS server * primary: 0xD00 * secondary: 0xD02 */ ByteBlockMultiWindow primaryWindow = new ByteBlockMultiWindow(); baseStartIndex = 0xCFA; numRows = 1; numCols = 2; primaryWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); baseStartIndex = 0xD00; numRows = 1; numCols = 2; primaryWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); dataType = AirportInfoRecord.IP_ADDRESS; name = "Primary DNS server"; this.put(name, new AirportInfoRecord(dataType, primaryWindow)); ByteBlockMultiWindow secondaryWindow = new ByteBlockMultiWindow(); baseStartIndex = 0xCFC; numRows = 1; numCols = 2; secondaryWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); baseStartIndex = 0xD02; numRows = 1; numCols = 2; secondaryWindow.addWindow(new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock)); dataType = AirportInfoRecord.IP_ADDRESS; name = "Secondary DNS server"; this.put(name, new AirportInfoRecord(dataType, secondaryWindow)); /** * .1.3.6.1.4.1.762.2.3.1.1.13 */ /** * DHCP lease time: 0xD06 * 4-byte unsigned integer giving lease time in seconds * Note that it's NOT little-endian */ baseStartIndex = 0xD06; numRows = 1; numCols = 4; dataType = AirportInfoRecord.UNSIGNED_INTEGER; name = "DHCP lease time"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Domain name (from DNS setting window): 0xD0A */ baseStartIndex = 0xD0A; numRows = 1; numCols = 32; dataType = AirportInfoRecord.CHAR_STRING; name = "Domain name"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Wireless subnet router IP address, when NAT enabled; 00's else: 0xD2A * Wireless subnet mask, when NAT enabled; FF's else: 0xD2E */ baseStartIndex = 0xD2A; numRows = 1; numCols = 4; dataType = AirportInfoRecord.IP_ADDRESS; name = "DHCP server router address"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0xD2E; numRows = 1; numCols = 4; dataType = AirportInfoRecord.IP_ADDRESS; name = "DHCP server subnet mask"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0xD4A; numRows = 1; numCols = 4; dataType = AirportInfoRecord.IP_ADDRESS; name = "NAT outbound public IP address"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0xD4E; numRows = 1; numCols = 4; dataType = AirportInfoRecord.IP_ADDRESS; name = "NAT outbound public subnet mask"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0xD52; numRows = 1; numCols = 4; dataType = AirportInfoRecord.IP_ADDRESS; name = "NAT outbound private IP address"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0xD56; numRows = 1; numCols = 4; dataType = AirportInfoRecord.IP_ADDRESS; name = "NAT outbound private subnet mask"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0xD66; numRows = 1; numCols = 4; dataType = AirportInfoRecord.IP_ADDRESS; name = "NAT inbound public subnet mask"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0xD6A; numRows = 1; numCols = 4; dataType = AirportInfoRecord.IP_ADDRESS; name = "NAT inbound private IP address"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0xD6E; numRows = 1; numCols = 4; dataType = AirportInfoRecord.IP_ADDRESS; name = "NAT inbound private subnet mask"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /* * Port mapping functions: * count of port mappings: 0xD62 * public port numbers: 0xDC2, in 2-byte pairs * first two octets of private IP addresses: 0xDEA, * in 2-byte pairs */ baseStartIndex = 0xD62; numRows = 1; numCols = 2; dataType = AirportInfoRecord.LITTLE_ENDIAN_UNSIGNED_INTEGER; name = "Count of port mappings"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0xD72; numRows = 1; numCols = 2 * MAX_NUM_PORT_MAPS; dataType = AirportInfoRecord.BYTE_STRING; name = "Public IP addresses, first two octets"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0xD9A; numRows = 1; numCols = 2 * MAX_NUM_PORT_MAPS; dataType = AirportInfoRecord.BYTE_STRING; name = "Public IP addresses, last two octets"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0xDC2; numRows = 1; numCols = 2 * MAX_NUM_PORT_MAPS; dataType = AirportInfoRecord.BYTE_STRING; name = "Public port numbers"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0xDEA; numRows = 1; numCols = 2 * MAX_NUM_PORT_MAPS; dataType = AirportInfoRecord.BYTE_STRING; name = "Private IP addresses, first two octets"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * .1.3.6.1.4.1.762.2.3.1.1.15 */ /** * Port mapping functions: * last two octets of private IP addresses: 0xE12, * in 2-byte pairs * private port numbers: 0xE3A, in 2-byte pairs */ baseStartIndex = 0xE12; numRows = 1; numCols = 2 * MAX_NUM_PORT_MAPS; dataType = AirportInfoRecord.BYTE_STRING; name = "Private IP addresses, last two octets"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0xE3A; numRows = 1; numCols = 2 * MAX_NUM_PORT_MAPS; dataType = AirportInfoRecord.BYTE_STRING; name = "Private port numbers"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** *.1.3.6.1.4.1.762.2.3.1.1.16 */ /** * Login string to transmit, if selected: 0xF08 * */ baseStartIndex = 0xF08; numRows = 1; numCols = MAX_NUM_LOGIN_CHARS; dataType = AirportInfoRecord.BYTE_STRING; name = "Login information string"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * The following are dealt with directly in the Access Control panel * * * Mac addresses for access control * count: byte 8*16 + 9 (maybe 8, with 2 digits) * addresses: byte 8*16 + 11, in 6-byte blocks * continue on from here. * NOTE!! Apple claims can have up to 497 MAC addresses; this would require 497*6 = 2982 bytes = 11.65 (16x16) blocks * In fact: * Mac addresses start at byte 15*256 + 8*16 + 11 = 3979 * Names start at byte 28*256 + 12*16 + 9 = 7369 * Difference is 3390 = 565 6-byte addresses (or 13.24 blocks) * baseStartIndex = 0xF87; numRows = 1; numCols = 2; dataType = AirportInfoRecord.UNSIGNED_INTEGER; name = "Access control MAC address count"; AirportInfoRecord macCountRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); this.put(name, macCountRecord); // Read in number of existing Mac addresses String countString = macCountRecord.toString(); int numMacAddresses = 0; try { numMacAddresses = Integer.parseInt(countString); } catch(NumberFormatException e) { System.out.println("Problem with number of Mac addresses"); } baseStartIndex = 0xF8A; numRows = 1; numCols = 4; dataType = AirportInfoRecord.BYTE_STRING; name = "Access control MAC address"; for (int i = 0; i < numMacAddresses; i++) { String nameString = name + i; this.put(nameString, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex += 6; } ** * .1.3.6.1.4.1.762.2.3.1.1.29 * ** * Host names for access control: byte 12*16 + 9 * Start here and continue over subsequent blocks... * 20 bytes for each (including null terminator, I think...) * using Apple's stated 497 Mac address limit, gives 497*20 = 9940 bytes; * = 38.83 blocks, putting us near the end; * In fact: * Names start at byte 28*256 + 12*16 + 9 = 7369 * Adding 9940 gives byte 17309 = 67*256 + 9*16 + 13 * Checksum seemingly starts at byte 11*16 + 6 of block 68, or at byte 17334 - or does it? maybe it's longer....the entry at position 2 is nonzero....that gives byte 17330, which is perfect if can have 498 MAC addresses....so maybe it's the whole 11th row that's the checksum stuff... * baseStartIndex = 0x1CC8; numRows = 1; numCols = 20; dataType = AirportInfoRecord.CHAR_STRING; name = "Access control host name"; for (int i = 0; i < numMacAddresses; i++) { String nameString = name + i; this.put(nameString, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex += 20; } */ /** * .1.3.6.1.4.1.762.2.3.1.1.63 */ /** * Username@domain, password * 0x3EAA: Character count of dial-up username@domain, username@domain, * character count of dial-up password, password. * Followed by 00 00 00 00, character count of PPPoE Client ID, * and then PPPoE Client ID, if PPPoE being used * Treat as single block; parsing done in display panel! */ baseStartIndex = 0x3EAA; numRows = 1; numCols = 128; // guess dataType = AirportInfoRecord.BYTE_STRING; name = "Dial-up username/password/PPPoE client ID"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * PPPoE Client ID * 0x3ED2: character count * 0x3ED3: characters */ baseStartIndex = 0x3ED2; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; name = "PPPoE Client ID character count"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x3ED3; numRows = 1; numCols = 128; // guess! dataType = AirportInfoRecord.CHAR_STRING; name = "PPPoE Client ID"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * .1.3.6.1.4.1.762.2.3.1.1.68 */ /** * Unknown fields, but sometimes aren't set...: 0x43b1, 0x43b3 * value always 01 in working config files */ baseStartIndex = 0x43b1; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Miscellaneous switch 1"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); baseStartIndex = 0x43b3; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Miscellaneous switch 2"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Login string approach: 0x43b5 * 01 = none * 02 = ? * 03 = send username, password * 04 = send username, password, ppp * 05 = send username, password, ppp, with waits for server info */ baseStartIndex = 0x43b5; numRows = 1; numCols = 1; dataType = AirportInfoRecord.BYTE; name = "Login string switch"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); /** * Checksum: */ baseStartIndex = 0x43B6; numRows = 1; numCols = 2; dataType = AirportInfoRecord.BYTE_STRING; name = "Checksum"; this.put(name, new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock)); } public AirportInfoRecord get(String name) { //System.out.println("Get info record " + name); return (AirportInfoRecord)super.get(name); } }airportconfig-1.5.2/airport/AirportInfoCheckBox.java0000644000175000017500000001040507503646614022124 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import java.util.*; import javax.swing.*; import byteblock.*; /** * Checkbox displaying and setting specific piece of Airport info. Provides facilities * for reading from / writing to multiple AirportInfoRecords, and specifying the value(s) * for each corresponding to the selected and unselected states. */ public class AirportInfoCheckBox extends JCheckBox implements AirportInfoComponent { private Vector theRecords; private class RecordSettings { public AirportInfoRecord theRecord; public String selectedValue; public String unselectedValue; public void writeValue(boolean selected) throws ValueFormatException { if (selected) { theRecord.setBytesFromString(selectedValue); } else { theRecord.setBytesFromString(unselectedValue); } } } /** * Create new checkbox with given label and no associated AirportInfoRecords. */ public AirportInfoCheckBox(String label) { super(label); theRecords = new Vector(); //redisplay done automatically when records added } /** * Create new checkbox with given label and supplied AirportInfoRecord, with selectedValue * and unselectedValue strings stored for subsequent writing (as appropriate). State of * checkbox set according to value in underlying byte block. */ public AirportInfoCheckBox(String label, AirportInfoRecord theRecord, String selectedValue, String unselectedValue) { super(label); theRecords = new Vector(); addInfoRecord(theRecord, selectedValue, unselectedValue); //redisplay done automatically by addInfoRecord } /** * Add additional AirportInfoRecord to list of byte block fields, with selectedValue * and unselectedValue strings stored for subsequent writing (as appropriate). State of * checkbox set according to value in all underlying byte blocks - if inconsistent, * set to unselected. */ public void addInfoRecord(AirportInfoRecord theRecord, String selectedValue, String unselectedValue) { RecordSettings recordSettings = new RecordSettings(); recordSettings.theRecord = theRecord; recordSettings.selectedValue = selectedValue; recordSettings.unselectedValue = unselectedValue; theRecords.insertElementAt(recordSettings, theRecords.size()); refreshDisplay(); } public void refreshDisplay() { boolean selected = true; Enumeration elements = theRecords.elements(); while (elements.hasMoreElements()) { RecordSettings nextSettings = (RecordSettings)elements.nextElement(); String currentValue = nextSettings.theRecord.toString(); String selectedValue = nextSettings.selectedValue; // just byte fields; so convert to integers to compare try { if(Integer.parseInt(currentValue, 16)!=Integer.parseInt(selectedValue, 16)) { selected = false; break; } } catch (NumberFormatException e) { selected = false; } } this.setSelected(selected); } /** * Write values to all of associated AirportInfoRecords according to selected state * of checkbox. */ public void writeValue() throws ValueFormatException { boolean selected = this.isSelected(); Enumeration elements = theRecords.elements(); while (elements.hasMoreElements()) ((RecordSettings)elements.nextElement()).writeValue(selected); } }airportconfig-1.5.2/airport/AirportInfoComboBox.java0000644000175000017500000000647307503646614022160 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import byteblock.*; /** * A ComboBox subclass for reading from and writing to an AirportInfoRecord. */ public class AirportInfoComboBox extends AirportInfoPanel implements AirportInfoComponent { private AirportInfoRecord theRecord; private JComboBox comboBox; /** * Associates ComboBox entry with value to be written; toString() method ensures * that itemLabel is displayed in ComboBox list */ private class Association { public Association(String itemLabel, String valueString) { this.itemLabel = itemLabel; this.valueString = valueString; } String itemLabel; String valueString; public String toString() { return itemLabel; } } /** * Creates ComboBox with given label associated with specified AirportInfoRecord. */ public AirportInfoComboBox(String label, AirportInfoRecord theRecord) { JLabel theLabel = new JLabel(label); comboBox = new JComboBox(); this.add("West", theLabel); this.add("East", comboBox); this.theRecord = theRecord; // display refreshed when items added } /** * Add item to ComboBox list, with specified item label and associated value string to * be written if item is selected. */ public void addItemAndValue(String itemLabel, String valueString) { // create an association object, and add it to the combo box Association newItem = new Association(itemLabel, valueString); comboBox.addItem(newItem); refreshDisplay(); } /** * Read current value in associated AirportInfoRecord, and set ComboBox to display * corresponding item. */ public void refreshDisplay() { // determine which label is associated with the current value, and select it String currentValue = theRecord.toString(); for (int i = 0; i < comboBox.getItemCount(); i++) { Association nextItem = (Association)(comboBox.getItemAt(i)); if (nextItem.valueString.equalsIgnoreCase(currentValue)) { comboBox.setSelectedIndex(i); break; } } } /** * Write the value corresponding to the currently selected item into the associated * AirportInfoRecord. */ public void writeValue() throws ValueFormatException { Association theItem = (Association)(comboBox.getSelectedItem()); theRecord.setBytesFromString(theItem.valueString); } }airportconfig-1.5.2/airport/AirportInfoComponent.java0000644000175000017500000000246407503646614022406 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import byteblock.*; /** * Interface for all components which display and edit Airport configuration information. */ public interface AirportInfoComponent { /** * Component should re-read data from the AirportInfoRecord containing its data. */ public void refreshDisplay(); /** * Component should write data to the AirportInfoRecord containing its data. */ public void writeValue() throws ValueFormatException; }airportconfig-1.5.2/airport/AirportInfoLabelledTextField.java0000644000175000017500000001013307503646614023751 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; import byteblock.*; /** * Creates a labelled text box to display and edit the information in an AirportInfoRecord. * Size of textfield is set automatically according to datatype. */ public class AirportInfoLabelledTextField extends AirportInfoPanel { public String name; public JTextField theField; private AirportInfoRecord theRecord; /** * Creates new display for viewing and editing the information in the supplied * AirportInfoRecord. Size of textfield is supplied. */ public AirportInfoLabelledTextField(String name, AirportInfoRecord theRecord, int fieldSize) { this.name = name; this.theRecord = theRecord; JLabel l = new JLabel(name); theField = new JTextField(fieldSize); this.setLayout(new BorderLayout(5,5)); this.add("West", l); this.add("East", theField); refreshDisplay(); } /** * Creates new display for viewing and editing the information in the supplied * AirportInfoRecord. Size of textfield is set automatically according to datatype. */ public AirportInfoLabelledTextField(String name, AirportInfoRecord theRecord) { this.name = name; this.theRecord = theRecord; setUpDisplay(); refreshDisplay(); } private void setUpDisplay() { JLabel l = new JLabel(name); //determine how large the text field should be to display the value int fieldSize = theRecord.byteBlockWindow.getSize(); switch (theRecord.dataType) { case AirportInfoRecord.CHAR_STRING: { // do nothing; field size OK as number of bytes break; } case AirportInfoRecord.PHONE_NUMBER: { fieldSize = 20; // should be enough for all digits and spaces break; } case AirportInfoRecord.IP_ADDRESS: { fieldSize = 15; break; } case AirportInfoRecord.UNSIGNED_INTEGER: case AirportInfoRecord.BYTE: case AirportInfoRecord.BYTE_STRING: default: { fieldSize *= 3; // to hold hex string: 2 chars per byte, plus space break; } } if (fieldSize > 40) fieldSize = 40; theField = new JTextField(fieldSize); this.setLayout(new BorderLayout(5,5)); this.add("West", l); this.add("East", theField); } /** * Read value from associated AirportInfoRecord window, and display value. */ public void refreshDisplay() { theField.setText(theRecord.toString()); } /** * Write value currently displayed into associated AirportInfoRecord window. */ public void writeValue() throws ValueFormatException { try { theRecord.setBytesFromString(theField.getText()); } catch (ValueFormatException e) { theField.selectAll(); theField.requestFocus(); throw e; } } /** * Write supplied value, rather than that currently displayed, into associated * AirportInfoRecord window. */ public void writeValue(String newValue) throws ValueFormatException { theField.setText(newValue); writeValue(); refreshDisplay(); } /** * Utility method to get text in enclosed textfield */ public String getText() { return theField.getText(); } }airportconfig-1.5.2/airport/AirportInfoListDisplay.java0000644000175000017500000000753007503646614022704 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.util.*; import java.net.*; import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.io.*; /** * A utility class that displays all of the information in the associated AirportInfo * object. Creates an AirportInfoLabelledTextField (labelled text box) for each piece of * information, and displays these in a scrollable pane. */ public class AirportInfoListDisplay extends JPanel implements Scrollable { /** * Create the display for the information contained in airportInfo. */ public AirportInfoListDisplay(AirportInfo airportInfo) { setUpDisplay(airportInfo); } private void setUpDisplay(AirportInfo airportInfo) { // 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; //this.setBackground(Color.white); //this.setOpaque(true); this.setLayout(theLayout); Enumeration keys = airportInfo.keys(); int i = 1; while (keys.hasMoreElements()) { String name = (String)keys.nextElement(); //if (name.endsWith("?")) { AirportInfoRecord nextRecord = airportInfo.get(name); AirportInfoLabelledTextField theDisplay = new AirportInfoLabelledTextField(name, nextRecord); c.gridx = 1; c.gridy = i; theLayout.setConstraints(theDisplay, c); this.add(theDisplay); i++; } } } public Dimension getPreferredScrollableViewportSize() { Dimension d; //d = getPreferredSize(); d = new Dimension(600,200); //System.out.println("preferred size returned: " + d.getHeight() + ", " + d.getWidth()); return d; } public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) // Components that display logical rows or columns should compute the scroll increment that // will completely expose one block of rows or columns, depending on the value of orientation. { return 10; } public boolean getScrollableTracksViewportHeight() // Return true if a viewport should always force the height of this Scrollable to // match the height of the viewport. { return false; } public boolean getScrollableTracksViewportWidth() // Return true if a viewport should always force the width of this Scrollable to // match the width of the viewport. { return false; } public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) // Components that display logical rows or columns should compute the scroll increment // that will completely expose one new row or column, depending on the value of orientation. { return 10; } }airportconfig-1.5.2/airport/AirportInfoPanel.java0000644000175000017500000000623207503646614021500 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import java.awt.event.*; import javax.swing.*; import byteblock.*; /** * Superclass for all panels displaying info with AirportInfoComponents. When * enabled, has all AirportInfoComponents write their values; if not enabled, * component values not written. */ public class AirportInfoPanel extends JPanel implements AirportInfoComponent, ItemListener { /** * If panel enabled, instruct all contained AirportInfoComponents to write * their values; if not enabled, no writing. */ public void writeValue() throws ValueFormatException { if (this.isEnabled()) { Component[] components = this.getComponents(); for (int i = 0; i < components.length; i++) if (components[i] instanceof AirportInfoComponent) { try { ((AirportInfoComponent)components[i]).writeValue(); } catch (ValueFormatException e) { // set focus to offending component (if it's not itself a container) if ( !(components[i] instanceof Container)) components[i].requestFocus(); throw e; // so can display this panel } } } } /** * Instruct all contained AirportInfoComponents to read their values from * their associated AirportInfoRecords, and update their displays accordingly. */ public void refreshDisplay() { Component[] components = this.getComponents(); for (int i = 0; i < components.length; i++) if (components[i] instanceof AirportInfoComponent) ((AirportInfoComponent)components[i]).refreshDisplay(); } /** * Used to trigger this panel to be enabled or disabled, by registering it * as a ChangeListener with an AbstractButton instance. When disabled, * contained components won't write their values to underlying ByteBlock. */ public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) this.setEnabled(true); else this.setEnabled(false); } /** * Enable and disable contained components. */ public void setEnabled(boolean enabled) { Component[] components = this.getComponents(); super.setEnabled(enabled); for (int i = 0; i < components.length; i++) components[i].setEnabled(enabled); } }airportconfig-1.5.2/airport/AirportInfoRadioButton.java0000644000175000017500000001003107503646614022663 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import java.util.*; import javax.swing.*; import byteblock.*; /** * Radio button displaying state of and setting value of specific piece of Airport info. * Provides facilities for reading from / writing to multiple AirportInfoRecords, and * specifying the value for each corresponding to the selected state. */ public class AirportInfoRadioButton extends JRadioButton implements AirportInfoComponent { private Vector theRecords; private class RecordSettings { public AirportInfoRecord theRecord; public String selectedValue; public void writeValue() throws ValueFormatException { theRecord.setBytesFromString(selectedValue); } } /** * Create new radio button with given label and no associated AirportInfoRecords. */ public AirportInfoRadioButton(String label) { super(label); theRecords = new Vector(); //redisplay done automatically when new record added } /** * Create new radio button with given label and supplied AirportInfoRecord, with * selectedValue string stored for subsequent writing (as appropriate). State of * radio button set according to value in underlying byte block. */ public AirportInfoRadioButton(String label, AirportInfoRecord theRecord, String selectedValue) { super(label); theRecords = new Vector(); addInfoRecord(theRecord, selectedValue); //redisplay done automatically by addInfoRecord } /** * Add additional AirportInfoRecord to list of byte block fields, with selectedValue * string stored for subsequent writing (as appropriate). State of checkbox set according * to value in all underlying byte blocks - if inconsistent, set to unselected. */ public void addInfoRecord(AirportInfoRecord theRecord, String selectedValue) { RecordSettings recordSettings = new RecordSettings(); recordSettings.theRecord = theRecord; recordSettings.selectedValue = selectedValue; theRecords.insertElementAt(recordSettings, theRecords.size()); refreshDisplay(); } public void refreshDisplay() { boolean selected = true; Enumeration elements = theRecords.elements(); while (elements.hasMoreElements()) { RecordSettings nextSettings = (RecordSettings)elements.nextElement(); String currentValue = nextSettings.theRecord.toString(); String selectedValue = nextSettings.selectedValue; // just byte fields; so convert to integers to compare - but use hex! try { if(Integer.parseInt(currentValue, 16)!=Integer.parseInt(selectedValue, 16)) selected = false; } catch (NumberFormatException e) { selected = false; } } this.setSelected(selected); } /** * Write values to all of associated AirportInfoRecords if checkbox selected. */ public void writeValue() throws ValueFormatException { boolean selected = this.isSelected(); if (selected) { Enumeration elements = theRecords.elements(); while (elements.hasMoreElements()) { RecordSettings nextSettings = (RecordSettings)elements.nextElement(); nextSettings.writeValue(); } } } }airportconfig-1.5.2/airport/AirportInfoRecord.java0000644000175000017500000003267507503646614021671 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.math.*; import java.util.*; import byteblock.*; /** * This class defines a structure to hold information about the location and format (type) * of a piece of information in the Airport memory block. Location is specified by a triple: * the object identifier number (1 to 68), row in the block (0 to 15), and column (0 to 15), * where the ByteBlockWindow begins; size of the window is specified by giving the number of * rows and columns in the window; and the datatype is specified as one of the class's constants. * * The class also implements a toString() method which provides a pretty-printed representation * of the value in the window based on its datatype, and a setBytesFromString() method which * writes a value to the window given an appropriately formatted String representation. */ public class AirportInfoRecord { public static final int CHAR_STRING = 0; public static final int IP_ADDRESS = 1; public static final int BYTE_STRING = 2; public static final int PHONE_NUMBER = 3; public static final int UNSIGNED_INTEGER = 4; public static final int BYTE = 5; public static final int LITTLE_ENDIAN_UNSIGNED_INTEGER = 6; public int dataType; public ByteBlockWindow byteBlockWindow; /** * Create a new record with the specified parameters, creating a new ByteBlockRectangularWindow * into the supplied ByteBlock. */ public AirportInfoRecord(int baseStartIndex, int numRows, int numCols, int dataType, ByteBlock baseBlock) { this.dataType = dataType; this.byteBlockWindow = new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, baseBlock); } /** * Create a new record of given datatype for the specified ByteBlockWindow. */ public AirportInfoRecord(int dataType, ByteBlockWindow window) { this.dataType = dataType; this.byteBlockWindow = window; } /** * Clear all bytes in the underlying ByteBlockWindow. */ public void clearWindow() { byteBlockWindow.clearBytes(); } /** * Method which provides a pretty-printed representation of the value in the ByteBlockWindow * based on its datatype. */ public String toString() { String returnString = new String(); switch (dataType) { case UNSIGNED_INTEGER: { try { byte[] bytes = byteBlockWindow.getBytes(); returnString = convertToUnsignedInteger(bytes); } catch (NumberFormatException e) { returnString = byteBlockWindow.toHexString(); } break; } case LITTLE_ENDIAN_UNSIGNED_INTEGER: { try { byte[] bytes = byteBlockWindow.getBytes(); bytes = reverseBytes(bytes); returnString = convertToUnsignedInteger(bytes); } catch (NumberFormatException e) { returnString = byteBlockWindow.toHexString(); } break; } case CHAR_STRING: { returnString = new String(byteBlockWindow.getBytes()); // strip off trailing nulls, if any int endIndex = returnString.indexOf(0x00); if (endIndex >= 0) returnString = returnString.substring(0, endIndex); break; } case PHONE_NUMBER: { returnString = convertToPhoneNumber(byteBlockWindow.getBytes()); break; } case IP_ADDRESS: { returnString = convertToIPAddress(byteBlockWindow.getBytes()); break; } case BYTE: case BYTE_STRING: default: { returnString = byteBlockWindow.toHexString(); break; } } return returnString; } private String convertToUnsignedInteger(byte[] bytes) { BigInteger bigInt = new BigInteger(1, bytes); return bigInt.toString(); } private String convertToIPAddress(byte[] bytes) { String returnString = new String(); int value; for (int i = 0; i < bytes.length - 1; i++) { value = bytes[i]; if (value < 0) value += 256; returnString += value + "."; } value = bytes[bytes.length - 1]; if (value < 0) value += 256; returnString += value; return returnString; } /** * Utility method that does single-digit mapping from nibble (half-byte, 4-bit) values * to appropriate char values. This is used in displaying phone numbers. The mapping is: * 0xA == '*' * 0xB == '#' * 0xC == ',' * 0xD == ' ' (note: also used for both (!) left and right parens... * 0xE == '-' * 0xF == '.' */ public static char decodePhoneDigit(byte digit) { char returnChar; if (digit == 0xA) // represents star returnChar = '*'; else if (digit == 0xB) // represents pound returnChar = '#'; else if (digit == 0xC) // represents comma returnChar = ','; else if (digit == 0xD) // represents space (or parens...) returnChar = ' '; else if (digit == 0xE) // represents dash returnChar = '-'; else if (digit == 0xF) // represents period returnChar = '.'; else returnChar = Byte.toString(digit).charAt(0); return returnChar; } private String convertToPhoneNumber(byte[] bytes) { String returnString = new String(); for (int i = 0; i < bytes.length; i++) { int left = (bytes[i] & 0xF0) >>> 4; int right = bytes[i] & 0x0F; if (left == 0xE) // represents dash returnString += "-"; else if (left == 0xD) // represents space returnString += " "; else if (left == 0xC) // represents comma returnString += ","; else returnString += left; if (right == 0xE) // represents dash returnString += "-"; else if (right == 0xD) // represents space returnString += " "; else if (right == 0xC) // represents comma returnString += ","; else returnString += right; } return returnString; } /** * Writes a value to the window given an appropriately formatted String representation for * the value. */ public void setBytesFromString(String valueString) throws ValueFormatException { byte[] bytes; int blockSize = byteBlockWindow.getSize(); switch (dataType) { case UNSIGNED_INTEGER: { bytes = convertFromUnsignedInteger(valueString); break; } case LITTLE_ENDIAN_UNSIGNED_INTEGER: { bytes = convertFromUnsignedInteger(valueString); bytes = reverseBytes(bytes); break; } case CHAR_STRING: { // add trailing null valueString += "\u0000"; if (valueString.length() > blockSize) { // System.out.println("Value format exception at " + OIDNum + " " + OIDRow + " " + OIDCol); throw new ValueFormatException("Maximum " + (blockSize - 1) + " characters."); } else bytes = valueString.getBytes(); break; } case PHONE_NUMBER: { bytes = convertFromPhoneNumber(valueString); break; } case IP_ADDRESS: { bytes = convertFromIPv4Address(valueString); break; } case BYTE: case BYTE_STRING: default: { bytes = convertFromHexString(valueString); break; } } // byteBlockWindow.writeBytes(startIndex, bytes); byteBlockWindow.writeBytes(bytes); } private byte[] convertFromIPv4Address(String addressString) throws ValueFormatException { // might be partial address int length = byteBlockWindow.getSize(); byte[] bytes = new byte[length]; int i = 0; int value; StringTokenizer st = new StringTokenizer(addressString, "."); if (st.countTokens() != length) { if (length == 4) throw new ValueFormatException("Bad IP address: must be of form a.b.c.d, with a,b,c and d between 0 and 255."); else throw new ValueFormatException("Bad dotted address supplied: should have " + length + " components."); } while (st.hasMoreTokens()) { try { String component = st.nextToken(); value = Integer.parseInt(component); if ((value < 0) || (value > 255)) throw new ValueFormatException("Bad IP address: must be of form a.b.c.d, with a,b,c and d between 0 and 255."); else { bytes[i] = (byte)value; i++; } } catch (NumberFormatException e) { throw new ValueFormatException("Bad IP address: must be of form a.b.c.d, with a,b,c and d between 0 and 255."); } } return bytes; } /** * Utility method that does single-digit mapping from char values to appropriate * nibble (half-byte, 4-bit) values. This is used in encoding phone numbers. * The mapping is: * 0xA == '*' * 0xB == '#' * 0xC == ',' * 0xD == ' ' (note: also used for both (!) left and right parens... * 0xE == '-' * 0xF == '.' */ public static byte encodePhoneDigit(char digit) throws NumberFormatException { byte nibble; if (digit == '*') nibble = 0xA; // represents star else if (digit == '#') nibble = 0xB; // represents pound else if (digit == ',') nibble = 0xC; // represents comma else if ((digit == ' ') || (digit == '(') || (digit == ')')) nibble = 0xD; // space or paren else if (digit == '-') nibble = 0xE; // represents dash else if (digit == '.') nibble = 0xF; // represents period else nibble = (byte)Character.digit(digit, 10); return nibble; } private byte[] convertFromPhoneNumber(String phoneNumber) throws ValueFormatException // Phone numbers are BCD encoded, with E for dash and D for space or paren { char[] chars = phoneNumber.toCharArray(); byte[] bytes = new byte[(chars.length + 1)/2]; for (int i = 0; i < chars.length; i++) { byte nibble; if (chars[i] == '-') // represents dash nibble = 0xE; else if ((chars[i] == ' ') || (chars[i] == '(') || (chars[i] == ')')) nibble = 0xD; // space or paren else if (chars[i] == ',') nibble = 0xC; // represents comma else { try { nibble = (byte)Integer.parseInt(phoneNumber.substring(i,i+1)); } catch(NumberFormatException e) { throw new ValueFormatException("Invalid phone number"); } } if (2 * (i/2) == i) // i even, shift left nibble = (byte)(nibble << 4); bytes[(i+1)/2] &= nibble; } return bytes; } private byte[] convertFromUnsignedInteger(String valueString) throws ValueFormatException { int length = byteBlockWindow.getSize(); byte[] bytes = new byte[length]; try { int minValue = 0; long maxValue = 1; for (int i = 0; i < length; i++) { maxValue *= 256; } maxValue -= 1; long value = Long.parseLong(valueString); if ((value < minValue) || (value > maxValue)) throw new ValueFormatException("Value must be between " + minValue + " and " + maxValue + "."); for (int i = 0; i < length; i++) { bytes[length - i - 1] = (byte)(value%256); value = value/256; } } catch (NumberFormatException e) { throw new ValueFormatException("Bad number format."); } return bytes; } private byte[] convertFromHexString(String hexString) throws ValueFormatException { int length = byteBlockWindow.getSize(); byte[] bytes = new byte[length]; // eliminate spaces in string hexString.trim(); int index; while((index = hexString.indexOf(' ')) != -1) { hexString = hexString.substring(0,index) + hexString.substring(index+1); } // make sure have even number of hex digits if (2 * (hexString.length()/2) != hexString.length()) throw new ValueFormatException("Must have an even number of hexadecimal digits."); // make sure don't have too many bytes if (hexString.length() / 2 > length) throw new ValueFormatException("Too many hexadecimal digits (maximum " + length + " bytes = " + 2*length + " hex digits)."); for (int i = 0; i < (hexString.length()/2); i++) { // get next pair of digits String digitString = hexString.substring(2*i,2*i+2); try { int value = Integer.parseInt(digitString, 16); bytes[i] = (byte)value; } catch (NumberFormatException e) { throw new ValueFormatException("Entries must be hexadecimal digits (0 through 9 and a through f or A through F) or spaces."); } } return bytes; } private byte[] reverseBytes(byte[] inBytes) { int length = inBytes.length; byte[] outBytes = new byte[length]; for (int i = 0; i < length; i++) { outBytes[i] = inBytes[length - i - 1]; } return outBytes; } }airportconfig-1.5.2/airport/AirportInfoRecordDisplay.java0000644000175000017500000000647107503646614023212 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; import byteblock.*; /** * Creates a labelled text box to display and edit the information in an AirportInfoRecord. * Size of textfield is set automatically according to datatype. */ public class AirportInfoRecordDisplay extends AirportInfoPanel { public String name; public JTextField theField; private AirportInfoRecord theRecord; /** * Creates new display for viewing and editing the information in the supplied * AirportInfoRecord. Size of textfield is set automatically according to datatype. */ public AirportInfoRecordDisplay(String name, AirportInfoRecord theRecord) { this.name = name; this.theRecord = theRecord; setUpDisplay(); refreshDisplay(); } private void setUpDisplay() { JLabel l = new JLabel(name); //determine how large the text field should be to display the value int fieldSize = theRecord.byteBlockWindow.getSize(); switch (theRecord.dataType) { case AirportInfoRecord.CHAR_STRING: { // do nothing; field size OK as number of bytes break; } case AirportInfoRecord.PHONE_NUMBER: { fieldSize = 20; // should be enough for all digits and spaces break; } case AirportInfoRecord.IP_ADDRESS: { fieldSize = 15; break; } case AirportInfoRecord.UNSIGNED_INTEGER: case AirportInfoRecord.BYTE: case AirportInfoRecord.BYTE_STRING: default: { fieldSize *= 3; // to hold hex string: 2 chars per byte, plus space break; } } if (fieldSize > 40) fieldSize = 40; theField = new JTextField(fieldSize); this.setLayout(new BorderLayout(5,5)); this.add("West", l); this.add("East", theField); } /** * Read value from associated AirportInfoRecord window, and display value. */ public void refreshDisplay() { theField.setText(theRecord.toString()); } /** * Write value currently displayed into associated AirportInfoRecord window. */ public void writeValue() throws ValueFormatException { theRecord.setBytesFromString(theField.getText()); } /** * Write supplied value, rather than that currently displayed, into associated * AirportInfoRecord window. */ public void writeValue(String newValue) throws ValueFormatException { theField.setText(newValue); writeValue(); refreshDisplay(); } }airportconfig-1.5.2/airport/AirportInfoTabbedPane.java0000644000175000017500000000666707503646614022442 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import java.awt.event.*; import javax.swing.*; import byteblock.*; /** * Tabbed pane holding panels which present various configuration information. */ public class AirportInfoTabbedPane extends JTabbedPane { /** * Create new tabbed pane holding panels which present various configuration information. * The supplied AirportInfo instance is passed to the contained panels. */ public AirportInfoTabbedPane(AirportInfo airportInfo) { setUpDisplay(airportInfo); } private void setUpDisplay(AirportInfo airportInfo) { AirportInfoPanel mainPanel = new AirportMainPanel(airportInfo); AirportInfoPanel wirelessPanel = new AirportWirelessPanel(airportInfo); AirportInfoPanel connectionPanel = new AirportNetworkPanel(airportInfo); AirportInfoPanel bridgingPanel = new AirportBridgingPanel(airportInfo); AirportInfoPanel dhcpPanel = new AirportDHCPPanel(airportInfo); AirportInfoPanel accessTablePanel = new AirportAccessControlTable(airportInfo); AirportInfoPanel portMapTablePanel = new AirportPortMappingPanel(airportInfo); AirportInfoPanel snmpPanel = new AirportSNMPPanel(airportInfo); AirportInfoPanel advancedPanel = new AirportAdvancedPanel(airportInfo); //AirportInfoPanel loginPanel = new AirportLoginInfoPanel(airportInfo); this.addTab("Main", mainPanel); this.addTab("Wireless LAN Settings", wirelessPanel); this.addTab("Network Connection", connectionPanel); this.addTab("Bridging Functions", bridgingPanel); this.addTab("DHCP Functions", dhcpPanel); this.addTab("Access Control", accessTablePanel); this.addTab("Port Mappings", portMapTablePanel); this.addTab("SNMP Settings", snmpPanel); this.addTab("Advanced Settings", advancedPanel); } /** * Instruct all contained panels to write their settings to the associated AirportInfoRecords, * and update displays accordingly. (Note that only the enabled AirportInfoComponents contained * in the panels will write their values.) */ public void writeData() throws ValueFormatException { int numTabs = this.getTabCount(); for (int i = 0; i < numTabs; i++) { Component nextPanel = this.getComponentAt(i); if (nextPanel instanceof AirportInfoPanel) { try { ((AirportInfoPanel)nextPanel).writeValue(); } catch (ValueFormatException e) { // display offending panel; component will have already requested focus this.setSelectedIndex(i); throw e; // terminate operation } } } } }airportconfig-1.5.2/airport/AirportInfoTextField.java0000644000175000017500000000672207503646614022335 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; import byteblock.*; /** * Creates a text box to display and edit information in an AirportInfoRecord. * Size of textfield is set automatically according to datatype. */ public class AirportInfoTextField extends JTextField implements AirportInfoComponent { private AirportInfoRecord theRecord; /** * Creates new textfield to display and edit information in an AirportInfoRecord. * Size of textfield is set automatically according to datatype. */ public AirportInfoTextField(AirportInfoRecord theRecord) { super(); this.theRecord = theRecord; //determine how large the text field should be to display the value int fieldSize = theRecord.byteBlockWindow.getSize(); switch (theRecord.dataType) { case AirportInfoRecord.CHAR_STRING: { // do nothing; field size OK as number of bytes break; } case AirportInfoRecord.PHONE_NUMBER: { fieldSize = 20; // should be enough for all digits and spaces break; } case AirportInfoRecord.IP_ADDRESS: { fieldSize = 15; break; } case AirportInfoRecord.UNSIGNED_INTEGER: case AirportInfoRecord.BYTE: case AirportInfoRecord.BYTE_STRING: default: { fieldSize *= 3; // to hold hex string: 2 chars per byte, plus space break; // or integer value } } if (fieldSize > 40) fieldSize = 40; this.setColumns(fieldSize); refreshDisplay(); } /** * Creates new textfield to display and edit information in an AirportInfoRecord. * Size of textfield is supplied as argument. */ public AirportInfoTextField(AirportInfoRecord theRecord, int fieldSize) { super(); this.theRecord = theRecord; this.setColumns(fieldSize); refreshDisplay(); } /** * Read value from associated AirportInfoRecord window, and display value. */ public void refreshDisplay() { setText(theRecord.toString()); } /** * Write value currently displayed into associated AirportInfoRecord window. */ public void writeValue() throws ValueFormatException { try { theRecord.setBytesFromString(getText()); } catch (ValueFormatException e) { this.selectAll(); this.requestFocus(); throw e; } } /** * Write supplied value, rather than that currently displayed, into associated * AirportInfoRecord window. */ public void writeValue(String newValue) throws ValueFormatException { setText(newValue); writeValue(); refreshDisplay(); } }airportconfig-1.5.2/airport/AirportMainPanel.java0000644000175000017500000001003407503646614021464 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; /** * Panel which maintains basic base station information: name, location, and contact individual. * Also provides textfield for entering new community name (base station password). */ public class AirportMainPanel extends AirportInfoPanel { private JTextField baseStationNameField, baseStationLocationField; private JTextField baseStationContactField, baseStationPasswordField; public AirportMainPanel(AirportInfo theInfo) { AirportInfoRecord nextRecord; nextRecord = theInfo.get("Base station name"); baseStationNameField = new AirportInfoTextField(nextRecord); nextRecord = theInfo.get("Base station location"); baseStationLocationField = new AirportInfoTextField(nextRecord); nextRecord = theInfo.get("Contact person name"); baseStationContactField = new AirportInfoTextField(nextRecord); nextRecord = theInfo.get("Read/write community"); baseStationPasswordField = new AirportInfoTextField(nextRecord); setUpDisplay(); } private void setUpDisplay() { // 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; c.insets = new Insets(2,2,2,2); c.anchor = GridBagConstraints.CENTER; c.weightx = 0; c.weighty = 0; JLabel theLabel; this.setLayout(theLayout); c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 1; theLabel = new JLabel("Base station name"); theLayout.setConstraints(theLabel, c); this.add(theLabel); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 1; theLayout.setConstraints(baseStationNameField, c); this.add(baseStationNameField); c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 2; theLabel = new JLabel("Base station location"); theLayout.setConstraints(theLabel, c); this.add(theLabel); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 2; theLayout.setConstraints(baseStationLocationField, c); this.add(baseStationLocationField); c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 3; theLabel = new JLabel("Contact person name"); theLayout.setConstraints(theLabel, c); this.add(theLabel); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 3; theLayout.setConstraints(baseStationContactField, c); this.add(baseStationContactField); c.insets = new Insets(20,2,2,2); c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 4; theLabel = new JLabel("Community name"); theLayout.setConstraints(theLabel, c); this.add(theLabel); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 4; theLayout.setConstraints(baseStationPasswordField, c); this.add(baseStationPasswordField); c.insets = new Insets(2,2,2,2); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 5; theLabel = new JLabel("(enter only if to be changed)"); theLayout.setConstraints(theLabel, c); this.add(theLabel); } }airportconfig-1.5.2/airport/AirportModemConfigPanel.java0000644000175000017500000001125507503646614022775 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * Panel which maintains data pertaining to modem configuration. Has settings for phone number, * username and password, and the like. */ public class AirportModemConfigPanel extends AirportInfoPanel implements ActionListener { private AirportPhoneNumberPanel phoneNumberPanel; private AirportLoginInfoDialog loginDialog; private AirportInfoLabelledTextField modemTimeoutField; private AirportInfoComboBox tonePulseDialingBox; private AirportInfoCheckBox automaticDialingCheckbox; private JButton loginButton; private AirportInfo theInfo; public AirportModemConfigPanel(AirportInfo theInfo) { this.theInfo = theInfo; // panel holding phone number, modem init string info phoneNumberPanel = new AirportPhoneNumberPanel(theInfo); // Button to show login panel when pressed... loginButton = new JButton("Username/Password/Login Script"); loginButton.setActionCommand("show login panel"); loginButton.addActionListener(this); modemTimeoutField = new AirportInfoLabelledTextField("Modem timeout (in 10-second units)", theInfo.get("Modem timeout")); tonePulseDialingBox = new AirportInfoComboBox("Tone or pulse (rotary) dialing", theInfo.get("Dialing type (tone or pulse)")); tonePulseDialingBox.addItemAndValue("Tone", "08"); tonePulseDialingBox.addItemAndValue("Pulse", "00"); automaticDialingCheckbox = new AirportInfoCheckBox("Automatic dialing", theInfo.get("Automatic dial"), "00", "02"); setUpDisplay(); } public void setUpDisplay() { // 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; c.insets = new Insets(2,10,2,10); c.anchor = GridBagConstraints.CENTER; c.weightx = .5; c.weighty = .5; this.setLayout(theLayout); c.gridwidth = 2; // add components c.anchor = GridBagConstraints.CENTER; c.gridx = 1; c.gridy = 1; theLayout.setConstraints(phoneNumberPanel, c); this.add(phoneNumberPanel); c.gridwidth = 1; c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 2; theLayout.setConstraints(loginButton, c); this.add(loginButton); c.gridwidth = 1; c.gridx = 2; c.gridy = 3; theLayout.setConstraints(automaticDialingCheckbox, c); this.add(automaticDialingCheckbox); c.gridheight = 1; c.gridx = 1; c.gridy = 2; theLayout.setConstraints(modemTimeoutField, c); this.add(modemTimeoutField); c.gridx = 1; c.gridy = 3; theLayout.setConstraints(tonePulseDialingBox, c); this.add(tonePulseDialingBox); } public void actionPerformed(ActionEvent theEvent) // respond to button pushes { String command = theEvent.getActionCommand(); if (command.equals("show login panel")) { // get top-level Frame to associate modal dialog with so will be minimzed and // maximized correctly. Component owner = this; while ( !((owner == null) || (owner instanceof Frame)) ) owner = owner.getParent(); Frame owningFrame = (Frame)owner; // create and display modal dialog holding dial-up username / password and login script loginDialog = new AirportLoginInfoDialog(owningFrame, "Login Information", true, theInfo); loginDialog.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 = loginDialog.getSize(); dim.height += 20; dim.width += 20; loginDialog.setSize(dim); loginDialog.show(); } } }airportconfig-1.5.2/airport/AirportNetworkPanel.java0000644000175000017500000001632307503646614022240 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * Panel which maintains data relevant to base station network connection. Has radio button selection * for modem vs Ethernet connection of base station to external network, plus DNS server fields. * Has subpanels for configuring the network connection: modem panel with settings for phone number, * username and password, and the like; Ethernet panel with choice of manual or DHCP config, plus * settings for base station IP address, router address and mask. These subpanels are enabled only * when associated connection method is selected. */ public class AirportNetworkPanel extends AirportInfoPanel implements ItemListener { private AirportInfoRadioButton modemButton, ethernetButton; private AirportInfoTextField primaryDNSField, secondaryDNSField, domainNameField; private AirportInfoPanel ethernetConfigPanel, modemConfigPanel, dnsPanel; private ButtonGroup modemEthernetButtonGroup; public AirportNetworkPanel(AirportInfo theInfo) { /* .1.3.6.1.4.1.762.2.3.1.1.2 Ethernet/Modem switch 1: byte 11 62 = modem 60 = Ethernet .1.3.6.1.4.1.762.2.3.1.1.5 Configuration interface: byte 6*16 + 1 03 = modem 00 = Ethernet */ modemButton = new AirportInfoRadioButton("Connect to network through modem"); modemButton.addInfoRecord(theInfo.get("Ethernet/Modem switch 1"), "62"); modemButton.addInfoRecord(theInfo.get("Configuration interface"), "03"); /** * .1.3.6.1.4.1.762.2.3.1.1.2 * * * also must handle base station configuration mode switch: byte 1*16 + 8, MASK 20 * 00 = manual or modem station config * 20 = DHCP station config */ modemButton.addInfoRecord(theInfo.get("Base station configuration mode switch"), "00"); ethernetButton = new AirportInfoRadioButton("Connect to network through Ethernet port"); ethernetButton.addInfoRecord(theInfo.get("Ethernet/Modem switch 1"), "60"); //ethernetButton.addInfoRecord(theInfo.get("Configuration interface"), "00"); modemEthernetButtonGroup = new ButtonGroup(); modemEthernetButtonGroup.add(modemButton); modemEthernetButtonGroup.add(ethernetButton); primaryDNSField = new AirportInfoTextField(theInfo.get("Primary DNS server")); secondaryDNSField = new AirportInfoTextField(theInfo.get("Secondary DNS server")); domainNameField = new AirportInfoTextField(theInfo.get("Domain name")); ethernetConfigPanel = new AirportEthernetConfigPanel(theInfo); modemConfigPanel = new AirportModemConfigPanel(theInfo); setUpDisplay(); } public void setUpDisplay() { // 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; JLabel label; /* // create and lay out button panel AirportInfoPanel buttonPanel = new AirportInfoPanel(); buttonPanel.setLayout(theLayout); // add components c.anchor = GridBagConstraints.CENTER; c.gridx = 2; c.gridy = 1; theLayout.setConstraints(modemButton, c); buttonPanel.add(modemButton); c.gridx = 1; c.gridy = 1; theLayout.setConstraints(ethernetButton, c); buttonPanel.add(ethernetButton); */ // create and lay out DNS panel dnsPanel = new AirportInfoPanel(); dnsPanel.setLayout(theLayout); // add components c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 1; label = new JLabel("Primary DNS server IP address"); theLayout.setConstraints(label, c); dnsPanel.add(label); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 1; theLayout.setConstraints(primaryDNSField, c); dnsPanel.add(primaryDNSField); c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 2; label = new JLabel("Secondary DNS server IP address"); theLayout.setConstraints(label, c); dnsPanel.add(label); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 2; theLayout.setConstraints(secondaryDNSField, c); dnsPanel.add(secondaryDNSField); c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 3; label = new JLabel("Domain name"); theLayout.setConstraints(label, c); dnsPanel.add(label); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 3; theLayout.setConstraints(domainNameField, c); dnsPanel.add(domainNameField); // now add panels to this this.setLayout(theLayout); c.anchor = GridBagConstraints.CENTER; c.gridx = 1; c.gridy = 1; theLayout.setConstraints(ethernetButton, c); this.add(ethernetButton); c.gridx = 2; c.gridy = 1; theLayout.setConstraints(modemButton, c); this.add(modemButton); c.gridwidth = 2; c.gridx = 1; c.gridy = 2; theLayout.setConstraints(ethernetConfigPanel, c); this.add(ethernetConfigPanel); c.gridx = 1; c.gridy = 2; theLayout.setConstraints(modemConfigPanel, c); this.add(modemConfigPanel); c.gridwidth = 2; c.gridx = 1; c.gridy = 3; theLayout.setConstraints(dnsPanel, c); this.add(dnsPanel); // make modem and ethernet config panel enablings dependent on button settings modemButton.addItemListener(modemConfigPanel); modemButton.addItemListener(this); modemConfigPanel.setEnabled(modemButton.isSelected()); modemConfigPanel.setVisible(modemButton.isSelected()); ethernetButton.addItemListener(ethernetConfigPanel); ethernetButton.addItemListener(this); ethernetConfigPanel.setEnabled(ethernetButton.isSelected()); ethernetConfigPanel.setVisible(ethernetButton.isSelected()); } /** * Used to trigger contained panels to be visible or not; panels themselves * are responsible for enabling/disabling themselves by virtue of being registered * as ItemListeners themselves. */ public void itemStateChanged(ItemEvent e) { modemConfigPanel.setVisible(modemButton.isSelected()); ethernetConfigPanel.setVisible(ethernetButton.isSelected()); } }airportconfig-1.5.2/airport/AirportPhoneNumberPanel.java0000644000175000017500000003202407503646614023025 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; import byteblock.*; /** * Utility subpanel which maintains dial-up phone number info. Could be easily extended to also permit * secondary phone number and modem initialization string editting. */ public class AirportPhoneNumberPanel extends AirportInfoPanel { private AirportInfo airportInfo; private JTextField modemInitField, primaryPhoneField, secondaryPhoneField; private AirportInfoComboBox countryCodeBox; private static final int countryCodePrefixCount = 5; // "*NC22", for example private static final int countFieldCount = 3; // one byte each for phone number counts, modem init count public AirportPhoneNumberPanel(AirportInfo airportInfo) { super(); this.airportInfo = airportInfo; // holds configuration info for telephone system countryCodeBox = new AirportInfoComboBox("Country", airportInfo.get("Phone country code")); // add settings for each different country system; each group is same! countryCodeBox.addItemAndValue("North America", "3232"); countryCodeBox.addItemAndValue("Guam (same as North America)", "3232"); countryCodeBox.addItemAndValue("Hong Kong (same as North America)", "3232"); countryCodeBox.addItemAndValue("India (same as North America)", "3232"); countryCodeBox.addItemAndValue("Latin America (same as North America)", "3232"); countryCodeBox.addItemAndValue("Phillipines (same as North America)", "3232"); countryCodeBox.addItemAndValue("Thailand (same as North America)", "3232"); countryCodeBox.addItemAndValue("Singapore", "3437"); countryCodeBox.addItemAndValue("China (same as Singapore)", "3437"); countryCodeBox.addItemAndValue("Czech Republic (same as Singapore)", "3437"); countryCodeBox.addItemAndValue("Slovak Republic (same as Singapore)", "3437"); countryCodeBox.addItemAndValue("Korea (same as Singapore)", "3437"); countryCodeBox.addItemAndValue("Malaysia (same as Singapore)", "3437"); countryCodeBox.addItemAndValue("Poland (same as Singapore)", "3437"); countryCodeBox.addItemAndValue("Taiwan (same as Singapore)", "3437"); countryCodeBox.addItemAndValue("Switzerland", "3135"); countryCodeBox.addItemAndValue("Portugal (same as Switzerland)", "3135"); countryCodeBox.addItemAndValue("Spain (same as Switzerland)", "3135"); countryCodeBox.addItemAndValue("Finland", "3034"); countryCodeBox.addItemAndValue("Germany (same as Finland)", "3034"); countryCodeBox.addItemAndValue("Iceland (same as Finland)", "3034"); countryCodeBox.addItemAndValue("Netherlands (same as Finland)", "3034"); countryCodeBox.addItemAndValue("Australia", "3430"); countryCodeBox.addItemAndValue("South Africa (same as Australia)", "3430"); countryCodeBox.addItemAndValue("United Kingdom", "3136"); countryCodeBox.addItemAndValue("Belgium (same as United Kingdom)", "3136"); countryCodeBox.addItemAndValue("Denmark (same as United Kingdom)", "3136"); countryCodeBox.addItemAndValue("Greece (same as United Kingdom)", "3136"); countryCodeBox.addItemAndValue("Ireland (same as United Kingdom)", "3136"); countryCodeBox.addItemAndValue("Norway (same as United Kingdom)", "3136"); countryCodeBox.addItemAndValue("New Zealand", "3438"); countryCodeBox.addItemAndValue("France", "3035"); countryCodeBox.addItemAndValue("Japan", "3433"); countryCodeBox.addItemAndValue("Austria", "3031"); countryCodeBox.addItemAndValue("Italy", "3038"); countryCodeBox.addItemAndValue("Sweden", "3134"); setUpDisplay(); } private void setUpDisplay() { modemInitField = new JTextField(10); primaryPhoneField = new JTextField(10); secondaryPhoneField = new JTextField(10); JLabel modemInitLabel = new JLabel("Modem init string"); JLabel primaryPhoneLabel = new JLabel("Phone number"); JLabel secondaryPhoneLabel = new JLabel("Secondary phone number"); // 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; this.setLayout(theLayout); // add stuff: just single phone number for now! c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 1; theLayout.setConstraints(primaryPhoneLabel, c); this.add(primaryPhoneLabel); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 1; theLayout.setConstraints(primaryPhoneField, c); this.add(primaryPhoneField); // also modem init string, for Steve Palm c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 2; theLayout.setConstraints(modemInitLabel, c); this.add(modemInitLabel); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 2; theLayout.setConstraints(modemInitField, c); this.add(modemInitField); // and modem country code box c.gridwidth = 2; c.gridx = 1; c.gridy = 3; theLayout.setConstraints(countryCodeBox, c); this.add(countryCodeBox); refreshDisplay(); } public void writeValue() throws ValueFormatException { // first, clear aggregate count, modem init, phone number field AirportInfoRecord aggregateInfoRecord = airportInfo.get("Modem init/phone number block"); aggregateInfoRecord.clearWindow(); // now write concatenated modem init string and phone numbers /** * * Modem stuff: starting at row 8, column 11 * continuation in columns 11 and 12 of subsequent rows * First three bytes: * Primary phone number count * Secondary phone number count * Modem init string count * Modem initialization string next, * continuation in columns 11 and 12 of subsequent rows * Phone numbers: starting immediately after init string * continuation in columns 11 and 12 of subsequent rows * uses BCD, with D for space/paren and E for dash * secondary number follows immediately * * Some subfields defined separately: * country code (above) * string counts for modem init, phone numbers * * SO * this field includes counts, modem init string and phone numbers; * count fields must overwrite first 3 bytes * */ String modemInitString = modemInitField.getText(); // add in prefix " *NC22"; spaces will be overwritten with phone number abd init string lengths; // default 22 country code will be overwritten with correct value by cuntry code box modemInitString = " *NC22" + modemInitString; String phoneNumberString = new String(); phoneNumberString += primaryPhoneField.getText(); phoneNumberString += secondaryPhoneField.getText(); byte[] phoneBytes = convertFromPhoneNumber(phoneNumberString); byte[] modemInitBytes = modemInitString.getBytes(); byte[] bytes = new byte[modemInitBytes.length + phoneBytes.length]; for(int i = 0; i < modemInitBytes.length; i++) bytes[i] = modemInitBytes[i]; for(int i = 0; i < phoneBytes.length; i++) bytes[i + modemInitBytes.length] = phoneBytes[i]; aggregateInfoRecord.byteBlockWindow.writeBytes(bytes); // now determine counts of info; set appropriate fields (overwriting first three bytes // of modem init string int initStringCount = modemInitField.getText().length(); // add country code string count, e.g., "*NC22" (not included in modem init string) initStringCount += countryCodePrefixCount; AirportInfoRecord initStringCountRecord = airportInfo.get("Modem init string length"); String modemInitCountString = new String(); modemInitCountString += initStringCount; initStringCountRecord.setBytesFromString(modemInitCountString); int primaryCount = primaryPhoneField.getText().length(); AirportInfoRecord primaryCountRecord = airportInfo.get("Primary phone number length"); String primaryCountString = new String(); primaryCountString += primaryCount; primaryCountRecord.setBytesFromString(primaryCountString); int secondaryCount = secondaryPhoneField.getText().length(); AirportInfoRecord secondaryCountRecord = airportInfo.get("Secondary phone number length"); String secondaryCountString = new String(); secondaryCountString += secondaryCount; secondaryCountRecord.setBytesFromString(secondaryCountString); // finally, write value from country code box countryCodeBox.writeValue(); } public void refreshDisplay() { int OIDNum, OIDRow, OIDCol, numRows, numCols, dataType; // determine counts of info AirportInfoRecord initStringCountRecord = airportInfo.get("Modem init string length"); int initStringCount = Integer.parseInt(initStringCountRecord.toString()); AirportInfoRecord primaryCountRecord = airportInfo.get("Primary phone number length"); int primaryCount = Integer.parseInt(primaryCountRecord.toString()); AirportInfoRecord secondaryCountRecord = airportInfo.get("Secondary phone number length"); int secondaryCount = Integer.parseInt(secondaryCountRecord.toString()); // now get pieces out of aggregate field AirportInfoRecord aggregateInfoRecord = airportInfo.get("Modem init/phone number block"); byte[] blockBytes = aggregateInfoRecord.byteBlockWindow.getBytes(); // get modem init string, excluding country code part int partialInitStringCount = initStringCount - countryCodePrefixCount; if(partialInitStringCount < 0) partialInitStringCount = 0; byte[] initStringBytes = new byte[partialInitStringCount]; for (int i = 0; i < partialInitStringCount; i++) initStringBytes[i] = blockBytes[i + countryCodePrefixCount + countFieldCount]; String modemInitString = new String(initStringBytes); modemInitField.setText(modemInitString); // get phone number strings int startNibble; int endNibble; int startByte = partialInitStringCount + countryCodePrefixCount + countFieldCount; startNibble = 2 * startByte; endNibble = 2 * startByte + primaryCount; String primaryPhoneNumber = convertToPhoneNumber(blockBytes, startNibble, endNibble); primaryPhoneField.setText(primaryPhoneNumber); startNibble = 2 * startByte + primaryCount; endNibble = 2 * startByte + primaryCount + secondaryCount; String secondaryPhoneNumber = convertToPhoneNumber(blockBytes, startNibble, endNibble); secondaryPhoneField.setText(secondaryPhoneNumber); } private String convertToPhoneNumber(byte[] bytes, int startNibble, int endNibble) // since phone numbers are BCD encoded, the start and count indices are in NIBBLES, i.e., // half-bytes!!!! { String returnString = new String(); if ( 2 * (startNibble/2) != startNibble) // odd start nibble { byte right = (byte)(bytes[startNibble/2] & 0x0F); returnString += AirportInfoRecord.decodePhoneDigit(right); } for (int i = (startNibble + 1)/2; i < (endNibble)/2; i++) { byte left = (byte)((bytes[i] & 0xF0) >>> 4); byte right = (byte)(bytes[i] & 0x0F); returnString += AirportInfoRecord.decodePhoneDigit(left); returnString += AirportInfoRecord.decodePhoneDigit(right); } if ( 2 * (endNibble/2) != endNibble) // odd end nibble { byte left = (byte)((bytes[endNibble/2] & 0xF0) >>> 4); returnString += AirportInfoRecord.decodePhoneDigit(left); } return returnString; } private byte[] convertFromPhoneNumber(String phoneNumber) throws ValueFormatException // Phone numbers are BCD encoded, with E for dash, D for space or paren, C for comma { char[] chars = phoneNumber.toCharArray(); byte[] bytes = new byte[(chars.length + 1)/2]; for (int i = 0; i < chars.length; i++) { byte nibble; try { nibble = AirportInfoRecord.encodePhoneDigit(chars[i]); } catch(NumberFormatException e) { throw new ValueFormatException("Invalid phone number"); } if (2 * (i/2) == i) // i even, shift left nibble = (byte)(nibble << 4); bytes[i/2] |= nibble; } return bytes; } }airportconfig-1.5.2/airport/AirportPortMappingTable.java0000644000175000017500000002604007503646614023034 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; import byteblock.*; /** * Handles display and updating of port mapping information. */ public class AirportPortMappingTable extends AirportInfoPanel { private AirportInfo airportInfo; private Vector addressVector; private JTable table; private AbstractTableModel tableModel; /** * Table model which maintains list of port mappings. */ private class PortMappingTableModel extends AbstractTableModel { public int getColumnCount() { return 3; } public int getRowCount() { return AirportInfo.MAX_NUM_PORT_MAPS; } public boolean isCellEditable(int row, int col) { if (row <= addressVector.size()) return true; else return false; } public String getColumnName(int col) { switch (col) { case 0: return "Public port number"; case 1: return "Private IP address"; case 2: return "Private port number"; default: return ""; } } public Object getValueAt(int row, int col) { if (row < addressVector.size()) return ((String[])addressVector.elementAt(row))[col]; else return ""; } public void setValueAt(Object newValue, int row, int col) { if (newValue instanceof String) { if (row < addressVector.size()) { String[] addressEntry = (String[])addressVector.elementAt(row); addressEntry[col] = (String)newValue; } else { String[] addressEntry = {"","",""}; addressEntry[col] = (String)newValue; addressVector.insertElementAt(addressEntry, addressVector.size()); } } } } /** * Create new table based on data in airportInfo. */ public AirportPortMappingTable(AirportInfo airportInfo) { this.airportInfo = airportInfo; setUpDisplay(); } private void setUpDisplay() { refreshDisplay(); } /** * Write the MAC addresses and hostnames in the list into the appropriate locations * in the byte block referenced by the AirportInfo object supplied in the constructor. * @throws ValueFormatException Thrown if either an IP address is malformed, or ports * are incorrect. Also sets editting focus to the offending cell. */ public void writeValue() throws ValueFormatException { int baseStartIndex, numRows, numCols, dataType; // first, record changes if cell currently being edited TableCellEditor editor = table.getCellEditor(); if(editor != null) editor.stopCellEditing(); ByteBlock baseBlock = airportInfo.baseBlock; // erase current info AirportInfoRecord eraseRecord; eraseRecord = airportInfo.get("Public port numbers"); eraseRecord.clearWindow(); eraseRecord = airportInfo.get("Private IP addresses, first two octets"); eraseRecord.clearWindow(); eraseRecord = airportInfo.get("Private IP addresses, last two octets"); eraseRecord.clearWindow(); eraseRecord = airportInfo.get("Private port numbers"); eraseRecord.clearWindow(); //create new info records /* * Port mapping functions: * count of port mappings: 0xD62 * public port numbers: 0xDC2, in 2-byte pairs * first two octets of private IP addresses: 0xDEA, * in 2-byte pairs * last two octets of private IP addresses: 0xE12, * in 2-byte pairs * private port numbers: 0xE3A, in 2-byte pairs */ int numPortMaps = 0; int publicPortStartIndex = 0xDC2; int publicPortNumRows = 1; int publicPortNumCols = 2; int publicPortDataType = AirportInfoRecord.UNSIGNED_INTEGER; int privateIPStartIndex = 0xDEA; int privateIPBeginningNumRows = 1; int privateIPBeginningNumCols = 2; int privateIPEndingIndex = 0xE12; int privateIPEndingNumRows = 1; int privateIPEndingNumCols = 2; int privateIPDataType = AirportInfoRecord.IP_ADDRESS; int privatePortStartIndex = 0xE3A; int privatePortNumRows = 1; int privatePortNumCols = 2; int privatePortDataType = AirportInfoRecord.UNSIGNED_INTEGER; for (int i = 0; i < addressVector.size(); i++) { String publicPort = ((String[])addressVector.elementAt(i))[0]; String privateIP = ((String[])addressVector.elementAt(i))[1]; String privatePort = ((String[])addressVector.elementAt(i))[2]; // if null row, just ignore if (! (publicPort.equals("") && privateIP.equals("") && privatePort.equals(""))) { // null address or port throws exception when write to info records try { AirportInfoRecord publicPortRecord = new AirportInfoRecord(publicPortStartIndex, publicPortNumRows, publicPortNumCols, publicPortDataType, baseBlock); publicPortRecord.setBytesFromString(publicPort); } catch (ValueFormatException e) { table.editCellAt(i,0); throw e; } try { // need to have a multi window since address octets not contiguous! ByteBlockMultiWindow privateIPWindow = new ByteBlockMultiWindow(); ByteBlockWindow privateIPBeginningWindow = new ByteBlockRectangularWindow(privateIPStartIndex, privateIPBeginningNumRows, privateIPBeginningNumCols, baseBlock); privateIPWindow.addWindow(privateIPBeginningWindow); ByteBlockWindow privateIPEndingWindow = new ByteBlockRectangularWindow(privateIPEndingIndex, privateIPEndingNumRows, privateIPEndingNumCols, baseBlock); privateIPWindow.addWindow(privateIPEndingWindow); AirportInfoRecord privateIPRecord = new AirportInfoRecord(privateIPDataType, privateIPWindow); privateIPRecord.setBytesFromString(privateIP); } catch (ValueFormatException e) { table.editCellAt(i,1); throw e; } try { AirportInfoRecord privatePortRecord = new AirportInfoRecord(privatePortStartIndex, privatePortNumRows, privatePortNumCols, privatePortDataType, baseBlock); privatePortRecord.setBytesFromString(privatePort); } catch (ValueFormatException e) { table.editCellAt(i,2); throw e; } // augment port map count, start indices publicPortStartIndex += 2; privateIPStartIndex += 2; privateIPEndingIndex += 2; privatePortStartIndex += 2; numPortMaps++; } } // finally, write the number of addresses written AirportInfoRecord portMapCountRecord = airportInfo.get("Count of port mappings"); String countString = new String(); countString += numPortMaps; portMapCountRecord.setBytesFromString(countString); } /** * Refresh the display based on the current data in the underlying byte block. */ public void refreshDisplay() { ByteBlock baseBlock = airportInfo.baseBlock; /* * Port mapping functions: * count of port mappings: 0xD62 * public port numbers: 0xDC2, in 2-byte pairs * first two octets of private IP addresses: 0xDEA, * in 2-byte pairs * last two octets of private IP addresses: 0xE12, * in 2-byte pairs * private port numbers: 0xE3A, in 2-byte pairs */ AirportInfoRecord portMapCountRecord = airportInfo.get("Count of port mappings"); // Read in appropriate number of Mac addresses String countString = portMapCountRecord.toString(); int numPortMaps = 0; try { numPortMaps = Integer.parseInt(countString); } catch(NumberFormatException e) { System.out.println("Problem with number of Mac addresses"); } // create new addressVector, with appropriate size addressVector = new Vector(); int publicPortStartIndex = 0xDC2; int publicPortNumRows = 1; int publicPortNumCols = 2; int publicPortDataType = AirportInfoRecord.UNSIGNED_INTEGER; int privateIPStartIndex = 0xDEA; int privateIPBeginningNumRows = 1; int privateIPBeginningNumCols = 2; int privateIPEndingIndex = 0xE12; int privateIPEndingNumRows = 1; int privateIPEndingNumCols = 2; int privateIPDataType = AirportInfoRecord.IP_ADDRESS; int privatePortStartIndex = 0xE3A; int privatePortNumRows = 1; int privatePortNumCols = 2; int privatePortDataType = AirportInfoRecord.UNSIGNED_INTEGER; for (int i = 0; i < numPortMaps; i++) { AirportInfoRecord publicPortRecord = new AirportInfoRecord(publicPortStartIndex, publicPortNumRows, publicPortNumCols, publicPortDataType, baseBlock); // need to have a multi window since IP address octets not contiguous! ByteBlockMultiWindow privateIPWindow = new ByteBlockMultiWindow(); ByteBlockWindow privateIPBeginningWindow = new ByteBlockRectangularWindow(privateIPStartIndex, privateIPBeginningNumRows, privateIPBeginningNumCols, baseBlock); privateIPWindow.addWindow(privateIPBeginningWindow); ByteBlockWindow privateIPEndingWindow = new ByteBlockRectangularWindow(privateIPEndingIndex, privateIPEndingNumRows, privateIPEndingNumCols, baseBlock); privateIPWindow.addWindow(privateIPEndingWindow); AirportInfoRecord privateIPRecord = new AirportInfoRecord(privateIPDataType, privateIPWindow); AirportInfoRecord privatePortRecord = new AirportInfoRecord(privatePortStartIndex, privatePortNumRows, privatePortNumCols, privatePortDataType, baseBlock); String[] addressEntry = new String[3]; addressEntry[0] = publicPortRecord.toString(); addressEntry[1] = privateIPRecord.toString(); addressEntry[2] = privatePortRecord.toString(); addressVector.insertElementAt(addressEntry, addressVector.size()); publicPortStartIndex += 2; privateIPStartIndex += 2; privateIPEndingIndex += 2; privatePortStartIndex += 2; } this.removeAll(); tableModel = new PortMappingTableModel(); table = new JTable(tableModel); table.setCellSelectionEnabled(true); table.setPreferredScrollableViewportSize(new Dimension(350,200)); JScrollPane scrollPane = new JScrollPane(table); this.add(scrollPane); } }airportconfig-1.5.2/airport/AirportUsernamePanel.java0000644000175000017500000001661707503646614022374 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; import byteblock.*; /** * Utility subpanel which maintains dial-up username and password. */ public class AirportUsernamePanel extends AirportInfoPanel { private AirportInfo airportInfo; private JTextField usernameField, passwordField; public AirportUsernamePanel(AirportInfo airportInfo) { super(); this.airportInfo = airportInfo; setUpDisplay(); } private void setUpDisplay() { usernameField = new JTextField(24); passwordField = new JTextField(24); JLabel usernameLabel = new JLabel("User name"); JLabel passwordLabel = new JLabel("Password"); // 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; this.setLayout(theLayout); // add stuff c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 1; theLayout.setConstraints(usernameLabel, c); this.add(usernameLabel); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 1; theLayout.setConstraints(usernameField, c); this.add(usernameField); c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 2; theLayout.setConstraints(passwordLabel, c); this.add(passwordLabel); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 2; theLayout.setConstraints(passwordField, c); this.add(passwordField); refreshDisplay(); } /** * Method writes character count of dial-up username, username, character count of dial-up password, * and password, terminated by hex byte "01" (not included in either count) if strings not empty. */ public void writeValue() throws ValueFormatException { int baseStartIndex, numRows, numCols, dataType; // erase entire block AirportInfoRecord usernamePasswordRecord = airportInfo.get("Dial-up username/password/PPPoE client ID"); usernamePasswordRecord.clearWindow(); //create new info records, since sizes of some fields may have changed ByteBlock baseBlock = airportInfo.baseBlock; String username = usernameField.getText(); String password = passwordField.getText(); /** * .1.3.6.1.4.1.762.2.3.1.1.63 * * Username@domain, password * byte 10*16 + 11: character count of dial-up username, username, * character count of dial-up password, password. * terminated by hex byte "01" (not included in either count) */ baseStartIndex = 0x3EAA; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; AirportInfoRecord usernameCountRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); int usernameCount = username.length(); String usernameCountString = new String(); usernameCountString += usernameCount; usernameCountRecord.setBytesFromString(usernameCountString); baseStartIndex = 0x3EAB; numRows = 1; numCols = usernameCount + 1; // annoying; to handle null-terminator-room check, unneeded here! dataType = AirportInfoRecord.CHAR_STRING; // name = "Dial-up username"; AirportInfoRecord usernameRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); usernameRecord.setBytesFromString(username); baseStartIndex = 0x3EAB + usernameCount; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; // name = "Dial-up password character count"; AirportInfoRecord passwordCountRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); int passwordCount = password.length(); String passwordCountString = new String(); passwordCountString += passwordCount; passwordCountRecord.setBytesFromString(passwordCountString); baseStartIndex = 0x3EAB + usernameCount + 1; numRows = 1; numCols = passwordCount + 2; dataType = AirportInfoRecord.CHAR_STRING; // name = "Dial-up password"; AirportInfoRecord passwordRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); // terminate password with hex byte "01" char[] terminator = new char[1]; terminator[0] = (char)0x01; password += new String(terminator); passwordRecord.setBytesFromString(password); } /** * Method reads string and parses into: character count of dial-up username, username, * character count of dial-up password, and password, terminated by hex byte "01" * (not included in either count). */ public void refreshDisplay() { int baseStartIndex, numRows, numCols, dataType; //create info records to use to read info for JTextFields ByteBlock baseBlock = airportInfo.baseBlock; /** * .1.3.6.1.4.1.762.2.3.1.1.63 * * Username@domain, password * byte 10*16 + 11: character count of dial-up username, username, * character count of dial-up password, password. */ baseStartIndex = 0x3EAA; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; AirportInfoRecord usernameCountRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); int usernameCount = Integer.parseInt(usernameCountRecord.toString()); baseStartIndex = 0x3EAB; numRows = 1; numCols = usernameCount; dataType = AirportInfoRecord.CHAR_STRING; // name = "Dial-up username"; AirportInfoRecord usernameRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); usernameField.setText(usernameRecord.toString()); baseStartIndex = 0x3EAB + usernameCount; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; // name = "Dial-up password character count"; AirportInfoRecord passwordCountRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); int passwordCount = Integer.parseInt(passwordCountRecord.toString()); baseStartIndex = 0x3EAB + usernameCount + 1; numRows = 1; numCols = passwordCount; dataType = AirportInfoRecord.CHAR_STRING; // name = "Dial-up password"; AirportInfoRecord passwordRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); passwordField.setText(passwordRecord.toString()); } }airportconfig-1.5.2/airport/AirportWirelessPanel.java0000644000175000017500000001362607503646614022407 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; /** * Panel which maintains wireless LAN information: network name, channel, and encryption switch and key. * Note that encryption key is supplied as 10-digit hex string (with no "0x" prefix). */ public class AirportWirelessPanel extends AirportInfoPanel { private AirportInfoLabelledTextField networkNameField, RTSThresholdField; private AirportInfoCheckBox encryptionBox, closedNetworkBox, RTSBox, microwaveRobustnessBox; private AirportInfoRadioButton encryptionKey1Button, encryptionKey2Button, encryptionKey3Button, encryptionKey4Button; private AirportInfoComboBox channelBox; private AirportEncryptionPanel encryptionPanel; public AirportWirelessPanel(AirportInfo theInfo) { networkNameField = new AirportInfoLabelledTextField("Network name", theInfo.get("Network name")); closedNetworkBox = new AirportInfoCheckBox("Closed network"); closedNetworkBox.addInfoRecord(theInfo.get("Closed network flag"), "40", "00"); RTSBox = new AirportInfoCheckBox("Use RTS/CTS"); RTSBox.addInfoRecord(theInfo.get("RTS/CTS flag"), "20", "00"); microwaveRobustnessBox = new AirportInfoCheckBox("Microwave robustness"); microwaveRobustnessBox.addInfoRecord(theInfo.get("Microwave robustness flag"), "20", "00"); RTSThresholdField = new AirportInfoLabelledTextField("RTS threshold", theInfo.get("RTS threshold")); /** * Encryption flag fields: * flag 1: masked with 0x08 * 00 = no encryption * 08 = use encryption * deny unencrypted data flag: masked with 0x80 * 00 = don't deny (no encryption) * 80 = deny (use encryption) * flag 3 * 00 = no encryption * 01 = use encryption * key size * 00 when no encryption * 05 when 40-bit encryption enabled */ encryptionBox = new AirportInfoCheckBox("Use encryption"); encryptionBox.addInfoRecord(theInfo.get("Encryption flag 1"), "08", "00"); encryptionBox.addInfoRecord(theInfo.get("Encryption flag 3"), "01", "00"); // following is taken care of in the encryption panel // encryptionBox.addInfoRecord(theInfo.get("Deny unencrypted data flag"), "80", "00"); channelBox = new AirportInfoComboBox("Wireless channel", theInfo.get("Wireless channel")); for (int i = 1; i < 12; i++) channelBox.addItemAndValue(Integer.toString(i), Integer.toString(i)); encryptionPanel = new AirportEncryptionPanel(theInfo); setUpDisplay(); } public void setUpDisplay() { // 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; c.insets = new Insets(2,2,2,2); c.anchor = GridBagConstraints.CENTER; c.weightx = 0; c.weighty = 0; AirportInfoPanel RTSPanel = new AirportInfoPanel(); RTSPanel.add(RTSThresholdField); AirportInfoPanel RTSMORPanel = new AirportInfoPanel(); RTSMORPanel.setLayout(theLayout); c.insets = new Insets(0,0,0,10); c.anchor = GridBagConstraints.WEST; c.gridx = 1; c.gridy = 1; theLayout.setConstraints(RTSBox, c); RTSMORPanel.add(RTSBox); c.insets = new Insets(0,10,0,10); c.anchor = GridBagConstraints.CENTER; c.gridx = 2; c.gridy = 1; theLayout.setConstraints(RTSPanel, c); RTSMORPanel.add(RTSPanel); c.insets = new Insets(0,10,0,0); c.anchor = GridBagConstraints.EAST; c.gridx = 3; c.gridy = 1; theLayout.setConstraints(microwaveRobustnessBox, c); RTSMORPanel.add(microwaveRobustnessBox); this.setLayout(theLayout); JLabel theLabel; c.insets = new Insets(2,2,2,2); c.anchor = GridBagConstraints.CENTER; c.gridwidth = 2; c.gridx = 1; c.gridy = 1; theLayout.setConstraints(networkNameField, c); this.add(networkNameField); c.anchor = GridBagConstraints.WEST; c.gridwidth = 1; c.gridx = 1; c.gridy = 2; theLayout.setConstraints(channelBox, c); this.add(channelBox); c.anchor = GridBagConstraints.CENTER; c.gridx = 2; c.gridy = 2; theLayout.setConstraints(closedNetworkBox, c); this.add(closedNetworkBox); c.anchor = GridBagConstraints.WEST; c.gridwidth = 2; c.gridx = 1; c.gridy = 3; theLayout.setConstraints(RTSMORPanel, c); this.add(RTSMORPanel); c.anchor = GridBagConstraints.NORTHWEST; c.gridwidth = 1; c.gridx = 1; c.gridy = 4; theLayout.setConstraints(encryptionBox, c); this.add(encryptionBox); c.anchor = GridBagConstraints.CENTER; c.gridx = 2; c.gridy = 4; theLayout.setConstraints(encryptionPanel, c); this.add(encryptionPanel); // make encryption panel enabling dependent on encryption box setting encryptionBox.addItemListener(encryptionPanel); encryptionPanel.setEnabled(encryptionBox.isSelected()); // make RTS threshold panel enabling dependent on RTS box setting RTSBox.addItemListener(RTSPanel); RTSPanel.setEnabled(RTSBox.isSelected()); } }airportconfig-1.5.2/airport/ValueFormatException.java0000644000175000017500000000227707503646614022375 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; /** * Used to report incorrect value format messages, when inappropriate string has been supplied * in a textfield. */ public class ValueFormatException extends Exception { /** * Construct new exception with specified error message. */ public ValueFormatException(String specifics) { super(specifics); } }airportconfig-1.5.2/airport/package.html0000644000175000017500000000475607503646614017713 0ustar julienjulien Airport package The airport package provides many classes useful for reading and writing configuration information from and to an Apple AirPort Base Station.

The configuration information is contained in a 17 k byte memory block that's conveniently viewed as a block with 1088 rows and 16 columns. In fact, the information is exchanged as 68 265-byte SNMPOctetStrings; information is retrieved by sending SNMP Get Requests for OID's 1.3.6.1.4.1.762.2.2.1.1.1 through 1.3.6.1.4.1.762.2.2.1.1.68, and is updated by sending SNMP Set Requests to OID's 1.3.6.1.4.1.762.2.3.1.1.1 through
1.3.6.1.4.1.762.2.3.1.1.68. Due to the necessity of the base station's "burning" received values into its EPROM (so they're maintained even if the unit is powered down), the above 68 Set Requests are followed by two additional Sets, to OID's 1.3.6.1.4.1.762.2.1.2.0 and 1.3.6.1.4.1.762.2.1.3.0, each sending an SNMPInteger with the number of bytes to be "burned in" to the EPROM (only 17336 bytes - not quite all of the 17 k-bytes sent, interestingly.)

When the 17 kB block has been retrieved from a base station, it is used to define a 1088 by 16 byte ByteBlock, which then has a number of windows defined into it enclosing various pieces of information. The ByteBlockWindows are actually defined from within AirportInfoRecord objects, which create the window and also associate a data type with the field. The datatype determines how information is translated between the byte representation and an editable String representation.

A number of user interface components are defined as AirportInfoComponent subclasses, which display and update the information contained in some region of the ByteBlock specified by an AirportInfoRecord. At the top level are AirportInfoPanels, which contain AirportInfoComponents and instruct these to write their values to the underlying windows in the byte block. Other subclasses provide buttons, checkboxes, and editable text fields; some of these may provide facilites for being associated with multiple AirportInfoRecords, for simultaneously writing into multiple fields. See the individual class documents for details. airportconfig-1.5.2/airport/AirportDHCPPanel.java0000644000175000017500000000727507503646614021333 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; /** * Panel which maintains data relevant to bridging (plus address allocation via DHCP and NAT). */ public class AirportDHCPPanel extends AirportInfoPanel { private AirportInfoCheckBox dhcpCheckbox, dhcpOnEthernetCheckbox; private AirportDHCPRangePanel dhcpRangePanel; private AirportInfoPanel dhcpInfoPanel; private AirportInfoLabelledScaledValueField dhcpLeaseTime; /** * Create new panel based on data referenced through the supplied AirportInfo object. */ public AirportDHCPPanel(AirportInfo theInfo) { /** * DHCP switch: 0x449 * 00 = no DHCP service provided * 80 = DHCP on, using specified range of IP addresses */ dhcpCheckbox = new AirportInfoCheckBox("Provide DHCP address delivery to wireless hosts",theInfo.get("DHCP switch"), "80", "00"); dhcpRangePanel = new AirportDHCPRangePanel(theInfo); // create textfield for DHCP lease time dhcpLeaseTime = new AirportInfoLabelledScaledValueField("DHCP lease time (minutes)", theInfo.get("DHCP lease time"), 60); dhcpOnEthernetCheckbox = new AirportInfoCheckBox("Distribute addresses on Ethernet port, too",theInfo.get("Ethernet DHCP switch"), "40", "00"); // create panel to hold info to be disabled when no DHCP service provided dhcpInfoPanel = new AirportInfoPanel(); setUpDisplay(); } private void setUpDisplay() { // 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 = 0; c.weighty = 0; JLabel theLabel; // add stuff to panel dhcpInfoPanel.setLayout(theLayout); c.anchor = GridBagConstraints.WEST; c.gridx = 1; c.gridy = 1; theLayout.setConstraints(dhcpRangePanel, c); dhcpInfoPanel.add(dhcpRangePanel); c.gridx = 1; c.gridy = 2; theLayout.setConstraints(dhcpLeaseTime, c); dhcpInfoPanel.add(dhcpLeaseTime); c.gridx = 1; c.gridy = 3; theLayout.setConstraints(dhcpOnEthernetCheckbox, c); dhcpInfoPanel.add(dhcpOnEthernetCheckbox); // add stuff to this this.setLayout(theLayout); c.anchor = GridBagConstraints.WEST; c.gridx = 1; c.gridy = 1; theLayout.setConstraints(dhcpCheckbox, c); this.add(dhcpCheckbox); c.gridx = 1; c.gridy = 2; theLayout.setConstraints(dhcpInfoPanel, c); this.add(dhcpInfoPanel); // make dhcpInfoPanel highlighting dependent on button setting dhcpCheckbox.addItemListener(dhcpInfoPanel); dhcpInfoPanel.setEnabled(dhcpCheckbox.isSelected()); } }airportconfig-1.5.2/airport/AirportUsernamePPPoEClientIDPanel.java0000644000175000017500000002344207503646614024606 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; import byteblock.*; /** * Utility subpanel which maintains dial-up username and password. */ public class AirportUsernamePPPoEClientIDPanel extends AirportInfoPanel { private AirportInfo airportInfo; private JTextField usernameField, passwordField, pppoeClientIDField; public AirportUsernamePPPoEClientIDPanel(AirportInfo airportInfo) { super(); this.airportInfo = airportInfo; setUpDisplay(); } private void setUpDisplay() { usernameField = new JTextField(24); passwordField = new JTextField(24); pppoeClientIDField = new JTextField(24); JLabel usernameLabel = new JLabel("User name"); JLabel passwordLabel = new JLabel("Password"); JLabel pppoeClientIDLabel = new JLabel("PPPoE client ID"); // 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; this.setLayout(theLayout); // add stuff c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 1; theLayout.setConstraints(usernameLabel, c); this.add(usernameLabel); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 1; theLayout.setConstraints(usernameField, c); this.add(usernameField); c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 2; theLayout.setConstraints(passwordLabel, c); this.add(passwordLabel); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 2; theLayout.setConstraints(passwordField, c); this.add(passwordField); c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 3; theLayout.setConstraints(pppoeClientIDLabel, c); this.add(pppoeClientIDLabel); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 3; theLayout.setConstraints(pppoeClientIDField, c); this.add(pppoeClientIDField); refreshDisplay(); } /** * Method writes character count of dial-up username, username, character count of dial-up password, * and password, terminated by hex byte "01" (not included in either count) if strings not empty. * Then followed by 4 nulls, then PPPoE client ID character count, then PPPoE client ID */ public void writeValue() throws ValueFormatException { int baseStartIndex, numRows, numCols, dataType; // erase entire block AirportInfoRecord usernamePasswordRecord = airportInfo.get("Dial-up username/password/PPPoE client ID"); usernamePasswordRecord.clearWindow(); //create new info records, since sizes of some fields may have changed ByteBlock baseBlock = airportInfo.baseBlock; String username = usernameField.getText(); String password = passwordField.getText(); String pppoeClientID = pppoeClientIDField.getText(); /** * .1.3.6.1.4.1.762.2.3.1.1.63 * * Username@domain, password * byte 10*16 + 11: character count of dial-up username, username, * character count of dial-up password, password. * terminated by hex byte "01" (not included in either count) */ baseStartIndex = 0x3EAA; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; AirportInfoRecord usernameCountRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); int usernameCount = username.length(); String usernameCountString = new String(); usernameCountString += usernameCount; usernameCountRecord.setBytesFromString(usernameCountString); baseStartIndex = 0x3EAA + 1; numRows = 1; numCols = usernameCount + 1; // annoying; to handle null-terminator-room check, unneeded here! dataType = AirportInfoRecord.CHAR_STRING; // name = "Dial-up username"; AirportInfoRecord usernameRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); usernameRecord.setBytesFromString(username); baseStartIndex = 0x3EAA + 1 + usernameCount; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; // name = "Dial-up password character count"; AirportInfoRecord passwordCountRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); int passwordCount = password.length(); String passwordCountString = new String(); passwordCountString += passwordCount; passwordCountRecord.setBytesFromString(passwordCountString); baseStartIndex = 0x3EAA + 1 + usernameCount + 1; numRows = 1; numCols = passwordCount + 6; dataType = AirportInfoRecord.CHAR_STRING; // name = "Dial-up password"; AirportInfoRecord passwordRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); // terminate password with hex byte "01", then padding "00 00 00 00" char[] terminator = new char[5]; terminator[0] = (char)0x01; password += new String(terminator); passwordRecord.setBytesFromString(password); baseStartIndex = 0x3EAA + 1 + usernameCount + 1 + passwordCount + 5; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; // name = "PPPoE client ID character count"; AirportInfoRecord pppoeClientIDCountRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); int pppoeClientIDCount = pppoeClientID.length(); String pppoeClientIDCountString = new String(); pppoeClientIDCountString += pppoeClientIDCount; pppoeClientIDCountRecord.setBytesFromString(pppoeClientIDCountString); baseStartIndex = 0x3EAA + 1 + usernameCount + 1 + passwordCount + 5 + 1; numRows = 1; numCols = pppoeClientIDCount + 1; dataType = AirportInfoRecord.CHAR_STRING; // name = "PPPoE client ID"; AirportInfoRecord pppoeClientIDRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); pppoeClientIDRecord.setBytesFromString(pppoeClientID); } /** * Method reads string and parses into: character count of dial-up username, username, * character count of dial-up password, and password, terminated by hex byte "01" * (not included in either count). */ public void refreshDisplay() { int baseStartIndex, numRows, numCols, dataType; //create info records to use to read info for JTextFields ByteBlock baseBlock = airportInfo.baseBlock; /** * .1.3.6.1.4.1.762.2.3.1.1.63 * * Username@domain, password * byte 10*16 + 11: character count of dial-up username, username, * character count of dial-up password, password. */ baseStartIndex = 0x3EAA; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; AirportInfoRecord usernameCountRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); int usernameCount = Integer.parseInt(usernameCountRecord.toString()); baseStartIndex = 0x3EAA + 1; numRows = 1; numCols = usernameCount; dataType = AirportInfoRecord.CHAR_STRING; // name = "Dial-up username"; AirportInfoRecord usernameRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); usernameField.setText(usernameRecord.toString()); baseStartIndex = 0x3EAA + 1 + usernameCount; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; // name = "Dial-up password character count"; AirportInfoRecord passwordCountRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); int passwordCount = Integer.parseInt(passwordCountRecord.toString()); baseStartIndex = 0x3EAA + 1 + usernameCount + 1; numRows = 1; numCols = passwordCount; dataType = AirportInfoRecord.CHAR_STRING; // name = "Dial-up password"; AirportInfoRecord passwordRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); passwordField.setText(passwordRecord.toString()); baseStartIndex = 0x3EAA + 1 + usernameCount + 1 + passwordCount + 5; numRows = 1; numCols = 1; dataType = AirportInfoRecord.UNSIGNED_INTEGER; // name = "Dial-up password character count"; AirportInfoRecord pppoeClientIDCountRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); int pppoeClientIDCount = Integer.parseInt(pppoeClientIDCountRecord.toString()); baseStartIndex = 0x3EAA + 1 + usernameCount + 1 + passwordCount + 5 + 1; numRows = 1; numCols = pppoeClientIDCount; dataType = AirportInfoRecord.CHAR_STRING; // name = "Dial-up password"; AirportInfoRecord pppoeClientIDRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); pppoeClientIDField.setText(pppoeClientIDRecord.toString()); } }airportconfig-1.5.2/airport/AirportEncryptionPanel.java0000644000175000017500000001377107503646614022745 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; import AirportBaseStationConfigurator; /** * Panel which maintains wireless LAN information: network name, channel, and encryption switch and key. * Note that encryption key is supplied as 10-digit hex string (with no "0x" prefix). */ public class AirportEncryptionPanel extends AirportInfoPanel { private AirportInfoTextField encryptionKey1Field, encryptionKey2Field, encryptionKey3Field, encryptionKey4Field; private AirportInfoRadioButton encryptionKey1Button, encryptionKey2Button, encryptionKey3Button, encryptionKey4Button; private ButtonGroup buttonGroup; private AirportInfoCheckBox allowUnencryptedDataBox; public AirportEncryptionPanel(AirportInfo theInfo) { encryptionKey1Button = new AirportInfoRadioButton("Use encryption key 1:"); encryptionKey1Button.addInfoRecord(theInfo.get("Encryption key selector"), "00"); encryptionKey1Button.addInfoRecord(theInfo.get("Encryption key 1 size"), AirportBaseStationConfigurator.encryptionKeySizeString); encryptionKey2Button = new AirportInfoRadioButton("Use encryption key 2:"); encryptionKey2Button.addInfoRecord(theInfo.get("Encryption key selector"), "40"); encryptionKey2Button.addInfoRecord(theInfo.get("Encryption key 2 size"), AirportBaseStationConfigurator.encryptionKeySizeString); encryptionKey3Button = new AirportInfoRadioButton("Use encryption key 3:"); encryptionKey3Button.addInfoRecord(theInfo.get("Encryption key selector"), "80"); encryptionKey3Button.addInfoRecord(theInfo.get("Encryption key 3 size"), AirportBaseStationConfigurator.encryptionKeySizeString); encryptionKey4Button = new AirportInfoRadioButton("Use encryption key 4:"); encryptionKey4Button.addInfoRecord(theInfo.get("Encryption key selector"), "C0"); encryptionKey4Button.addInfoRecord(theInfo.get("Encryption key 4 size"), AirportBaseStationConfigurator.encryptionKeySizeString); buttonGroup = new ButtonGroup(); buttonGroup.add(encryptionKey1Button); buttonGroup.add(encryptionKey2Button); buttonGroup.add(encryptionKey3Button); buttonGroup.add(encryptionKey4Button); encryptionKey1Field = new AirportInfoTextField(theInfo.get("Encryption key 1")); encryptionKey2Field = new AirportInfoTextField(theInfo.get("Encryption key 2")); encryptionKey3Field = new AirportInfoTextField(theInfo.get("Encryption key 3")); encryptionKey4Field = new AirportInfoTextField(theInfo.get("Encryption key 4")); /** * Deny unencrypted data flag: * byte 6*16 + 9, mask 0x80 (bit 8) * 00 = allow all packets * 80 = allow only encrypted packets */ allowUnencryptedDataBox = new AirportInfoCheckBox("Allow unencrypted data"); allowUnencryptedDataBox.addInfoRecord(theInfo.get("Deny unencrypted data flag"), "00", "80"); setUpDisplay(); } public void setUpDisplay() { // 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; c.insets = new Insets(2,2,2,2); c.anchor = GridBagConstraints.CENTER; c.weightx = .5; c.weighty = .5; this.setLayout(theLayout); JLabel theLabel; if (AirportBaseStationConfigurator.encryptionKeySizeString.equals("0D")) { c.gridwidth = 2; c.gridx = 1; c.gridy = 1; theLabel = new JLabel("NOTE: wireless card in base station must be changed to Gold version for 128-bit encryption to function!"); theLayout.setConstraints(theLabel, c); this.add(theLabel); } c.gridwidth = 1; c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 2; theLayout.setConstraints(encryptionKey1Button, c); this.add(encryptionKey1Button); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 2; theLayout.setConstraints(encryptionKey1Field, c); this.add(encryptionKey1Field); c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 3; theLayout.setConstraints(encryptionKey2Button, c); this.add(encryptionKey2Button); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 3; theLayout.setConstraints(encryptionKey2Field, c); this.add(encryptionKey2Field); c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 4; theLayout.setConstraints(encryptionKey3Button, c); this.add(encryptionKey3Button); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 4; theLayout.setConstraints(encryptionKey3Field, c); this.add(encryptionKey3Field); c.anchor = GridBagConstraints.EAST; c.gridx = 1; c.gridy = 5; theLayout.setConstraints(encryptionKey4Button, c); this.add(encryptionKey4Button); c.anchor = GridBagConstraints.WEST; c.gridx = 2; c.gridy = 5; theLayout.setConstraints(encryptionKey4Field, c); this.add(encryptionKey4Field); c.gridwidth = 2; c.anchor = GridBagConstraints.CENTER; c.gridx = 1; c.gridy = 6; theLayout.setConstraints(allowUnencryptedDataBox, c); this.add(allowUnencryptedDataBox); } }airportconfig-1.5.2/airport/AirportDistanceRatePanel.java0000644000175000017500000001444407503646614023157 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; /** * Panel which maintains wireless LAN information: network name, channel, and encryption switch and key. * Note that encryption key is supplied as 10-digit hex string (with no "0x" prefix). */ public class AirportDistanceRatePanel extends AirportInfoPanel { private AirportInfoRadioButton large1MbpsButton, large2MbpsButton; private AirportInfoRadioButton medium1MbpsButton, medium2MbpsButton, medium5MbpsButton; private AirportInfoRadioButton small1MbpsButton, small2MbpsButton, small5MbpsButton, small11MbpsButton; private ButtonGroup buttonGroup; public AirportDistanceRatePanel(AirportInfo theInfo) { /** * Distance between access points, rate: 0x0169 * mask 0x0F (lower nibble) * * large medium small * 1 Mbps 00 01 02 * 2 Mbps 04 05 06 * 5.5 Mbps na 09 0a * 11 Mbps na na 0e */ large1MbpsButton = new AirportInfoRadioButton(""); large1MbpsButton.addInfoRecord(theInfo.get("Distance and rate field"), "00"); medium1MbpsButton = new AirportInfoRadioButton(""); medium1MbpsButton.addInfoRecord(theInfo.get("Distance and rate field"), "01"); small1MbpsButton = new AirportInfoRadioButton(""); small1MbpsButton.addInfoRecord(theInfo.get("Distance and rate field"), "02"); large2MbpsButton = new AirportInfoRadioButton(""); large2MbpsButton.addInfoRecord(theInfo.get("Distance and rate field"), "04"); medium2MbpsButton = new AirportInfoRadioButton(""); medium2MbpsButton.addInfoRecord(theInfo.get("Distance and rate field"), "05"); small2MbpsButton = new AirportInfoRadioButton(""); small2MbpsButton.addInfoRecord(theInfo.get("Distance and rate field"), "06"); medium5MbpsButton = new AirportInfoRadioButton(""); medium5MbpsButton.addInfoRecord(theInfo.get("Distance and rate field"), "09"); small5MbpsButton = new AirportInfoRadioButton(""); small5MbpsButton.addInfoRecord(theInfo.get("Distance and rate field"), "0A"); small11MbpsButton = new AirportInfoRadioButton(""); small11MbpsButton.addInfoRecord(theInfo.get("Distance and rate field"), "0E"); buttonGroup = new ButtonGroup(); buttonGroup.add(large1MbpsButton); buttonGroup.add(medium1MbpsButton); buttonGroup.add(small1MbpsButton); buttonGroup.add(large2MbpsButton); buttonGroup.add(medium2MbpsButton); buttonGroup.add(small2MbpsButton); buttonGroup.add(medium5MbpsButton); buttonGroup.add(small5MbpsButton); buttonGroup.add(small11MbpsButton); setUpDisplay(); } public void setUpDisplay() { // 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; c.insets = new Insets(2,2,2,2); c.anchor = GridBagConstraints.CENTER; c.weightx = .5; c.weighty = .5; this.setLayout(theLayout); JLabel theLabel; c.gridwidth = 3; c.gridx = 2; c.gridy = 1; theLabel = new JLabel("Distance between access points"); theLayout.setConstraints(theLabel, c); this.add(theLabel); c.gridwidth = 1; c.insets = new Insets(2,10,8,10); c.gridx = 1; c.gridy = 2; theLabel = new JLabel("Rate:"); theLayout.setConstraints(theLabel, c); this.add(theLabel); c.gridx = 2; c.gridy = 2; theLabel = new JLabel("Large "); theLayout.setConstraints(theLabel, c); this.add(theLabel); c.gridx = 3; c.gridy = 2; theLabel = new JLabel("Medium"); theLayout.setConstraints(theLabel, c); this.add(theLabel); c.gridx = 4; c.gridy = 2; theLabel = new JLabel("Small "); theLayout.setConstraints(theLabel, c); this.add(theLabel); c.insets = new Insets(2,2,2,2); c.gridx = 1; c.gridy = 3; theLabel = new JLabel("1 Mbps"); theLayout.setConstraints(theLabel, c); this.add(theLabel); c.gridx = 2; c.gridy = 3; theLayout.setConstraints(large1MbpsButton, c); this.add(large1MbpsButton); c.gridx = 3; c.gridy = 3; theLayout.setConstraints(medium1MbpsButton, c); this.add(medium1MbpsButton); c.gridx = 4; c.gridy = 3; theLayout.setConstraints(small1MbpsButton, c); this.add(small1MbpsButton); c.gridx = 1; c.gridy = 4; theLabel = new JLabel("2 Mbps"); theLayout.setConstraints(theLabel, c); this.add(theLabel); c.gridx = 2; c.gridy = 4; theLayout.setConstraints(large2MbpsButton, c); this.add(large2MbpsButton); c.gridx = 3; c.gridy = 4; theLayout.setConstraints(medium2MbpsButton, c); this.add(medium2MbpsButton); c.gridx = 4; c.gridy = 4; theLayout.setConstraints(small2MbpsButton, c); this.add(small2MbpsButton); c.gridx = 1; c.gridy = 5; theLabel = new JLabel("5.5 Mbps"); theLayout.setConstraints(theLabel, c); this.add(theLabel); c.gridx = 3; c.gridy = 5; theLayout.setConstraints(medium5MbpsButton, c); this.add(medium5MbpsButton); c.gridx = 4; c.gridy = 5; theLayout.setConstraints(small5MbpsButton, c); this.add(small5MbpsButton); c.gridx = 1; c.gridy = 6; theLabel = new JLabel("11 Mbps"); theLayout.setConstraints(theLabel, c); this.add(theLabel); c.gridx = 4; c.gridy = 6; theLayout.setConstraints(small11MbpsButton, c); this.add(small11MbpsButton); } }airportconfig-1.5.2/airport/AirportSNMPPanel.java0000644000175000017500000001034007503646614021355 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; /** * Panel which maintains wireless LAN information: network name, channel, and encryption switch and key. * Note that encryption key is supplied as 10-digit hex string (with no "0x" prefix). */ public class AirportSNMPPanel extends AirportInfoPanel { private AirportInfoLabelledTextField trapHostPasswordField, trapHostIPAddressField, syslogHostIPAddressField; private AirportInfoComboBox syslogHostFacilityBox; //private AirportSNMPAccessControlTable snmpAccessControlTable; public AirportSNMPPanel(AirportInfo theInfo) { /* 0x0478: syslog IP address 0x0440: syslog host facility(0 - 8) 0x047C: trap host IP address 0x0056: trap host password 0x0076: read password */ trapHostPasswordField = new AirportInfoLabelledTextField("Trap host password:", theInfo.get("Trap community")); trapHostIPAddressField = new AirportInfoLabelledTextField("Trap host IP address:", theInfo.get("Trap host IP address")); syslogHostIPAddressField = new AirportInfoLabelledTextField("Syslog host IP address:", theInfo.get("Syslog host IP address")); syslogHostFacilityBox = new AirportInfoComboBox("Syslog host facility", theInfo.get("Syslog host facility")); for (int i = 0; i < 9; i++) syslogHostFacilityBox.addItemAndValue(Integer.toString(i), Integer.toString(i)); /** * * SNMP access control list: require multi-block windows * * 0x0636: number of entries (0-5) * * 0x0638, 0x063a, 0x063c, 0x063e, 0x0640: first two octets of IP addresses * 0x0642, 0x0644, 0x0646, 0x0648, 0x064a: second two octets of IP addresses * * 0x064c, 0x064e, 0x0650, 0x0652, 0x0654: first two octets of masks * 0x0656, 0x0658, 0x065a, 0x065c, 0x065e: second two octets of masks * * 0x0660, 0x0662, 0x0664, 0x0666, 0x0668: interfaces: 2-byte little-endian (any = ff ff) */ // Nuts! The base station doesn't restrict SNMP access.... :-( //snmpAccessControlTable = new AirportSNMPAccessControlTable(theInfo); setUpDisplay(); } public void setUpDisplay() { // 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; c.insets = new Insets(8,2,2,2); c.anchor = GridBagConstraints.CENTER; c.weightx = 0; c.weighty = 0; this.setLayout(theLayout); JLabel theLabel; c.gridx = 1; c.gridy = 1; theLayout.setConstraints(trapHostIPAddressField, c); this.add(trapHostIPAddressField); c.gridx = 2; c.gridy = 1; theLayout.setConstraints(trapHostPasswordField, c); this.add(trapHostPasswordField); c.gridx = 1; c.gridy = 2; theLayout.setConstraints(syslogHostIPAddressField, c); this.add(syslogHostIPAddressField); c.gridx = 2; c.gridy = 2; theLayout.setConstraints(syslogHostFacilityBox, c); this.add(syslogHostFacilityBox); c.gridwidth = 2; /* c.gridx = 1; c.gridy = 3; theLabel = new JLabel("SNMP Access Control List"); theLayout.setConstraints(theLabel, c); this.add(theLabel); c.gridx = 1; c.gridy = 4; theLayout.setConstraints(snmpAccessControlTable, c); this.add(snmpAccessControlTable); */ } }airportconfig-1.5.2/airport/AirportAdvancedPanel.java0000644000175000017500000000424707503646614022316 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; /** * Panel which maintains wireless LAN information: network name, channel, and encryption switch and key. * Note that encryption key is supplied as 10-digit hex string (with no "0x" prefix). */ public class AirportAdvancedPanel extends AirportInfoPanel { private AirportDistanceRatePanel distanceRatePanel; public AirportAdvancedPanel(AirportInfo theInfo) { distanceRatePanel = new AirportDistanceRatePanel(theInfo); setUpDisplay(); } public void setUpDisplay() { // 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; c.insets = new Insets(8,2,2,2); c.anchor = GridBagConstraints.CENTER; c.weightx = 0; c.weighty = 0; this.setLayout(theLayout); JLabel theLabel; c.gridx = 1; c.gridy = 1; theLabel = new JLabel("Wireless LAN Multicast Rate / Access Point Separation Setting"); theLayout.setConstraints(theLabel, c); this.add(theLabel); c.gridx = 1; c.gridy = 2; theLayout.setConstraints(distanceRatePanel, c); this.add(distanceRatePanel); } }airportconfig-1.5.2/airport/AirportSNMPAccessControlTable.java0000644000175000017500000003456607503646614024050 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; import byteblock.*; /** * Handles display and updating of IP addresses, masks and interface numbers used for SNMP access control. */ public class AirportSNMPAccessControlTable extends AirportInfoPanel { private AirportInfo airportInfo; private Vector addressVector; private JTable table; private AbstractTableModel tableModel; private JComboBox interfaceComboBox; private Hashtable interfaceNameToNumberHashtable, interfaceNumberToNameHashtable; /** * Table model which maintains list of IP addresses, masks and interface numbers. */ private class AccessAddressTableModel extends AbstractTableModel { public int getColumnCount() { return 3; } public int getRowCount() { return AirportInfo.MAX_NUM_SNMP_ACCESS_ENTRIES; } public boolean isCellEditable(int row, int col) { if (row <= addressVector.size()) return true; else return false; } public String getColumnName(int col) { switch (col) { case 0: return "IP address"; case 1: return "Address mask"; default: return "Interface"; } } /* * JTable uses this method to determine the default renderer/ * editor for each cell. */ public Class getColumnClass(int column) { String temp = ""; return temp.getClass(); } public Object getValueAt(int row, int col) { if (row < addressVector.size()) { return ((String[])addressVector.elementAt(row))[col]; } else return ""; } public void setValueAt(Object newValue, int row, int col) { if (row < addressVector.size()) { String[] addressEntry = (String[])addressVector.elementAt(row); addressEntry[col] = (String)newValue; } else { String[] addressEntry = {"", "", ""}; addressEntry[col] = (String)newValue; addressVector.insertElementAt(addressEntry, addressVector.size()); } fireTableCellUpdated(row, col); } } /** * Create new table based on data in airportInfo. */ public AirportSNMPAccessControlTable(AirportInfo airportInfo) { this.airportInfo = airportInfo; interfaceComboBox = new JComboBox(); interfaceComboBox.addItem("All"); interfaceComboBox.addItem("Ethernet"); interfaceComboBox.addItem("Wireless"); interfaceComboBox.addItem("Modem"); interfaceNameToNumberHashtable = new Hashtable(); interfaceNameToNumberHashtable.put("Ethernet", "0"); interfaceNameToNumberHashtable.put("Wireless", "1"); interfaceNameToNumberHashtable.put("Modem", "2"); interfaceNameToNumberHashtable.put("All", "65535"); interfaceNumberToNameHashtable = new Hashtable(); interfaceNumberToNameHashtable.put("0", "Ethernet"); interfaceNumberToNameHashtable.put("1", "Wireless"); interfaceNumberToNameHashtable.put("2", "Modem"); interfaceNumberToNameHashtable.put("65535", "All"); setUpDisplay(); } private void setUpDisplay() { refreshDisplay(); } /** * Write the IP addresses and masks in the list into the appropriate locations * in the byte block referenced by the AirportInfo object supplied in the constructor. * @throws ValueFormatException Thrown if an IP address or mask is malformed. Also sets * editting focus to the offending cell. */ public void writeValue() throws ValueFormatException { int baseStartIndex, numRows, numCols, dataType; // first, record changes if cell currently being edited TableCellEditor editor = table.getCellEditor(); if(editor != null) editor.stopCellEditing(); ByteBlock baseBlock = airportInfo.baseBlock; // erase current blocks of info baseStartIndex = 0x0638; numRows = 1; numCols = 10 * AirportInfo.MAX_NUM_SNMP_ACCESS_ENTRIES; dataType = AirportInfoRecord.BYTE_STRING; AirportInfoRecord portMapBlockRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, baseBlock); portMapBlockRecord.clearWindow(); //create new info records /* * * SNMP access control list: require multi-block windows * * 0x0636: number of entries (0-5) * * 0x0638, 0x063a, 0x063c, 0x063e, 0x0640: first two octets of IP addresses * 0x0642, 0x0644, 0x0646, 0x0648, 0x064a: second two octets of IP addresses * * 0x064c, 0x064e, 0x0650, 0x0652, 0x0654: first two octets of masks * 0x0656, 0x0658, 0x065a, 0x065c, 0x065e: second two octets of masks * * 0x0660, 0x0662, 0x0664, 0x0666, 0x0668: interfaces: 2-byte little-endian (any = ff ff) */ int numSNMPEntries = 0; int ipAddressStartIndex = 0x0638; int ipAddressBeginningNumRows = 1; int ipAddressBeginningNumCols = 2; int ipAddressEndingIndex = 0x0642; int ipAddressEndingNumRows = 1; int ipAddressEndingNumCols = 2; int ipAddressDataType = AirportInfoRecord.IP_ADDRESS; int ipMaskStartIndex = 0x064c; int ipMaskBeginningNumRows = 1; int ipMaskBeginningNumCols = 2; int ipMaskEndingIndex = 0x0656; int ipMaskEndingNumRows = 1; int ipMaskEndingNumCols = 2; int ipMaskDataType = AirportInfoRecord.IP_ADDRESS; int interfaceNumberStartIndex = 0x0660; int interfaceNumberNumRows = 1; int interfaceNumberNumCols = 2; int interfaceNumberDataType = AirportInfoRecord.LITTLE_ENDIAN_UNSIGNED_INTEGER; for (int i = 0; i < addressVector.size(); i++) { String ipAddress = ((String[])addressVector.elementAt(i))[0]; String ipMask = ((String[])addressVector.elementAt(i))[1]; String interfaceName = ((String[])addressVector.elementAt(i))[2]; // if null row, just ignore if (! (ipAddress.equals(""))) { // null address or port throws exception when write to info records try { // need to have a multi window since address octets not contiguous! ByteBlockMultiWindow ipAddressWindow = new ByteBlockMultiWindow(); ByteBlockWindow ipAddressBeginningWindow = new ByteBlockRectangularWindow(ipAddressStartIndex, ipAddressBeginningNumRows, ipAddressBeginningNumCols, baseBlock); ipAddressWindow.addWindow(ipAddressBeginningWindow); ByteBlockWindow ipAddressEndingWindow = new ByteBlockRectangularWindow(ipAddressEndingIndex, ipAddressEndingNumRows, ipAddressEndingNumCols, baseBlock); ipAddressWindow.addWindow(ipAddressEndingWindow); AirportInfoRecord ipAddressRecord = new AirportInfoRecord(ipAddressDataType, ipAddressWindow); ipAddressRecord.setBytesFromString(ipAddress); } catch (ValueFormatException e) { table.editCellAt(i,0); throw e; } try { // need to have a multi window since address octets not contiguous! ByteBlockMultiWindow ipMaskWindow = new ByteBlockMultiWindow(); ByteBlockWindow ipMaskBeginningWindow = new ByteBlockRectangularWindow(ipMaskStartIndex, ipMaskBeginningNumRows, ipMaskBeginningNumCols, baseBlock); ipMaskWindow.addWindow(ipMaskBeginningWindow); ByteBlockWindow ipMaskEndingWindow = new ByteBlockRectangularWindow(ipMaskEndingIndex, ipMaskEndingNumRows, ipMaskEndingNumCols, baseBlock); ipMaskWindow.addWindow(ipMaskEndingWindow); AirportInfoRecord ipMaskRecord = new AirportInfoRecord(ipMaskDataType, ipMaskWindow); ipMaskRecord.setBytesFromString(ipMask); } catch (ValueFormatException e) { table.editCellAt(i,1); throw e; } try { AirportInfoRecord interfaceNumberRecord = new AirportInfoRecord(interfaceNumberStartIndex, interfaceNumberNumRows, interfaceNumberNumCols, interfaceNumberDataType, baseBlock); // need to convert name to number using Hashtable String interfaceNumber = (String)interfaceNameToNumberHashtable.get(interfaceName); interfaceNumberRecord.setBytesFromString(interfaceNumber); } catch (ValueFormatException e) { table.editCellAt(i,2); throw e; } // augment port map count, start indices ipAddressStartIndex += 2; ipAddressEndingIndex += 2; ipMaskStartIndex += 2; ipMaskEndingIndex += 2; interfaceNumberStartIndex += 2; numSNMPEntries++; } } // finally, write the number of addresses written AirportInfoRecord snmpAccessControlCountRecord = airportInfo.get("SNMP access control list length"); String countString = new String(); countString += numSNMPEntries; snmpAccessControlCountRecord.setBytesFromString(countString); } /** * Refresh the display based on the current data in the underlying byte block. */ public void refreshDisplay() { ByteBlock baseBlock = airportInfo.baseBlock; /* * * SNMP access control list: require multi-block windows * * 0x0636: number of entries (0-5) * * 0x0638, 0x063a, 0x063c, 0x063e, 0x0640: first two octets of IP addresses * 0x0642, 0x0644, 0x0646, 0x0648, 0x064a: second two octets of IP addresses * * 0x064c, 0x064e, 0x0650, 0x0652, 0x0654: first two octets of masks * 0x0656, 0x0658, 0x065a, 0x065c, 0x065e: second two octets of masks * * 0x0660, 0x0662, 0x0664, 0x0666, 0x0668: interfaces: 2-byte little-endian (any = ff ff) */ AirportInfoRecord snmpAccessControlCountRecord = airportInfo.get("SNMP access control list length"); // Read in appropriate number of Mac addresses String countString = snmpAccessControlCountRecord.toString(); int numSNMPEntries = 0; try { numSNMPEntries = Integer.parseInt(countString); } catch(NumberFormatException e) { System.out.println("Problem with number of SNMP access control entries"); } // create new addressVector, with appropriate size addressVector = new Vector(); int ipAddressStartIndex = 0x0638; int ipAddressBeginningNumRows = 1; int ipAddressBeginningNumCols = 2; int ipAddressEndingIndex = 0x0642; int ipAddressEndingNumRows = 1; int ipAddressEndingNumCols = 2; int ipAddressDataType = AirportInfoRecord.IP_ADDRESS; int ipMaskStartIndex = 0x064c; int ipMaskBeginningNumRows = 1; int ipMaskBeginningNumCols = 2; int ipMaskEndingIndex = 0x0656; int ipMaskEndingNumRows = 1; int ipMaskEndingNumCols = 2; int ipMaskDataType = AirportInfoRecord.IP_ADDRESS; int interfaceNumberStartIndex = 0x0660; int interfaceNumberNumRows = 1; int interfaceNumberNumCols = 2; int interfaceNumberDataType = AirportInfoRecord.LITTLE_ENDIAN_UNSIGNED_INTEGER; for (int i = 0; i < numSNMPEntries; i++) { // need to have a multi window since IP address octets not contiguous! ByteBlockMultiWindow ipAddressWindow = new ByteBlockMultiWindow(); ByteBlockWindow ipAddressBeginningWindow = new ByteBlockRectangularWindow(ipAddressStartIndex, ipAddressBeginningNumRows, ipAddressBeginningNumCols, baseBlock); ipAddressWindow.addWindow(ipAddressBeginningWindow); ByteBlockWindow ipAddressEndingWindow = new ByteBlockRectangularWindow(ipAddressEndingIndex, ipAddressEndingNumRows, ipAddressEndingNumCols, baseBlock); ipAddressWindow.addWindow(ipAddressEndingWindow); AirportInfoRecord ipAddressRecord = new AirportInfoRecord(ipAddressDataType, ipAddressWindow); ByteBlockMultiWindow ipMaskWindow = new ByteBlockMultiWindow(); ByteBlockWindow ipMaskBeginningWindow = new ByteBlockRectangularWindow(ipMaskStartIndex, ipMaskBeginningNumRows, ipMaskBeginningNumCols, baseBlock); ipMaskWindow.addWindow(ipMaskBeginningWindow); ByteBlockWindow ipMaskEndingWindow = new ByteBlockRectangularWindow(ipMaskEndingIndex, ipMaskEndingNumRows, ipMaskEndingNumCols, baseBlock); ipMaskWindow.addWindow(ipMaskEndingWindow); AirportInfoRecord ipMaskRecord = new AirportInfoRecord(ipMaskDataType, ipMaskWindow); AirportInfoRecord interfaceNumberRecord = new AirportInfoRecord(interfaceNumberStartIndex, interfaceNumberNumRows, interfaceNumberNumCols, interfaceNumberDataType, baseBlock); String[] addressEntry = new String[3]; addressEntry[0] = ipAddressRecord.toString(); addressEntry[1] = ipMaskRecord.toString(); // need to convert number to name using Hashtable String interfaceNumber = interfaceNumberRecord.toString(); System.out.println("Interface number: " + interfaceNumber); addressEntry[2] = (String)interfaceNumberToNameHashtable.get(interfaceNumber); System.out.println("Interface value: " + addressEntry[2]); addressVector.insertElementAt(addressEntry, addressVector.size()); ipAddressStartIndex += 2; ipAddressEndingIndex += 2; ipMaskStartIndex += 2; ipMaskEndingIndex += 2; interfaceNumberStartIndex += 2; } this.removeAll(); tableModel = new AccessAddressTableModel(); table = new JTable(tableModel); table.setCellSelectionEnabled(true); //Set up the editor for the interface column. table.getColumn("Interface").setCellEditor(new DefaultCellEditor(interfaceComboBox)); table.setPreferredScrollableViewportSize(new Dimension(300,80)); JScrollPane scrollPane = new JScrollPane(table); this.add(scrollPane); } }airportconfig-1.5.2/airport/AirportLoginStringTable.java0000644000175000017500000002534407503646614023041 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; import byteblock.*; /** * Handles display and updating of entries used in login string. */ public class AirportLoginStringTable extends AirportInfoPanel { private AirportInfo airportInfo; private Vector tableContentsVector; private JTable table; private JScrollPane tableScrollPane; private AbstractTableModel tableModel; private JComboBox elementTypeComboBox; private final int MAX_NUM_LOGIN_STRING_ENTRIES = 20; /** * Table model which maintains list of login string elements. */ private class LoginStringTableModel extends AbstractTableModel { public int getColumnCount() { return 3; } public int getRowCount() { return MAX_NUM_LOGIN_STRING_ENTRIES; } public boolean isCellEditable(int row, int col) { if (row <= tableContentsVector.size()) { if (col < 2) return true; else // carriage return column; editable only if send or receive (not delay) { if (row == tableContentsVector.size()) return false; else { Object[] currentRow = (Object[])tableContentsVector.elementAt(row); if ( ((String)currentRow[0]).equals("Send string") || ((String)currentRow[0]).equals("Expect string") ) return true; else return false; } } } else return false; } public String getColumnName(int col) { switch (col) { case 0: return "Element type"; case 1: return "Value"; default: return "Carriage return"; } } /* * JTable uses this method to determine the default renderer/ * editor for each cell. */ public Class getColumnClass(int column) { String stringDummy = ""; Boolean booleanDummy = new Boolean(true); switch (column) { case 0: return stringDummy.getClass(); case 1: return stringDummy.getClass(); default: return booleanDummy.getClass(); } } public Object getValueAt(int row, int col) { //System.out.println("Get value: " + row + ", " + col); if (row < tableContentsVector.size()) { return ((Object[])tableContentsVector.elementAt(row))[col]; } else { if (col < 2) return ""; else return new Boolean(false); } } public void setValueAt(Object newValue, int row, int col) { if (row < tableContentsVector.size()) { Object[] addressEntry = (Object[])tableContentsVector.elementAt(row); addressEntry[col] = newValue; // if change type to "delay", erase cr entry if ( (col == 0) && (((String)newValue).equals("Delay (seconds)")) ) { addressEntry[2] = new Boolean(false); fireTableCellUpdated(row, 2); } } else { Object[] addressEntry = {"", "", new Boolean(false)}; addressEntry[col] = newValue; tableContentsVector.insertElementAt(addressEntry, tableContentsVector.size()); } //System.out.println("New value: " + newValue); fireTableCellUpdated(row, col); } } /** * Create new table based on data in airportInfo. */ public AirportLoginStringTable(AirportInfo airportInfo) { this.airportInfo = airportInfo; tableContentsVector = new Vector(); elementTypeComboBox = new JComboBox(); elementTypeComboBox.addItem(""); elementTypeComboBox.addItem("Expect string"); elementTypeComboBox.addItem("Send string"); elementTypeComboBox.addItem("Delay (seconds)"); setUpDisplay(); } private void setUpDisplay() { refreshDisplay(); } /** * Write the modem string information into the appropriate location * in the byte block referenced by the AirportInfo object supplied in the constructor. * @throws ValueFormatException Thrown if an entry is malformed. Also sets * editting focus to the offending cell. */ public void writeValue() throws ValueFormatException { // first, record changes if cell currently being edited TableCellEditor editor = table.getCellEditor(); if(editor != null) editor.stopCellEditing(); // erase current block of info AirportInfoRecord loginStringBlockRecord = airportInfo.get("Login information string"); loginStringBlockRecord.clearWindow(); byte[] loginBytes = new byte[AirportInfo.MAX_NUM_LOGIN_CHARS]; int currentPosition = 0; for (int i = 0; i < tableContentsVector.size(); i++) { String elementTypeString = (String)((Object[])tableContentsVector.elementAt(i))[0]; String elementValueString = (String)((Object[])tableContentsVector.elementAt(i))[1]; boolean carriageReturnFlag = ((Boolean)((Object[])tableContentsVector.elementAt(i))[2]).booleanValue(); // if null type, just ignore if (!(elementTypeString.equals(""))) { try { // set start byte: // Send string = 0x40, Expect string = 0x80, Delay = 0xC0 // plus number of characters to follow, or delay value if (elementTypeString.equals("Expect string") || elementTypeString.equals("Send string")) { if (elementTypeString.equals("Expect string")) loginBytes[currentPosition] = (byte)0x80; else if (elementTypeString.equals("Send string")) loginBytes[currentPosition] = (byte)0x40; loginBytes[currentPosition] += elementValueString.length(); if (carriageReturnFlag == true) ++loginBytes[currentPosition]; ++currentPosition; byte[] valueBytes = elementValueString.getBytes(); for (int j = 0; j < elementValueString.length(); j++) { loginBytes[currentPosition] = valueBytes[j]; ++currentPosition; } if (carriageReturnFlag == true) { loginBytes[currentPosition] = 0x0D; // CR in ACSCII ++currentPosition; } } else if (elementTypeString.equals("Delay (seconds)")) { int delayValue = Integer.parseInt(elementValueString); loginBytes[currentPosition] = (byte)(0xC0 + delayValue); ++currentPosition; if ((delayValue < 0) || (delayValue > 63)) { table.editCellAt(i,1); throw new ValueFormatException("Delay must be between 0 and 63 seconds"); } } } catch (NumberFormatException e) { table.editCellAt(i,1); throw new ValueFormatException("Bad delay value"); } catch (ArrayIndexOutOfBoundsException e) { throw new ValueFormatException("Login string too long (maximum size 127 characters)"); } loginStringBlockRecord.byteBlockWindow.writeBytes(loginBytes); } } } /** * Refresh the display based on the current data in the underlying byte block. */ public void refreshDisplay() { AirportInfoRecord loginStringBlockRecord = airportInfo.get("Login information string"); byte[] loginBytes = loginStringBlockRecord.byteBlockWindow.getBytes(); int currentPosition = 0; WhileLoop: while (currentPosition < loginBytes.length) { int typeAndLength = loginBytes[currentPosition]; ++currentPosition; // make positive if (typeAndLength < 0) typeAndLength += 256; int length = typeAndLength % 64; int type = typeAndLength - length; switch (type) { case 0xC0: // delay entry { Object[] addressEntry = {"Delay (seconds)", Integer.toString(length), new Boolean(false)}; tableContentsVector.insertElementAt(addressEntry, tableContentsVector.size()); break; } case 0x40: // send string, receive string entry case 0x80: { String valueString = new String(loginBytes); valueString = valueString.substring(currentPosition, currentPosition + length); currentPosition += length; boolean crFlag; if (loginBytes[currentPosition - 1] == 0x0d) // see if last char is CR { // if last char is CR, strip it off and set crFlag valueString = valueString.substring(0, length - 1); crFlag = true; } else { crFlag = false; } Object[] addressEntry = new Object[3]; addressEntry[1] = valueString; addressEntry[2] = new Boolean(crFlag); if (type == 0x40) { addressEntry[0] = "Send string"; } else // (type == 0x80) { addressEntry[0] = "Expect string"; } tableContentsVector.insertElementAt(addressEntry, tableContentsVector.size()); break; } default: { // break out of while loop... break WhileLoop; } } } // remove all components... this.removeAll(); // create new table model and table... tableModel = new LoginStringTableModel(); table = new JTable(tableModel); table.setCellSelectionEnabled(true); //Set the editor for the interface column. table.getColumn("Element type").setCellEditor(new DefaultCellEditor(elementTypeComboBox)); table.setPreferredScrollableViewportSize(new Dimension(300,150)); // add it to a scroll pane tableScrollPane = new JScrollPane(table); this.add(tableScrollPane); } /** * Enable and disable JTable as well as any other contained components. */ public void setEnabled(boolean enabled) { super.setEnabled(enabled); table.setEnabled(enabled); } }airportconfig-1.5.2/airport/AirportLoginInfoDialog.java0000644000175000017500000000731407503646614022633 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * Frame which presents data pertaining to modem login info. */ public class AirportLoginInfoDialog extends JDialog implements ActionListener { private AirportLoginInfoPanel loginPanel; private JButton okButton, cancelButton; private JTextArea messagesArea; public AirportLoginInfoDialog(Frame owner, String title, boolean modal, AirportInfo theInfo) { super(owner, title, modal); // close only on Cancel or OK button press this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); // panel holding login info loginPanel = new AirportLoginInfoPanel(theInfo); setUpDisplay(); } public void setUpDisplay() { okButton = new JButton("OK"); okButton.setActionCommand("ok"); okButton.addActionListener(this); cancelButton = new JButton("Cancel"); cancelButton.setActionCommand("cancel"); cancelButton.addActionListener(this); messagesArea = new JTextArea(4,60); JScrollPane messagesScroll = new JScrollPane(messagesArea); // 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; c.insets = new Insets(2,2,2,2); c.anchor = GridBagConstraints.CENTER; c.weightx = .5; c.weighty = .5; this.getContentPane().setLayout(theLayout); // add components c.gridwidth = 2; c.gridx = 1; c.gridy = 1; theLayout.setConstraints(loginPanel, c); this.getContentPane().add(loginPanel); c.gridwidth = 1; c.gridx = 1; c.gridy = 2; theLayout.setConstraints(okButton, c); this.getContentPane().add(okButton); c.gridx = 2; c.gridy = 2; theLayout.setConstraints(cancelButton, c); this.getContentPane().add(cancelButton); c.gridwidth = 2; c.gridx = 1; c.gridy = 3; JLabel messageLabel = new JLabel("Messages"); theLayout.setConstraints(messageLabel, c); this.getContentPane().add(messageLabel); c.gridwidth = 2; c.gridx = 1; c.gridy = 4; theLayout.setConstraints(messagesScroll, c); this.getContentPane().add(messagesScroll); } public void actionPerformed(ActionEvent theEvent) // respond to button pushes { String command = theEvent.getActionCommand(); if (command.equals("ok")) { try { loginPanel.writeValue(); this.setVisible(false); this.dispose(); } catch (ValueFormatException ve) { messagesArea.append("Problem with supplied value: " + ve.getMessage() + "\n"); } } if (command.equals("cancel")) { this.setVisible(false); this.dispose(); } } }airportconfig-1.5.2/airport/AirportPPPoELoginInfoDialog.java0000644000175000017500000000735607503646614023505 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * Frame which presents data pertaining to modem login info. */ public class AirportPPPoELoginInfoDialog extends JDialog implements ActionListener { private AirportUsernamePPPoEClientIDPanel loginPanel; private JButton okButton, cancelButton; private JTextArea messagesArea; public AirportPPPoELoginInfoDialog(Frame owner, String title, boolean modal, AirportInfo theInfo) { super(owner, title, modal); // close only on Cancel or OK button press this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); // panel holding login info loginPanel = new AirportUsernamePPPoEClientIDPanel(theInfo); setUpDisplay(); } public void setUpDisplay() { okButton = new JButton("OK"); okButton.setActionCommand("ok"); okButton.addActionListener(this); cancelButton = new JButton("Cancel"); cancelButton.setActionCommand("cancel"); cancelButton.addActionListener(this); messagesArea = new JTextArea(4,60); JScrollPane messagesScroll = new JScrollPane(messagesArea); // 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; c.insets = new Insets(2,2,2,2); c.anchor = GridBagConstraints.CENTER; c.weightx = .5; c.weighty = .5; this.getContentPane().setLayout(theLayout); // add components c.gridwidth = 2; c.gridx = 1; c.gridy = 1; theLayout.setConstraints(loginPanel, c); this.getContentPane().add(loginPanel); c.gridwidth = 1; c.gridx = 1; c.gridy = 2; theLayout.setConstraints(okButton, c); this.getContentPane().add(okButton); c.gridx = 2; c.gridy = 2; theLayout.setConstraints(cancelButton, c); this.getContentPane().add(cancelButton); c.gridwidth = 2; c.gridx = 1; c.gridy = 3; JLabel messageLabel = new JLabel("Messages"); theLayout.setConstraints(messageLabel, c); this.getContentPane().add(messageLabel); c.gridwidth = 2; c.gridx = 1; c.gridy = 4; theLayout.setConstraints(messagesScroll, c); this.getContentPane().add(messagesScroll); } public void actionPerformed(ActionEvent theEvent) // respond to button pushes { String command = theEvent.getActionCommand(); if (command.equals("ok")) { try { loginPanel.writeValue(); this.setVisible(false); this.dispose(); } catch (ValueFormatException ve) { messagesArea.append("Problem with supplied value: " + ve.getMessage() + "\n"); } } if (command.equals("cancel")) { this.setVisible(false); this.dispose(); } } }airportconfig-1.5.2/airport/AirportPortMappingPanel.java0000644000175000017500000000450507503646614023046 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; /** * Panel which maintains basic base station information: name, location, and contact individual. * Also provides textfield for entering new community name (base station password). */ public class AirportPortMappingPanel extends AirportInfoPanel { private AirportInfoCheckBox portMappingCheckbox; private AirportPortMappingTable portMappingTable; public AirportPortMappingPanel(AirportInfo theInfo) { portMappingCheckbox = new AirportInfoCheckBox("Use port mapping", theInfo.get("Port mapping switch"), "04", "00"); portMappingTable = new AirportPortMappingTable(theInfo); setUpDisplay(); } private void setUpDisplay() { // 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; c.insets = new Insets(2,2,2,2); c.anchor = GridBagConstraints.CENTER; c.weightx = 0; c.weighty = 0; JLabel theLabel; this.setLayout(theLayout); c.gridx = 1; c.gridy = 1; c.anchor = GridBagConstraints.WEST; theLayout.setConstraints(portMappingCheckbox, c); this.add(portMappingCheckbox); c.gridx = 1; c.gridy = 2; c.anchor = GridBagConstraints.CENTER; theLayout.setConstraints(portMappingTable, c); this.add(portMappingTable); } }airportconfig-1.5.2/airport/AirportPPPoEConfigPanel.java0000644000175000017500000001401307503646614022652 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * Panel maintaining configuration information for Ethernet network connection. */ public class AirportPPPoEConfigPanel extends AirportInfoPanel implements ActionListener { private JButton loginButton; private ButtonGroup connectionGroup; private AirportInfoRadioButton pppoeAlwaysStayConnectedButton, pppoeAutomaticConnectButton, pppoeManualConnectButton; private AirportInfoLabelledScaledValueField pppoeDisconnectTimeoutField; private AirportInfo theInfo; private AirportInfoPanel pppoeDisconnectTimeoutPanel; /** * Create new panel with information from supplied AirportInfo object. */ public AirportPPPoEConfigPanel(AirportInfo theInfo) { this.theInfo = theInfo; pppoeAlwaysStayConnectedButton = new AirportInfoRadioButton("Always stay connected",theInfo.get("PPPoE stay connected"), "40"); pppoeAutomaticConnectButton = new AirportInfoRadioButton("Connect automatically",theInfo.get("PPPoE auto connect"), "04"); pppoeManualConnectButton = new AirportInfoRadioButton("Don't connect automatically",theInfo.get("PPPoE auto connect"), "06"); connectionGroup = new ButtonGroup(); connectionGroup.add(pppoeAlwaysStayConnectedButton); connectionGroup.add(pppoeAutomaticConnectButton); connectionGroup.add(pppoeManualConnectButton); pppoeDisconnectTimeoutField = new AirportInfoLabelledScaledValueField("PPPoE idle timeout (minutes; 0 = never)", theInfo.get("PPPoE idle timeout"), 6); setUpDisplay(); } private void setUpDisplay() { // 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(1,1,1,1); c.insets = theMargin; c.anchor = GridBagConstraints.CENTER; c.weightx = .5; c.weighty = .5; JLabel theLabel; // Button to show login panel when pressed... loginButton = new JButton("Username/Password"); loginButton.setActionCommand("show login panel"); loginButton.addActionListener(this); // panel for PPPoE timeout field pppoeDisconnectTimeoutPanel = new AirportInfoPanel(); pppoeDisconnectTimeoutPanel.add(pppoeDisconnectTimeoutField); this.setLayout(theLayout); c.gridx = 1; c.gridy = 2; c.gridwidth = 1; theLayout.setConstraints(pppoeAlwaysStayConnectedButton, c); this.add(pppoeAlwaysStayConnectedButton); c.gridx = 1; c.gridy = 3; theLayout.setConstraints(pppoeAutomaticConnectButton, c); this.add(pppoeAutomaticConnectButton); c.gridx = 1; c.gridy = 4; theLayout.setConstraints(pppoeManualConnectButton, c); this.add(pppoeManualConnectButton); c.gridx = 2; c.gridy = 2; c.gridheight = 3; c.anchor = GridBagConstraints.CENTER; theLayout.setConstraints(loginButton, c); this.add(loginButton); c.gridx = 1; c.gridy = 5; c.gridwidth = 2; c.anchor = GridBagConstraints.WEST; theLayout.setConstraints(pppoeDisconnectTimeoutPanel, c); this.add(pppoeDisconnectTimeoutPanel); // make pppoeDisconnectTimeoutPanel enabling dependent on connect status pppoeAutomaticConnectButton.addItemListener(pppoeDisconnectTimeoutPanel); pppoeManualConnectButton.addItemListener(pppoeDisconnectTimeoutPanel); // pppoeDisconnectTimeoutPanel.setEnabled(pppoeAutomaticConnectButton.isSelected() || pppoeManualConnectButton.isSelected()); pppoeDisconnectTimeoutPanel.setEnabled(pppoeAutomaticConnectButton.isSelected() || pppoeManualConnectButton.isSelected()); } /** * Override base class method to enable and disable contained components. */ public void setEnabled(boolean enabled) { super.setEnabled(enabled); if (enabled == true) { // if enabling, set enabling of pppoeDisconnectTimeoutPanel pppoeDisconnectTimeoutPanel.setEnabled(pppoeAutomaticConnectButton.isSelected() || pppoeManualConnectButton.isSelected()); } } public void actionPerformed(ActionEvent theEvent) // respond to button pushes { String command = theEvent.getActionCommand(); if (command.equals("show login panel")) { // get top-level Frame to associate modal dialog with so will be minimzed and // maximized correctly. Component owner = this; while ( !((owner == null) || (owner instanceof Frame)) ) owner = owner.getParent(); Frame owningFrame = (Frame)owner; // create and display modal dialog holding dial-up username / password and login script AirportPPPoELoginInfoDialog loginDialog = new AirportPPPoELoginInfoDialog(owningFrame, "PPPoE Login Information", true, theInfo); loginDialog.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 = loginDialog.getSize(); dim.height += 20; dim.width += 20; loginDialog.setSize(dim); loginDialog.show(); } } }airportconfig-1.5.2/airport/AirportInfoScaledValueField.java0000644000175000017500000001011707503646614023572 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; import byteblock.*; /** * Creates a text box to display and edit information in an AirportInfoRecord. * Size of textfield is set automatically according to datatype. */ public class AirportInfoScaledValueField extends JTextField implements AirportInfoComponent { private AirportInfoRecord theRecord; private int scalingFactor; /** * Creates new textfield to display and edit value information in an AirportInfoRecord. * Size of textfield is set automatically according to value size and scaling. */ public AirportInfoScaledValueField(AirportInfoRecord theRecord, int scalingFactor) { super(); this.theRecord = theRecord; this.scalingFactor = scalingFactor; //determine how large the text field should be to display the value int fieldSize = theRecord.byteBlockWindow.getSize(); fieldSize *= 3; // to hold hex string: 2 chars per byte, plus space if (fieldSize > 40) fieldSize = 40; this.setColumns(fieldSize); refreshDisplay(); } /** * Creates new textfield to display and edit information in an AirportInfoRecord. * Size of textfield is supplied as argument. */ public AirportInfoScaledValueField(AirportInfoRecord theRecord, int scalingFactor, int fieldSize) { super(); this.theRecord = theRecord; this.scalingFactor = scalingFactor; this.setColumns(fieldSize); refreshDisplay(); } /** * Read value from associated AirportInfoRecord window, and display value. */ public void refreshDisplay() { try { long storedValue = Long.parseLong(theRecord.toString()); long displayValue = storedValue/scalingFactor; String valueString = new String(); valueString += displayValue; setText(valueString); } catch (NumberFormatException e) { // won't happen! } } /** * Write value currently displayed into associated AirportInfoRecord window. */ public void writeValue() throws ValueFormatException { long displayValue = 0; try { displayValue = Long.parseLong(getText()); } catch (NumberFormatException e) { this.selectAll(); this.requestFocus(); throw new ValueFormatException("Bad number format."); } // see how big the value can be int numBytes = theRecord.byteBlockWindow.getSize(); long minValue = 0; long maxValue = 1; for (int i = 0; i < numBytes; i++) { maxValue *= 256; } maxValue -= 1; maxValue /= scalingFactor; if ((displayValue < minValue) || (displayValue > maxValue)) { this.selectAll(); this.requestFocus(); throw new ValueFormatException("Value must be between " + minValue + " and " + maxValue + "."); } long storedValue = displayValue*scalingFactor; String valueString = new String(); valueString += storedValue; theRecord.setBytesFromString(valueString); } /** * Write supplied value, rather than that currently displayed, into associated * AirportInfoRecord window. */ public void writeValue(String newValue) throws ValueFormatException { setText(newValue); writeValue(); refreshDisplay(); } }airportconfig-1.5.2/airport/AirportInfoLabelledScaledValueField.java0000644000175000017500000000630607503646614025224 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package airport; import java.awt.*; import javax.swing.*; import byteblock.*; /** * Creates a labelled text box to display and edit the information in an AirportInfoRecord. * Size of textfield is set automatically according to datatype. */ public class AirportInfoLabelledScaledValueField extends AirportInfoPanel { public String name; public AirportInfoScaledValueField theField; private AirportInfoRecord theRecord; /** * Creates new display for viewing and editing the information in the supplied * AirportInfoRecord. Size of textfield is supplied. */ public AirportInfoLabelledScaledValueField(String name, AirportInfoRecord theRecord, int scalingFactor, int fieldSize) { this.name = name; this.theRecord = theRecord; JLabel l = new JLabel(name); theField = new AirportInfoScaledValueField(theRecord, scalingFactor, fieldSize); this.setLayout(new BorderLayout(2,2)); this.add("West", l); this.add("East", theField); refreshDisplay(); } /** * Creates new display for viewing and editing the information in the supplied * AirportInfoRecord. Size of textfield is set automatically according to datatype. */ public AirportInfoLabelledScaledValueField(String name, AirportInfoRecord theRecord, int scalingFactor) { this.name = name; this.theRecord = theRecord; JLabel l = new JLabel(name); theField = new AirportInfoScaledValueField(theRecord, scalingFactor); this.setLayout(new BorderLayout(5,5)); this.add("West", l); this.add("East", theField); refreshDisplay(); } /** * Read value from associated AirportInfoRecord window, and display value. */ public void refreshDisplay() { theField.refreshDisplay(); } /** * Write value currently displayed into associated AirportInfoRecord window. */ public void writeValue() throws ValueFormatException { theField.writeValue(); } /** * Write supplied value, rather than that currently displayed, into associated * AirportInfoRecord window. */ public void writeValue(String newValue) throws ValueFormatException { theField.writeValue(newValue); } /** * Utility method to get text in enclosed textfield */ public String getText() { return theField.getText(); } }airportconfig-1.5.2/byteblock/0000755000175000017500000000000007521635753015716 5ustar julienjulienairportconfig-1.5.2/byteblock/ByteBlock.java0000644000175000017500000000457407503646614020447 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package byteblock; /** * Defines a rectangular block of bytes; used as the base block for byte block * windows. */ public class ByteBlock { public byte[] bytes; public int numRows, numCols; /** * Defines a new block of bytes with specified number of rows and columns. */ public ByteBlock(int rows, int cols) { numRows = rows; numCols = cols; bytes = new byte[numRows*numCols]; } /** * Defines a block of bytes with specified number of rows and columns, * using the supplied byte array for initialization (copies the supplied * array). */ public ByteBlock(int rows, int cols, byte[] b) { this(rows, cols); // copy the byte array int end; if (b.length > rows*cols) end = rows*cols; else end = b.length; for (int i = 0; i < end; i++) { bytes[i] = b[i]; } } /** * Returns hexadecimal representation of byte block (with newlines * separating rows). */ public String toString() { String returnString = new String(); for (int i = 0; i < numRows; i++) { for (int j = 0; j < numCols; j++) { int baseIndex = j + i * numCols; int value = bytes[baseIndex]; if (value < 0) value += 256; returnString += getHex(value) + " "; } returnString += "\n"; } return returnString; } private String getHex(int b) { String returnString = new String(Integer.toHexString(b)); if (returnString.length() < 2) returnString = "0" + returnString; return returnString; } }airportconfig-1.5.2/byteblock/ByteBlockMaskedWindow.java0000644000175000017500000001546107503646614022761 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package byteblock; /** * Extends ByteBlockRectangularWindow to include a mask specifying only those bits in each byte * which will be read or written (corresponding to the positions of 1's in the mask byte). */ public class ByteBlockMaskedWindow extends ByteBlockRectangularWindow { private byte mask; /** * Create a window for the specified ByteBlock which uses the specified mask. */ public ByteBlockMaskedWindow(ByteBlock block, byte mask) { super(block); this.mask = mask; } /** * Create a rectangular window into the specified ByteBlock using the specified mask. * The resulting window will have the specified number of * rows and columns, and will start at the specified index of the base block. */ public ByteBlockMaskedWindow(int baseStartIndex, int numRows, int numCols, ByteBlock block, byte mask) { super(baseStartIndex, numRows, numCols, block); this.mask = mask; } /* * Create a sub-window of an existing window. Note that the resulting window * depends on the number of rows and columns of the base block; in particular, * both numRows and numCols must be <= to those of base block. public MaskedByteBlockWindow(int numRows, int numCols, int baseStartIndex, ByteBlockRectangularWindow parent, byte mask) { super(numRows, numCols, baseStartIndex, parent); this.mask = mask; } */ /** * Return the sequence of bytes in the window between the specified indices, masking * each with this instance's byte mask. */ public byte[] getBytes(int startIndex, int endIndex) { byte[] byteString = super.getBytes(startIndex, endIndex); for (int i = 0; i < byteString.length; i++) { byteString[i] = (byte)(byteString[i] & mask); } return byteString; } /** * Set all bytes in window from (and including) startByte to (and excluding) * endByte to 0x00, masking with this instance's byte mask. */ public void clearBytes(int startIndex, int endIndex) { // create inverse mask so can erase only appropriate bits in each byte byte notMask = (byte)(0xFF ^ mask); // exclusive OR // set endIndex so don't write outside of window delimiter if (endIndex > numRows*numCols) endIndex = numRows*numCols; // get starting row and column of this window in its base block int blockStartRow = baseStartIndex/baseBlock.numCols; int blockStartCol = baseStartIndex - blockStartRow * baseBlock.numCols; for (int i = startIndex; i < endIndex; i++) { // find row and column of byteString index in this window int row = i/numCols; int col = i - row*numCols; // convert this to index in base block int baseIndex = (col + blockStartCol) + (row + blockStartRow) * baseBlock.numCols; // now erase only those bits allowed by mask baseBlock.bytes[baseIndex] = (byte)(baseBlock.bytes[baseIndex] & notMask); } } /** * Write a sequence of bytes into the window, starting at the specified index and * masking with this instance's byte mask. Note that this automatically clears all * the other bytes - masked, of course. */ public void writeBytes(int startIndex, byte[] byteString) { // clear all bytes first - but just those screened by mask, since will be using // this class's clear() method clearBytes(); // set endIndex so don't write outside of window delimiter int endIndex = startIndex + byteString.length; if (endIndex > numRows*numCols) endIndex = numRows*numCols; // get starting row and column of this window in its base block int blockStartRow = baseStartIndex/baseBlock.numCols; int blockStartCol = baseStartIndex - blockStartRow * baseBlock.numCols; for (int i = startIndex; i < endIndex; i++) { // find row and column of byteString index in this window int row = i/numCols; int col = i - row*numCols; // convert this to index in base block int baseIndex = (col + blockStartCol) + (row + blockStartRow) * baseBlock.numCols; baseBlock.bytes[baseIndex] = (byte)(baseBlock.bytes[baseIndex] | (byteString[i-startIndex] & mask)); } } /** * Return a String representing the bytes in the window between the specified indices, * masked with this instance's byte mask, with spaces between pairs of hex digits. */ public String toString(int startIndex, int endIndex) { String returnString = new String(); int blockStartRow = baseStartIndex/baseBlock.numCols; int blockStartCol = baseStartIndex - blockStartRow * baseBlock.numCols; for (int i = startIndex; i < endIndex; i++) { // find row and column of byteString index in this window int row = i/numCols; int col = i - row*numCols; // convert this to index in base block int baseIndex = (col + blockStartCol) + (row + blockStartRow) * baseBlock.numCols; int value = baseBlock.bytes[baseIndex] & mask; if (value < 0) value += 256; returnString += getHex(value) + " "; if (col == numCols - 1) returnString += "\n"; } return returnString; } /** * Return a String representing the bytes in the window between the specified indices, * masked with this instance's byte mask, without spaces between pairs of hex digits. */ public String toHexString(int startIndex, int endIndex) { String returnString = new String(); int blockStartRow = baseStartIndex/baseBlock.numCols; int blockStartCol = baseStartIndex - blockStartRow * baseBlock.numCols; for (int i = startIndex; i < endIndex; i++) { // find row and column of byteString index in this window int row = i/numCols; int col = i - row*numCols; // convert this to index in base block int baseIndex = (col + blockStartCol) + (row + blockStartRow) * baseBlock.numCols; int value = baseBlock.bytes[baseIndex] & mask; if (value < 0) value += 256; returnString += getHex(value); } return returnString; } }airportconfig-1.5.2/byteblock/ByteBlockMultiWindow.java0000644000175000017500000001045607503646614022646 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package byteblock; import java.util.*; /** * Groups a list of byte block windows into a single logical window. Windows are added * to a window list; bytes are written and read sequentially from the windows in the list. */ public class ByteBlockMultiWindow extends ByteBlockWindow { private Vector windowList; private int totalSize; /** * Create a new multi-window, with an initially empty window list. */ public ByteBlockMultiWindow() { windowList = new Vector(); totalSize = 0; } /** * Add the specified window to the end of the window list. */ public void addWindow(ByteBlockWindow newWindow) { windowList.insertElementAt(newWindow, windowList.size()); totalSize += newWindow.getSize(); } /** * Return the total number of bytes, which equals the sum of the sizes of the windows * in the window list. */ public int getSize() { return totalSize; } /** * Return the sequence of bytes in the windows, in the order in which the windows * appear in the window list. */ public byte[] getBytes() { // create new array of correct size byte[] returnBytes = new byte[totalSize]; int k = 0; // get bytes from windows in list, copy bytes into new array for (int i = 0; i < windowList.size(); i++) { byte[] nextBytes = ((ByteBlockWindow)windowList.elementAt(i)).getBytes(); for (int j = 0; j < nextBytes.length; j++) { returnBytes[k] = nextBytes[j]; k++; } } return returnBytes; } /** * Set the bytes in all of the windows in the window list to 0x00. */ public void clearBytes() { // clear windows in list for (int i = 0; i < windowList.size(); i++) ((ByteBlockWindow)windowList.elementAt(i)).clearBytes(); } /** * Write a sequence of bytes into the window, writing the bytes sequentially * into the windows in the window list. Note that this automatically clears * the other bytes. */ public void writeBytes(byte[] byteString) { // write bytes sequentially into windows in list int k = 0; // current array index for (int i = 0; i < windowList.size(); i++) { ByteBlockWindow nextWindow = (ByteBlockWindow)windowList.elementAt(i); int nextWindowSize = nextWindow.getSize(); // see if have enough bytes left in list to write into window if (k + nextWindowSize > byteString.length) nextWindowSize = byteString.length - k; // create new array to write into window byte[] subString = new byte[nextWindowSize]; // fill array for (int j = 0; j < nextWindowSize; j++) { subString[j] = byteString[k]; k++; } nextWindow.writeBytes(subString); // if no more bytes in input, break if (k >= byteString.length) break; } } /** * Return the sequence of bytes in the windows in the window list, with spaces. */ public String toString() { String returnString = new String(); for (int i = 0; i < windowList.size(); i++) { returnString += ((ByteBlockWindow)windowList.elementAt(i)).toString(); } return returnString; } /** * Return the sequence of bytes in the windows in the window list, without spaces. */ public String toHexString() { String returnString = new String(); for (int i = 0; i < windowList.size(); i++) { returnString += ((ByteBlockWindow)windowList.elementAt(i)).toHexString(); } return returnString; } }airportconfig-1.5.2/byteblock/ByteBlockRectangularWindow.java0000644000175000017500000002040507503646614024016 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package byteblock; /** * A rectangular window into a byte block. */ public class ByteBlockRectangularWindow extends ByteBlockWindow { protected int numRows, numCols; protected int baseStartIndex; /** * Create a window based on an existing base block, with the same number of rows and columns. */ public ByteBlockRectangularWindow(ByteBlock block) { this.numRows = block.numRows; this.numCols = block.numCols; this.baseStartIndex = 0; baseBlock = block; } /** * Create a window into the specified base block, with specified number of rows and columns, * and starting at specified index of the base block. Note that the number of columns need * not be less than the number of columns in the base block, and a rectangular window can * extend beyond the base block's boundary, "wrapping" into the other side. */ public ByteBlockRectangularWindow(int baseStartIndex, int numRows, int numCols, ByteBlock block) { this.numRows = numRows; this.numCols = numCols; this.baseStartIndex = baseStartIndex; baseBlock = block; } /* * Create a sub-window of an existing window. Note that the resulting window * depends on the number of rows and columns of the base block; in particular, * both numRows and numCols must be <= to those of base block. public ByteBlockRectangularWindow(int baseStartIndex, int numRows, int numCols, ByteBlockWindow parent) { this.numRows = numRows; this.numCols = numCols; this.baseStartIndex = parent.baseStartIndex + baseStartIndex; //this.startIndex = 0; //this.endIndex = numRows*numCols; baseBlock = parent.baseBlock; } */ /** * Return the total number of bytes in the window (= numRows * numCols). */ public int getSize() { return numRows * numCols; } /** * Return the sequence of bytes in the window. */ public byte[] getBytes() { return getBytes(0, numRows*numCols); } /** * Return the sequence of bytes in the window between the specified indices. */ public byte[] getBytes(int startIndex, int endIndex) { // set endIndex so don't try to read outside of window delimiter if (endIndex > numRows*numCols) endIndex = numRows*numCols; byte[] byteString = new byte[endIndex - startIndex]; // get starting row and column of this window in its base block int blockStartRow = baseStartIndex/baseBlock.numCols; int blockStartCol = baseStartIndex - blockStartRow * baseBlock.numCols; for (int i = startIndex; i < endIndex; i++) { // find row and column of byteString index in this window int row = i/numCols; int col = i - row*numCols; // convert this to index in base block int baseIndex = (col + blockStartCol) + (row + blockStartRow) * baseBlock.numCols; byteString[i-startIndex] = baseBlock.bytes[baseIndex]; } return byteString; } /** * Set all bytes in window to 0x00. */ public void clearBytes() { clearBytes(0, numRows*numCols); } /** * Set all bytes in window from (and including) startByte to (and excluding) * endByte to 0x00. */ public void clearBytes(int startIndex, int endIndex) { // set endIndex so don't write outside of window delimiter if (endIndex > numRows*numCols) endIndex = numRows*numCols; // get starting row and column of this window in its base block int blockStartRow = baseStartIndex/baseBlock.numCols; int blockStartCol = baseStartIndex - blockStartRow * baseBlock.numCols; for (int i = startIndex; i < endIndex; i++) { // find row and column of byteString index in this window int row = i/numCols; int col = i - row*numCols; // convert this to index in base block int baseIndex = (col + blockStartCol) + (row + blockStartRow) * baseBlock.numCols; baseBlock.bytes[baseIndex] = 0; } } /** * Write the sequence of bytes supplied into the window, starting from the beginning. Note * that this automatically clears all the other bytes in the case in which the number of * bytes supplied is less than the total number of bytes in the window. */ public void writeBytes(byte[] byteString) { writeBytes(0, byteString); } /** * Write a sequence of bytes into the window, starting at the specified index. Note * that this automatically clears all the other bytes in the window. */ public void writeBytes(int startIndex, byte[] byteString) { // clear all bytes first clearBytes(); // set endIndex so don't write outside of window delimiter int endIndex = startIndex + byteString.length; if (endIndex > numRows*numCols) endIndex = numRows*numCols; // get starting row and column of this window in its base block int blockStartRow = baseStartIndex/baseBlock.numCols; int blockStartCol = baseStartIndex - blockStartRow * baseBlock.numCols; for (int i = startIndex; i < endIndex; i++) { // find row and column of byteString index in this window int row = i/numCols; int col = i - row*numCols; // convert this to index in base block int baseIndex = (col + blockStartCol) + (row + blockStartRow) * baseBlock.numCols; baseBlock.bytes[baseIndex] = byteString[i-startIndex]; } } /** * Return a String representing the bytes in the window, with spaces between pairs of hex digits. */ public String toString() { return toString(0, numRows*numCols); } /** * Return a String representing the bytes in the window between the specified indices, * with spaces between pairs of hex digits. */ public String toString(int startIndex, int endIndex) { String returnString = new String(); int blockStartRow = baseStartIndex/baseBlock.numCols; int blockStartCol = baseStartIndex - blockStartRow * baseBlock.numCols; for (int i = startIndex; i < endIndex; i++) { // find row and column of byteString index in this window int row = i/numCols; int col = i - row*numCols; // convert this to index in base block int baseIndex = (col + blockStartCol) + (row + blockStartRow) * baseBlock.numCols; int value = baseBlock.bytes[baseIndex]; if (value < 0) value += 256; returnString += getHex(value) + " "; if (col == numCols - 1) returnString += "\n"; } return returnString; } /** * Return a String representing the bytes in the window, without spaces between bytes. */ public String toHexString() { return toHexString(0, numRows*numCols); } /** * Return a String representing the bytes in the window between the specified indices, * without spaces between bytes. */ public String toHexString(int startIndex, int endIndex) { String returnString = new String(); int blockStartRow = baseStartIndex/baseBlock.numCols; int blockStartCol = baseStartIndex - blockStartRow * baseBlock.numCols; for (int i = startIndex; i < endIndex; i++) { // find row and column of byteString index in this window int row = i/numCols; int col = i - row*numCols; // convert this to index in base block int baseIndex = (col + blockStartCol) + (row + blockStartRow) * baseBlock.numCols; int value = baseBlock.bytes[baseIndex]; if (value < 0) value += 256; returnString += getHex(value); } return returnString; } }airportconfig-1.5.2/byteblock/ByteBlockWindow.java0000644000175000017500000000425207503646614021630 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package byteblock; /** * Abstract base class for "windows" into byte blocks, which are used to * read and write data of various types. */ public abstract class ByteBlockWindow { protected ByteBlock baseBlock; /** * Return the total number of bytes in the window. */ public abstract int getSize(); /** * Return the sequence of bytes in the window. */ public abstract byte[] getBytes(); /** * Set all bytes in window to 0x00. */ public abstract void clearBytes(); /** * Write a sequence of bytes into the window. Note that this * automatically clears the other bytes. */ public abstract void writeBytes(byte[] byteString); /** * Return a String representation of the data in the window, * as a string of hexadecimal pairs, separated by spaces. */ public abstract String toString(); /** * Return a String representation of the data in the window, * as a string of hexadecimal pairs, without spaces. */ public abstract String toHexString(); /** * Return a hexadecimal pair representation of a byte. */ protected String getHex(int b) { String returnString = new String(Integer.toHexString(b)); // add leading 0 if needed if (returnString.length()%2 == 1) returnString = "0" + returnString; return returnString; } }airportconfig-1.5.2/byteblock/package.html0000644000175000017500000000612707503646614020203 0ustar julienjulien ByteBlock package The byteblock package defines classes used to manage rectangular "blocks" of bytes and  "windows" into such blocks. Typically, an underlying ByteBlock is created with a specified number of rows and columns (in the AirPort configurator, the underlying block of 17 k bytes is represented as a block with 16*68 rows and 16 columns). Then various ByteBlockWindow subclasses are created which expose specified regions of the byte block for reading or writing specific pieces of data.

The most common subclass is the ByteBlockRectangularWindow, which defines a window with a specified number of rows and columns, starting at a specified position (row and column) in the base block, which "wraps" if necessary onto subsequent rows. For example, using the AirPort base block, a rectangular window which starts at row 0, column 8, of the base block, and 1 row and 32 columns, will wrap onto rows 1 and 2, ending with the byte in column 7 of row 2. These rectangular windows also accomodate some of the more unusual field organizations in the AirPort, such as the 2-column-wide ("vertically oriented") network name field, as well as simple single-byte (1 row by 1 column) indicator or count fields.

A subclass of ByteBlockRectangularWindow is ByteBlockMaskedWindow, which includes a mask applied to each byte before reading or writing a value (only the bits in each byte corresponding to 1's in the mask are read or written). These masked windows are useful when a byte is "shared" by two indicators - for example, the high-order 4 bits might indicate the state of one parameter, while the low-order bits indicate the state of another.

Finally, the ByteBlockMultiWindow subclass of ByteBlockWindow permits a field to be comprised of multiple windows which are viewed as a single contiguous field for reading and writing. For example, the field for the DNS server IP address in the AirPort memory block consists of the first two bytes of the address in one location and the the other two in another location, with other data located in between. To accomodate this, a ByteBlockMultiWindow can be created, and two 2-byte ByteBlockRectangularWindows created at the appropriate locations and then added to the ByteBlockMultiWindow. Note that the order in which information is written to the windows comprising the multi-window is determined by the order in which they are added to the multi-window. Also note that the comprising windows need not be disjoint, but that the later-added windows will overwrite overlapping entries in the earlier-added windows when a value is written.

The basic operations for any window are getBytes(), clearBytes(), and setBytes(); note that writing is truncated at the window edge if the byte array being written is larger than the window. airportconfig-1.5.2/snmp/0000755000175000017500000000000007521635767014722 5ustar julienjulienairportconfig-1.5.2/snmp/SNMPBERCodec.java0000644000175000017500000001623407503646614017630 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; import java.util.*; import java.io.*; /** * SNMPBERCodec defines methods for converting from ASN.1 BER encoding to SNMPObject subclasses. The extraction * process usually produces a tree structure of objects with an SNMPSequence object at the root; this * is the usual behavior when a received encoded message is received from an SNMP device. */ public class SNMPBERCodec { public static final byte SNMPINTEGER = 0x02; public static final byte SNMPBITSTRING = 0x03; public static final byte SNMPOCTETSTRING = 0x04; public static final byte SNMPNULL = 0x05; public static final byte SNMPOBJECTIDENTIFIER = 0x06; public static final byte SNMPSEQUENCE = 0x30; public static final byte SNMPIPADDRESS = (byte)0x40; public static final byte SNMPCOUNTER32 = (byte)0x41; public static final byte SNMPGAUGE32 = (byte)0x42; public static final byte SNMPTIMETICKS = (byte)0x43; public static final byte SNMPOPAQUE = (byte)0x44; public static final byte SNMPNSAPADDRESS = (byte)0x45; public static final byte SNMPCOUNTER64 = (byte)0x46; public static final byte SNMPUINTEGER32 = (byte)0x47; public static final byte SNMPGETREQUEST = (byte)0xA0; public static final byte SNMPGETNEXTREQUEST = (byte)0xA1; public static final byte SNMPGETRESPONSE = (byte)0xA2; public static final byte SNMPSETREQUEST = (byte)0xA3; // SNMPv2p constants; unused!! public static final byte SNMPv2pCOMMUNICATION = (byte)0xA2; public static final byte SNMPv2pAUTHORIZEDMESSAGE = (byte)0xA1; public static final byte SNMPv2pENCRYPTEDMESSAGE = (byte)0xA1; public static final byte SNMPv2pENCRYPTEDDATA = (byte)0xA1; public static final byte SNMPUNKNOWNOBJECT = 0x00; /** * Extracts an SNMP object given its type, length, value triple as an SNMPTLV object. * Called by SNMPObject subclass constructors. * @throws SNMPBadValueException Indicates byte array in value field is uninterprettable for * specified SNMP object type. */ public static SNMPObject extractEncoding(SNMPTLV theTLV) throws SNMPBadValueException { switch (theTLV.tag) { case SNMPINTEGER: { return new SNMPInteger(theTLV.value); } case SNMPSEQUENCE: { return new SNMPSequence(theTLV.value); } case SNMPOBJECTIDENTIFIER: { return new SNMPObjectIdentifier(theTLV.value); } case SNMPOCTETSTRING: { return new SNMPOctetString(theTLV.value); } case SNMPIPADDRESS: { return new SNMPIPAddress(theTLV.value); } case SNMPCOUNTER32: { return new SNMPCounter32(theTLV.value); } case SNMPGAUGE32: { return new SNMPGauge32(theTLV.value); } case SNMPTIMETICKS: { return new SNMPTimeTicks(theTLV.value); } case SNMPNSAPADDRESS: { return new SNMPNSAPAddress(theTLV.value); } case SNMPCOUNTER64: { return new SNMPCounter64(theTLV.value); } case SNMPUINTEGER32: { return new SNMPUInteger32(theTLV.value); } case SNMPGETREQUEST: case SNMPGETNEXTREQUEST: case SNMPGETRESPONSE: case SNMPSETREQUEST: { return new SNMPPDU(theTLV.value, theTLV.tag); } case SNMPNULL: case SNMPOPAQUE: { return new SNMPNull(); } default: { System.out.println("Unrecognized tag"); //return new SNMPOctetString(theTLV.value); return new SNMPUnknownObject(theTLV.value); } } } /** * Extracts the type, length and value of the SNMP object whose BER encoding begins at the * specified position in the given byte array. (??what about errors??) */ public static SNMPTLV extractNextTLV(byte[] enc, int position) { SNMPTLV nextTLV = new SNMPTLV(); int currentPos = position; // get tag if ((enc[currentPos] % 32) < 31) { // single byte tag; extract value nextTLV.tag = (int)(enc[currentPos]); } else { // multiple byte tag; for now, just return value in subsequent bytes ... // but need to think about universal / application fields, etc... nextTLV.tag = 0; do { currentPos++; nextTLV.tag = nextTLV.tag * 128 + (int)(enc[currentPos] % 128); } while ((enc[currentPos]/128) >= 1); } currentPos++; // now at start of length info // get length of data int dataLength; int unsignedValue = enc[currentPos]; if (unsignedValue < 0) unsignedValue += 256; if ((unsignedValue / 128) < 1) { // single byte length; extract value dataLength = unsignedValue; } else { // multiple byte length; first byte's value (minus first bit) is # of length bytes int numBytes = (unsignedValue % 128); dataLength = 0; for (int i = 0; i < numBytes; i++) { currentPos++; unsignedValue = enc[currentPos]; if (unsignedValue < 0) unsignedValue += 256; dataLength = dataLength * 256 + unsignedValue; } } currentPos++; // now at start of data // set total length nextTLV.totalLength = currentPos - position + dataLength; // extract data portion ByteArrayOutputStream outBytes = new ByteArrayOutputStream(); outBytes.write(enc, currentPos, dataLength); nextTLV.value = outBytes.toByteArray(); return nextTLV; } /** * Utility function for encoding a length as a BER byte sequence */ public static byte[] encodeLength(int length) { ByteArrayOutputStream outBytes = new ByteArrayOutputStream(); // see if can be represented in single byte // don't forget the first bit is the "long field test" bit!! if (length < 128) { byte[] len = {(byte)length}; outBytes.write(len, 0, 1); } else { // too big for one byte // see how many are needed: int numBytes = 0; int temp = length; while (temp > 0) { ++numBytes; temp = (int)Math.floor(temp / 256); } byte num = (byte)numBytes; num += 128; // set the "long format" bit outBytes.write(num); byte[] len = new byte[numBytes]; for (int i = numBytes-1; i >= 0; --i) { len[i] = (byte)(length % 256); length = (int)Math.floor(length / 256); } outBytes.write(len, 0, numBytes); } return outBytes.toByteArray(); } }airportconfig-1.5.2/snmp/SNMPBadValueException.java0000644000175000017500000000235707503646614021625 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; /** * Exception thrown whenever attempt made to create SNMPObject subclass with inappropriate * data, or to set its value with inappropriate data, */ public class SNMPBadValueException extends Exception { public SNMPBadValueException() { super(); } /** * Create exception with message string. */ public SNMPBadValueException(String s) { super(s); } }airportconfig-1.5.2/snmp/SNMPCounter32.java0000644000175000017500000000613107503646614020041 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; import java.math.*; /** * Defines a 32-bit counter, whose value wraps if initialized with a larger * value. For an indicator which "pegs" at its maximum value if initialized with * a larger value, use SNMPGauge32; for a counter with a wider range, use SNMPCounter64. * @see snmp.SNMPGauge32 * @see snmp.SNMPCounter64 */ public class SNMPCounter32 extends SNMPInteger { // maximum value is 2^32 - 1 private static BigInteger maxValue = new BigInteger("4294967295"); protected byte tag = SNMPBERCodec.SNMPCOUNTER32; /** Initialize value to 0. */ public SNMPCounter32() { this(0); // initialize value to 0 } public SNMPCounter32(long newValue) { value = new BigInteger(new Long(newValue).toString()); // wrap if value > maxValue value = value.mod(maxValue); } /** Used to initialize from the BER encoding, usually received in a response from * an SNMP device responding to an SNMPGetRequest. * @throws SNMPBadValueException Indicates an invalid BER encoding supplied. Shouldn't * occur in normal operation, i.e., when valid responses are received from devices. */ public SNMPCounter32(byte[] enc) throws SNMPBadValueException { extractValueFromBEREncoding(enc); // wrap if value > maxValue value = value.mod(maxValue); } /** Used to set the value with an instance of java.lang.Integer or * java.lang.BigInteger. The value of the constructed SNMPCounter32 object is the * supplied value mod 2^32. * @throws SNMPBadValueException Indicates an incorrect object type supplied. */ public void setValue(Object newValue) throws SNMPBadValueException { if (newValue instanceof BigInteger) { value = (BigInteger)newValue; value = value.mod(maxValue); // wrap when value exceeds 2^32 } else if (newValue instanceof Integer) { value = new BigInteger(newValue.toString()); value = value.mod(maxValue); // wrap when value exceeds 2^32 } else if (newValue instanceof String) { value = value = new BigInteger((String)newValue); value = value.mod(maxValue); // wrap when value exceeds 2^32 } else throw new SNMPBadValueException(" Counter32: bad object supplied to set value "); } }airportconfig-1.5.2/snmp/SNMPCounter64.java0000644000175000017500000000616507503646614020055 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; import java.math.*; /** Defines a 64-bit counter, whose value wraps if initialized with a larger * value. For an indicator which "pegs" at its maximum value if initialized with * a larger value, use SNMPGauge32; for a counter with a smaller range, use SNMPCounter32. * @see snmp.SNMPGauge32 * @see snmp.SNMPCounter32 */ public class SNMPCounter64 extends SNMPInteger { // maximum value is 2^64 - 1; using approximation!! private static BigInteger maxValue = new BigInteger("18446744070000000000"); protected byte tag = SNMPBERCodec.SNMPCOUNTER64; /** Initialize value to 0. */ public SNMPCounter64() { this(0); // initialize value to 0 } public SNMPCounter64(long newValue) { value = new BigInteger(new Long(newValue).toString()); // wrap if value > maxValue value = value.mod(maxValue); } /** Used to initialize from the BER encoding, usually received in a response from * an SNMP device responding to an SNMPGetRequest. * @throws SNMPBadValueException Indicates an invalid BER encoding supplied. Shouldn't * occur in normal operation, i.e., when valid responses are received from devices. */ public SNMPCounter64(byte[] enc) throws SNMPBadValueException { extractValueFromBEREncoding(enc); // wrap if value > maxValue value = value.mod(maxValue); } /** Used to set the value with an instance of java.lang.Integer or * java.lang.BigInteger. The value of the constructed SNMPCounter64 object is the * supplied value mod 2^64. * @throws SNMPBadValueException Indicates an incorrect object type supplied. */ public void setValue(Object newValue) throws SNMPBadValueException { if (newValue instanceof BigInteger) { value = (BigInteger)newValue; value = value.mod(maxValue); // wrap when value exceeds 2^64 } else if (newValue instanceof Integer) { value = value = new BigInteger(newValue.toString()); value = value.mod(maxValue); // wrap when value exceeds 2^64 } else if (newValue instanceof String) { value = value = new BigInteger((String)newValue); value = value.mod(maxValue); // wrap when value exceeds 2^64 } else throw new SNMPBadValueException(" Counter64: bad object supplied to set value "); } }airportconfig-1.5.2/snmp/SNMPGauge32.java0000644000175000017500000000605007503646614017452 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; import java.math.*; /** Defines a 32-bit gauge, whose value "pegs" at the maximum if initialized with a larger * value. For an indicator which wraps when it reaches its maximum value, use SNMPCounter32; * for a counter with a wider range, use SNMPCounter64. * @see snmp.SNMPCounter32 * @see snmp.SNMPCounter64 */ public class SNMPGauge32 extends SNMPInteger { // maximum value is 2^32 - 1 (hack w/ 4*107...) private static BigInteger maxValue = new BigInteger("4294967295"); protected byte tag = SNMPBERCodec.SNMPGAUGE32; /** Initialize value to 0. */ public SNMPGauge32() { this(0); // initialize value to 0 } public SNMPGauge32(long newValue) { value = new BigInteger(new Long(newValue).toString()); // peg if value > maxValue value = value.min(maxValue); } /** Used to initialize from the BER encoding, usually received in a response from * an SNMP device responding to an SNMPGetRequest. * @throws SNMPBadValueException Indicates an invalid BER encoding supplied. Shouldn't * occur in normal operation, i.e., when valid responses are received from devices. */ public SNMPGauge32(byte[] enc) throws SNMPBadValueException { extractValueFromBEREncoding(enc); // peg if value > maxValue value = value.min(maxValue); } /** Used to set the value with an instance of java.lang.Integer or * java.lang.BigInteger. The value of the constructed SNMPGauge32 object is the * supplied value or 2^32, whichever is less. * @throws SNMPBadValueException Indicates an incorrect object type supplied. */ public void setValue(Object newValue) throws SNMPBadValueException { // plateau when value hits maxValue if (newValue instanceof BigInteger) { value = (BigInteger)newValue; value = value.min(maxValue); } else if (newValue instanceof Integer) { value = value = new BigInteger(newValue.toString()); value = value.min(maxValue); } else if (newValue instanceof String) { value = value = new BigInteger((String)newValue); value = value.min(maxValue); } else throw new SNMPBadValueException(" Gauge32: bad object supplied to set value "); } }airportconfig-1.5.2/snmp/SNMPGetException.java0000644000175000017500000000244107503646614020653 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; /** * Exception thrown when attempt to get value of SNMP OID from device fails. Reason could be that * specified variable not supported by device, or that supplied community name has insufficient * privileges. */ public class SNMPGetException extends Exception { public SNMPGetException() { super(); } /** * Create exception with message string. */ public SNMPGetException(String s) { super(s); } }airportconfig-1.5.2/snmp/SNMPIPAddress.java0000644000175000017500000001030407503646614020070 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; import java.util.*; import java.io.*; /** * Class to hold IP addresses; special case of SNMP Octet String. */ public class SNMPIPAddress extends SNMPOctetString { // length limited to 4 octets protected byte tag = SNMPBERCodec.SNMPIPADDRESS; /** * Initialize to 0.0.0.0 */ public SNMPIPAddress() { // initialize to 0.0.0.0 data = new byte[4]; for (int i = 0; i < 4; i++) data[i] = 0; } /* public SNMPIPAddress(String string) throws SNMPBadValueException { if (string.length() == 4) this.data = string.getBytes[]; else throw new SNMPBadValueException(" IPAddress: bad length string supplied to set value "); } */ /** * Used to initialize from the BER encoding, as received in a response from * an SNMP device responding to an SNMPGetRequest, or from a supplied byte array * containing the address components. * @throws SNMPBadValueException Indicates an invalid array supplied: must have length 4. */ public SNMPIPAddress(byte[] enc) throws SNMPBadValueException { if (enc.length == 4) { data = enc; } else // wrong size { throw new SNMPBadValueException(" IPAddress: bad BER encoding supplied to set value "); } } /** * Used to set the value from a byte array containing the address. * @throws SNMPBadValueException Indicates an incorrect object type supplied, or array of * incorrect size. */ public void setValue(Object newAddress) throws SNMPBadValueException { if ((newAddress instanceof byte[]) && (((byte[])newAddress).length == 4)) data = (byte[])newAddress; else if (newAddress instanceof String) { data = parseIPAddress((String)newAddress); } else throw new SNMPBadValueException(" IPAddress: bad data supplied to set value "); } /** * Return pretty-printed IP address. */ public String toString() { String returnString = new String(); if (data.length > 0) { int convert = data[0]; if (convert < 0) convert += 256; returnString += convert; for (int i = 1; i < data.length; i++) { convert = data[i]; if (convert < 0) convert += 256; returnString += "." + convert; } } return returnString; } private byte[] parseIPAddress(String addressString) throws SNMPBadValueException { try { StringTokenizer st = new StringTokenizer(addressString, " ."); int size = 0; while (st.hasMoreTokens()) { // figure out how many values are in string size++; st.nextToken(); } if (size != 4) { throw new SNMPBadValueException(" IPAddress: wrong number of components supplied to set value "); } byte[] returnBytes = new byte[size]; st = new StringTokenizer(addressString, " ."); for (int i = 0; i < size; i++) { int addressComponent = (Integer.parseInt(st.nextToken())); if ((addressComponent < 0) || (addressComponent > 255)) throw new SNMPBadValueException(" IPAddress: invalid component supplied to set value "); returnBytes[i] = (byte)addressComponent; } return returnBytes; } catch (NumberFormatException e) { throw new SNMPBadValueException(" IPAddress: invalid component supplied to set value "); } } }airportconfig-1.5.2/snmp/SNMPInteger.java0000644000175000017500000001016607503646614017655 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; import java.math.*; import java.io.*; /** Defines an arbitrarily-sized integer value; there is no limit on size due to the use * of Java.lang.BigInteger to store the value internally. For an indicator which "pegs" at its * maximum value if initialized with a larger value, use SNMPGauge32; for a counter which wraps, * use SNMPCounter32 or SNMPCounter64. * @see snmp.SNMPCounter32 * @see snmp.SNMPGauge32 * @see snmp.SNMPCounter64 */ public class SNMPInteger extends SNMPObject { protected BigInteger value; protected byte tag = SNMPBERCodec.SNMPINTEGER; /** Initialize value to 0. */ public SNMPInteger() { this(0); // initialize value to 0 } public SNMPInteger(long value) { this.value = new BigInteger(new Long(value).toString()); } /** Used to initialize from the BER encoding, usually received in a response from * an SNMP device responding to an SNMPGetRequest. * @throws SNMPBadValueException Indicates an invalid BER encoding supplied. Shouldn't * occur in normal operation, i.e., when valid responses are received from devices. */ public SNMPInteger(byte[] enc) throws SNMPBadValueException { extractValueFromBEREncoding(enc); } /** Returns a java.lang.BigInteger object with the current value. */ public Object getValue() { return value; } /** Used to set the value with an instance of java.lang.Integer or * java.lang.BigInteger. * @throws SNMPBadValueException Indicates an incorrect object type supplied. */ public void setValue(Object newValue) throws SNMPBadValueException { if (newValue instanceof BigInteger) value = (BigInteger)newValue; else if (newValue instanceof Integer) value = new BigInteger(((Integer)newValue).toString()); else if (newValue instanceof String) value = new BigInteger((String)newValue); else throw new SNMPBadValueException(" Integer: bad object supplied to set value "); } /** Returns the full BER encoding (type, length, value) of the SNMPInteger subclass. */ public byte[] getBEREncoding() { ByteArrayOutputStream outBytes = new ByteArrayOutputStream(); // write contents // boy, was THIS easy! Love that Java! BigInteger big = new BigInteger(value.toString()); byte[] data = big.toByteArray(); // calculate encoding for length of data byte[] len = SNMPBERCodec.encodeLength(data.length); // encode T,L,V info outBytes.write(tag); outBytes.write(len, 0, len.length); outBytes.write(data, 0, data.length); return outBytes.toByteArray(); } /** Used to extract a value from the BER encoding of the value. Called in constructors for * SNMPInteger subclasses. * @throws SNMPBadValueException Indicates an invalid BER encoding supplied. Shouldn't * occur in normal operation, i.e., when valid responses are received from devices. */ public void extractValueFromBEREncoding(byte[] enc) throws SNMPBadValueException { try { value = new BigInteger(enc); } catch (NumberFormatException e) { throw new SNMPBadValueException(" Integer: bad BER encoding supplied to set value "); } } public String toString() { return new String(value.toString()); } }airportconfig-1.5.2/snmp/SNMPMessage.java0000644000175000017500000000663607503646614017653 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; import java.util.*; /** * Defines the SNMPMessage class as a special case of SNMPSequence. Defines a * top-level SNMP message, as per the following definitions from RFC 1157 and * RFC 1901. RFC1157-SNMP DEFINITIONS IMPORTS FROM RFC1155-SMI; -- top-level message Message ::= SEQUENCE { version -- version-1 for this RFC INTEGER { version-1(0) }, community -- community name OCTET STRING, data -- e.g., PDUs if trivial ANY -- authentication is being used } -- From RFC 1901: COMMUNITY-BASED-SNMPv2 DEFINITIONS ::= BEGIN -- top-level message Message ::= SEQUENCE { version INTEGER { version(1) -- modified from RFC 1157 }, community -- community name OCTET STRING, data -- PDUs as defined in [4] ANY } } END */ public class SNMPMessage extends SNMPSequence { /** * Create an SNMP message with specified version, community, and pdu. * Use version = 0 for SNMP version 1, or version = 1 for enhanced capapbilities * provided through RFC 1157. */ public SNMPMessage(int version, String community, SNMPPDU pdu) throws SNMPBadValueException { super(); Vector contents = new Vector(); contents.insertElementAt(new SNMPInteger(version), 0); contents.insertElementAt(new SNMPOctetString(community), 1); contents.insertElementAt(pdu, 2); this.setValue(contents); } /** * Construct an SNMPMessage from a received ASN.1 byte representation. * @throws SNMPBadValueException Indicates invalid SNMP message encoding supplied. */ public SNMPMessage(byte[] enc) throws SNMPBadValueException { super(enc); } /** * Utility method which returns the PDU contained in the SNMP message. The pdu is the third component * of the sequence, after the version and community name. */ public SNMPPDU getPDU() { Vector contents = (Vector)(this.getValue()); return (SNMPPDU)(contents.elementAt(2)); } }airportconfig-1.5.2/snmp/SNMPNSAPAddress.java0000644000175000017500000001047607503646614020333 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; import java.util.*; import java.io.*; /** * Defines class for holding physical 6-byte addresses. */ public class SNMPNSAPAddress extends SNMPOctetString { // length limited to 6 octets protected byte tag = SNMPBERCodec.SNMPNSAPADDRESS; /** * Initialize address to 0.0.0.0.0.0. */ public SNMPNSAPAddress() { // initialize to 0.0.0.0.0.0 data = new byte[6]; for (int i = 0; i < 6; i++) data[i] = 0; } /* public SNMPNSAPAddress(String string) throws SNMPBadValueException { if (string.length() == 6) this.string = (String)string; else throw new SNMPBadValueException(" NSAPAddress: bad length string supplied to set value "); } */ /** * Used to initialize from the BER encoding, as received in a response from * an SNMP device responding to an SNMPGetRequest, or from a supplied byte array * containing the address components. * @throws SNMPBadValueException Indicates an invalid array supplied: must have length 6. */ public SNMPNSAPAddress(byte[] enc) throws SNMPBadValueException { if (enc.length == 6) { data = enc; } else // wrong size { throw new SNMPBadValueException(" NSAPAddress: bad BER encoding supplied to set value "); } } /** * Used to set the value from a byte array containing the address. * @throws SNMPBadValueException Indicates an incorrect object type supplied, or array of * incorrect size. */ public void setValue(Object newAddress) throws SNMPBadValueException { if ((newAddress instanceof byte[]) && (((byte[])newAddress).length == 6)) data = (byte[])newAddress; else if (newAddress instanceof String) { data = parseNSAPAddress((String)newAddress); } else throw new SNMPBadValueException(" NSAPAddress: bad length byte string supplied to set value "); } /** * Return pretty-printed (dash-separated) address. */ public String toString() { String returnString = new String(); if (data.length > 0) { int convert = data[0]; if (convert < 0) convert += 256; returnString += Integer.toHexString(convert); for (int i = 1; i < data.length; i++) { convert = data[i]; if (convert < 0) convert += 256; returnString += "-" + Integer.toHexString(convert); } } return returnString; } private byte[] parseNSAPAddress(String addressString) throws SNMPBadValueException { try { StringTokenizer st = new StringTokenizer(addressString, " .-"); // break on spaces, dots or dashes int size = 0; while (st.hasMoreTokens()) { // figure out how many values are in string size++; st.nextToken(); } if (size != 6) { throw new SNMPBadValueException(" NSAPAddress: wrong number of components supplied to set value "); } byte[] returnBytes = new byte[size]; st = new StringTokenizer(addressString, " .-"); for (int i = 0; i < size; i++) { int addressComponent = (Integer.parseInt(st.nextToken(), 16)); if ((addressComponent < 0) || (addressComponent > 255)) throw new SNMPBadValueException(" NSAPAddress: invalid component supplied to set value "); returnBytes[i] = (byte)addressComponent; } return returnBytes; } catch (NumberFormatException e) { throw new SNMPBadValueException(" NSAPAddress: invalid component supplied to set value "); } } }airportconfig-1.5.2/snmp/SNMPNull.java0000644000175000017500000000334607503646614017174 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; /** * Object representing the SNMP Null data type. */ public class SNMPNull extends SNMPObject { /** * Returns Java null reference. */ public Object getValue() { return null; } /** * Always throws SNMPBadValueException (which null value did you want, anyway?) */ public void setValue(Object o) throws SNMPBadValueException { throw new SNMPBadValueException(" Null: attempt to set value "); } /** * Return BER encoding for a null object: two bytes, tag and length of 0. */ public byte[] getBEREncoding() { byte[] encoding = new byte[2]; // set tag byte encoding[0] = SNMPBERCodec.SNMPNULL; // len = 0 since no payload! encoding[1] = 0; // no V! return encoding; } /** * Returns String "Null".. */ public String toString() { return new String("Null"); } }airportconfig-1.5.2/snmp/SNMPObject.java0000644000175000017500000000317207503646614017465 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; /** * Abstract base class of all SNMP data type classes. */ public abstract class SNMPObject { /** * Must return a Java object appropriate to represent the value/data contained * in the SNMP object */ public abstract Object getValue(); /** * Must set the value of the SNMP object when supplied with an appropriate * Java object containing an appropriate value. */ public abstract void setValue(Object o) throws SNMPBadValueException; /** * Must return the BER byte encoding (type, length, value) of the SNMP object. */ public abstract byte[] getBEREncoding(); /** * Should return an appropriate human-readable representation of the stored value. */ public abstract String toString(); }airportconfig-1.5.2/snmp/SNMPObjectIdentifier.java0000644000175000017500000002120307503646614021463 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; import java.util.*; import java.io.*; /** * Class representing ASN.1 object identifiers. These are unbounded sequences (arrays) of * natural numbers, written as dot-separated strings. */ public class SNMPObjectIdentifier extends SNMPObject { private int[] digits; // array of integers /** * Create a new empty object identifier (0-length array). */ public SNMPObjectIdentifier() { digits = new int[0]; } /** * Create a new object identifier from the supplied string of dot-separated nonegative * decimal integer values. * @throws SNMPBadValueException Indicates incorrectly-formatted string supplied. */ public SNMPObjectIdentifier(String digitString) throws SNMPBadValueException { convertDigitString(digitString); } /** * Create a new object identifier from the supplied array of nonegative * integer values. * @throws SNMPBadValueException Negative value(s) supplied. */ public SNMPObjectIdentifier(int[] digits) throws SNMPBadValueException { for (int i = 0; i < digits.length; i++) { if (digits[i] < 0) throw new SNMPBadValueException("Negative value supplied for SNMPObjectIdentifier."); } this.digits = digits; } /** * Used to initialize from the BER encoding, as received in a response from * an SNMP device responding to an SNMPGetRequest. * @throws SNMPBadValueException Indicates an invalid BER encoding supplied. Shouldn't * occur in normal operation, i.e., when valid responses are received from devices. */ public SNMPObjectIdentifier(byte[] enc) throws SNMPBadValueException { extractFromBEREncoding(enc); } /** * Return array of integers corresponding to components of identifier. */ public Object getValue() { return digits; } /** * Used to set the value from an integer array containing the identifier components, or from * a String containing a dot-separated sequence of nonegative values. * @throws SNMPBadValueException Indicates an incorrect object type supplied, or negative array * elements, or an incorrectly formatted String. */ public void setValue(Object digits) throws SNMPBadValueException { if (digits instanceof int[]) { for (int i = 0; i < ((int[])digits).length; i++) { if (((int[])digits)[i] < 0) throw new SNMPBadValueException("Negative value supplied for SNMPObjectIdentifier."); } this.digits = (int[])digits; } else if (digits instanceof String) { convertDigitString((String)digits); } else throw new SNMPBadValueException(" Object Identifier: bad object supplied to set value "); } /** * Return BER encoding for this object identifier. */ public byte[] getBEREncoding() { ByteArrayOutputStream outBytes = new ByteArrayOutputStream(); byte type = SNMPBERCodec.SNMPOBJECTIDENTIFIER; // write contents of array of values byte[] data = encodeArray(); // calculate encoding for length of data byte[] len = SNMPBERCodec.encodeLength(data.length); // encode T,L,V info outBytes.write(type); outBytes.write(len, 0, len.length); outBytes.write(data, 0, data.length); return outBytes.toByteArray(); } private byte[] encodeArray() { ByteArrayOutputStream outBytes = new ByteArrayOutputStream(); int numElements = digits.length; // encode first two identifier digits as one byte, using the 40*x + y rule; // of course, if only one element, just use 40*x; if none, do nothing if (numElements >= 2) { outBytes.write((byte)(40*digits[0] + digits[1])); } else if (numElements ==1) { outBytes.write((byte)(40*digits[0])); } for (int i = 2; i < numElements; ++i) { byte[] nextBytes = encodeValue(digits[i]); outBytes.write(nextBytes, 0, nextBytes.length); } return outBytes.toByteArray(); } private byte[] encodeValue(int v) { // see how many bytes are needed: each value uses just // 7 bits of each byte, with high-order bit functioning as // a continuation marker int numBytes = 0; int temp = v; do { ++numBytes; temp = (int)Math.floor(temp / 128); } while (temp > 0); byte[] enc = new byte[numBytes]; // encode lowest-order byte, without setting high bit enc[numBytes-1] = (byte)(v % 128); v = (int)Math.floor(v / 128); //.encode other bytes with high bit set for (int i = numBytes-2; i >= 0; --i) { enc[i] = (byte)((v % 128) + 128); v = (int)Math.floor(v / 128); } return enc; } private void convertDigitString(String digitString) throws SNMPBadValueException { try { StringTokenizer st = new StringTokenizer(digitString, " ."); int size = 0; while (st.hasMoreTokens()) { // figure out how many values are in string size++; st.nextToken(); } int[] returnDigits = new int[size]; st = new StringTokenizer(digitString, " ."); for (int i = 0; i < size; i++) { returnDigits[i] = Integer.parseInt(st.nextToken()); if (returnDigits[i] < 0) throw new SNMPBadValueException(" Object Identifier: bad string supplied to set value "); } digits = returnDigits; } catch (NumberFormatException e) { throw new SNMPBadValueException(" Object Identifier: bad string supplied for object identifier value "); } } private void extractFromBEREncoding(byte[] enc) throws SNMPBadValueException { // note: masks must be ints; byte internal representation issue(?) int bitTest = 0x80; // test for leading 1 int highBitMask = 0x7F; // mask out high bit for value // first, compute number of "digits"; // will just be number of bytes with leading 0's int numInts = 0; for (int i = 0; i < enc.length; i++) { if ((enc[i] & bitTest) == 0) //high-order bit not set; count numInts++; } if (numInts > 0) { // create new int array to hold digits; since first value is 40*x + y, // need one extra entry in array to hold this. digits = new int[numInts + 1]; int currentByte = -1; // will be incremented to 0 int value = 0; // read in values 'til get leading 0 in byte do { currentByte++; value = value*128 + (enc[currentByte] & highBitMask); } while ((enc[currentByte] & bitTest) > 0); // implies high bit set! // now handle 40a + b digits[0] = (int)Math.floor(value / 40); digits[1] = value % 40; // now read in rest! for (int i = 2; i < numInts + 1; i++) { // read in values 'til get leading 0 in byte value = 0; do { currentByte++; value = value*128 + (enc[currentByte] & highBitMask); } while ((enc[currentByte] & bitTest) > 0); digits[i] = value; } } else { // no digits; create empty digit array digits = new int[0]; } } /** * Test two obeject identifiers for equality. */ public boolean equals(SNMPObjectIdentifier other) { int[] otherDigits = (int[])(other.getValue()); boolean areEqual = true; if (digits.length != otherDigits.length) { areEqual = false; } else { for (int i = 0; i < digits.length; i++) { if (digits[i] != otherDigits[i]) { areEqual = false; break; } } } return areEqual; } /** * Return dot-separated sequence of decimal values. */ public String toString() { String valueString = new String(); if (digits.length > 0) { valueString += digits[0]; for (int i = 1; i < digits.length; ++i) { valueString += "." + digits[i]; } } return valueString; } }airportconfig-1.5.2/snmp/SNMPOctetString.java0000644000175000017500000001104007503646614020515 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; import java.util.*; import java.io.*; /** * Class representing a general string of octets. */ public class SNMPOctetString extends SNMPObject { protected byte[] data; protected byte tag = SNMPBERCodec.SNMPOCTETSTRING; /** * Create a zero-length octet string. */ public SNMPOctetString() { data = new byte[0]; } /** * Create an octet string from the bytes of the supplied String. */ public SNMPOctetString(String stringData) { this.data = stringData.getBytes(); } /** * Create an octet string from the supplied byte array. The array may be either * user-supplied, or part of a retrieved BER encoding. Note that the BER encoding * of the data of an octet string is just the raw bytes. */ public SNMPOctetString(byte[] enc) { extractFromBEREncoding(enc); } /** * Return the array of raw bytes. */ public Object getValue() { return data; } /** * Used to set the value from a byte array. * @throws SNMPBadValueException Indicates an incorrect object type supplied. */ public void setValue(Object data) throws SNMPBadValueException { if (data instanceof byte[]) this.data = (byte[])data; else if (data instanceof String) this.data = ((String)data).getBytes(); else throw new SNMPBadValueException(" Octet String: bad object supplied to set value "); } /** * Returns the BER encoding for the octet string. Note the the "value" part of the * BER type,length,value triple is just the sequence of raw bytes. */ public byte[] getBEREncoding() { ByteArrayOutputStream outBytes = new ByteArrayOutputStream(); // calculate encoding for length of data byte[] len = SNMPBERCodec.encodeLength(data.length); // encode T,L,V info outBytes.write(tag); outBytes.write(len, 0, len.length); outBytes.write(data, 0, data.length); return outBytes.toByteArray(); } protected void extractFromBEREncoding(byte[] enc) { data = new byte[enc.length]; // copy data for (int i = 0; i < enc.length; i++) { data[i] = enc[i]; } } /** * Returns a String constructed from the raw bytes. If the bytes contain non-printable * ASCII characters, tant pis! (Though it's fun when the bell rings!) */ public String toString() { String returnString; /* if ((data.length == 4) || (data.length == 6)) { returnString = new String(); int convert = data[0]; if (convert < 0) convert += 256; returnString += convert; for (int i = 1; i < data.length; i++) { convert = data[i]; if (convert < 0) convert += 256; returnString += "." + convert; } } else returnString = new String(data); */ /* byte[] converted = new byte[data.length]; for (int i = 0; i < data.length; i++) { if (data[i] == 0) converted[i] = 0x20; // space character else converted[i] = data[i]; } returnString = new String(converted); */ returnString = new String(data); return returnString; } 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; } /** * Returns a space-separated hex string corresponding to the raw bytes. */ public String toHexString() { String returnString = new String(); for (int i = 0; i < data.length; i++) { returnString += hexByte(data[i]) + " "; } return returnString; } }airportconfig-1.5.2/snmp/SNMPPDU.java0000644000175000017500000001265407503646614016714 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; import java.util.*; import java.io.*; import java.math.*; /** * The SNMPPDU class represents an SNMP PDU from RFC 1157, as indicated below. This * forms the payload of an SNMP message. -- protocol data units PDUs ::= CHOICE { get-request GetRequest-PDU, get-next-request GetNextRequest-PDU, get-response GetResponse-PDU, set-request SetRequest-PDU, trap Trap-PDU } -- PDUs GetRequest-PDU ::= [0] IMPLICIT PDU GetNextRequest-PDU ::= [1] IMPLICIT PDU GetResponse-PDU ::= [2] IMPLICIT PDU SetRequest-PDU ::= [3] IMPLICIT PDU PDU ::= SEQUENCE { request-id INTEGER, error-status -- sometimes ignored INTEGER { noError(0), tooBig(1), noSuchName(2), badValue(3), readOnly(4), genErr(5) }, error-index -- sometimes ignored INTEGER, variable-bindings -- values are sometimes ignored VarBindList } -- variable bindings VarBind ::= SEQUENCE { name ObjectName, value ObjectSyntax } VarBindList ::= SEQUENCE OF VarBind END */ public class SNMPPDU extends SNMPSequence { //protected int type; /** * Create a new PDU of the specified type, with given request ID, error status, and error index, * and containing the supplied SNMP sequence as data. */ public SNMPPDU(int pduType, int requestID, int errorStatus, int errorIndex, SNMPSequence varList) throws SNMPBadValueException { super(); Vector contents = new Vector(); type = pduType; contents.insertElementAt(new SNMPInteger(requestID), 0); contents.insertElementAt(new SNMPInteger(errorStatus), 1); contents.insertElementAt(new SNMPInteger(errorIndex), 2); contents.insertElementAt(varList, 3); this.setValue(contents); } /** * Create a new PDU of the specified type from the supplied BER encoding. * @throws SNMPBadValueException Indicates invalid SNMP PDU encoding supplied in enc. */ public SNMPPDU(byte[] enc, int pduType) throws SNMPBadValueException { type = pduType; extractFromBEREncoding(enc); } /** * A utility method that extracts the variable binding list from the pdu. Useful for retrieving * the set of (object identifier, value) pairs returned in response to a request to an SNMP * device. The variable binding list is just an SNMP sequence containing the identifier, value pairs. * @see snmp.SNMPVarBindList */ public SNMPSequence getVarBindList() { Vector contents = (Vector)(this.getValue()); return (SNMPSequence)(contents.elementAt(3)); } /** * A utility method that extracts the request ID number from this PDU. */ public int getRequestID() { Vector contents = (Vector)(this.getValue()); return ((BigInteger)((SNMPInteger)(contents.elementAt(0))).getValue()).intValue(); } /** * A utility method that extracts the error status for this PDU; if nonzero, can get index of * problematic variable using getErrorIndex(). */ public int getErrorStatus() { Vector contents = (Vector)(this.getValue()); return ((BigInteger)((SNMPInteger)(contents.elementAt(1))).getValue()).intValue(); } /** * A utility method that returns the error index for this PDU, identifying the problematic variable. */ public int getErrorIndex() { Vector contents = (Vector)(this.getValue()); return ((BigInteger)((SNMPInteger)(contents.elementAt(2))).getValue()).intValue(); } }airportconfig-1.5.2/snmp/SNMPSequence.java0000644000175000017500000001314307503646614020026 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; import java.util.*; import java.io.*; /** * One of the most important SNMP classes. Represents a sequence of other SNMP data types. * Virtually all compound structures are subclasses of SNMPSequence - for example, the * top-level SNMPMessage, and the SNMPPDU it contains, are both just specializations of * SNMPSequence. Sequences are frequently nested within other sequences. */ public class SNMPSequence extends SNMPObject { protected Vector sequence; // Vector of whatever is in sequence protected int type = SNMPBERCodec.SNMPSEQUENCE; /** * Create a new empty sequence. */ public SNMPSequence() { sequence = new Vector(); } /** * Create a new SNMP sequence from the supplied Vector of SNMPObjects. * @throws SNMPBadValueException Thrown if non-SNMP object supplied in Vector v. */ public SNMPSequence(Vector v) throws SNMPBadValueException { Enumeration e = v.elements(); while (e.hasMoreElements()) { if (!(e.nextElement() instanceof SNMPObject)) throw new SNMPBadValueException("Non-SNMPObject supplied to SNMPSequence."); } sequence = v; } /** * Construct an SNMPMessage from a received ASN.1 byte representation. * @throws SNMPBadValueException Indicates invalid SNMP sequence encoding supplied. */ public SNMPSequence(byte[] enc) throws SNMPBadValueException { extractFromBEREncoding(enc); } /** * Returns a Vector containing the SNMPObjects in the sequence. */ public Object getValue() { return sequence; } /** * Used to set the contained SNMP objects from a supplied Vector. * @throws SNMPBadValueException Indicates an incorrect object type supplied, or that the supplied * Vector contains non-SNMPObjects. */ public void setValue(Object newSequence) throws SNMPBadValueException { if (newSequence instanceof Vector) { // check that all objects in vector are SNMPObjects Enumeration e = ((Vector)newSequence).elements(); while (e.hasMoreElements()) { if (!(e.nextElement() instanceof SNMPObject)) throw new SNMPBadValueException("Non-SNMPObject supplied to SNMPSequence."); } this.sequence = (Vector)newSequence; } else throw new SNMPBadValueException(" Sequence: bad object supplied to set value "); } /** * Return the number of SNMPObjects contained in the sequence. */ public int size() { return sequence.size(); } /** * Add the SNMP object to the end of the sequence. * @throws SNMPBadValueException Relevant only in subclasses */ public void addSNMPObject(SNMPObject newObject) throws SNMPBadValueException { sequence.insertElementAt(newObject, sequence.size()); } /** * Return the SNMP object at the specified index. Indices are 0-based. */ public SNMPObject getSNMPObjectAt(int index) { return (SNMPObject)(sequence.elementAt(index)); } /** * Return the BER encoding for the sequence. */ public byte[] getBEREncoding() { ByteArrayOutputStream outBytes = new ByteArrayOutputStream(); // recursively write contents of Vector byte[] data = encodeVector(); // calculate encoding for length of data byte[] len = SNMPBERCodec.encodeLength(data.length); // encode T,L,V info outBytes.write(type); outBytes.write(len, 0, len.length); outBytes.write(data, 0, data.length); return outBytes.toByteArray(); } private byte[] encodeVector() { ByteArrayOutputStream outBytes = new ByteArrayOutputStream(); int numElements = sequence.size(); for (int i = 0; i < numElements; ++i) { byte[] nextBytes = ((SNMPObject)(sequence.elementAt(i))).getBEREncoding(); outBytes.write(nextBytes, 0, nextBytes.length); } return outBytes.toByteArray(); } protected void extractFromBEREncoding(byte[] enc) throws SNMPBadValueException { Vector newVector = new Vector(); int totalLength = enc.length; int position = 0; while (position < totalLength) { SNMPTLV nextTLV = SNMPBERCodec.extractNextTLV(enc, position); newVector.insertElementAt(SNMPBERCodec.extractEncoding(nextTLV), newVector.size()); position += nextTLV.totalLength; } sequence = newVector; } /** * Return a sequence of representations of the contained objects, separated by spaces * and enclosed in parentheses. */ public String toString() { String valueString = new String("("); for (int i = 0; i < sequence.size(); ++i) { valueString += " " + ((SNMPObject)sequence.elementAt(i)).toString() + " "; } valueString += ")"; return valueString; } }airportconfig-1.5.2/snmp/SNMPSetException.java0000644000175000017500000000244707503646614020675 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; /** * Exception thrown when attempt to set the value of an SNMP OID on a device fails. Reason could be * that specified variable not supported by device, or that supplied community name has insufficient * privileges. */ public class SNMPSetException extends Exception { public SNMPSetException() { super(); } /** * Create exception with message string. */ public SNMPSetException(String s) { super(s); } }airportconfig-1.5.2/snmp/SNMPTLV.java0000644000175000017500000000176707503646614016734 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; /** * Utility class holding components of an ASN.1 (type, length, value) triple. */ class SNMPTLV { int tag, totalLength; byte[] value; }airportconfig-1.5.2/snmp/SNMPTimeTicks.java0000644000175000017500000000242207503646614020150 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; /** * SNMP datatype used to represent time value. Just extension of SNMPInteger. */ public class SNMPTimeTicks extends SNMPInteger { protected byte tag = SNMPBERCodec.SNMPTIMETICKS; public SNMPTimeTicks() { this(0); // initialize value to 0 } public SNMPTimeTicks(long value) { super(value); } public SNMPTimeTicks(byte[] enc) throws SNMPBadValueException { super(enc); } }airportconfig-1.5.2/snmp/SNMPUInteger32.java0000644000175000017500000000602507503646614020146 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; import java.math.*; /** * Defines a 32-bit unsigned integer value; wraps if initialized with a larger value. * @see snmp.SNMPInteger */ public class SNMPUInteger32 extends SNMPInteger { // maximum value is 2^32 - 1 private static BigInteger maxValue = new BigInteger("4294967295"); protected byte tag = SNMPBERCodec.SNMPUINTEGER32; /** * Initialize value to 0. */ public SNMPUInteger32() { this(0); // initialize value to 0 } /** * Initialize value to newValue; wrap if newValue too big for 32 bits. */ public SNMPUInteger32(long newValue) { value = new BigInteger(new Long(newValue).toString()); // wrap if value > maxValue value = value.mod(maxValue); } /** * Used to initialize from the BER encoding, usually received in a response from * an SNMP device responding to an SNMPGetRequest. * @throws SNMPBadValueException Indicates an invalid BER encoding supplied. Shouldn't * occur in normal operation, i.e., when valid responses are received from devices. */ public SNMPUInteger32(byte[] enc) throws SNMPBadValueException { extractValueFromBEREncoding(enc); // wrap if value > maxValue value = value.mod(maxValue); } /** * Used to set the value with an instance of java.lang.Integer or * java.lang.BigInteger. The value of the constructed SNMPUInteger32 object is the * supplied value mod 2^32. * @throws SNMPBadValueException Indicates an incorrect object type supplied. */ public void setValue(Object newValue) throws SNMPBadValueException { if (newValue instanceof BigInteger) { value = (BigInteger)newValue; value = value.mod(maxValue); // wrap when value exceeds 2^32 } else if (newValue instanceof Integer) { value = value = new BigInteger(newValue.toString()); value = value.mod(maxValue); // wrap when value exceeds 2^32 } else if (newValue instanceof String) { value = value = new BigInteger((String)newValue); value = value.mod(maxValue); // wrap when value exceeds 2^32 } else throw new SNMPBadValueException(" Unsigned Integer: bad object supplied to set value "); } }airportconfig-1.5.2/snmp/SNMPUnknownObject.java0000644000175000017500000000453407503646614021050 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; import java.util.*; import java.io.*; /** * Used when an unknown SNMP object type is encountered. Just takes a byte array * for its constructor, and uses this as raw bytes. */ public class SNMPUnknownObject extends SNMPObject { private byte[] data; /** * Just takes a byte array, and uses this as raw bytes. */ public SNMPUnknownObject(byte[] enc) { data = enc; } /** * Return a byte array containing the raw bytes supplied. */ public Object getValue() { return data; } /** * Takes a byte array containing the raw bytes stored as the value. */ public void setValue(Object data) throws SNMPBadValueException { if (data instanceof byte[]) this.data = (byte[])data; else throw new SNMPBadValueException(" Unknown Object: bad object supplied to set value "); } /** * Return the BER encoding of this object. */ public byte[] getBEREncoding() { ByteArrayOutputStream outBytes = new ByteArrayOutputStream(); byte type = SNMPBERCodec.SNMPUNKNOWNOBJECT; // calculate encoding for length of data byte[] len = SNMPBERCodec.encodeLength(data.length); // encode T,L,V info outBytes.write(type); outBytes.write(len, 0, len.length); outBytes.write(data, 0, data.length); return outBytes.toByteArray(); } /** * Return String created from raw bytes of this object. */ public String toString() { return new String(data); } }airportconfig-1.5.2/snmp/SNMPVarBindList.java0000644000175000017500000000365507503646614020446 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; import java.util.*; /** * The SNMPVarBindList class is a specialization of SNMPSequence that contains a list of * SNMPVariablePair objects. * @see snmp.SNMPVariablePair -- variable bindings VarBind ::= SEQUENCE { name ObjectName, value ObjectSyntax } VarBindList ::= SEQUENCE OF VarBind END */ public class SNMPVarBindList extends SNMPSequence { /** * Create a new empty variable binding list. */ public SNMPVarBindList() { super(); } /** * Return the variable pairs in the list, separated by newlines. */ public String toString() { Vector sequence = (Vector)(this.getValue()); String valueString = new String(); for (int i = 0; i < sequence.size(); ++i) { valueString += ((SNMPObject)sequence.elementAt(i)).toString() + "\n"; } return valueString; } }airportconfig-1.5.2/snmp/SNMPVariablePair.java0000644000175000017500000000351407503646614020620 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; import java.util.*; /** * The SNMPVariablePair class implements the VarBind specification detailed below from RFC 1157. * It is a specialization of SNMPSequence, defining a 2-element sequence containing a single * (object identifier, value) pair. Note that the values are themselves SNMPObjects. -- variable bindings VarBind ::= SEQUENCE { name ObjectName, value ObjectSyntax } */ public class SNMPVariablePair extends SNMPSequence { /** * Create a new variable pair having the supplied object identifier and vale. */ public SNMPVariablePair(SNMPObjectIdentifier objectID, SNMPObject value) throws SNMPBadValueException { super(); Vector contents = new Vector(); contents.insertElementAt(objectID, 0); contents.insertElementAt(value, 1); this.setValue(contents); } }airportconfig-1.5.2/snmp/SNMPv1CommunicationInterface.java0000644000175000017500000004703407503646614023161 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 * */ package snmp; import java.io.*; import java.math.*; import java.net.*; import java.util.*; /** * The class SNMPv1CommunicationInterface defines methods for communicating with SNMP entities. * The approach is that from version 1 of SNMP, using no encryption of data. Communication occurs * via UDP, using port 161, the standard SNMP port. */ public class SNMPv1CommunicationInterface { public static final int SNMPPORT = 161; public static final int MAXSIZE = 512; private int version; private InetAddress hostAddress; private String community; DatagramSocket dSocket; public int requestID = 1; /** * Construct a new communication object to communicate with the specified host using the * given community name. The version setting should be either 0 (version 1) or 1 (version 2, * a la RFC 1157). */ public SNMPv1CommunicationInterface(int version, InetAddress hostAddress, String community) throws SocketException { this.version = version; this.hostAddress = hostAddress; this.community = community; dSocket = new DatagramSocket(); dSocket.setSoTimeout(15000); //15 seconds } /** * Permits setting timeout value for underlying datagram socket (in milliseconds). */ public void setSocketTimeout(int socketTimeout) throws SocketException { dSocket.setSoTimeout(socketTimeout); } /** * Close the "connection" with the devive. */ public void closeConnection() throws SocketException { dSocket.close(); } /** * Retrieve all MIB variable values subsequent to the starting object identifier * given in startID (in dotted-integer notation). Return as SNMPVarBindList object. * Uses SNMPGetNextRequests to retrieve variable values in sequence. * @throws IOException Thrown when timeout experienced while waiting for response to request. * @throws SNMPBadValueException */ public SNMPVarBindList retrieveAllMIBInfo(String startID) throws IOException, SNMPBadValueException { // send GetNextRequests until receive // an error message or a repeat of the object identifier we sent out SNMPVarBindList retrievedVars = new SNMPVarBindList(); int errorStatus = 0; int errorIndex = 0; SNMPObjectIdentifier requestedObjectIdentifier = new SNMPObjectIdentifier(startID); SNMPVariablePair nextPair = new SNMPVariablePair(requestedObjectIdentifier, new SNMPInteger(0)); SNMPSequence varList = new SNMPSequence(); varList.addSNMPObject(nextPair); SNMPPDU pdu = new SNMPPDU(SNMPBERCodec.SNMPGETNEXTREQUEST, requestID, errorStatus, errorIndex, varList); SNMPMessage message = new SNMPMessage(version, community, pdu); byte[] messageEncoding = message.getBEREncoding(); DatagramPacket outPacket = new DatagramPacket(messageEncoding, messageEncoding.length, hostAddress, SNMPPORT); dSocket.send(outPacket); while (errorStatus == 0) { DatagramPacket inPacket = new DatagramPacket(new byte[MAXSIZE], MAXSIZE); dSocket.receive(inPacket); byte[] encodedMessage = inPacket.getData(); SNMPMessage receivedMessage = new SNMPMessage(SNMPBERCodec.extractNextTLV(encodedMessage,0).value); //errorStatus = ((BigInteger)((SNMPInteger)((receivedMessage.getPDU()).getSNMPObjectAt(1))).getValue()).intValue(); varList = (receivedMessage.getPDU()).getVarBindList(); SNMPSequence newPair = (SNMPSequence)(varList.getSNMPObjectAt(0)); SNMPObjectIdentifier newObjectIdentifier = (SNMPObjectIdentifier)(newPair.getSNMPObjectAt(0)); SNMPObject newValue = newPair.getSNMPObjectAt(1); retrievedVars.addSNMPObject(newPair); if (requestedObjectIdentifier.equals(newObjectIdentifier)) break; requestedObjectIdentifier = newObjectIdentifier; requestID++; pdu = new SNMPPDU(SNMPBERCodec.SNMPGETNEXTREQUEST, requestID, errorStatus, errorIndex, varList); message = new SNMPMessage(version, community, pdu); messageEncoding = message.getBEREncoding(); outPacket = new DatagramPacket(messageEncoding, messageEncoding.length, hostAddress, SNMPPORT); dSocket.send(outPacket); } return retrievedVars; } 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; } /** * Retrieve the MIB variable values corresponding to the object identifier * given in itemID (in dotted-integer notation). Return as SNMPVarBindList object; if no * such variable (either due to device not supporting it, or community name having incorrect * access privilege), variable value will be SNMPNull object * @throws IOException Thrown when timeout experienced while waiting for response to request. * @throws SNMPBadValueException */ public SNMPVarBindList getMIBEntry(String itemID) throws IOException, SNMPBadValueException, SNMPGetException { // send GetRequest to specified host to retrieve specified object identifier SNMPVarBindList retrievedVars = new SNMPVarBindList(); int errorStatus = 0; int errorIndex = 0; SNMPObjectIdentifier requestedObjectIdentifier = new SNMPObjectIdentifier(itemID); SNMPVariablePair nextPair = new SNMPVariablePair(requestedObjectIdentifier, new SNMPInteger(0)); SNMPSequence varList = new SNMPSequence(); varList.addSNMPObject(nextPair); SNMPPDU pdu = new SNMPPDU(SNMPBERCodec.SNMPGETREQUEST, requestID, errorStatus, errorIndex, varList); SNMPMessage message = new SNMPMessage(version, community, pdu); byte[] messageEncoding = message.getBEREncoding(); /* System.out.println("Request Message bytes:"); for (int i = 0; i < messageEncoding.length; ++i) System.out.print(hexByte(messageEncoding[i]) + " "); */ DatagramPacket outPacket = new DatagramPacket(messageEncoding, messageEncoding.length, hostAddress, SNMPPORT); dSocket.send(outPacket); DatagramPacket inPacket = new DatagramPacket(new byte[MAXSIZE], MAXSIZE); while (true) // wait until receive reply for requestID & OID (or error) { dSocket.receive(inPacket); byte[] encodedMessage = inPacket.getData(); /* System.out.println("Message bytes:"); for (int i = 0; i < encodedMessage.length; ++i) { System.out.print(hexByte(encodedMessage[i]) + " "); } */ SNMPMessage receivedMessage = new SNMPMessage(SNMPBERCodec.extractNextTLV(encodedMessage,0).value); SNMPPDU receivedPDU = receivedMessage.getPDU(); // check request identifier; if incorrect, just ignore packet and continue waiting if (receivedPDU.getRequestID() == requestID) { // check error status; if retrieval problem, throw SNMPGetException if (receivedPDU.getErrorStatus() != 0) throw new SNMPGetException("OID " + itemID + " not available for retrieval"); varList = receivedPDU.getVarBindList(); SNMPSequence newPair = (SNMPSequence)(varList.getSNMPObjectAt(0)); SNMPObjectIdentifier newObjectIdentifier = (SNMPObjectIdentifier)(newPair.getSNMPObjectAt(0)); SNMPObject newValue = newPair.getSNMPObjectAt(1); // check the object identifier to make sure the correct variable has been received; // if not, just continue waiting for receive if (newObjectIdentifier.toString().equals(itemID)) { // got the right one; add it to retrieved var list and break! retrievedVars.addSNMPObject(newPair); break; } } } requestID++; return retrievedVars; } /** * Retrieve the MIB variable value corresponding to the object identifier following that * given in itemID (in dotted-integer notation). Return as SNMPVarBindList object; if no * such variable (either due to device not supporting it, or community name having incorrect * access privilege), variable value will be SNMPNull object * @throws IOException Thrown when timeout experienced while waiting for response to request. * @throws SNMPBadValueException */ public SNMPVarBindList getNextMIBEntry(String itemID) throws IOException, SNMPBadValueException, SNMPGetException { // send GetRequest to specified host to retrieve specified object identifier SNMPVarBindList retrievedVars = new SNMPVarBindList(); int errorStatus = 0; int errorIndex = 0; SNMPObjectIdentifier requestedObjectIdentifier = new SNMPObjectIdentifier(itemID); SNMPVariablePair nextPair = new SNMPVariablePair(requestedObjectIdentifier, new SNMPInteger(0)); SNMPSequence varList = new SNMPSequence(); varList.addSNMPObject(nextPair); SNMPPDU pdu = new SNMPPDU(SNMPBERCodec.SNMPGETNEXTREQUEST, requestID, errorStatus, errorIndex, varList); SNMPMessage message = new SNMPMessage(version, community, pdu); byte[] messageEncoding = message.getBEREncoding(); /* System.out.println("Request Message bytes:"); for (int i = 0; i < messageEncoding.length; ++i) System.out.print(hexByte(messageEncoding[i]) + " "); */ DatagramPacket outPacket = new DatagramPacket(messageEncoding, messageEncoding.length, hostAddress, SNMPPORT); dSocket.send(outPacket); DatagramPacket inPacket = new DatagramPacket(new byte[MAXSIZE], MAXSIZE); while (true) // wait until receive reply for requestID & OID (or error) { dSocket.receive(inPacket); byte[] encodedMessage = inPacket.getData(); /* System.out.println("Message bytes:"); for (int i = 0; i < encodedMessage.length; ++i) { System.out.print(hexByte(encodedMessage[i]) + " "); } */ SNMPMessage receivedMessage = new SNMPMessage(SNMPBERCodec.extractNextTLV(encodedMessage,0).value); SNMPPDU receivedPDU = receivedMessage.getPDU(); // check request identifier; if incorrect, just ignore packet and continue waiting if (receivedPDU.getRequestID() == requestID) { // check error status; if retrieval problem, throw SNMPGetException if (receivedPDU.getErrorStatus() != 0) throw new SNMPGetException("OID " + itemID + " not available for retrieval"); varList = receivedPDU.getVarBindList(); SNMPSequence newPair = (SNMPSequence)(varList.getSNMPObjectAt(0)); SNMPObjectIdentifier newObjectIdentifier = (SNMPObjectIdentifier)(newPair.getSNMPObjectAt(0)); SNMPObject newValue = newPair.getSNMPObjectAt(1); retrievedVars.addSNMPObject(newPair); break; } } requestID++; return retrievedVars; } /** * Set the MIB variable value of the object identifier * given in startID (in dotted-integer notation). Return SNMPVarBindList object returned * by device in its response; can be used to check that setting was successful. * Uses SNMPGetNextRequests to retrieve variable values in sequence. * @throws IOException Thrown when timeout experienced while waiting for response to request. * @throws SNMPBadValueException */ public SNMPVarBindList setMIBEntry(String itemID, SNMPObject newValue) throws IOException, SNMPBadValueException, SNMPSetException { // send SetRequest to specified host to set value of specified object identifier SNMPVarBindList retrievedVars = new SNMPVarBindList(); int errorStatus = 0; int errorIndex = 0; SNMPObjectIdentifier requestedObjectIdentifier = new SNMPObjectIdentifier(itemID); SNMPVariablePair nextPair = new SNMPVariablePair(requestedObjectIdentifier, newValue); SNMPSequence varList = new SNMPSequence(); varList.addSNMPObject(nextPair); SNMPPDU pdu = new SNMPPDU(SNMPBERCodec.SNMPSETREQUEST, requestID, errorStatus, errorIndex, varList); SNMPMessage message = new SNMPMessage(version, community, pdu); byte[] messageEncoding = message.getBEREncoding(); /* System.out.println("Message bytes:"); for (int i = 0; i < messageEncoding.length; ++i) { System.out.print(getHex(messageEncoding[i]) + " "); } */ DatagramPacket outPacket = new DatagramPacket(messageEncoding, messageEncoding.length, hostAddress, SNMPPORT); dSocket.send(outPacket); DatagramPacket inPacket = new DatagramPacket(new byte[MAXSIZE], MAXSIZE); while (true) // wait until receive reply for correct OID (or error) { dSocket.receive(inPacket); byte[] encodedMessage = inPacket.getData(); /* System.out.println("Message bytes:"); for (int i = 0; i < encodedMessage.length; ++i) { System.out.print((encodedMessage[i]) + " "); } */ SNMPMessage receivedMessage = new SNMPMessage(SNMPBERCodec.extractNextTLV(encodedMessage,0).value); SNMPPDU receivedPDU = receivedMessage.getPDU(); // check request identifier; if incorrect, just ignore packet and continue waiting if (receivedPDU.getRequestID() == requestID) { // check error status; if retrieval problem, throw SNMPGetException if (receivedPDU.getErrorStatus() != 0) { switch (receivedPDU.getErrorStatus()) { case 1: throw new SNMPSetException("Value supplied for OID " + itemID + " too big."); case 2: throw new SNMPSetException("OID " + itemID + " not available for setting."); case 3: throw new SNMPSetException("Bad value supplied for OID " + itemID + "."); case 4: throw new SNMPSetException("OID " + itemID + " read-only."); default: throw new SNMPSetException("Error setting OID " + itemID + "."); } } varList = receivedPDU.getVarBindList(); SNMPSequence newPair = (SNMPSequence)(varList.getSNMPObjectAt(0)); // check the object identifier to make sure the correct variable has been received; // if not, just continue waiting for receive if (((SNMPObjectIdentifier)newPair.getSNMPObjectAt(0)).toString().equals(itemID)) { // got the right one; add it to retrieved var list and break! retrievedVars.addSNMPObject(newPair); break; } } } requestID++; return retrievedVars; } /* public void broadcastDiscovery(String itemID) throws IOException, SNMPBadValueException { // send GetRequest to all hosts to retrieve specified object identifier int errorStatus = 0; int errorIndex = 0; int requestID = 0; SNMPObjectIdentifier requestedObjectIdentifier = new SNMPObjectIdentifier(itemID); SNMPVariablePair nextPair = new SNMPVariablePair(requestedObjectIdentifier, new SNMPInteger(0)); SNMPSequence varList = new SNMPSequence(); varList.addSNMPObject(nextPair); SNMPPDU pdu = new SNMPPDU(SNMPBERCodec.SNMPGETREQUEST, requestID, errorStatus, errorIndex, varList); SNMPMessage message = new SNMPMessage(0, community, pdu); byte[] messageEncoding = message.getBEREncoding(); DatagramPacket outPacket = new DatagramPacket(messageEncoding, messageEncoding.length, hostAddress, SNMPPORT); dSocket.send(outPacket); } public String receiveDiscovery() throws IOException, SNMPBadValueException { // receive responses from hosts responding to discovery message int MAXSIZE = 512; String returnString = new String(); int errorStatus = 0; int errorIndex = 0; int requestID = 0; DatagramPacket inPacket = new DatagramPacket(new byte[MAXSIZE], MAXSIZE); dSocket.receive(inPacket); String hostString = inPacket.getAddress().toString(); returnString += "Packet received from: " + hostString + "\n"; byte[] encodedMessage = inPacket.getData(); returnString += "Message bytes:" + "\n"; for (int i = 0; i < encodedMessage.length; ++i) { returnString += (encodedMessage[i]) + " "; } SNMPMessage receivedMessage = new SNMPMessage(SNMPBERCodec.extractNextTLV(encodedMessage,0).value); SNMPSequence varList = (receivedMessage.getPDU()).getVarBindList(); SNMPSequence newPair = (SNMPSequence)(varList.getSNMPObjectAt(0)); SNMPObject newValue = newPair.getSNMPObjectAt(1); // return just value string returnString += newValue.toString() + "\n\n"; returnString += "Received message contents:\n"; returnString += receivedMessage.toString() + "\n"; System.out.println(receivedMessage.toString()); return returnString; } public String discoverDevices(String itemID) throws IOException, SNMPBadValueException { // send GetRequest to all hosts to retrieve specified object identifier int MAXSIZE = 512; String returnString = new String(); try { int errorStatus = 0; int errorIndex = 0; DatagramSocket dSocket = new DatagramSocket(); int requestID = 0; SNMPObjectIdentifier requestedObjectIdentifier = new SNMPObjectIdentifier(itemID); SNMPVariablePair nextPair = new SNMPVariablePair(requestedObjectIdentifier, new SNMPInteger(0)); SNMPSequence varList = new SNMPSequence(); varList.addSNMPObject(nextPair); SNMPPDU pdu = new SNMPPDU(SNMPBERCodec.SNMPGETREQUEST, requestID, errorStatus, errorIndex, varList); SNMPMessage message = new SNMPMessage(0, community, pdu); byte[] messageEncoding = message.getBEREncoding(); DatagramPacket outPacket = new DatagramPacket(messageEncoding, messageEncoding.length, hostAddress, SNMPPORT); dSocket.send(outPacket); DatagramPacket inPacket = new DatagramPacket(new byte[MAXSIZE], MAXSIZE); while (true) { dSocket.receive(inPacket); String hostString = inPacket.getAddress().toString(); returnString += "Packet received from: " + hostString + "\n"; byte[] encodedMessage = inPacket.getData(); returnString += "Message bytes:" + "\n"; for (int i = 0; i < encodedMessage.length; ++i) { returnString += (encodedMessage[i]) + " "; } SNMPMessage receivedMessage = new SNMPMessage(SNMPBERCodec.extractNextTLV(encodedMessage,0).value); returnString += "Received message contents:\n"; returnString += receivedMessage.toString() + "\n"; } } catch (Exception e) { } return returnString; } private String getHex(byte theByte) { int b = theByte; if (b < 0) b += 256; String returnString = new String(Integer.toHexString(b)); // add leading 0 if needed if (returnString.length()%2 == 1) returnString = "0" + returnString; return returnString; } */ }airportconfig-1.5.2/snmp/package.html0000644000175000017500000000362407503646614017201 0ustar julienjulien SNMP package The snmp package defines classes used to communicate with SNMP devices. Classes corresponding to each of the basic SNMP data types are defined, each extending the SNMPObject abstarct class. In addition, some utility classes provide additional functionality.

Each of the SNMPObject subclasses defines methods to create an object, either from a "reasonable" representation (e.g., Java.lang.Integer for an SNMPInteger object, or a suitable String such as "1.2.1.1.3.2.1.1.0" for an SNMPObjectIdentifier), or from a byte array presumed to contain a valid ASN.1 Basic Encoding Rules (BER) encoding of a value of the appropriate type. The objects also define methods that permit their values to be set, and generate their BER encodings.

SNMPSequence subclasses, in particular, contain Vectors of other SNMPObject subclasses. They can be created "manually", with objects added as desired, or can be created from a BER encoding of the sequence contents, recursively creating the contained objects. BER generation also recursively generates the BER for each contained component; thus calling  mySequence.getBerEncoding() automatically generates the encoding for the entire sequence, including the contained components. SNMPBERCodec contains a number of static utility methods for converting to and from BER encodings, as well as constants used by the various classes.

Finally, SNMPv1CommunicationsInterface defines methods for sending SNMP Get and Set requests to devices; this class handles all of the communication tasks needed for developing simple SNMP applications. airportconfig-1.5.2/snmp/snmp0000644000175000017500000000007407503646614015614 0ustar julienjulien!../../../Airport Configurator Project/source/snmpairportconfig-1.5.2/AirportBaseStation128BitConfigurator.java0000644000175000017500000010724507503646614023644 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 byteblock.*; import snmp.*; import airport.*; public class AirportBaseStationConfigurator extends JFrame implements ActionListener { public static final String encryptionKeySizeString = "0D"; public static final int encryptionKeySize = 13; public static final String aboutString = "Airport Base Station Configurator 128-bit Encryption "; JButton discoverDevicesButton, retrieveItemButton, updateBaseStationButton; JTextField hostIDField; JTextField communityField; GridBagLayout mainLayout = new GridBagLayout(); MenuBar theMenubar; Menu fileMenu; MenuItem quitItem, openItem, saveItem, aboutItem, uploadFirmwareItem; private final int baseBlockSize = 68*16*16; private ByteBlock baseBlock = new ByteBlock(68*16, 16); private final int configurationSize = 17336; // total number of significant bytes, including checksum AirportInfo airportInfo; AirportInfoTabbedPane infoPane; JTextArea messagesArea; SNMPv1CommunicationInterface comInterface; SNMPVarBindList retrievedVars; // WindowCloseAdapter to catch window close-box closings private class WindowCloseAdapter extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } }; public AirportBaseStationConfigurator() { airportInfo = new AirportInfo(baseBlock); setUpDisplay(); retrievedVars = new SNMPVarBindList(); } 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 // thanks to Jer for this one! addWindowListener(new WindowCloseAdapter()); this.setTitle("AirPort Base Station 128-Bit Encryption Configurator"); this.getRootPane().setBorder(new BevelBorder(BevelBorder.RAISED)); theMenubar = new MenuBar(); this.setMenuBar(theMenubar); fileMenu = new Menu("File"); openItem = new MenuItem("Open saved settings..."); openItem.setShortcut(new MenuShortcut('o')); openItem.setActionCommand("open settings"); openItem.addActionListener(this); fileMenu.add(openItem); saveItem = new MenuItem("Save settings..."); saveItem.setShortcut(new MenuShortcut('s')); saveItem.setActionCommand("save settings"); saveItem.addActionListener(this); fileMenu.add(saveItem); fileMenu.addSeparator(); uploadFirmwareItem = new MenuItem("Upload new base station firmware..."); uploadFirmwareItem.setActionCommand("upload firmware"); uploadFirmwareItem.addActionListener(this); fileMenu.add(uploadFirmwareItem); fileMenu.addSeparator(); aboutItem = new MenuItem("About..."); aboutItem.setActionCommand("about"); aboutItem.addActionListener(this); fileMenu.add(aboutItem); quitItem = new MenuItem("Quit"); quitItem.setShortcut(new MenuShortcut('q')); quitItem.setActionCommand("quit"); quitItem.addActionListener(this); fileMenu.add(quitItem); theMenubar.add(fileMenu); JLabel hostIDLabel = new JLabel("Device address:"); hostIDField = new JTextField(10); hostIDField.setText("10.0.1.1"); JLabel communityLabel = new JLabel("Community name (password):"); communityField = new JPasswordField(10); //communityField = new JTextField(10); //communityField.setText("public"); discoverDevicesButton = new JButton("Discover Devices"); discoverDevicesButton.setActionCommand("discover devices"); discoverDevicesButton.addActionListener(this); retrieveItemButton = new JButton("Retrieve Settings"); retrieveItemButton.setActionCommand("retrieve data"); retrieveItemButton.addActionListener(this); updateBaseStationButton = new JButton("Update Base Station"); updateBaseStationButton.setActionCommand("update base station"); updateBaseStationButton.addActionListener(this); updateBaseStationButton.setEnabled(false); //initially disabled until read in or open settings // 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(discoverDevicesButton, c); buttonPanel.add(discoverDevicesButton); c.gridx = 2; c.gridy = 1; theLayout.setConstraints(retrieveItemButton, c); buttonPanel.add(retrieveItemButton); c.gridx = 3; c.gridy = 1; theLayout.setConstraints(updateBaseStationButton, c); buttonPanel.add(updateBaseStationButton); JPanel hostPanel = new JPanel(); hostPanel.setLayout(theLayout); c.gridx = 1; c.gridy = 1; theLayout.setConstraints(hostIDLabel, c); hostPanel.add(hostIDLabel); c.gridx = 2; c.gridy = 1; theLayout.setConstraints(hostIDField, c); hostPanel.add(hostIDField); c.gridx = 3; c.gridy = 1; theLayout.setConstraints(communityLabel, c); hostPanel.add(communityLabel); c.gridx = 4; c.gridy = 1; theLayout.setConstraints(communityField, c); hostPanel.add(communityField); infoPane = new AirportInfoTabbedPane(airportInfo); JPanel messagesPanel = new JPanel(); messagesPanel.setLayout(theLayout); messagesArea = new JTextArea(4,60); 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(messagesScroll, c); messagesPanel.add(messagesScroll); this.getContentPane().setLayout(mainLayout); c.gridx = 1; c.gridy = 1; mainLayout.setConstraints(hostPanel, c); this.getContentPane().add(hostPanel); c.gridx = 1; c.gridy = 2; mainLayout.setConstraints(buttonPanel, c); this.getContentPane().add(buttonPanel); c.gridx = 1; c.gridy = 3; mainLayout.setConstraints(infoPane, c); this.getContentPane().add(infoPane); c.gridx = 1; c.gridy = 4; mainLayout.setConstraints(messagesPanel, c); this.getContentPane().add(messagesPanel); c.gridx = 1; c.gridy = 5; JLabel authorLabel = new JLabel(" Version 1.5.2/128 J. Sevy, November 2001 "); authorLabel.setFont(new Font("SansSerif", Font.ITALIC, 8)); mainLayout.setConstraints(authorLabel, c); this.getContentPane().add(authorLabel); } public void actionPerformed(ActionEvent theEvent) // respond to button pushes, menu selections { String command = theEvent.getActionCommand(); if (command == "quit") { System.exit(0); } if (command == "about") { AboutDialog aboutDialog = new AboutDialog(this); } if (command == "discover devices") { AirportDiscoverer discoverer = new AirportDiscoverer(); } if (command == "retrieve data") { try { if (comInterface != null) comInterface.closeConnection(); String community = communityField.getText(); InetAddress hostAddress = InetAddress.getByName(hostIDField.getText()); int version = 0; // SNMPv1 messagesArea.append("Retrieving settings from base station " + hostAddress + "......\n"); comInterface = new SNMPv1CommunicationInterface(version, hostAddress, community); for (int k = 1; k <= 68; k++) { String itemID = "1.3.6.1.4.1.762.2.2.1.1." + k; SNMPVarBindList newVars = comInterface.getMIBEntry(itemID); SNMPSequence pair = (SNMPSequence)(newVars.getSNMPObjectAt(0)); SNMPOctetString value = (SNMPOctetString)(pair.getSNMPObjectAt(1)); // get the 256 bytes byte[] bytes = (byte[])value.getValue(); // create a window to write bytes into int startIndex = (k-1)*256; int rows = 16; int cols = 16; ByteBlockRectangularWindow currentBlock = new ByteBlockRectangularWindow(startIndex, rows, cols, baseBlock); // write the bytes currentBlock.writeBytes(bytes); } // would like to check checksum to make sure retrieved block is valid, at least... // however, base station doesn't return valid checksum when data retrieved - // it's just a partial echo of the last checksum sent to it :-( messagesArea.append("Settings retrieved.\n"); // now refresh display this.refreshInfoPane(); // enable updating updateBaseStationButton.setEnabled(true); } catch(UnknownHostException e) { messagesArea.append("Error retrieving settings: unknown host.\n"); } catch(SocketException e) { messagesArea.append("Error retrieving settings: " + e + "\n"); } catch(IOException e) { messagesArea.append("Error retrieving settings: timed out waiting for response.\n"); } catch (SNMPBadValueException e) { // will never occur! messagesArea.append("Error retrieving settings: bad SNMP value received.\n"); } catch (SNMPGetException e) { messagesArea.append("Error retrieving settings: incorrect community name (password).\n"); } catch (Exception e) { messagesArea.append("Error retrieving settings: " + e.getMessage() + "\n"); } } if (command == "save settings") { try { infoPane.writeData(); setDependentData(); setStaticData(); setChecksum(baseBlock, configurationSize - 2); FileDialog fd = new FileDialog(this, "Save current settings as...", FileDialog.SAVE); fd.show(); if (fd.getFile() != null) { File newFile = new File(fd.getDirectory(), fd.getFile()); FileOutputStream fStream = new FileOutputStream(newFile); fStream.write(baseBlock.bytes, 0, configurationSize); fStream.flush(); fStream.close(); } } catch (ValueFormatException ve) { messagesArea.append("Problem with supplied value: " + ve.getMessage() + "\n"); } catch (Exception e) { messagesArea.append("Error saving settings: " + e.getMessage() + "\n"); } } if (command == "update base station") { try { infoPane.writeData(); setDependentData(); setStaticData(); setChecksum(baseBlock, configurationSize - 2); // second checksum set in transmitBlocks() // configurationSize = 17336 indicates number of bytes to burn to prom: // includes first checksum (but not second, which is "transmission" // checksum - added by transmitBlocks method) transmitBlocks(baseBlock, configurationSize); } catch (ValueFormatException ve) { messagesArea.append("Problem with supplied value: " + ve.getMessage() + "\n"); } } if (command == "open settings") { try { FileDialog fd = new FileDialog(this, "Open settings file...", FileDialog.LOAD); fd.show(); if (fd.getFile() != null) { File newFile = new File(fd.getDirectory(), fd.getFile()); FileInputStream fStream = new FileInputStream(newFile); byte[] newBytes = new byte[17408]; fStream.read(newBytes); fStream.close(); // check checksum to make sure block is valid, at least... // save current bytes in case new ones invalid byte[] currentBytes = baseBlock.bytes; baseBlock.bytes = newBytes; // make sure checksum is valid, to verify this is a valid settings file // first make sure file big enough to even check checksum! if ( (newFile.length() < configurationSize) || (!checksumValid()) ) { // reset base block to current bytes baseBlock.bytes = currentBytes; throw new Exception("invalid settings file."); } // now refresh display of data this.refreshInfoPane(); // enable updating updateBaseStationButton.setEnabled(true); } } catch (Exception e) { messagesArea.append("Error opening settings: " + e.getMessage() + "\n"); } } if (command == "upload firmware") { try { FileDialog fd = new FileDialog(this, "Select firmware file...", FileDialog.LOAD); fd.show(); if (fd.getFile() != null) { File firmwareFile = new File(fd.getDirectory(), fd.getFile()); FileInputStream fStream = new FileInputStream(firmwareFile); int fileLength = (int)firmwareFile.length(); // determine number of 256-byte blocks that need to be sent int numBlocks = (int)Math.ceil((double)fileLength/256); // create underlying ByteBlock with appropriate number of sub-blocks ByteBlock firmwareBlock = new ByteBlock(numBlocks*16, 16); fStream.read(firmwareBlock.bytes); fStream.close(); // verify this is a valid firmware file; can unfortunately only verify the embedded // configuration checksum.... AND apparently the Apple-supplied formware files computed the // checksum before the community name default passwords (4 "public" and one count of 06) // were inserted. Thus the checksum computation differs by 0xA02 for these files, // so the checksum check is a little weird.... // first make sure file big enough to even check checksum! if (fileLength < configurationSize) { throw new Exception("invalid firmware file."); } else if ( (!appleFirmwareChecksumValid(firmwareBlock)) && (!checksumValid(firmwareBlock)) ) { throw new Exception("invalid firmware file."); } // put up a dialog permitting the user to select uploading the current settings, if // they're valid... String messageString = "Upload firmware to base station " + hostIDField.getText() + "?"; String response = new String("Cancel"); // see if current settings are valid; if so, these become upload option if (updateBaseStationButton.isEnabled()) { String[] possibleValues = { "Upload firmware with current settings", "Upload firmware with default settings", "Cancel" }; int selectedValue = JOptionPane.showOptionDialog(null, messageString, "Firmware Upload", JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, null, possibleValues, possibleValues[0]); if ( !(selectedValue == JOptionPane.CLOSED_OPTION) ) response = possibleValues[selectedValue]; } else { String[] possibleValues = { "Upload firmware with default settings", "Cancel" }; int selectedValue = JOptionPane.showOptionDialog(null, messageString, "Firmware Upload", JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, null, possibleValues, possibleValues[0]); if ( !(selectedValue == JOptionPane.CLOSED_OPTION) ) response = possibleValues[selectedValue]; } // if current settings selected, upload these to base station with firmware; // if not, leave default settings alone in firmware bytes if (response.equals("Upload firmware with current settings")) { // note that current settings could throw ValueFormatException! infoPane.writeData(); setDependentData(); setStaticData(); setCommunityNames(); // so base station will know what to use after reset!! setChecksum(baseBlock, configurationSize - 2); // copy current setting bytes into firmware bytes for (int i = 0; i < configurationSize; i++) firmwareBlock.bytes[i] = baseBlock.bytes[i]; // now transmit info transmitBlocks(firmwareBlock, fileLength); } else if (response.equals("Upload firmware with default settings")) { // just transmit firmware info with default settings transmitBlocks(firmwareBlock, fileLength); } } } catch (ValueFormatException ve) { messagesArea.append("Problem with supplied value: " + ve.getMessage() + "\n"); } catch (Exception e) { messagesArea.append("Error updating firmware: " + e.getMessage() + "\n"); } } } private void refreshInfoPane() { // first, remove current infoPane this.remove(infoPane); //now create new tabbed pane to hold info infoPane = new AirportInfoTabbedPane(airportInfo); // set params for layout manager 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; // then add pane to frame c.gridx = 1; c.gridy = 3; mainLayout.setConstraints(infoPane, c); this.getContentPane().add(infoPane); // call validate to update display this.validate(); } private void setDependentData() throws ValueFormatException { /* * Write values for DHCP/NAT-delivered base station IP address, router * IP address, mask; do here since requires "cross-reference" between data * in separate panels. */ boolean ethernetConnection = false, modemConnection = false; // flags specifying base station connection and boolean dhcpConfig = false, manualConfig = false; // configuration style boolean natEnabled = false, dhcpEnabled = false; // flags indicating address delivery services of base station boolean portMappingEnabled = false; // set flags for Ethernet/Modem mode AirportInfoRecord ethernetModemSwitch1Record = airportInfo.get("Ethernet/Modem switch 1"); String ethernetModemSwitch1Setting = ethernetModemSwitch1Record.toString(); AirportInfoRecord ethernetModemSwitch2Record = airportInfo.get("Configuration interface"); String ethernetModemSwitch2Setting = ethernetModemSwitch2Record.toString(); if (ethernetModemSwitch1Setting.equals("60") || ethernetModemSwitch2Setting.equals("00")) ethernetConnection = true; if (ethernetModemSwitch1Setting.equals("62") || ethernetModemSwitch2Setting.equals("03")) modemConnection = true; //set flags for base station configuration mode AirportInfoRecord baseConfigModeRecord = airportInfo.get("Base station configuration mode switch"); String baseConfigModeSetting = baseConfigModeRecord.toString(); if (baseConfigModeSetting.equals("00")) manualConfig = true; if (baseConfigModeSetting.equals("20")) dhcpConfig = true; // set flags for NAT/DHCP mode AirportInfoRecord dhcpSwitchRecord = airportInfo.get("DHCP switch"); String dhcpSetting = dhcpSwitchRecord.toString(); if (dhcpSetting.equals("80")) dhcpEnabled = true; AirportInfoRecord natSwitchRecord = airportInfo.get("NAT switch"); String natSetting = natSwitchRecord.toString(); if (natSetting.equals("02")) natEnabled = true; // set flag for port mapping AirportInfoRecord portMappingSwitchRecord = airportInfo.get("Port mapping switch"); String portMappingSwitchSetting = portMappingSwitchRecord.toString(); if (portMappingSwitchSetting.equals("04")) portMappingEnabled = true; // get records for setting dependent data AirportInfoRecord natInboundPrivateIPAddressRecord = airportInfo.get("NAT inbound private IP address"); AirportInfoRecord natInboundPrivateSubnetMaskRecord = airportInfo.get("NAT inbound private subnet mask"); AirportInfoRecord natOutboundPrivateIPAddressRecord = airportInfo.get("NAT outbound private IP address"); AirportInfoRecord natOutboundPrivateSubnetMaskRecord = airportInfo.get("NAT outbound private subnet mask"); AirportInfoRecord natOutboundPublicIPAddressRecord = airportInfo.get("NAT outbound public IP address"); AirportInfoRecord natOutboundPublicSubnetMaskRecord = airportInfo.get("NAT outbound public subnet mask"); AirportInfoRecord dhcpServerRouterIPAddressRecord = airportInfo.get("DHCP server router address"); AirportInfoRecord dhcpServerSubnetMaskRecord = airportInfo.get("DHCP server subnet mask"); AirportInfoRecord baseStationIPAddressRecord = airportInfo.get("Base station IP address"); AirportInfoRecord subnetMaskRecord = airportInfo.get("Subnet mask"); AirportInfoRecord routerIPAddressRecord = airportInfo.get("Router IP address"); // when NAT enabled, set data that depends on settings from other panels if (natEnabled) { // set NAT outbound IP address and mask if (modemConnection) { natOutboundPublicIPAddressRecord.setBytesFromString("0.0.0.0"); natOutboundPublicSubnetMaskRecord.setBytesFromString("255.255.255.0"); } if (ethernetConnection) { if (manualConfig) { natOutboundPublicIPAddressRecord.setBytesFromString(baseStationIPAddressRecord.toString()); natOutboundPublicSubnetMaskRecord.setBytesFromString(subnetMaskRecord.toString()); } else if (dhcpConfig) { natOutboundPublicIPAddressRecord.setBytesFromString("0.0.0.0"); natOutboundPublicSubnetMaskRecord.setBytesFromString("255.255.255.0"); } } } // if serving DHCP, set router and subnet mask if (dhcpEnabled) { if (natEnabled) { // use private network parameters dhcpServerRouterIPAddressRecord.setBytesFromString(natInboundPrivateIPAddressRecord.toString()); dhcpServerSubnetMaskRecord.setBytesFromString(natInboundPrivateSubnetMaskRecord.toString()); } else { // use global base station parameters dhcpServerRouterIPAddressRecord.setBytesFromString(routerIPAddressRecord.toString()); dhcpServerSubnetMaskRecord.setBytesFromString(subnetMaskRecord.toString()); } } // if port mapping, and using manual Ethernet config, need to put in base station IP address // as the public IP address in the port maps if (portMappingEnabled && ethernetConnection && manualConfig) { // get count of port maps AirportInfoRecord portMappingCountRecord = airportInfo.get("Count of port mappings"); int portMapCount = Integer.parseInt(portMappingCountRecord.toString()); // get starting indices and other parameters for the byte block multi-windows // that will hold the public IP address for port mapping, which is just the // manually configured base station IP address int publicIPStartIndex = 0xD72; int publicIPBeginningNumRows = 1; int publicIPBeginningNumCols = 2; int publicIPEndingIndex = 0xD9A; int publicIPEndingNumRows = 1; int publicIPEndingNumCols = 2; int publicIPDataType = AirportInfoRecord.IP_ADDRESS; //set the public IP address for each port map for (int i = 0; i < portMapCount; i++) { // need to use a multi-window, since the first two and last two octets are separated ByteBlockMultiWindow publicIPWindow = new ByteBlockMultiWindow(); ByteBlockWindow publicIPBeginningWindow = new ByteBlockRectangularWindow(publicIPStartIndex, publicIPBeginningNumRows, publicIPBeginningNumCols, baseBlock); publicIPWindow.addWindow(publicIPBeginningWindow); ByteBlockWindow publicIPEndingWindow = new ByteBlockRectangularWindow(publicIPEndingIndex, publicIPEndingNumRows, publicIPEndingNumCols, baseBlock); publicIPWindow.addWindow(publicIPEndingWindow); AirportInfoRecord publicIPRecord = new AirportInfoRecord(publicIPDataType, publicIPWindow); publicIPRecord.setBytesFromString(baseStationIPAddressRecord.toString()); // augment addresses publicIPStartIndex += 2; publicIPEndingIndex += 2; } } } private void setStaticData() throws ValueFormatException { // set read community password field AirportInfoRecord readCommunityRecord = airportInfo.get("Read community"); readCommunityRecord.setBytesFromString("public"); /* // set miscellaneous switches that are sometimes zero in "plain vanilla" config files String miscellaneousSetting; AirportInfoRecord miscellaneousRecord1 = airportInfo.get("Miscellaneous switch 1"); miscellaneousSetting = miscellaneousRecord1.toString(); if (miscellaneousSetting.equals("00")) miscellaneousRecord1.setBytesFromString("01"); AirportInfoRecord miscellaneousRecord2 = airportInfo.get("Miscellaneous switch 2"); miscellaneousSetting = miscellaneousRecord2.toString(); if (miscellaneousSetting.equals("00")) miscellaneousRecord2.setBytesFromString("01"); */ } private void setCommunityNames() throws ValueFormatException { // Set community name into password field so base station will know what to use after reboot! // Find out if there's an entry in the main panel; if so, use this, otherwise use // current community name field AirportInfoRecord communityNameRecord = airportInfo.get("Read/write community"); String communityName = communityNameRecord.toString(); if (communityName.equals("")) communityName = communityField.getText(); communityNameRecord.setBytesFromString(communityName); //System.out.println("Community name: " + communityName); // set trap community password field AirportInfoRecord trapCommunityRecord = airportInfo.get("Trap community"); trapCommunityRecord.setBytesFromString("public"); // set remaining community password field (and count field) AirportInfoRecord remainingCommunityCountRecord = airportInfo.get("Remaining community count"); remainingCommunityCountRecord.setBytesFromString("06"); AirportInfoRecord remainingCommunityRecord = airportInfo.get("Remaining community"); remainingCommunityRecord.setBytesFromString("public"); } private void transmitBlocks(ByteBlock byteBlock, int numBytes) { try { String community = communityField.getText(); InetAddress hostAddress = InetAddress.getByName(hostIDField.getText()); messagesArea.append("Sending data to base station " + hostAddress + "......\n"); if (comInterface == null) { int version = 0; // SNMPv1 comInterface = new SNMPv1CommunicationInterface(version, hostAddress, community); } comInterface.requestID = 1; byte[] bytes = byteBlock.bytes; // determine number of 256-byte blocks that need to be sent int numBlocks = (int)Math.ceil((double)(numBytes + 2)/256); // +2 leaves room for transmission checksum // send all but last block for (int k = 1; k < numBlocks; k++) { String itemID = "1.3.6.1.4.1.762.2.3.1.1." + k; // create new 256 byte array byte[] newBytes = new byte[256]; // copy block of 256 bytes from given bytes to new array for (int j = 0; j < 256; j++) { newBytes[j] = bytes[256*(k-1) + j]; } // create SNMP octet string from these bytes SNMPOctetString theObject = new SNMPOctetString(newBytes); // send the bytes SNMPVarBindList newVars = comInterface.setMIBEntry(itemID, theObject); } // now send last block String itemID = "1.3.6.1.4.1.762.2.3.1.1." + numBlocks; // create new 256 byte array byte[] newBytes = new byte[256]; // copy remaining bytes from given bytes to new array int endPosition = numBytes - (numBlocks-1)*256; for (int j = 0; j < endPosition; j++) { newBytes[j] = bytes[256*(numBlocks-1) + j]; } // now set transmission checksum as 2 bytes following last (legitimate) bytes; // note that number of blocks was chosen to be (numBytes+2)/256, ensuring room ByteBlock lastBlock = new ByteBlock(16, 16, newBytes); short checksum = computeChecksum(byteBlock.bytes, numBytes); setChecksum(checksum, lastBlock, endPosition); // create SNMP octet string from these bytes SNMPOctetString theObject = new SNMPOctetString(lastBlock.bytes); // send the bytes SNMPVarBindList newVars = comInterface.setMIBEntry(itemID, theObject); // now send reset signal: indicates number of bytes to burn to prom. // also indicates location of checksum SNMPInteger numBytesWritten = new SNMPInteger(numBytes); //System.out.println("Number of bytes to burn in: " + numBytesWritten); itemID = "1.3.6.1.4.1.762.2.1.2.0"; newVars = comInterface.setMIBEntry(itemID, numBytesWritten); itemID = "1.3.6.1.4.1.762.2.1.3.0"; newVars = comInterface.setMIBEntry(itemID, numBytesWritten); messagesArea.append("Data transmitted; base station restarting.\n"); } catch(UnknownHostException e) { messagesArea.append("Error transmitting data: unknown host.\n"); } catch(SocketException e) { messagesArea.append("Error transmitting data: " + e.getMessage() + "\n"); } catch(IOException e) { messagesArea.append("Error transmitting data: timed out waiting for response.\n"); } catch (SNMPSetException e) { messagesArea.append("Error transmitting data: " + e.getMessage() + "\n"); } catch (SNMPBadValueException e) { // will never occur! messagesArea.append("Error transmitting data: bad SNMP value.\n"); } } /* * Compute the 2-byte checksum for the bytes up to (but not including) the indicated position */ private short computeChecksum(byte[] bytes, int position) { short sum = 0; for (int i = 0; i < position; i++) { sum += bytes[i]; if(bytes[i] < 0) sum += 256; } return sum; } private void setChecksum(short sum, ByteBlock byteBlock, int position) { String checksumString = littleEndianHexString(sum); // create info record to write into int numRows = 1; int numCols = 2; int baseStartIndex = position; ByteBlockWindow checksumWindow = new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, byteBlock); int dataType = AirportInfoRecord.BYTE_STRING; AirportInfoRecord checksumRecord = new AirportInfoRecord(dataType, checksumWindow); checksumRecord.byteBlockWindow.clearBytes(); // write in new checksum try { checksumRecord.setBytesFromString(checksumString); } catch (ValueFormatException ve) { // won't occur! messagesArea.append("Problem writing checksum with value " + checksumString + ".\n"); } } /* * Convenience method for writing checksum value into same block it's computed from. This * is the usual case for config files; however, the more general routine is used to set * the transmission checksum immediately following the transmitted data bytes. */ private void setChecksum(ByteBlock byteBlock, int position) { short sum = computeChecksum(byteBlock.bytes, position); setChecksum(sum, byteBlock, position); } /** * Return little-endian hex string */ private String littleEndianHexString(short value) { int intValue = value; intValue = intValue & 0xFFFF; int switched = ((intValue << 8) | (intValue >>> 8)) & 0xFFFF; String returnString = Integer.toHexString(switched); // add leading zeros if needed while (returnString.length() < 4) returnString = "0" + returnString; return returnString; } /** * Used to validate checksum in stored settings, to ensure file is legitimate! Verify just * first checksum, for compatibility with Apple configurator's stored settings. */ private boolean checksumValid(ByteBlock byteBlock) { short sum = computeChecksum(byteBlock.bytes, configurationSize - 2); String computedChecksumString = littleEndianHexString(sum); //System.out.println("Computed checksum: " + computedChecksumString); // get configuration checksum from block int baseStartIndex = 0x43B6; int numRows = 1; int numCols = 2; int dataType = AirportInfoRecord.BYTE_STRING; AirportInfoRecord checksumRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, byteBlock); String existingChecksumString = checksumRecord.toString(); //System.out.println("Existing checksum: " + existingChecksumString); if (computedChecksumString.equals(existingChecksumString)) return true; else return false; } private boolean checksumValid() { return checksumValid(baseBlock); } // Apparently the Apple-supplied firmware files computed the // checksum before the community name default passwords (4 "public" and one count of 06) // were inserted. Thus the checksum computation should differ by 0xA02 for these files. // Thus the need for this "hacked" checksum validation.... private boolean appleFirmwareChecksumValid(ByteBlock byteBlock) { short sum = computeChecksum(byteBlock.bytes, configurationSize - 2); sum -= 0xA02; String computedChecksumString = littleEndianHexString(sum); //System.out.println("Computed checksum: " + computedChecksumString); // get configuration checksum from block int baseStartIndex = 0x43B6; int numRows = 1; int numCols = 2; int dataType = AirportInfoRecord.BYTE_STRING; AirportInfoRecord checksumRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, byteBlock); String existingChecksumString = checksumRecord.toString(); //System.out.println("Existing checksum: " + existingChecksumString); if (computedChecksumString.equals(existingChecksumString)) return true; else return false; } public static void main(String args[]) { try { AirportBaseStationConfigurator theApp = new AirportBaseStationConfigurator(); theApp.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 = theApp.getSize(); dim.height += 20; dim.width += 20; theApp.setSize(dim); theApp.show(); } catch (Exception e) {} } }airportconfig-1.5.2/AirportBaseStationConfiguratorMicro.java0000644000175000017500000010736407503646614023746 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 byteblock.*; import snmp.*; import airport.*; public class AirportBaseStationConfigurator extends JFrame implements ActionListener { public static final String encryptionKeySizeString = "05"; public static final int encryptionKeySize = 5; public static final String aboutString = "Airport Base Station Configurator Micro Edition "; JButton discoverDevicesButton, retrieveItemButton, updateBaseStationButton; JTextField hostIDField; JTextField communityField; GridBagLayout mainLayout = new GridBagLayout(); MenuBar theMenubar; Menu fileMenu; MenuItem quitItem, openItem, saveItem, aboutItem, uploadFirmwareItem; private final int baseBlockSize = 68*16*16; private ByteBlock baseBlock = new ByteBlock(68*16, 16); private final int configurationSize = 17336; // total number of significant bytes, including checksum AirportInfo airportInfo; AirportInfoTabbedPane infoPane; JTextArea messagesArea; SNMPv1CommunicationInterface comInterface; SNMPVarBindList retrievedVars; // WindowCloseAdapter to catch window close-box closings private class WindowCloseAdapter extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } }; public AirportBaseStationConfigurator() { airportInfo = new AirportInfo(baseBlock); setUpDisplay(); retrievedVars = new SNMPVarBindList(); } 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 // thanks to Jer for this one! addWindowListener(new WindowCloseAdapter()); this.setTitle("AirPort Base Station Configurator"); this.getRootPane().setBorder(new BevelBorder(BevelBorder.RAISED)); theMenubar = new MenuBar(); this.setMenuBar(theMenubar); fileMenu = new Menu("File"); openItem = new MenuItem("Open saved settings..."); openItem.setShortcut(new MenuShortcut('o')); openItem.setActionCommand("open settings"); openItem.addActionListener(this); fileMenu.add(openItem); saveItem = new MenuItem("Save settings..."); saveItem.setShortcut(new MenuShortcut('s')); saveItem.setActionCommand("save settings"); saveItem.addActionListener(this); fileMenu.add(saveItem); fileMenu.addSeparator(); uploadFirmwareItem = new MenuItem("Upload new base station firmware..."); uploadFirmwareItem.setActionCommand("upload firmware"); uploadFirmwareItem.addActionListener(this); fileMenu.add(uploadFirmwareItem); fileMenu.addSeparator(); aboutItem = new MenuItem("About..."); aboutItem.setActionCommand("about"); aboutItem.addActionListener(this); fileMenu.add(aboutItem); fileMenu.addSeparator(); quitItem = new MenuItem("Quit"); quitItem.setShortcut(new MenuShortcut('q')); quitItem.setActionCommand("quit"); quitItem.addActionListener(this); fileMenu.add(quitItem); theMenubar.add(fileMenu); JLabel hostIDLabel = new JLabel("Device address:"); hostIDField = new JTextField(10); hostIDField.setText("10.0.1.1"); JLabel communityLabel = new JLabel("Community name (password):"); communityField = new JPasswordField(10); //communityField = new JTextField(10); //communityField.setText("public"); discoverDevicesButton = new JButton("Discover Devices"); discoverDevicesButton.setActionCommand("discover devices"); discoverDevicesButton.addActionListener(this); retrieveItemButton = new JButton("Retrieve Settings"); retrieveItemButton.setActionCommand("retrieve data"); retrieveItemButton.addActionListener(this); updateBaseStationButton = new JButton("Update Base Station"); updateBaseStationButton.setActionCommand("update base station"); updateBaseStationButton.addActionListener(this); updateBaseStationButton.setEnabled(false); //initially disabled until read in or open settings // 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(discoverDevicesButton, c); buttonPanel.add(discoverDevicesButton); c.gridx = 2; c.gridy = 1; theLayout.setConstraints(retrieveItemButton, c); buttonPanel.add(retrieveItemButton); c.gridx = 3; c.gridy = 1; theLayout.setConstraints(updateBaseStationButton, c); buttonPanel.add(updateBaseStationButton); JPanel hostPanel = new JPanel(); hostPanel.setLayout(theLayout); c.gridx = 1; c.gridy = 1; theLayout.setConstraints(hostIDLabel, c); hostPanel.add(hostIDLabel); c.gridx = 2; c.gridy = 1; theLayout.setConstraints(hostIDField, c); hostPanel.add(hostIDField); c.gridx = 3; c.gridy = 1; theLayout.setConstraints(communityLabel, c); hostPanel.add(communityLabel); c.gridx = 4; c.gridy = 1; theLayout.setConstraints(communityField, c); hostPanel.add(communityField); infoPane = new AirportInfoTabbedPane(airportInfo); JPanel messagesPanel = new JPanel(); messagesPanel.setLayout(theLayout); messagesArea = new JTextArea(2,60); JScrollPane messagesScroll = new JScrollPane(messagesArea); messagesScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); /* 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(messagesScroll, c); messagesPanel.add(messagesScroll); */ this.getContentPane().setLayout(mainLayout); c.gridx = 1; c.gridy = 1; mainLayout.setConstraints(hostPanel, c); this.getContentPane().add(hostPanel); c.gridx = 1; c.gridy = 2; mainLayout.setConstraints(buttonPanel, c); this.getContentPane().add(buttonPanel); c.gridx = 1; c.gridy = 3; mainLayout.setConstraints(infoPane, c); this.getContentPane().add(infoPane); c.gridx = 1; c.gridy = 4; mainLayout.setConstraints(messagesScroll, c); this.getContentPane().add(messagesScroll); } public void actionPerformed(ActionEvent theEvent) // respond to button pushes, menu selections { String command = theEvent.getActionCommand(); if (command.equals("quit")) { System.exit(0); } if (command == "about") { AboutDialog aboutDialog = new AboutDialog(this); } if (command.equals("discover devices")) { AirportDiscoverer discoverer = new AirportDiscoverer(); } if (command.equals("retrieve data")) { try { if (comInterface != null) comInterface.closeConnection(); String community = communityField.getText(); InetAddress hostAddress = InetAddress.getByName(hostIDField.getText()); int version = 0; // SNMPv1 messagesArea.append("Retrieving settings from base station " + hostAddress + "......\n"); comInterface = new SNMPv1CommunicationInterface(version, hostAddress, community); for (int k = 1; k <= 68; k++) { String itemID = "1.3.6.1.4.1.762.2.2.1.1." + k; SNMPVarBindList newVars = comInterface.getMIBEntry(itemID); SNMPSequence pair = (SNMPSequence)(newVars.getSNMPObjectAt(0)); SNMPOctetString value = (SNMPOctetString)(pair.getSNMPObjectAt(1)); // get the 256 bytes byte[] bytes = (byte[])value.getValue(); // create a window to write bytes into int startIndex = (k-1)*256; int rows = 16; int cols = 16; ByteBlockRectangularWindow currentBlock = new ByteBlockRectangularWindow(startIndex, rows, cols, baseBlock); // write the bytes currentBlock.writeBytes(bytes); } // would like to check checksum to make sure retrieved block is valid, at least... // however, base station doesn't return valid checksum when data retrieved - // it's just a partial echo of the last checksum sent to it :-( messagesArea.append("Settings retrieved.\n"); // now refresh display this.refreshInfoPane(); // enable updating updateBaseStationButton.setEnabled(true); } catch(UnknownHostException e) { messagesArea.append("Error retrieving settings: unknown host.\n"); } catch(SocketException e) { messagesArea.append("Error retrieving settings: " + e + "\n"); } catch(IOException e) { messagesArea.append("Error retrieving settings: timed out waiting for response.\n"); } catch (SNMPBadValueException e) { // will never occur! messagesArea.append("Error retrieving settings: bad SNMP value received.\n"); } catch (SNMPGetException e) { messagesArea.append("Error retrieving settings: incorrect community name (password).\n"); } catch (Exception e) { messagesArea.append("Error retrieving settings: " + e.getMessage() + "\n"); } } if (command.equals("save settings")) { try { infoPane.writeData(); setDependentData(); setStaticData(); setChecksum(baseBlock, configurationSize - 2); FileDialog fd = new FileDialog(this, "Save current settings as...", FileDialog.SAVE); fd.show(); if (fd.getFile() != null) { File newFile = new File(fd.getDirectory(), fd.getFile()); FileOutputStream fStream = new FileOutputStream(newFile); fStream.write(baseBlock.bytes, 0, configurationSize); fStream.flush(); fStream.close(); } } catch (ValueFormatException ve) { messagesArea.append("Problem with supplied value: " + ve.getMessage() + "\n"); } catch (Exception e) { messagesArea.append("Error saving settings: " + e.getMessage() + "\n"); } } if (command.equals("update base station")) { try { infoPane.writeData(); setDependentData(); setStaticData(); setChecksum(baseBlock, configurationSize - 2); // second checksum set in transmitBlocks() // configurationSize = 17336 indicates number of bytes to burn to prom: // includes first checksum (but not second, which is "transmission" // checksum - added by transmitBlocks method) transmitBlocks(baseBlock, configurationSize); } catch (ValueFormatException ve) { messagesArea.append("Problem with supplied value: " + ve.getMessage() + "\n"); } } if (command.equals("open settings")) { try { FileDialog fd = new FileDialog(this, "Open settings file...", FileDialog.LOAD); fd.show(); if (fd.getFile() != null) { File newFile = new File(fd.getDirectory(), fd.getFile()); FileInputStream fStream = new FileInputStream(newFile); byte[] newBytes = new byte[17408]; fStream.read(newBytes); fStream.close(); // check checksum to make sure block is valid, at least... // save current bytes in case new ones invalid byte[] currentBytes = baseBlock.bytes; baseBlock.bytes = newBytes; // see if shift key held down while open selected; if so, don't check checksum boolean shiftKeyDown = ((theEvent.getModifiers() & ActionEvent.SHIFT_MASK) > 0); // make sure checksum is valid, to verify this is a valid settings file // first make sure file big enough to even check checksum! if ( (newFile.length() < configurationSize) || (!shiftKeyDown && !checksumValid()) ) { // reset base block to current bytes baseBlock.bytes = currentBytes; throw new Exception("invalid settings file."); } // now refresh display of data this.refreshInfoPane(); // enable updating updateBaseStationButton.setEnabled(true); } } catch (Exception e) { messagesArea.append("Error opening settings: " + e.getMessage() + "\n"); } } if (command.equals("upload firmware")) { try { FileDialog fd = new FileDialog(this, "Select firmware file...", FileDialog.LOAD); fd.show(); if (fd.getFile() != null) { File firmwareFile = new File(fd.getDirectory(), fd.getFile()); FileInputStream fStream = new FileInputStream(firmwareFile); int fileLength = (int)firmwareFile.length(); // determine number of 256-byte blocks that need to be sent int numBlocks = (int)Math.ceil((double)fileLength/256); // create underlying ByteBlock with appropriate number of sub-blocks ByteBlock firmwareBlock = new ByteBlock(numBlocks*16, 16); fStream.read(firmwareBlock.bytes); fStream.close(); // verify this is a valid firmware file; can unfortunately only verify the embedded // configuration checksum.... AND apparently the Apple-supplied formware files computed the // checksum before the community name default passwords (4 "public" and one count of 06) // were inserted. Thus the checksum computation differs by 0xA02 for these files, // so the checksum check is a little weird.... // first make sure file big enough to even check checksum! if (fileLength < configurationSize) { throw new Exception("invalid firmware file."); } else if ( (!appleFirmwareChecksumValid(firmwareBlock)) && (!checksumValid(firmwareBlock)) ) { throw new Exception("invalid firmware file."); } // put up a dialog permitting the user to select uploading the current settings, if // they're valid... String messageString = "Upload firmware to base station " + hostIDField.getText() + "?"; String response = new String("Cancel"); // see if current settings are valid; if so, these become upload option if (updateBaseStationButton.isEnabled()) { String[] possibleValues = { "Upload firmware with current settings", "Upload firmware with default settings", "Cancel" }; int selectedValue = JOptionPane.showOptionDialog(null, messageString, "Firmware Upload", JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, null, possibleValues, possibleValues[0]); if ( !(selectedValue == JOptionPane.CLOSED_OPTION) ) response = possibleValues[selectedValue]; } else { String[] possibleValues = { "Upload firmware with default settings", "Cancel" }; int selectedValue = JOptionPane.showOptionDialog(null, messageString, "Firmware Upload", JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, null, possibleValues, possibleValues[0]); if ( !(selectedValue == JOptionPane.CLOSED_OPTION) ) response = possibleValues[selectedValue]; } // if current settings selected, upload these to base station with firmware; // if not, leave default settings alone in firmware bytes if (response.equals("Upload firmware with current settings")) { // note that current settings could throw ValueFormatException! infoPane.writeData(); setDependentData(); setStaticData(); setCommunityNames(); // so base station will know what to use after reset!! setChecksum(baseBlock, configurationSize - 2); // copy current setting bytes into firmware bytes for (int i = 0; i < configurationSize; i++) firmwareBlock.bytes[i] = baseBlock.bytes[i]; // now transmit info transmitBlocks(firmwareBlock, fileLength); } else if (response.equals("Upload firmware with default settings")) { // just transmit firmware info with default settings transmitBlocks(firmwareBlock, fileLength); } } } catch (ValueFormatException ve) { messagesArea.append("Problem with supplied value: " + ve.getMessage() + "\n"); } catch (Exception e) { messagesArea.append("Error updating firmware: " + e.getMessage() + "\n"); } } } private void refreshInfoPane() { // first, remove current infoPane this.remove(infoPane); //now create new tabbed pane to hold info infoPane = new AirportInfoTabbedPane(airportInfo); // set params for layout manager 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; // then add pane to frame c.gridx = 1; c.gridy = 3; mainLayout.setConstraints(infoPane, c); this.getContentPane().add(infoPane); // call validate to update display this.validate(); } private void setDependentData() throws ValueFormatException { /* * Write values for DHCP/NAT-delivered base station IP address, router * IP address, mask; do here since requires "cross-reference" between data * in separate panels. */ boolean ethernetConnection = false, modemConnection = false; // flags specifying base station connection and boolean dhcpConfig = false, manualConfig = false; // configuration style boolean natEnabled = false, dhcpEnabled = false; // flags indicating address delivery services of base station boolean portMappingEnabled = false; // set flags for Ethernet/Modem mode AirportInfoRecord ethernetModemSwitch1Record = airportInfo.get("Ethernet/Modem switch 1"); String ethernetModemSwitch1Setting = ethernetModemSwitch1Record.toString(); AirportInfoRecord ethernetModemSwitch2Record = airportInfo.get("Configuration interface"); String ethernetModemSwitch2Setting = ethernetModemSwitch2Record.toString(); if (ethernetModemSwitch1Setting.equals("60") || ethernetModemSwitch2Setting.equals("00")) ethernetConnection = true; if (ethernetModemSwitch1Setting.equals("62") || ethernetModemSwitch2Setting.equals("03")) modemConnection = true; //set flags for base station configuration mode AirportInfoRecord baseConfigModeRecord = airportInfo.get("Base station configuration mode switch"); String baseConfigModeSetting = baseConfigModeRecord.toString(); if (baseConfigModeSetting.equals("00")) manualConfig = true; if (baseConfigModeSetting.equals("20")) dhcpConfig = true; // set flags for NAT/DHCP mode AirportInfoRecord dhcpSwitchRecord = airportInfo.get("DHCP switch"); String dhcpSetting = dhcpSwitchRecord.toString(); if (dhcpSetting.equals("80")) dhcpEnabled = true; AirportInfoRecord natSwitchRecord = airportInfo.get("NAT switch"); String natSetting = natSwitchRecord.toString(); if (natSetting.equals("02")) natEnabled = true; // set flag for port mapping AirportInfoRecord portMappingSwitchRecord = airportInfo.get("Port mapping switch"); String portMappingSwitchSetting = portMappingSwitchRecord.toString(); if (portMappingSwitchSetting.equals("04")) portMappingEnabled = true; // get records for setting dependent data AirportInfoRecord natInboundPrivateIPAddressRecord = airportInfo.get("NAT inbound private IP address"); AirportInfoRecord natInboundPrivateSubnetMaskRecord = airportInfo.get("NAT inbound private subnet mask"); AirportInfoRecord natOutboundPrivateIPAddressRecord = airportInfo.get("NAT outbound private IP address"); AirportInfoRecord natOutboundPrivateSubnetMaskRecord = airportInfo.get("NAT outbound private subnet mask"); AirportInfoRecord natOutboundPublicIPAddressRecord = airportInfo.get("NAT outbound public IP address"); AirportInfoRecord natOutboundPublicSubnetMaskRecord = airportInfo.get("NAT outbound public subnet mask"); AirportInfoRecord dhcpServerRouterIPAddressRecord = airportInfo.get("DHCP server router address"); AirportInfoRecord dhcpServerSubnetMaskRecord = airportInfo.get("DHCP server subnet mask"); AirportInfoRecord baseStationIPAddressRecord = airportInfo.get("Base station IP address"); AirportInfoRecord subnetMaskRecord = airportInfo.get("Subnet mask"); AirportInfoRecord routerIPAddressRecord = airportInfo.get("Router IP address"); // when NAT enabled, set data that depends on settings from other panels if (natEnabled) { // set NAT outbound IP address and mask if (modemConnection) { natOutboundPublicIPAddressRecord.setBytesFromString("0.0.0.0"); natOutboundPublicSubnetMaskRecord.setBytesFromString("255.255.255.0"); } if (ethernetConnection) { if (manualConfig) { natOutboundPublicIPAddressRecord.setBytesFromString(baseStationIPAddressRecord.toString()); natOutboundPublicSubnetMaskRecord.setBytesFromString(subnetMaskRecord.toString()); } else if (dhcpConfig) { natOutboundPublicIPAddressRecord.setBytesFromString("0.0.0.0"); natOutboundPublicSubnetMaskRecord.setBytesFromString("255.255.255.0"); } } } // if serving DHCP, set router and subnet mask if (dhcpEnabled) { if (natEnabled) { // use private network parameters dhcpServerRouterIPAddressRecord.setBytesFromString(natInboundPrivateIPAddressRecord.toString()); dhcpServerSubnetMaskRecord.setBytesFromString(natInboundPrivateSubnetMaskRecord.toString()); } else { // use global base station parameters dhcpServerRouterIPAddressRecord.setBytesFromString(routerIPAddressRecord.toString()); dhcpServerSubnetMaskRecord.setBytesFromString(subnetMaskRecord.toString()); } } // if port mapping, and using manual Ethernet config, need to put in base station IP address // as the public IP address in the port maps if (portMappingEnabled && ethernetConnection && manualConfig) { // get count of port maps AirportInfoRecord portMappingCountRecord = airportInfo.get("Count of port mappings"); int portMapCount = Integer.parseInt(portMappingCountRecord.toString()); // get starting indices and other parameters for the byte block multi-windows // that will hold the public IP address for port mapping, which is just the // manually configured base station IP address int publicIPStartIndex = 0xD72; int publicIPBeginningNumRows = 1; int publicIPBeginningNumCols = 2; int publicIPEndingIndex = 0xD9A; int publicIPEndingNumRows = 1; int publicIPEndingNumCols = 2; int publicIPDataType = AirportInfoRecord.IP_ADDRESS; //set the public IP address for each port map for (int i = 0; i < portMapCount; i++) { // need to use a multi-window, since the first two and last two octets are separated ByteBlockMultiWindow publicIPWindow = new ByteBlockMultiWindow(); ByteBlockWindow publicIPBeginningWindow = new ByteBlockRectangularWindow(publicIPStartIndex, publicIPBeginningNumRows, publicIPBeginningNumCols, baseBlock); publicIPWindow.addWindow(publicIPBeginningWindow); ByteBlockWindow publicIPEndingWindow = new ByteBlockRectangularWindow(publicIPEndingIndex, publicIPEndingNumRows, publicIPEndingNumCols, baseBlock); publicIPWindow.addWindow(publicIPEndingWindow); AirportInfoRecord publicIPRecord = new AirportInfoRecord(publicIPDataType, publicIPWindow); publicIPRecord.setBytesFromString(baseStationIPAddressRecord.toString()); // augment addresses publicIPStartIndex += 2; publicIPEndingIndex += 2; } } } private void setStaticData() throws ValueFormatException { // set read community password field AirportInfoRecord readCommunityRecord = airportInfo.get("Read community"); readCommunityRecord.setBytesFromString("public"); /* // set miscellaneous switches that are sometimes zero in "plain vanilla" config files String miscellaneousSetting; AirportInfoRecord miscellaneousRecord1 = airportInfo.get("Miscellaneous switch 1"); miscellaneousSetting = miscellaneousRecord1.toString(); if (miscellaneousSetting.equals("00")) miscellaneousRecord1.setBytesFromString("01"); AirportInfoRecord miscellaneousRecord2 = airportInfo.get("Miscellaneous switch 2"); miscellaneousSetting = miscellaneousRecord2.toString(); if (miscellaneousSetting.equals("00")) miscellaneousRecord2.setBytesFromString("01"); */ } private void setCommunityNames() throws ValueFormatException { // Set community name into password field so base station will know what to use after reboot! // Find out if there's an entry in the main panel; if so, use this, otherwise use // current community name field AirportInfoRecord communityNameRecord = airportInfo.get("Read/write community"); String communityName = communityNameRecord.toString(); if (communityName.equals("")) communityName = communityField.getText(); communityNameRecord.setBytesFromString(communityName); //System.out.println("Community name: " + communityName); // set trap community password field AirportInfoRecord trapCommunityRecord = airportInfo.get("Trap community"); trapCommunityRecord.setBytesFromString("public"); // set remaining community password field (and count field) AirportInfoRecord remainingCommunityCountRecord = airportInfo.get("Remaining community count"); remainingCommunityCountRecord.setBytesFromString("06"); AirportInfoRecord remainingCommunityRecord = airportInfo.get("Remaining community"); remainingCommunityRecord.setBytesFromString("public"); } private void transmitBlocks(ByteBlock byteBlock, int numBytes) { try { String community = communityField.getText(); InetAddress hostAddress = InetAddress.getByName(hostIDField.getText()); messagesArea.append("Sending data to base station " + hostAddress + "......\n"); if (comInterface == null) { int version = 0; // SNMPv1 comInterface = new SNMPv1CommunicationInterface(version, hostAddress, community); } comInterface.requestID = 1; byte[] bytes = byteBlock.bytes; // determine number of 256-byte blocks that need to be sent int numBlocks = (int)Math.ceil((double)(numBytes + 2)/256); // +2 leaves room for transmission checksum // send all but last block for (int k = 1; k < numBlocks; k++) { String itemID = "1.3.6.1.4.1.762.2.3.1.1." + k; // create new 256 byte array byte[] newBytes = new byte[256]; // copy block of 256 bytes from given bytes to new array for (int j = 0; j < 256; j++) { newBytes[j] = bytes[256*(k-1) + j]; } // create SNMP octet string from these bytes SNMPOctetString theObject = new SNMPOctetString(newBytes); // send the bytes SNMPVarBindList newVars = comInterface.setMIBEntry(itemID, theObject); } // now send last block String itemID = "1.3.6.1.4.1.762.2.3.1.1." + numBlocks; // create new 256 byte array byte[] newBytes = new byte[256]; // copy remaining bytes from given bytes to new array int endPosition = numBytes - (numBlocks-1)*256; for (int j = 0; j < endPosition; j++) { newBytes[j] = bytes[256*(numBlocks-1) + j]; } // now set transmission checksum as 2 bytes following last (legitimate) bytes; // note that number of blocks was chosen to be (numBytes+2)/256, ensuring room ByteBlock lastBlock = new ByteBlock(16, 16, newBytes); short checksum = computeChecksum(byteBlock.bytes, numBytes); setChecksum(checksum, lastBlock, endPosition); // create SNMP octet string from these bytes SNMPOctetString theObject = new SNMPOctetString(lastBlock.bytes); // send the bytes SNMPVarBindList newVars = comInterface.setMIBEntry(itemID, theObject); // now send reset signal: indicates number of bytes to burn to prom. // also indicates location of checksum SNMPInteger numBytesWritten = new SNMPInteger(numBytes); //System.out.println("Number of bytes to burn in: " + numBytesWritten); itemID = "1.3.6.1.4.1.762.2.1.2.0"; newVars = comInterface.setMIBEntry(itemID, numBytesWritten); itemID = "1.3.6.1.4.1.762.2.1.3.0"; newVars = comInterface.setMIBEntry(itemID, numBytesWritten); messagesArea.append("Data transmitted; base station restarting.\n"); } catch(UnknownHostException e) { messagesArea.append("Error transmitting data: unknown host.\n"); } catch(SocketException e) { messagesArea.append("Error transmitting data: " + e.getMessage() + "\n"); } catch(IOException e) { messagesArea.append("Error transmitting data: timed out waiting for response.\n"); } catch (SNMPSetException e) { messagesArea.append("Error transmitting data: " + e.getMessage() + "\n"); } catch (SNMPBadValueException e) { // will never occur! messagesArea.append("Error transmitting data: bad SNMP value.\n"); } } /* * Compute the 2-byte checksum for the bytes up to (but not including) the indicated position */ private short computeChecksum(byte[] bytes, int position) { short sum = 0; for (int i = 0; i < position; i++) { sum += bytes[i]; if(bytes[i] < 0) sum += 256; } return sum; } private void setChecksum(short sum, ByteBlock byteBlock, int position) { String checksumString = littleEndianHexString(sum); // create info record to write into int numRows = 1; int numCols = 2; int baseStartIndex = position; ByteBlockWindow checksumWindow = new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, byteBlock); int dataType = AirportInfoRecord.BYTE_STRING; AirportInfoRecord checksumRecord = new AirportInfoRecord(dataType, checksumWindow); checksumRecord.byteBlockWindow.clearBytes(); // write in new checksum try { checksumRecord.setBytesFromString(checksumString); } catch (ValueFormatException ve) { // won't occur! messagesArea.append("Problem writing checksum with value " + checksumString + ".\n"); } } /* * Convenience method for writing checksum value into same block it's computed from. This * is the usual case for config files; however, the more general routine is used to set * the transmission checksum immediately following the transmitted data bytes. */ private void setChecksum(ByteBlock byteBlock, int position) { short sum = computeChecksum(byteBlock.bytes, position); setChecksum(sum, byteBlock, position); } /** * Return little-endian hex string */ private String littleEndianHexString(short value) { int intValue = value; intValue = intValue & 0xFFFF; int switched = ((intValue << 8) | (intValue >>> 8)) & 0xFFFF; String returnString = Integer.toHexString(switched); // add leading zeros if needed while (returnString.length() < 4) returnString = "0" + returnString; return returnString; } /** * Used to validate checksum in stored settings, to ensure file is legitimate! Verify just * first checksum, for compatibility with Apple configurator's stored settings. */ private boolean checksumValid(ByteBlock byteBlock) { short sum = computeChecksum(byteBlock.bytes, configurationSize - 2); String computedChecksumString = littleEndianHexString(sum); //System.out.println("Computed checksum: " + computedChecksumString); // get configuration checksum from block int baseStartIndex = 0x43B6; int numRows = 1; int numCols = 2; int dataType = AirportInfoRecord.BYTE_STRING; AirportInfoRecord checksumRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, byteBlock); String existingChecksumString = checksumRecord.toString(); //System.out.println("Existing checksum: " + existingChecksumString); if (computedChecksumString.equals(existingChecksumString)) return true; else return false; } private boolean checksumValid() { return checksumValid(baseBlock); } // Apparently the Apple-supplied firmware files computed the // checksum before the community name default passwords (4 "public" and one count of 06) // were inserted. Thus the checksum computation should differ by 0xA02 for these files. // Thus the need for this "hacked" checksum validation.... private boolean appleFirmwareChecksumValid(ByteBlock byteBlock) { short sum = computeChecksum(byteBlock.bytes, configurationSize - 2); sum -= 0xA02; String computedChecksumString = littleEndianHexString(sum); //System.out.println("Computed checksum: " + computedChecksumString); // get configuration checksum from block int baseStartIndex = 0x43B6; int numRows = 1; int numCols = 2; int dataType = AirportInfoRecord.BYTE_STRING; AirportInfoRecord checksumRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, byteBlock); String existingChecksumString = checksumRecord.toString(); //System.out.println("Existing checksum: " + existingChecksumString); if (computedChecksumString.equals(existingChecksumString)) return true; else return false; } public static void main(String args[]) { try { AirportBaseStationConfigurator theApp = new AirportBaseStationConfigurator(); theApp.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 = theApp.getSize(); //dim.height += 10; dim.width += 20; theApp.setSize(dim); //theApp.setSize(640,480); theApp.show(); } catch (Exception e) {} } }airportconfig-1.5.2/AboutDialog.java0000644000175000017500000001176407503646614017004 0ustar julienjulien/* * SNMP Inquisitor * * Copyright (C) 2000, Jonathan Sevy * * 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.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; public class AboutDialog extends JDialog implements Runnable, ActionListener { private JLabel aboutLabel1 = new JLabel(" "); private JLabel aboutLabel2 = new JLabel(" "); private JLabel aboutLabel3 = new JLabel(" "); private JLabel aboutLabel4 = new JLabel(" "); private String aboutString1 = AirportBaseStationConfigurator.aboutString; private String aboutString2 = "Version 1.5.2 "; private String aboutString3 = "J. Sevy "; private String aboutString4 = "October 2001 "; private JButton okButton; Thread displayThread; public AboutDialog(JFrame parent) { super(parent, "About...", true /*modal*/); this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); setUpDisplay(); this.setLocation(Math.round((parent.size().width - this.size().width)/2), Math.round((parent.size().height - this.size().height)/2)); // create and start display thread displayThread = new Thread(this); displayThread.start(); this.show(); } public void hide() { super.hide(); // interrupt thread so it can exit.. displayThread.interrupt(); } private void setUpDisplay() { // 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; c.insets = new Insets(2,2,2,2); c.anchor = GridBagConstraints.CENTER; c.weightx = 0; c.weighty = 0; JPanel aboutPanel = new JPanel(); aboutPanel.setLayout(theLayout); c.gridx = 1; c.gridy = 1; theLayout.setConstraints(aboutLabel1, c); aboutPanel.add(aboutLabel1); c.gridx = 1; c.gridy = 2; theLayout.setConstraints(aboutLabel2, c); aboutPanel.add(aboutLabel2); c.gridx = 1; c.gridy = 3; theLayout.setConstraints(aboutLabel3, c); aboutPanel.add(aboutLabel3); c.gridx = 1; c.gridy = 4; theLayout.setConstraints(aboutLabel4, c); aboutPanel.add(aboutLabel4); okButton = new JButton("OK"); okButton.setActionCommand("ok"); okButton.addActionListener(this); this.getContentPane().setLayout(theLayout); c.gridx = 1; c.gridy = 1; theLayout.setConstraints(aboutPanel, c); this.getContentPane().add(aboutPanel); c.gridx = 1; c.gridy = 2; theLayout.setConstraints(okButton, c); this.getContentPane().add(okButton); this.pack(); this.setSize(300, 150); } public void actionPerformed(ActionEvent theEvent) // respond to button pushes, menu selections { String command = theEvent.getActionCommand(); if (command.equals("ok")) { this.hide(); } } public void run() { try { Color textColor = new Color(255, 0, 255); aboutLabel1.setForeground(textColor); // write message out a character at a time... int numChars = aboutString1.length(); Font titleFont = new Font("SansSerif",Font.BOLD + Font.ITALIC, 12); Font labelFont = new Font("SansSerif",Font.PLAIN, 10); aboutLabel1.setFont(titleFont); aboutLabel1.setText(aboutString1); aboutLabel1.setSize(0, 30); for (int i = 0; i < this.getWidth() - 20; i++) { aboutLabel1.setSize(i, 30); Thread.currentThread().sleep(6); } aboutLabel2.setText(aboutString2); aboutLabel3.setText(aboutString3); aboutLabel4.setText(aboutString4); aboutLabel2.setFont(labelFont); aboutLabel3.setFont(labelFont); aboutLabel4.setFont(labelFont); // change color of other strings... int numSteps = 255; for (int i = 0; i < numSteps; i++) { textColor = new Color(255, 255-i, i); aboutLabel2.setForeground(textColor); aboutLabel3.setForeground(textColor); aboutLabel4.setForeground(textColor); Thread.currentThread().sleep(20); } } catch(Exception e) { // don't bother informing of exception; just exit... //System.out.println(e); } // later! } }airportconfig-1.5.2/AirportBaseStationMultiConfigurator.java0000644000175000017500000012136407503646614023763 0ustar julienjulien/* * AirportBaseStationConfigurator * * Copyright (C) 2000, Jonathan Sevy * * 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 byteblock.*; import snmp.*; import airport.*; public class AirportBaseStationConfigurator extends JFrame implements ActionListener { public static final String encryptionKeySizeString = "05"; public static final int encryptionKeySize = 5; public static final String aboutString = "Airport Base Station Multiple Configurator "; JButton discoverDevicesButton, retrieveItemButton, updateBaseStationButton, updateAllButton, addAddressButton; //JTextField hostIDField; JComboBox addressBox; JTextField communityField; GridBagLayout mainLayout = new GridBagLayout(); MenuBar theMenubar; Menu fileMenu; MenuItem quitItem, openItem, saveItem, aboutItem, uploadFirmwareItem, uploadFirmwareToAllItem, openAddressListItem, saveAddressListItem; private final int baseBlockSize = 68*16*16; private ByteBlock baseBlock = new ByteBlock(68*16, 16); private final int configurationSize = 17336; // total number of significant bytes, including checksum AirportInfo airportInfo; AirportInfoTabbedPane infoPane; JTextArea messagesArea; SNMPv1CommunicationInterface comInterface; SNMPVarBindList retrievedVars; // WindowCloseAdapter to catch window close-box closings private class WindowCloseAdapter extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } }; public AirportBaseStationConfigurator() { airportInfo = new AirportInfo(baseBlock); setUpDisplay(); retrievedVars = new SNMPVarBindList(); } 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 // thanks to Jer for this one! addWindowListener(new WindowCloseAdapter()); this.setTitle("AirPort Base Station Configurator"); this.getRootPane().setBorder(new BevelBorder(BevelBorder.RAISED)); theMenubar = new MenuBar(); this.setMenuBar(theMenubar); fileMenu = new Menu("File"); openItem = new MenuItem("Open saved settings..."); openItem.setShortcut(new MenuShortcut('o')); openItem.setActionCommand("open settings"); openItem.addActionListener(this); fileMenu.add(openItem); saveItem = new MenuItem("Save settings..."); saveItem.setShortcut(new MenuShortcut('s')); saveItem.setActionCommand("save settings"); saveItem.addActionListener(this); fileMenu.add(saveItem); fileMenu.addSeparator(); openAddressListItem = new MenuItem("Open address list..."); openAddressListItem.setActionCommand("open address list"); openAddressListItem.addActionListener(this); fileMenu.add(openAddressListItem); saveAddressListItem = new MenuItem("Save address list..."); saveAddressListItem.setActionCommand("save address list"); saveAddressListItem.addActionListener(this); fileMenu.add(saveAddressListItem); fileMenu.addSeparator(); uploadFirmwareItem = new MenuItem("Upload new base station firmware to selected base station..."); uploadFirmwareItem.setActionCommand("upload firmware"); uploadFirmwareItem.addActionListener(this); fileMenu.add(uploadFirmwareItem); uploadFirmwareToAllItem = new MenuItem("Upload new base station firmware to all base stations..."); uploadFirmwareToAllItem.setActionCommand("upload firmware to all"); uploadFirmwareToAllItem.addActionListener(this); fileMenu.add(uploadFirmwareToAllItem); fileMenu.addSeparator(); aboutItem = new MenuItem("About..."); aboutItem.setActionCommand("about"); aboutItem.addActionListener(this); fileMenu.add(aboutItem); quitItem = new MenuItem("Quit"); quitItem.setShortcut(new MenuShortcut('q')); quitItem.setActionCommand("quit"); quitItem.addActionListener(this); fileMenu.add(quitItem); theMenubar.add(fileMenu); JLabel hostIDLabel = new JLabel("Device address:"); addressBox = new JComboBox(); addressBox.addItem("10.0.1.1"); JLabel communityLabel = new JLabel("Community name (password):"); communityField = new JPasswordField(10); //communityField = new JTextField(10); //communityField.setText("public"); addAddressButton = new JButton("Add Address"); addAddressButton.setActionCommand("add address"); addAddressButton.addActionListener(this); discoverDevicesButton = new JButton("Discover Devices"); discoverDevicesButton.setActionCommand("discover devices"); discoverDevicesButton.addActionListener(this); retrieveItemButton = new JButton("Retrieve Settings"); retrieveItemButton.setActionCommand("retrieve data"); retrieveItemButton.addActionListener(this); updateBaseStationButton = new JButton("Update Selected Base Station"); updateBaseStationButton.setActionCommand("update base station"); updateBaseStationButton.addActionListener(this); updateBaseStationButton.setEnabled(false); //initially disabled until read in or open settings updateAllButton = new JButton("Update All Base Stations"); updateAllButton.setActionCommand("update all base stations"); updateAllButton.addActionListener(this); updateAllButton.setEnabled(false); //initially disabled until read in or open settings // 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(discoverDevicesButton, c); buttonPanel.add(discoverDevicesButton); c.gridx = 2; c.gridy = 1; theLayout.setConstraints(retrieveItemButton, c); buttonPanel.add(retrieveItemButton); c.gridx = 3; c.gridy = 1; theLayout.setConstraints(updateBaseStationButton, c); buttonPanel.add(updateBaseStationButton); c.gridx = 4; c.gridy = 1; theLayout.setConstraints(updateAllButton, c); buttonPanel.add(updateAllButton); JPanel hostPanel = new JPanel(); hostPanel.setLayout(theLayout); c.gridx = 1; c.gridy = 1; theLayout.setConstraints(hostIDLabel, c); hostPanel.add(hostIDLabel); c.gridx = 2; c.gridy = 1; theLayout.setConstraints(addressBox, c); hostPanel.add(addressBox); c.gridx = 3; c.gridy = 1; theLayout.setConstraints(addAddressButton, c); hostPanel.add(addAddressButton); c.gridx = 4; c.gridy = 1; theLayout.setConstraints(communityLabel, c); hostPanel.add(communityLabel); c.gridx = 5; c.gridy = 1; theLayout.setConstraints(communityField, c); hostPanel.add(communityField); infoPane = new AirportInfoTabbedPane(airportInfo); JPanel messagesPanel = new JPanel(); messagesPanel.setLayout(theLayout); messagesArea = new JTextArea(4,60); 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(messagesScroll, c); messagesPanel.add(messagesScroll); this.getContentPane().setLayout(mainLayout); c.gridx = 1; c.gridy = 1; mainLayout.setConstraints(hostPanel, c); this.getContentPane().add(hostPanel); c.gridx = 1; c.gridy = 2; mainLayout.setConstraints(buttonPanel, c); this.getContentPane().add(buttonPanel); c.gridx = 1; c.gridy = 3; mainLayout.setConstraints(infoPane, c); this.getContentPane().add(infoPane); c.gridx = 1; c.gridy = 4; mainLayout.setConstraints(messagesPanel, c); this.getContentPane().add(messagesPanel); c.gridx = 1; c.gridy = 5; JLabel authorLabel = new JLabel(" Version 1.5.2 J. Sevy, November 2001 "); authorLabel.setFont(new Font("SansSerif", Font.ITALIC, 8)); mainLayout.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")) { System.exit(0); } if (command == "about") { AboutDialog aboutDialog = new AboutDialog(this); } if (command == "add address") { String newAddress = JOptionPane.showInputDialog("Enter new IP address"); if ( !((newAddress == null) || (newAddress.equals(""))) ) addressBox.addItem(newAddress); } if (command.equals("discover devices")) { AirportDiscoverer discoverer = new AirportDiscoverer(); } if (command.equals("retrieve data")) { try { if (comInterface != null) comInterface.closeConnection(); String community = communityField.getText(); InetAddress hostAddress = InetAddress.getByName((String)addressBox.getSelectedItem()); int version = 0; // SNMPv1 messagesArea.append("Retrieving settings from base station " + hostAddress + "......\n"); comInterface = new SNMPv1CommunicationInterface(version, hostAddress, community); for (int k = 1; k <= 68; k++) { String itemID = "1.3.6.1.4.1.762.2.2.1.1." + k; SNMPVarBindList newVars = comInterface.getMIBEntry(itemID); SNMPSequence pair = (SNMPSequence)(newVars.getSNMPObjectAt(0)); SNMPOctetString value = (SNMPOctetString)(pair.getSNMPObjectAt(1)); // get the 256 bytes byte[] bytes = (byte[])value.getValue(); // create a window to write bytes into int startIndex = (k-1)*256; int rows = 16; int cols = 16; ByteBlockRectangularWindow currentBlock = new ByteBlockRectangularWindow(startIndex, rows, cols, baseBlock); // write the bytes currentBlock.writeBytes(bytes); } // would like to check checksum to make sure retrieved block is valid, at least... // however, base station doesn't return valid checksum when data retrieved - // it's just a partial echo of the last checksum sent to it :-( messagesArea.append("Settings retrieved.\n"); // now refresh display this.refreshInfoPane(); // enable updating updateBaseStationButton.setEnabled(true); updateAllButton.setEnabled(true); } catch(UnknownHostException e) { messagesArea.append("Error retrieving settings: unknown host.\n"); } catch(SocketException e) { messagesArea.append("Error retrieving settings: " + e + "\n"); } catch(IOException e) { messagesArea.append("Error retrieving settings: timed out waiting for response.\n"); } catch (SNMPBadValueException e) { // will never occur! messagesArea.append("Error retrieving settings: bad SNMP value received.\n"); } catch (SNMPGetException e) { messagesArea.append("Error retrieving settings: incorrect community name (password).\n"); } catch (Exception e) { messagesArea.append("Error retrieving settings: " + e.getMessage() + "\n"); } } if (command.equals("save settings")) { try { infoPane.writeData(); setDependentData(); setStaticData(); setChecksum(baseBlock, configurationSize - 2); FileDialog fd = new FileDialog(this, "Save current settings as...", FileDialog.SAVE); fd.show(); if (fd.getFile() != null) { File newFile = new File(fd.getDirectory(), fd.getFile()); FileOutputStream fStream = new FileOutputStream(newFile); fStream.write(baseBlock.bytes, 0, configurationSize); fStream.flush(); fStream.close(); } } catch (ValueFormatException ve) { messagesArea.append("Problem with supplied value: " + ve.getMessage() + "\n"); } catch (Exception e) { messagesArea.append("Error saving settings: " + e.getMessage() + "\n"); } } if (command.equals("update base station") || command.equals("update all base stations")) { try { infoPane.writeData(); setDependentData(); setStaticData(); setChecksum(baseBlock, configurationSize - 2); // second checksum set in transmitBlocks() // configurationSize = 17336 indicates number of bytes to burn to prom: // includes first checksum (but not second, which is "transmission" // checksum - added by transmitBlocks method) if (command.equals("update base station")) { String baseStationAddress = (String)addressBox.getSelectedItem(); transmitBlocks(baseBlock, configurationSize, baseStationAddress); } else if (command.equals("update all base stations")) { for (int i = 0; i < addressBox.getItemCount(); i++) { String baseStationAddress = (String)addressBox.getItemAt(i); transmitBlocks(baseBlock, configurationSize, baseStationAddress); } } } catch (ValueFormatException ve) { messagesArea.append("Problem with supplied value: " + ve.getMessage() + "\n"); } } if (command.equals("open settings")) { try { FileDialog fd = new FileDialog(this, "Open settings file...", FileDialog.LOAD); fd.show(); if (fd.getFile() != null) { File newFile = new File(fd.getDirectory(), fd.getFile()); FileInputStream fStream = new FileInputStream(newFile); byte[] newBytes = new byte[17408]; fStream.read(newBytes); fStream.close(); // check checksum to make sure block is valid, at least... // save current bytes in case new ones invalid byte[] currentBytes = baseBlock.bytes; baseBlock.bytes = newBytes; // see if shift key held down while open selected; if so, don't check checksum boolean shiftKeyDown = ((theEvent.getModifiers() & ActionEvent.SHIFT_MASK) > 0); // make sure checksum is valid, to verify this is a valid settings file // first make sure file big enough to even check checksum! if ( (newFile.length() < configurationSize) || (!shiftKeyDown && !checksumValid()) ) { // reset base block to current bytes baseBlock.bytes = currentBytes; throw new Exception("invalid settings file."); } // now refresh display of data this.refreshInfoPane(); // enable updating updateBaseStationButton.setEnabled(true); } } catch (Exception e) { messagesArea.append("Error opening settings: " + e.getMessage() + "\n"); } } if (command.equals("open address list")) { try { FileDialog fd = new FileDialog(this, "Open base station address list...", FileDialog.LOAD); fd.show(); if (fd.getFile() != null) { File newFile = new File(fd.getDirectory(), fd.getFile()); BufferedReader fReader = new BufferedReader(new FileReader(newFile)); // reinitialize address combo box addressBox.removeAllItems(); String nextAddress; // assume have one address per line while ((nextAddress = fReader.readLine()) != null) { addressBox.addItem(nextAddress); } // if no addresses added, add default address 10.0.1.1 if (addressBox.getItemCount() == 0) { addressBox.addItem("10.0.1.1"); } } } catch (Exception e) { messagesArea.append("Error opening address list: " + e.getMessage() + "\n"); } } if (command.equals("save address list")) { try { FileDialog fd = new FileDialog(this, "Save current address list as...", FileDialog.SAVE); fd.show(); if (fd.getFile() != null) { File newFile = new File(fd.getDirectory(), fd.getFile()); FileWriter fStream = new FileWriter(newFile); for (int i = 0; i < addressBox.getItemCount(); i++) { String baseStationAddress = (String)addressBox.getItemAt(i); fStream.write(baseStationAddress + "\n"); } fStream.close(); } } catch (Exception e) { messagesArea.append("Error saving address list: " + e.getMessage() + "\n"); } } if (command.equals("upload firmware") || command.equals("upload firmware to all")) { try { FileDialog fd = new FileDialog(this, "Select firmware file...", FileDialog.LOAD); fd.show(); if (fd.getFile() != null) { File firmwareFile = new File(fd.getDirectory(), fd.getFile()); FileInputStream fStream = new FileInputStream(firmwareFile); int fileLength = (int)firmwareFile.length(); // determine number of 256-byte blocks that need to be sent int numBlocks = (int)Math.ceil((double)fileLength/256); // create underlying ByteBlock with appropriate number of sub-blocks ByteBlock firmwareBlock = new ByteBlock(numBlocks*16, 16); fStream.read(firmwareBlock.bytes); fStream.close(); // verify this is a valid firmware file; can unfortunately only verify the embedded // configuration checksum.... AND apparently the Apple-supplied formware files computed the // checksum before the community name default passwords (4 "public" and one count of 06) // were inserted. Thus the checksum computation differs by 0xA02 for these files, // so the checksum check is a little weird.... // first make sure file big enough to even check checksum! if (fileLength < configurationSize) { throw new Exception("invalid firmware file."); } else if ( (!appleFirmwareChecksumValid(firmwareBlock)) && (!checksumValid(firmwareBlock)) ) { throw new Exception("invalid firmware file."); } // put up a dialog permitting the user to select uploading the current settings, if // they're valid... String messageString = "Upload firmware to base station " + (String)addressBox.getSelectedItem() + "?"; String response = new String("Cancel"); // see if current settings are valid; if so, these become upload option if (updateBaseStationButton.isEnabled()) { String[] possibleValues = { "Upload firmware with current settings", "Upload firmware with default settings", "Cancel" }; int selectedValue = JOptionPane.showOptionDialog(null, messageString, "Firmware Upload", JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, null, possibleValues, possibleValues[0]); if ( !(selectedValue == JOptionPane.CLOSED_OPTION) ) response = possibleValues[selectedValue]; } else { String[] possibleValues = { "Upload firmware with default settings", "Cancel" }; int selectedValue = JOptionPane.showOptionDialog(null, messageString, "Firmware Upload", JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, null, possibleValues, possibleValues[0]); if ( !(selectedValue == JOptionPane.CLOSED_OPTION) ) response = possibleValues[selectedValue]; } // if current settings selected, upload these to base station with firmware; // if not, leave default settings alone in firmware bytes if (response.equals("Upload firmware with current settings")) { // note that current settings could throw ValueFormatException! infoPane.writeData(); setDependentData(); setStaticData(); setCommunityNames(); // so base station will know what to use after reset!! setChecksum(baseBlock, configurationSize - 2); // copy current setting bytes into firmware bytes for (int i = 0; i < configurationSize; i++) firmwareBlock.bytes[i] = baseBlock.bytes[i]; // now transmit info if (command.equals("upload firmware")) { String baseStationAddress = (String)addressBox.getSelectedItem(); transmitBlocks(firmwareBlock, fileLength, baseStationAddress); } else if (command.equals("upload firmware to all")) { for (int i = 0; i < addressBox.getItemCount(); i++) { String baseStationAddress = (String)addressBox.getItemAt(i); transmitBlocks(firmwareBlock, fileLength, baseStationAddress); } } } else if (response.equals("Upload firmware with default settings")) { if (command.equals("upload firmware")) { String baseStationAddress = (String)addressBox.getSelectedItem(); transmitBlocks(firmwareBlock, fileLength, baseStationAddress); } else if (command.equals("upload firmware to all")) { for (int i = 0; i < addressBox.getItemCount(); i++) { String baseStationAddress = (String)addressBox.getItemAt(i); transmitBlocks(firmwareBlock, fileLength, baseStationAddress); } } } } } catch (ValueFormatException ve) { messagesArea.append("Problem with supplied value: " + ve.getMessage() + "\n"); } catch (Exception e) { messagesArea.append("Error updating firmware: " + e.getMessage() + "\n"); } } } private void refreshInfoPane() { // first, remove current infoPane this.remove(infoPane); //now create new tabbed pane to hold info infoPane = new AirportInfoTabbedPane(airportInfo); // set params for layout manager 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; // then add pane to frame c.gridx = 1; c.gridy = 3; mainLayout.setConstraints(infoPane, c); this.getContentPane().add(infoPane); // call validate to update display this.validate(); } private void setDependentData() throws ValueFormatException { /* * Write values for DHCP/NAT-delivered base station IP address, router * IP address, mask; do here since requires "cross-reference" between data * in separate panels. */ boolean ethernetConnection = false, modemConnection = false; // flags specifying base station connection and boolean dhcpConfig = false, manualConfig = false; // configuration style boolean natEnabled = false, dhcpEnabled = false; // flags indicating address delivery services of base station boolean portMappingEnabled = false; // set flags for Ethernet/Modem mode AirportInfoRecord ethernetModemSwitch1Record = airportInfo.get("Ethernet/Modem switch 1"); String ethernetModemSwitch1Setting = ethernetModemSwitch1Record.toString(); AirportInfoRecord ethernetModemSwitch2Record = airportInfo.get("Configuration interface"); String ethernetModemSwitch2Setting = ethernetModemSwitch2Record.toString(); if (ethernetModemSwitch1Setting.equals("60") || ethernetModemSwitch2Setting.equals("00")) ethernetConnection = true; if (ethernetModemSwitch1Setting.equals("62") || ethernetModemSwitch2Setting.equals("03")) modemConnection = true; //set flags for base station configuration mode AirportInfoRecord baseConfigModeRecord = airportInfo.get("Base station configuration mode switch"); String baseConfigModeSetting = baseConfigModeRecord.toString(); if (baseConfigModeSetting.equals("00")) manualConfig = true; if (baseConfigModeSetting.equals("20")) dhcpConfig = true; // set flags for NAT/DHCP mode AirportInfoRecord dhcpSwitchRecord = airportInfo.get("DHCP switch"); String dhcpSetting = dhcpSwitchRecord.toString(); if (dhcpSetting.equals("80")) dhcpEnabled = true; AirportInfoRecord natSwitchRecord = airportInfo.get("NAT switch"); String natSetting = natSwitchRecord.toString(); if (natSetting.equals("02")) natEnabled = true; // set flag for port mapping AirportInfoRecord portMappingSwitchRecord = airportInfo.get("Port mapping switch"); String portMappingSwitchSetting = portMappingSwitchRecord.toString(); if (portMappingSwitchSetting.equals("04")) portMappingEnabled = true; // get records for setting dependent data AirportInfoRecord natInboundPrivateIPAddressRecord = airportInfo.get("NAT inbound private IP address"); AirportInfoRecord natInboundPrivateSubnetMaskRecord = airportInfo.get("NAT inbound private subnet mask"); AirportInfoRecord natOutboundPrivateIPAddressRecord = airportInfo.get("NAT outbound private IP address"); AirportInfoRecord natOutboundPrivateSubnetMaskRecord = airportInfo.get("NAT outbound private subnet mask"); AirportInfoRecord natOutboundPublicIPAddressRecord = airportInfo.get("NAT outbound public IP address"); AirportInfoRecord natOutboundPublicSubnetMaskRecord = airportInfo.get("NAT outbound public subnet mask"); AirportInfoRecord dhcpServerRouterIPAddressRecord = airportInfo.get("DHCP server router address"); AirportInfoRecord dhcpServerSubnetMaskRecord = airportInfo.get("DHCP server subnet mask"); AirportInfoRecord baseStationIPAddressRecord = airportInfo.get("Base station IP address"); AirportInfoRecord subnetMaskRecord = airportInfo.get("Subnet mask"); AirportInfoRecord routerIPAddressRecord = airportInfo.get("Router IP address"); // when NAT enabled, set data that depends on settings from other panels if (natEnabled) { // set NAT outbound IP address and mask if (modemConnection) { natOutboundPublicIPAddressRecord.setBytesFromString("0.0.0.0"); natOutboundPublicSubnetMaskRecord.setBytesFromString("255.255.255.0"); } if (ethernetConnection) { if (manualConfig) { natOutboundPublicIPAddressRecord.setBytesFromString(baseStationIPAddressRecord.toString()); natOutboundPublicSubnetMaskRecord.setBytesFromString(subnetMaskRecord.toString()); } else if (dhcpConfig) { natOutboundPublicIPAddressRecord.setBytesFromString("0.0.0.0"); natOutboundPublicSubnetMaskRecord.setBytesFromString("255.255.255.0"); } } } // if serving DHCP, set router and subnet mask if (dhcpEnabled) { if (natEnabled) { // use private network parameters dhcpServerRouterIPAddressRecord.setBytesFromString(natInboundPrivateIPAddressRecord.toString()); dhcpServerSubnetMaskRecord.setBytesFromString(natInboundPrivateSubnetMaskRecord.toString()); } else { // use global base station parameters dhcpServerRouterIPAddressRecord.setBytesFromString(routerIPAddressRecord.toString()); dhcpServerSubnetMaskRecord.setBytesFromString(subnetMaskRecord.toString()); } } // if port mapping, and using manual Ethernet config, need to put in base station IP address // as the public IP address in the port maps if (portMappingEnabled && ethernetConnection && manualConfig) { // get count of port maps AirportInfoRecord portMappingCountRecord = airportInfo.get("Count of port mappings"); int portMapCount = Integer.parseInt(portMappingCountRecord.toString()); // get starting indices and other parameters for the byte block multi-windows // that will hold the public IP address for port mapping, which is just the // manually configured base station IP address int publicIPStartIndex = 0xD72; int publicIPBeginningNumRows = 1; int publicIPBeginningNumCols = 2; int publicIPEndingIndex = 0xD9A; int publicIPEndingNumRows = 1; int publicIPEndingNumCols = 2; int publicIPDataType = AirportInfoRecord.IP_ADDRESS; //set the public IP address for each port map for (int i = 0; i < portMapCount; i++) { // need to use a multi-window, since the first two and last two octets are separated ByteBlockMultiWindow publicIPWindow = new ByteBlockMultiWindow(); ByteBlockWindow publicIPBeginningWindow = new ByteBlockRectangularWindow(publicIPStartIndex, publicIPBeginningNumRows, publicIPBeginningNumCols, baseBlock); publicIPWindow.addWindow(publicIPBeginningWindow); ByteBlockWindow publicIPEndingWindow = new ByteBlockRectangularWindow(publicIPEndingIndex, publicIPEndingNumRows, publicIPEndingNumCols, baseBlock); publicIPWindow.addWindow(publicIPEndingWindow); AirportInfoRecord publicIPRecord = new AirportInfoRecord(publicIPDataType, publicIPWindow); publicIPRecord.setBytesFromString(baseStationIPAddressRecord.toString()); // augment addresses publicIPStartIndex += 2; publicIPEndingIndex += 2; } } } private void setStaticData() throws ValueFormatException { // set read community password field AirportInfoRecord readCommunityRecord = airportInfo.get("Read community"); readCommunityRecord.setBytesFromString("public"); /* // set miscellaneous switches that are sometimes zero in "plain vanilla" config files String miscellaneousSetting; AirportInfoRecord miscellaneousRecord1 = airportInfo.get("Miscellaneous switch 1"); miscellaneousSetting = miscellaneousRecord1.toString(); if (miscellaneousSetting.equals("00")) miscellaneousRecord1.setBytesFromString("01"); AirportInfoRecord miscellaneousRecord2 = airportInfo.get("Miscellaneous switch 2"); miscellaneousSetting = miscellaneousRecord2.toString(); if (miscellaneousSetting.equals("00")) miscellaneousRecord2.setBytesFromString("01"); */ } private void setCommunityNames() throws ValueFormatException { // Set community name into password field so base station will know what to use after reboot! // Find out if there's an entry in the main panel; if so, use this, otherwise use // current community name field AirportInfoRecord communityNameRecord = airportInfo.get("Read/write community"); String communityName = communityNameRecord.toString(); if (communityName.equals("")) communityName = communityField.getText(); communityNameRecord.setBytesFromString(communityName); //System.out.println("Community name: " + communityName); // set trap community password field AirportInfoRecord trapCommunityRecord = airportInfo.get("Trap community"); trapCommunityRecord.setBytesFromString("public"); // set remaining community password field (and count field) AirportInfoRecord remainingCommunityCountRecord = airportInfo.get("Remaining community count"); remainingCommunityCountRecord.setBytesFromString("06"); AirportInfoRecord remainingCommunityRecord = airportInfo.get("Remaining community"); remainingCommunityRecord.setBytesFromString("public"); } private void transmitBlocks(ByteBlock byteBlock, int numBytes, String hostAddressString) { try { String community = communityField.getText(); InetAddress hostAddress = InetAddress.getByName(hostAddressString); messagesArea.append("Sending data to base station " + hostAddress + "......\n"); if (comInterface == null) { int version = 0; // SNMPv1 comInterface = new SNMPv1CommunicationInterface(version, hostAddress, community); } comInterface.requestID = 1; byte[] bytes = byteBlock.bytes; // determine number of 256-byte blocks that need to be sent int numBlocks = (int)Math.ceil((double)(numBytes + 2)/256); // +2 leaves room for transmission checksum // send all but last block for (int k = 1; k < numBlocks; k++) { String itemID = "1.3.6.1.4.1.762.2.3.1.1." + k; // create new 256 byte array byte[] newBytes = new byte[256]; // copy block of 256 bytes from given bytes to new array for (int j = 0; j < 256; j++) { newBytes[j] = bytes[256*(k-1) + j]; } // create SNMP octet string from these bytes SNMPOctetString theObject = new SNMPOctetString(newBytes); // send the bytes SNMPVarBindList newVars = comInterface.setMIBEntry(itemID, theObject); } // now send last block String itemID = "1.3.6.1.4.1.762.2.3.1.1." + numBlocks; // create new 256 byte array byte[] newBytes = new byte[256]; // copy remaining bytes from given bytes to new array int endPosition = numBytes - (numBlocks-1)*256; for (int j = 0; j < endPosition; j++) { newBytes[j] = bytes[256*(numBlocks-1) + j]; } // now set transmission checksum as 2 bytes following last (legitimate) bytes; // note that number of blocks was chosen to be (numBytes+2)/256, ensuring room ByteBlock lastBlock = new ByteBlock(16, 16, newBytes); short checksum = computeChecksum(byteBlock.bytes, numBytes); setChecksum(checksum, lastBlock, endPosition); // create SNMP octet string from these bytes SNMPOctetString theObject = new SNMPOctetString(lastBlock.bytes); // send the bytes SNMPVarBindList newVars = comInterface.setMIBEntry(itemID, theObject); // now send reset signal: indicates number of bytes to burn to prom. // also indicates location of checksum SNMPInteger numBytesWritten = new SNMPInteger(numBytes); //System.out.println("Number of bytes to burn in: " + numBytesWritten); itemID = "1.3.6.1.4.1.762.2.1.2.0"; newVars = comInterface.setMIBEntry(itemID, numBytesWritten); itemID = "1.3.6.1.4.1.762.2.1.3.0"; newVars = comInterface.setMIBEntry(itemID, numBytesWritten); messagesArea.append("Data transmitted; base station restarting.\n"); } catch(UnknownHostException e) { messagesArea.append("Error transmitting data: unknown host.\n"); } catch(SocketException e) { messagesArea.append("Error transmitting data: " + e.getMessage() + "\n"); } catch(IOException e) { messagesArea.append("Error transmitting data: timed out waiting for response.\n"); } catch (SNMPSetException e) { messagesArea.append("Error transmitting data: " + e.getMessage() + "\n"); } catch (SNMPBadValueException e) { // will never occur! messagesArea.append("Error transmitting data: bad SNMP value.\n"); } } /* * Compute the 2-byte checksum for the bytes up to (but not including) the indicated position */ private short computeChecksum(byte[] bytes, int position) { short sum = 0; for (int i = 0; i < position; i++) { sum += bytes[i]; if(bytes[i] < 0) sum += 256; } return sum; } private void setChecksum(short sum, ByteBlock byteBlock, int position) { String checksumString = littleEndianHexString(sum); // create info record to write into int numRows = 1; int numCols = 2; int baseStartIndex = position; ByteBlockWindow checksumWindow = new ByteBlockRectangularWindow(baseStartIndex, numRows, numCols, byteBlock); int dataType = AirportInfoRecord.BYTE_STRING; AirportInfoRecord checksumRecord = new AirportInfoRecord(dataType, checksumWindow); checksumRecord.byteBlockWindow.clearBytes(); // write in new checksum try { checksumRecord.setBytesFromString(checksumString); } catch (ValueFormatException ve) { // won't occur! messagesArea.append("Problem writing checksum with value " + checksumString + ".\n"); } } /* * Convenience method for writing checksum value into same block it's computed from. This * is the usual case for config files; however, the more general routine is used to set * the transmission checksum immediately following the transmitted data bytes. */ private void setChecksum(ByteBlock byteBlock, int position) { short sum = computeChecksum(byteBlock.bytes, position); setChecksum(sum, byteBlock, position); } /** * Return little-endian hex string */ private String littleEndianHexString(short value) { int intValue = value; intValue = intValue & 0xFFFF; int switched = ((intValue << 8) | (intValue >>> 8)) & 0xFFFF; String returnString = Integer.toHexString(switched); // add leading zeros if needed while (returnString.length() < 4) returnString = "0" + returnString; return returnString; } /** * Used to validate checksum in stored settings, to ensure file is legitimate! Verify just * first checksum, for compatibility with Apple configurator's stored settings. */ private boolean checksumValid(ByteBlock byteBlock) { short sum = computeChecksum(byteBlock.bytes, configurationSize - 2); String computedChecksumString = littleEndianHexString(sum); //System.out.println("Computed checksum: " + computedChecksumString); // get configuration checksum from block int baseStartIndex = 0x43B6; int numRows = 1; int numCols = 2; int dataType = AirportInfoRecord.BYTE_STRING; AirportInfoRecord checksumRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, byteBlock); String existingChecksumString = checksumRecord.toString(); //System.out.println("Existing checksum: " + existingChecksumString); if (computedChecksumString.equals(existingChecksumString)) return true; else return false; } private boolean checksumValid() { return checksumValid(baseBlock); } // Apparently the Apple-supplied firmware files computed the // checksum before the community name default passwords (4 "public" and one count of 06) // were inserted. Thus the checksum computation should differ by 0xA02 for these files. // Thus the need for this "hacked" checksum validation.... private boolean appleFirmwareChecksumValid(ByteBlock byteBlock) { short sum = computeChecksum(byteBlock.bytes, configurationSize - 2); sum -= 0xA02; String computedChecksumString = littleEndianHexString(sum); //System.out.println("Computed checksum: " + computedChecksumString); // get configuration checksum from block int baseStartIndex = 0x43B6; int numRows = 1; int numCols = 2; int dataType = AirportInfoRecord.BYTE_STRING; AirportInfoRecord checksumRecord = new AirportInfoRecord(baseStartIndex, numRows, numCols, dataType, byteBlock); String existingChecksumString = checksumRecord.toString(); //System.out.println("Existing checksum: " + existingChecksumString); if (computedChecksumString.equals(existingChecksumString)) return true; else return false; } public static void main(String args[]) { try { AirportBaseStationConfigurator theApp = new AirportBaseStationConfigurator(); theApp.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 = theApp.getSize(); dim.height += 20; dim.width += 20; theApp.setSize(dim); theApp.show(); } catch (Exception e) {} } }