Return-Path: <jis@MIT.EDU>
Received: from MIT.EDU by po12.mit.edu (8.9.2/4.7) id XAA25506; Tue, 19 Dec 2000 23:08:46 -0500 (EST)
Received: from JIS.MIT.EDU by MIT.EDU with SMTP id AA28765; Tue, 19 Dec 00 23:10:19 EST
Received: from localhost.localdomain (localhost [127.0.0.1]) by jis.mit.edu (8.9.1b+Sun/8.9.3) with ESMTP id XAA06930; Tue, 19 Dec 2000 23:08:44 -0500 (EST)
Received: (from jis@localhost) by localhost.localdomain (8.8.7/8.8.7) id XAA02391; Tue, 19 Dec 2000 23:08:36 -0500
X-Authentication-Warning: localhost.localdomain: jis set sender to jis@mit.edu using -f
Date: Tue, 19 Dec 2000 23:08:36 -0500
From: "Jeffrey I. Schiller" <jis@MIT.EDU>
To: Jon Sevy <jsevy@mcs.drexel.edu>
Cc: jis@MIT.EDU
Subject: Improvement to AirportBaseStationConfigurator (patch enclosed)
Message-Id: <20001219230836.B2318@mit.edu>
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="82I3+IH0IqGh5yIs"
Content-Disposition: inline
User-Agent: Mutt/1.2.5i
Status: O
X-Status: 
X-Keywords:                  
X-UID: 49
X-Evolution: 00000023-0020


--82I3+IH0IqGh5yIs
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

	Turns out that even when you have the airport in NAT mode, it
still behaves as a transparent bridge. Although this is normally
harmless, I ran into a situation where I really wanted to disable the
bridging function. Turns out that someone in the same collision domain
as my cable modem has a new Lucent RG-1000. I caught it ARP'ing for
10.0.1.2 on the cable using a return address of 10.0.1.1. Because the
airport was bridging, it forwarded this ARP along which resulted in the
poisoning of the ARP cache on my wireless host (it now had the MAC
address for 10.0.1.1 as the other guy's RG-1000 instead of my airport,
result: no communications!).

	Well, you can turn off bridging. It took me a while of fooling
with the Karlnet configuration tool, but I eventually figured out that
the "do you bridge" bit is in the same byte as the access control switch
(offset 0x448). The low order bit controls whether or not bridging is
on.

	I have enclosed (MIME attachment) a patch file (diff -c output)
for the changes needed to the AirportBaseStationConfigurator so that it
provides a checkbox to turn off bridging. Because of the shared byte, I
had to do a bit of a kludge to pull this off and you are of course
welcome to re-write it (perhaps a bit level abstraction is needed as an
AirportInfoRecord).

	Btw. There appears to be a deprecated file
"AirportConnectionInfo.java" file included in the distribution. It
appears to be missing its first few lines (where the package declaration
lives) so it doesn't compile properly.

			-Jeff

--82I3+IH0IqGh5yIs
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=PATCH1

*** AirportAccessControlTable.java.ori	Sun Aug 27 22:26:04 2000
--- AirportAccessControlTable.java	Tue Dec 19 22:19:52 2000
***************
*** 42,48 ****
  	private Vector addressVector;
  	private JTable table;
  	private AbstractTableModel tableModel;
! 	
  	
  	/**
  	*	Table model which maintains list of MAC addresses and host names.
--- 42,48 ----
  	private Vector addressVector;
  	private JTable table;
  	private AbstractTableModel tableModel;
!         private AirportBridgingPanel bridgingPanel;
  	
  	/**
  	*	Table model which maintains list of MAC addresses and host names.
***************
*** 104,113 ****
  		
  	}
  	
! 	
! 	
! 	
! 	
  	/**
  	*	Create new table based on data in airportInfo.
  	*/
--- 104,111 ----
  		
  	}
  	
! 
! 
  	/**
  	*	Create new table based on data in airportInfo.
  	*/
***************
*** 259,272 ****
  		*	Access control switch: byte 4*16 + 9  
  		*		01 = no access control
  		*		81 = access control used
  		*/
  		
  		String accessSwitchValue = new String();
  		
! 		if (numMacAddresses > 0)
  			accessSwitchValue = "81";
! 		else
  			accessSwitchValue = "01";
  			
  		AirportInfoRecord accessControlSwitchRecord = airportInfo.get("Access control switch");
  		accessControlSwitchRecord.setBytesFromString(accessSwitchValue);
--- 257,278 ----
  		*	Access control switch: byte 4*16 + 9  
  		*		01 = no access control
  		*		81 = access control used
+ 		*		00 = no access control, bridging OFF
+ 		*		80 = access control used, bridging OFF
  		*/
  		
  		String accessSwitchValue = new String();
+ 		boolean bridgingOff = bridgingPanel.getBridgingOff();
  		
! 		if (numMacAddresses > 0) {
! 		    if (bridgingOff) accessSwitchValue = "80"; 
! 		    else
  			accessSwitchValue = "81";
! 		} else {
! 		    if (bridgingOff) accessSwitchValue = "00";
! 		    else
  			accessSwitchValue = "01";
+ 		}
  			
  		AirportInfoRecord accessControlSwitchRecord = airportInfo.get("Access control switch");
  		accessControlSwitchRecord.setBytesFromString(accessSwitchValue);
***************
*** 365,372 ****
  		
  	}
  	
! 	
! 	
! 	
  
! }
\ No newline at end of file
--- 371,381 ----
  		
  	}
  	
!     // The following is a kludge so that we can find the bridging panel
!     // to determine whether or not we need to disable bridging.
! 
!         void setBridgeControl(AirportBridgingPanel bpanel) {
! 	    this.bridgingPanel = bpanel;
! 	}
  
! }
*** AirportBridgingPanel.java.ori	Sun Aug 27 22:26:04 2000
--- AirportBridgingPanel.java	Tue Dec 19 22:27:11 2000
***************
*** 38,43 ****
--- 38,45 ----
  	private AirportDHCPRangePanel dhcpRangePanel, natRangePanel;
  	private AirportInfoPanel dhcpOnEthernetPanel;
  	private AirportInfoCheckBox dhcpOnEthernetCheckbox;
+         private AirportInfoCheckBox turnOffBridgingCheckbox;
+         private AirportInfoPanel turnOffBridgingPanel;
  	private JTable portMappingList;
  	
  	
***************
*** 82,87 ****
--- 84,102 ----
  		dhcpOnEthernetPanel = new AirportInfoPanel();
  		dhcpOnEthernetPanel.add(dhcpOnEthernetCheckbox);
  		
+ 		// Add checkbox to disable bridging completely. Only
+ 		// enabled if NAT is selected
+ 
+ 		turnOffBridgingCheckbox = new AirportInfoCheckBox("Disable Bridging as well");
+ 		turnOffBridgingPanel = new AirportInfoPanel();
+ 		turnOffBridgingPanel.add(turnOffBridgingCheckbox);
+ 
+ 		AirportInfoRecord accessControlSwitch = theInfo.get("Access control switch");
+ 		String accessControlValue = accessControlSwitch.toString();
+ 		if (accessControlValue.equals("00") ||
+ 		    accessControlValue.equals("80"))
+ 		    turnOffBridgingCheckbox.setSelected(true);
+ 
  		setUpDisplay();
  	}
  	
***************
*** 158,172 ****
  		theLayout.setConstraints(natPlusButton, c);
  		this.add(natPlusButton);
  		
- 		
  		c.gridx = 1;
  		c.gridy = 7;
  		theLayout.setConstraints(dhcpOnEthernetPanel, c);
  		this.add(dhcpOnEthernetPanel);
  		
  		/*
  		c.gridx = 1;
! 		c.gridy = 8;
  		theLabel = new JLabel("Port mapping:");
  		theLayout.setConstraints(theLabel, c);
  		this.add(theLabel);
--- 173,191 ----
  		theLayout.setConstraints(natPlusButton, c);
  		this.add(natPlusButton);
  		
  		c.gridx = 1;
  		c.gridy = 7;
+ 		theLayout.setConstraints(turnOffBridgingPanel, c);
+ 		this.add(turnOffBridgingPanel);
+ 		
+ 		c.gridx = 1;
+ 		c.gridy = 8;
  		theLayout.setConstraints(dhcpOnEthernetPanel, c);
  		this.add(dhcpOnEthernetPanel);
  		
  		/*
  		c.gridx = 1;
! 		c.gridy = 9;
  		theLabel = new JLabel("Port mapping:");
  		theLayout.setConstraints(theLabel, c);
  		this.add(theLabel);
***************
*** 193,203 ****
  		natPlusButton.addItemListener(natRangePanel);
  		natRangePanel.setEnabled(natButton.isSelected() || natPlusButton.isSelected());
  		natRangePanel.setVisible(false);
! 		
  		
  		
  	}
  	
! 	
! 	
! }
\ No newline at end of file
--- 212,233 ----
  		natPlusButton.addItemListener(natRangePanel);
  		natRangePanel.setEnabled(natButton.isSelected() || natPlusButton.isSelected());
  		natRangePanel.setVisible(false);
! 
! 		// Make Bridging Off panel dependent on status of nat buttons
! 
! 		natButton.addItemListener(turnOffBridgingPanel);
! 		natPlusButton.addItemListener(turnOffBridgingPanel);
! 		turnOffBridgingPanel.setEnabled(natButton.isSelected() ||
! 						natPlusButton.isSelected());
  		
  		
  	}
  	
!         boolean getBridgingOff() {
! 	    if(natButton.isSelected() ||
! 	       natPlusButton.isSelected())
! 		if (turnOffBridgingCheckbox.isSelected())
! 		    return (true);
! 	    return (false);
! 	}
! }
*** AirportInfoTabbedPane.java.ori	Sun Aug 27 22:26:04 2000
--- AirportInfoTabbedPane.java	Tue Dec 19 22:14:18 2000
***************
*** 58,65 ****
  		AirportInfoPanel mainPanel = new AirportMainPanel(airportInfo);
  		AirportInfoPanel wirelessPanel = new AirportWirelessPanel(airportInfo);
  		AirportInfoPanel connectionPanel = new AirportNetworkPanel(airportInfo);
! 		AirportInfoPanel bridgingPanel = new AirportBridgingPanel(airportInfo);
! 		AirportInfoPanel accessTablePanel = new AirportAccessControlTable(airportInfo);
  		AirportInfoPanel portMapTablePanel = new AirportPortMappingTable(airportInfo);
  		
  		this.addTab("Main", mainPanel);
--- 58,72 ----
  		AirportInfoPanel mainPanel = new AirportMainPanel(airportInfo);
  		AirportInfoPanel wirelessPanel = new AirportWirelessPanel(airportInfo);
  		AirportInfoPanel connectionPanel = new AirportNetworkPanel(airportInfo);
! 		AirportBridgingPanel bridgingPanel = new AirportBridgingPanel(airportInfo);
! 		AirportAccessControlTable accessTablePanel = new AirportAccessControlTable(airportInfo);
! 		// OK, this is a complete kludge. We have to tell the
! 		// AccessControlTable about the bridge panel because it needs
! 		// to query the bridge panel to determine what value to
! 		// store in the accessControl byte because the same byte
! 		// is used to control whether or not bridging is enabled
! 		accessTablePanel.setBridgeControl(bridgingPanel);
! 
  		AirportInfoPanel portMapTablePanel = new AirportPortMappingTable(airportInfo);
  		
  		this.addTab("Main", mainPanel);
***************
*** 113,116 ****
  	}
  	
  
! }
\ No newline at end of file
--- 120,123 ----
  	}
  	
  
! }

--82I3+IH0IqGh5yIs--

