From 8ea9c98d6ebee233be02ff887991747077789c9e Mon Sep 17 00:00:00 2001 From: angryziber Date: Mon, 13 Aug 2007 19:13:52 +0000 Subject: [PATCH] CIDR-style ("/24") netmasks are now supported git-svn-id: https://ipscan.svn.sourceforge.net/svnroot/ipscan/trunk@192 375186e5-ef17-0410-b0b6-91563547dcda --- .../azib/ipscan/core/InetAddressUtils.java | 21 +++++++- .../ipscan/gui/feeders/RangeFeederGUI.java | 50 +++++++++---------- .../ipscan/core/InetAddressUtilsTest.java | 8 +++ 3 files changed, 52 insertions(+), 27 deletions(-) diff --git a/src/net/azib/ipscan/core/InetAddressUtils.java b/src/net/azib/ipscan/core/InetAddressUtils.java index 2e834b02..1a8a8baf 100755 --- a/src/net/azib/ipscan/core/InetAddressUtils.java +++ b/src/net/azib/ipscan/core/InetAddressUtils.java @@ -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"). + *

+ * 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); } /** diff --git a/src/net/azib/ipscan/gui/feeders/RangeFeederGUI.java b/src/net/azib/ipscan/gui/feeders/RangeFeederGUI.java index 8c24233b..eb5d8da9 100755 --- a/src/net/azib/ipscan/gui/feeders/RangeFeederGUI.java +++ b/src/net/azib/ipscan/gui/feeders/RangeFeederGUI.java @@ -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" diff --git a/test/net/azib/ipscan/core/InetAddressUtilsTest.java b/test/net/azib/ipscan/core/InetAddressUtilsTest.java index 2637d805..abc12432 100755 --- a/test/net/azib/ipscan/core/InetAddressUtilsTest.java +++ b/test/net/azib/ipscan/core/InetAddressUtilsTest.java @@ -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