CIDR-style ("/24") netmasks are now supported

git-svn-id: https://ipscan.svn.sourceforge.net/svnroot/ipscan/trunk@192 375186e5-ef17-0410-b0b6-91563547dcda
This commit is contained in:
angryziber 2007-08-13 19:13:52 +00:00
parent 047a1b9619
commit 8ea9c98d6e
3 changed files with 52 additions and 27 deletions

View File

@ -99,14 +99,31 @@ public class InetAddressUtils {
/**
* Parses the netmask string provided in special text format:
* A.B.C.D, where each term is 0-255 or empty. If any term is empty, it is the same as 255.
* Another supported format is CIDR ("/24").
* <p/>
* Only IPv4 is supported.
*
* @param netmaskString
* @throws UnknownHostException
*/
public static InetAddress parseNetmask(String netmaskString) throws UnknownHostException {
if (netmaskString.startsWith("/")) {
// CIDR netmask, e.g. "/24" - number of bits set from the left
int totalBits = Integer.parseInt(netmaskString.substring(1));
byte[] mask = new byte[4]; // Warning: assume IPv4 here
for (int i = 0; i < mask.length; i++) {
int curByteBits = totalBits >= 8 ? 8 : totalBits;
totalBits -= curByteBits;
mask[i] = (byte)((((1 << curByteBits)-1)<<(8-curByteBits)) & 0xFF);
}
return InetAddress.getByAddress(mask);
}
// IP-like netmask (IPv4)
netmaskString = netmaskString.replaceAll("\\.\\.", ".255.");
netmaskString = netmaskString.replaceAll("\\.\\.", ".255.");
InetAddress netmask = InetAddress.getByName(netmaskString);
return netmask;
return InetAddress.getByName(netmaskString);
}
/**

View File

@ -24,9 +24,6 @@ import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
@ -34,14 +31,14 @@ import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
/**
* GUI for initialization of RangeFeeder.
*
* TODO: delete button doesn't work well in edit fields
*
* @author Anton Keks
*/
public class RangeFeederGUI extends AbstractFeederGUI {
@ -143,20 +140,18 @@ public class RangeFeederGUI extends AbstractFeederGUI {
netmaskCombo.setText(getStringLabel("netmask"));
netmaskCombo.setVisibleItemCount(10);
// Warning: IPv4 specific netmasks
netmaskCombo.add("/16"); // TODO: implement these
netmaskCombo.add("/16");
netmaskCombo.add("/24");
netmaskCombo.add("/28");
netmaskCombo.add("255...240");
netmaskCombo.add("255...224");
// Warning: IPv4 specific netmasks
netmaskCombo.add("255...192");
netmaskCombo.add("255...128");
netmaskCombo.add("255...0");
netmaskCombo.add("255..0.0");
netmaskCombo.add("255.0.0.0");
NetmaskSelectionListener netmaskSelectionListener = new NetmaskSelectionListener();
netmaskCombo.addSelectionListener(netmaskSelectionListener);
netmaskCombo.addTraverseListener(netmaskSelectionListener);
NetmaskListener netmaskSelectionListener = new NetmaskListener();
netmaskCombo.addListener(SWT.Selection, netmaskSelectionListener);
netmaskCombo.addListener(SWT.Traverse, netmaskSelectionListener);
formData = new FormData();
formData.top = new FormAttachment(startIPText);
formData.left = new FormAttachment(ipUpButton, 5);
@ -218,12 +213,22 @@ public class RangeFeederGUI extends AbstractFeederGUI {
}
}
final class NetmaskSelectionListener implements SelectionListener, TraverseListener {
public void widgetDefaultSelected(SelectionEvent event) {
widgetSelected(event);
}
public void widgetSelected(SelectionEvent event) {
final class NetmaskListener implements Listener {
public void handleEvent(Event event) {
if (event.type == SWT.Traverse) {
// skip any other traversal besides RETURN
if (event.detail != SWT.TRAVERSE_RETURN)
return;
event.doit = false;
}
if (event.type == SWT.Selection) {
// this is a workaround for a strange bug: if text is just typed in the combo,
// then this event is sent after each keypress, but we want it to be fired
// only if something is selected from the drop down
if (netmaskCombo.indexOf(netmaskCombo.getText()) < 0)
return;
}
try {
String netmaskString = netmaskCombo.getText();
InetAddress netmask = InetAddressUtils.parseNetmask(netmaskString);
@ -232,18 +237,13 @@ public class RangeFeederGUI extends AbstractFeederGUI {
startIPText.setText(InetAddressUtils.startRangeByNetmask(startIP, netmask).getHostAddress());
endIPText.setText(InetAddressUtils.endRangeByNetmask(startIP, netmask).getHostAddress());
isEndIPUnedited = false;
netmaskCombo.forceFocus();
}
catch (UnknownHostException e) {
throw new FeederException("invalidNetmask");
}
}
public void keyTraversed(TraverseEvent e) {
if (e.detail == SWT.TRAVERSE_RETURN) {
widgetSelected(null);
e.doit = false;
}
}
}
} // @jve:decl-index=0:visual-constraint="10,10"

View File

@ -62,6 +62,14 @@ public class InetAddressUtilsTest {
assertEquals("255.255.255.192", InetAddressUtils.parseNetmask("255...192").getHostAddress());
assertEquals("255.0.255.0", InetAddressUtils.parseNetmask("255.0..0").getHostAddress());
assertEquals("0.0.0.0", InetAddressUtils.parseNetmask("0.0.0.0").getHostAddress());
assertEquals("0.0.0.0", InetAddressUtils.parseNetmask("/0").getHostAddress());
assertEquals("128.0.0.0", InetAddressUtils.parseNetmask("/1").getHostAddress());
assertEquals("255.255.0.0", InetAddressUtils.parseNetmask("/16").getHostAddress());
assertEquals("255.255.255.0", InetAddressUtils.parseNetmask("/24").getHostAddress());
assertEquals("255.255.255.128", InetAddressUtils.parseNetmask("/25").getHostAddress());
assertEquals("255.255.255.248", InetAddressUtils.parseNetmask("/29").getHostAddress());
assertEquals("255.255.255.255", InetAddressUtils.parseNetmask("/32").getHostAddress());
}
@Test