diff --git a/TODO b/TODO index 92a9cd6f..c0ff63f8 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,5 @@ Before 3.0: -* multiple requestedPort support, more docs * save default selection of pinger (Combined for non-root users) * command-line scanning start * fetcher-specific options diff --git a/resources/Labels.txt b/resources/Labels.txt index 64d7f2f4..9c206790 100755 --- a/resources/Labels.txt +++ b/resources/Labels.txt @@ -192,7 +192,7 @@ fetcher.ping.ttl.info=Shows the TTL (Time To Live) value in ping reply packets ( fetcher.hostname=Hostname fetcher.hostname.info=Shows the hostname of the host obtained by the reverse DNS lookup.\n\nThis is the registered host name on the DNS server and may be different from the host name configured on the machine itself. fetcher.ports=Ports -fetcher.ports.info=Shows the list of open ports from the ones that were scanned.\n\nA port is open when it is possible to complete TCP handshake with it and estabilish a connection.\nYou can select scanned ports in the Preferences dialog. +fetcher.ports.info=Shows the list of open ports from the ones that were scanned.\n\nA port is open when it is possible to complete TCP handshake with it and estabilish a connection.\nYou can select scanned ports in the Preferences dialog.\n\nThe number in the column heading shows the current number of selected ports for scanning; '+' is shown if requested ports for each host are scanned as well. fetcher.ports.filtered=Filtered Ports fetcher.ports.filtered.info=Shows the list of filtered ports from the ones that were scanned.\n\nA port is filtered when no response is being received to the connection attempt within specified amount of time. If a port is filtered, then it is probably blocked by a firewall. fetcher.comment=Comments @@ -222,6 +222,8 @@ preferences.ports.timing.adaptTimeout=Adapt timeout to ping roundtrip time (if a preferences.ports.timing.minTimeout=Minimal adapted connect timeout (in ms): preferences.ports.ports=Port selection preferences.ports.portsDescription=Specify ports to scan here. Ranges are supported.\nExample: 1-3,5,7,10-15,6000-6100\nIf many ports are specified, scanning can take a lot of time. +preferences.ports.addRequested=For each host, add requested specific ports +preferences.ports.addRequested.info=Feeders may support specifying requested ports in addition to addresses (e.g. File Feeder, in form of address:port)\nThis allows for rescanning of exported IP:Port list files. Can be useful for HTTP proxy lists and such.\nChecking this will always scan each host's requested ports in addition to the common ports specified above. preferences.display.list=Display in the results list preferences.display.list.ALL=All scanned hosts preferences.display.list.ALIVE=Alive hosts (responding to pings) only diff --git a/src/net/azib/ipscan/config/ScannerConfig.java b/src/net/azib/ipscan/config/ScannerConfig.java index a2681a86..c893d5aa 100755 --- a/src/net/azib/ipscan/config/ScannerConfig.java +++ b/src/net/azib/ipscan/config/ScannerConfig.java @@ -27,6 +27,7 @@ public class ScannerConfig { public boolean adaptPortTimeout; public int minPortTimeout; public String portString; + public boolean useRequestedPorts; public String notAvailableText; public String notScannedText; @@ -49,6 +50,7 @@ public class ScannerConfig { adaptPortTimeout = preferences.getBoolean("adaptPortTimeout", !Platform.CRIPPLED_WINDOWS); minPortTimeout = preferences.getInt("minPortTimeout", 100); portString = preferences.get("portString", ""); + useRequestedPorts = preferences.getBoolean("useRequestedPorts", true); notAvailableText = preferences.get("notAvailableText", Labels.getLabel("fetcher.value.notAvailable")); notScannedText = preferences.get("notScannedText", Labels.getLabel("fetcher.value.notScanned")); } @@ -68,6 +70,7 @@ public class ScannerConfig { preferences.putBoolean("adaptPortTimeout", adaptPortTimeout); preferences.putInt("minPortTimeout", minPortTimeout); preferences.put("portString", portString); + preferences.putBoolean("useRequestedPorts", useRequestedPorts); preferences.put("notAvailableText", notAvailableText); preferences.put("notScannedText", notScannedText); } diff --git a/src/net/azib/ipscan/core/PortIterator.java b/src/net/azib/ipscan/core/PortIterator.java index 6a401af5..9b07c49d 100755 --- a/src/net/azib/ipscan/core/PortIterator.java +++ b/src/net/azib/ipscan/core/PortIterator.java @@ -5,6 +5,8 @@ */ package net.azib.ipscan.core; +import java.util.Iterator; + /** * A class for iteration of ports, specified in special format, like: @@ -12,7 +14,7 @@ package net.azib.ipscan.core; * * @author Anton Keks */ -public final class PortIterator implements Cloneable { +public final class PortIterator implements Iterator, Cloneable { private int[] portRangeStart; private int[] portRangeEnd; @@ -63,7 +65,7 @@ public final class PortIterator implements Cloneable { /** * @return next port number */ - public int next() { + public Integer next() { int returnPort = currentPort++; if (currentPort > portRangeEnd[rangeIndex]) { @@ -98,5 +100,9 @@ public final class PortIterator implements Cloneable { return null; } } + + public void remove() { + throw new UnsupportedOperationException(); + } } diff --git a/src/net/azib/ipscan/core/ScanningSubject.java b/src/net/azib/ipscan/core/ScanningSubject.java index 260a13a4..db440af1 100755 --- a/src/net/azib/ipscan/core/ScanningSubject.java +++ b/src/net/azib/ipscan/core/ScanningSubject.java @@ -6,7 +6,10 @@ package net.azib.ipscan.core; import java.net.InetAddress; +import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; +import java.util.List; import java.util.Map; import net.azib.ipscan.config.Config; @@ -30,8 +33,8 @@ public class ScanningSubject { /** The address being scanned */ private InetAddress address; - /** The requested port that the user wishes to put more attention to, can be null. E.g. port 3128 for scanning of proxy servers. */ - private Integer requestedPort; + /** The requested ports that the user wishes to put more attention to, can be null. E.g. port 3128 for scanning of proxy servers. */ + private List requestedPorts; /** Arbitrary parameters for sharing among different (but related) Fetchers */ private Map parameters; /** The result type constant value, can be modified by some Fetchers */ @@ -106,18 +109,24 @@ public class ScanningSubject { this.isAborted = true; } + public boolean isAnyPortRequested() { + return requestedPorts != null; + } + /** - * @return the port that the user wishes to pay attention to, e.g. 3128 for proxies, or null. + * @return ports that the user wishes to pay attention to, e.g. 3128 for proxies, or null. */ - public Integer getRequestedPort() { - return requestedPort; + public Iterator requestedPortsIterator() { + return requestedPorts == null ? null : requestedPorts.iterator(); } /** * @param requestedPort the port that user wants to scan */ - public void setRequestedPort(Integer requestedPort) { - this.requestedPort = requestedPort; + public void addRequestedPort(Integer requestedPort) { + if (requestedPorts == null) + requestedPorts = new ArrayList(); + requestedPorts.add(requestedPort); } /** @@ -142,7 +151,15 @@ public class ScanningSubject { @Override public String toString() { - return address.getHostAddress() + requestedPort != null ? ":" + requestedPort : ""; + StringBuilder sb = new StringBuilder(address.getHostAddress()); + if (requestedPorts != null) { + sb.append(':'); + for (Integer port : requestedPorts) + sb.append(port).append(','); + if (sb.charAt(sb.length()-1) == ',') + sb.deleteCharAt(sb.length()-1); + } + return sb.toString(); } } diff --git a/src/net/azib/ipscan/feeders/FileFeeder.java b/src/net/azib/ipscan/feeders/FileFeeder.java index d934c54d..77f9da3b 100755 --- a/src/net/azib/ipscan/feeders/FileFeeder.java +++ b/src/net/azib/ipscan/feeders/FileFeeder.java @@ -13,8 +13,8 @@ import java.io.Reader; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; @@ -37,7 +37,7 @@ public class FileFeeder extends AbstractFeeder { static final Logger LOG = LoggerFactory.getLogger(); /** Found IP address Strings are put here */ - private List foundIPAddresses; + private Map foundIPAddresses; private Iterator foundIPAddressesIterator; private int currentIndex; @@ -66,23 +66,27 @@ public class FileFeeder extends AbstractFeeder { BufferedReader fileReader = new BufferedReader(reader); currentIndex = 0; - foundIPAddresses = new LinkedList(); + foundIPAddresses = new LinkedHashMap(); try { String fileLine; while ((fileLine = fileReader.readLine()) != null) { Matcher matcher = InetAddressUtils.IP_ADDRESS_REGEX.matcher(fileLine); while (matcher.find()) { try { - String address = matcher.group(); - ScanningSubject subject = new ScanningSubject(InetAddress.getByName(address)); + String address = matcher.group(); + ScanningSubject subject = foundIPAddresses.get(address); + if (subject == null) + subject = new ScanningSubject(InetAddress.getByName(address)); + if (!matcher.hitEnd() && fileLine.charAt(matcher.end()) == ':') { // see if any valid port is requested Matcher portMatcher = PORT_REGEX.matcher(fileLine.substring(matcher.end()+1)); if (portMatcher.lookingAt()) { - subject.setRequestedPort(Integer.valueOf(portMatcher.group())); + subject.addRequestedPort(Integer.valueOf(portMatcher.group())); } } - foundIPAddresses.add(subject); + + foundIPAddresses.put(address, subject); } catch (UnknownHostException e) { LOG.log(Level.WARNING, "malformedIP", e); @@ -100,12 +104,10 @@ public class FileFeeder extends AbstractFeeder { try { fileReader.close(); } - catch (IOException e) { - // ignore, what else to do? - } + catch (IOException e) {} } - foundIPAddressesIterator = foundIPAddresses.iterator(); + foundIPAddressesIterator = foundIPAddresses.values().iterator(); } public int percentageComplete() { diff --git a/src/net/azib/ipscan/fetchers/PortTextFetcher.java b/src/net/azib/ipscan/fetchers/PortTextFetcher.java index 0e6e3adf..5cb15508 100644 --- a/src/net/azib/ipscan/fetchers/PortTextFetcher.java +++ b/src/net/azib/ipscan/fetchers/PortTextFetcher.java @@ -13,6 +13,8 @@ import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketException; import java.net.SocketTimeoutException; +import java.util.Collections; +import java.util.Iterator; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; @@ -45,45 +47,48 @@ public abstract class PortTextFetcher extends AbstractFetcher { } public Object scan(ScanningSubject subject) { - Socket socket = new Socket(); - try { - // TODO: support multiple ports and check them sequentially - socket.connect(new InetSocketAddress(subject.getAddress(), subject.getRequestedPort() != null ? subject.getRequestedPort() : defaultPort), subject.getAdaptedPortTimeout()); - socket.setTcpNoDelay(true); - socket.setSoTimeout(scannerConfig.portTimeout*2); - socket.setSoLinger(true, 0); - - socket.getOutputStream().write(textToSend.getBytes()); - - BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); - String line; - while ((line = in.readLine()) != null) { - Matcher matcher = matchingRegexp.matcher(line); - if (matcher.find()) { - // mark that additional info is available - subject.setResultType(ResultType.WITH_PORTS); - // return the required contents - return matcher.group(1); + Iterator portIterator = subject.isAnyPortRequested() ? subject.requestedPortsIterator() : Collections.singleton(defaultPort).iterator(); + + while (portIterator.hasNext() && !Thread.currentThread().isInterrupted()) { + Socket socket = new Socket(); + try { + socket.connect(new InetSocketAddress(subject.getAddress(), portIterator.next()), subject.getAdaptedPortTimeout()); + socket.setTcpNoDelay(true); + socket.setSoTimeout(scannerConfig.portTimeout*2); + socket.setSoLinger(true, 0); + + socket.getOutputStream().write(textToSend.getBytes()); + + BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + String line; + while ((line = in.readLine()) != null) { + Matcher matcher = matchingRegexp.matcher(line); + if (matcher.find()) { + // mark that additional info is available + subject.setResultType(ResultType.WITH_PORTS); + // return the required contents + return matcher.group(1); + } } } - } - catch (ConnectException e) { - // no connection - } - catch (SocketTimeoutException e) { - // no information - } - catch (SocketException e) { - // connection reset - } - catch (IOException e) { - LOG.log(Level.FINE, subject.getAddress().toString(), e); - } - finally { - try { - socket.close(); + catch (ConnectException e) { + // no connection + } + catch (SocketTimeoutException e) { + // no information + } + catch (SocketException e) { + // connection reset + } + catch (IOException e) { + LOG.log(Level.FINE, subject.getAddress().toString(), e); + } + finally { + try { + socket.close(); + } + catch (IOException e) {} } - catch (IOException e) {} } return null; } diff --git a/src/net/azib/ipscan/fetchers/PortsFetcher.java b/src/net/azib/ipscan/fetchers/PortsFetcher.java index 7cf57261..9c27b7d6 100755 --- a/src/net/azib/ipscan/fetchers/PortsFetcher.java +++ b/src/net/azib/ipscan/fetchers/PortsFetcher.java @@ -10,6 +10,7 @@ import java.net.ConnectException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketTimeoutException; +import java.util.Iterator; import java.util.SortedSet; import java.util.TreeSet; @@ -17,9 +18,9 @@ import net.azib.ipscan.config.ScannerConfig; import net.azib.ipscan.core.PortIterator; import net.azib.ipscan.core.ScanningSubject; import net.azib.ipscan.core.ScanningResult.ResultType; -import net.azib.ipscan.core.values.NotAvailable; import net.azib.ipscan.core.values.NotScanned; import net.azib.ipscan.core.values.NumericRangeList; +import net.azib.ipscan.util.SequenceIterator; /** * PortsFetcher scans TCP ports. @@ -51,7 +52,7 @@ public class PortsFetcher extends AbstractFetcher { @Override public String getFullName() { int numPorts = new PortIterator(config.portString).size(); - return getName() + " " + (numPorts > 0 ? "[" + numPorts + "]" : NotAvailable.VALUE); + return getName() + " [" + numPorts + (config.useRequestedPorts ? "+" : "" ) + "]"; } /** @@ -60,6 +61,7 @@ public class PortsFetcher extends AbstractFetcher { * @param subject the address to scan * @return true if any ports were scanned, false otherwise */ + @SuppressWarnings("unchecked") protected boolean scanPorts(ScanningSubject subject) { SortedSet openPorts = getOpenPorts(subject); @@ -74,17 +76,21 @@ public class PortsFetcher extends AbstractFetcher { Socket socket = null; // clone port iterator for performance instead of creating for every thread - PortIterator i = portIteratorPrototype.copy(); - if (!i.hasNext()) { + Iterator portsIterator = portIteratorPrototype.copy(); + if (config.useRequestedPorts && subject.isAnyPortRequested()) { + // add requested ports to the iteration + portsIterator = new SequenceIterator(portsIterator, subject.requestedPortsIterator()); + } + if (!portsIterator.hasNext()) { // no ports are configured for scanning return false; } - while (i.hasNext() && !Thread.currentThread().isInterrupted()) { + while (portsIterator.hasNext() && !Thread.currentThread().isInterrupted()) { // TODO: UDP ports? // TODO: reuse sockets? socket = new Socket(); - int port = i.next(); + int port = portsIterator.next(); try { // set some optimization options socket.setReuseAddress(true); diff --git a/src/net/azib/ipscan/gui/PreferencesDialog.java b/src/net/azib/ipscan/gui/PreferencesDialog.java index 9a0abb03..1305f3a8 100755 --- a/src/net/azib/ipscan/gui/PreferencesDialog.java +++ b/src/net/azib/ipscan/gui/PreferencesDialog.java @@ -67,6 +67,7 @@ public class PreferencesDialog extends AbstractModalDialog { private TabItem portsTabItem; private Text portTimeoutText; private Button adaptTimeoutCheckbox; + private Button addRequestedPortsCheckbox; private Text minPortTimeoutText; private Text portsText; private Text notAvailableText; @@ -357,6 +358,10 @@ public class PreferencesDialog extends AbstractModalDialog { portsText = new Text(portsGroup, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL); portsText.setLayoutData(new RowData(SWT.DEFAULT, 60)); portsText.addKeyListener(new PortsTextValidationListener()); + + addRequestedPortsCheckbox = new Button(portsGroup, SWT.CHECK); + addRequestedPortsCheckbox.setText(Labels.getLabel("preferences.ports.addRequested")); + addRequestedPortsCheckbox.setToolTipText(Labels.getLabel("preferences.ports.addRequested.info")); } /** @@ -402,6 +407,7 @@ public class PreferencesDialog extends AbstractModalDialog { minPortTimeoutText.setText(Integer.toString(scannerConfig.minPortTimeout)); minPortTimeoutText.setEnabled(scannerConfig.adaptPortTimeout); portsText.setText(scannerConfig.portString); + addRequestedPortsCheckbox.setSelection(scannerConfig.useRequestedPorts); notAvailableText.setText(scannerConfig.notAvailableText); notScannedText.setText(scannerConfig.notScannedText); displayMethod[guiConfig.displayMethod.ordinal()].setSelection(true); @@ -437,6 +443,7 @@ public class PreferencesDialog extends AbstractModalDialog { scannerConfig.adaptPortTimeout = adaptTimeoutCheckbox.getSelection(); scannerConfig.minPortTimeout = parseIntValue(minPortTimeoutText); scannerConfig.portString = portsText.getText(); + scannerConfig.useRequestedPorts = addRequestedPortsCheckbox.getSelection(); scannerConfig.notAvailableText = notAvailableText.getText(); scannerConfig.notScannedText = notScannedText.getText(); for (int i = 0; i < displayMethod.length; i++) { diff --git a/src/net/azib/ipscan/gui/ResultTable.java b/src/net/azib/ipscan/gui/ResultTable.java index 403e738d..4986ab88 100755 --- a/src/net/azib/ipscan/gui/ResultTable.java +++ b/src/net/azib/ipscan/gui/ResultTable.java @@ -38,6 +38,7 @@ public class ResultTable extends Table implements FetcherRegistryUpdateListener private ScanningResultList scanningResults; private GUIConfig guiConfig; + private FetcherRegistry fetcherRegistry; private Image[] listImages = new Image[ResultType.values().length]; @@ -49,6 +50,7 @@ public class ResultTable extends Table implements FetcherRegistryUpdateListener super(parent, SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION | SWT.VIRTUAL); this.guiConfig = guiConfig; this.scanningResults = scanningResultList; + this.fetcherRegistry = fetcherRegistry; setHeaderVisible(true); setLinesVisible(true); @@ -95,10 +97,10 @@ public class ResultTable extends Table implements FetcherRegistryUpdateListener tableColumn.addListener(SWT.Selection, columnClickListener); tableColumn.addListener(SWT.Resize, columnResizeListener); } - updateFetcherNames(fetcherRegistry); + updateColumnNames(); } - public void updateFetcherNames(FetcherRegistry fetcherRegistry) { + public void updateColumnNames() { int i = 0; for (Fetcher fetcher : fetcherRegistry.getSelectedFetchers()) { getColumn(i++).setText(fetcher.getFullName()); diff --git a/src/net/azib/ipscan/gui/actions/ToolsActions.java b/src/net/azib/ipscan/gui/actions/ToolsActions.java index 23c78ee6..b794f066 100755 --- a/src/net/azib/ipscan/gui/actions/ToolsActions.java +++ b/src/net/azib/ipscan/gui/actions/ToolsActions.java @@ -48,6 +48,7 @@ public class ToolsActions { // refresh the results and status bar in case anything was changed resultTable.updateResults(); + resultTable.updateColumnNames(); statusBar.updateConfigText(); } } diff --git a/src/net/azib/ipscan/util/SequenceIterator.java b/src/net/azib/ipscan/util/SequenceIterator.java new file mode 100644 index 00000000..ad7a6d6b --- /dev/null +++ b/src/net/azib/ipscan/util/SequenceIterator.java @@ -0,0 +1,44 @@ +/** + * This file is a part of Angry IP Scanner source code, + * see http://www.azib.net/ for more information. + * Licensed under GPLv2. + */ + +package net.azib.ipscan.util; + +import java.util.Iterator; + +/** + * SequenceIterator - joins several iterators together to provide a seamless iteration. + * + * @author Anton Keks + */ +public class SequenceIterator implements Iterator { + private Iterator[] iterators; + int currentIndex = 0; + + public SequenceIterator(Iterator... iterators) { + this.iterators = iterators; + + // check that last iterator is not empty (otherwise the code below won't work) + if (!iterators[iterators.length-1].hasNext()) + throw new IllegalArgumentException(); + } + + public boolean hasNext() { + // combined iterator has elements until the last iterator has them + return iterators[iterators.length-1].hasNext(); + } + + public E next() { + // take the next iterator if current ran out of elements + if (!iterators[currentIndex].hasNext()) + currentIndex++; + + return iterators[currentIndex].next(); + } + + public void remove() { + iterators[currentIndex].remove(); + } +} diff --git a/test/net/azib/ipscan/feeders/FileFeederTest.java b/test/net/azib/ipscan/feeders/FileFeederTest.java index 0c14c602..2eaaeb49 100755 --- a/test/net/azib/ipscan/feeders/FileFeederTest.java +++ b/test/net/azib/ipscan/feeders/FileFeederTest.java @@ -3,14 +3,15 @@ package net.azib.ipscan.feeders; import static net.azib.ipscan.feeders.FeederTestUtils.assertFeederException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; import java.io.StringReader; +import java.util.Iterator; import net.azib.ipscan.config.LabelsTest; +import net.azib.ipscan.core.ScanningSubject; import org.junit.Test; @@ -117,13 +118,18 @@ public class FileFeederTest { @Test public void requestedPortsAreDetected() throws Exception { - StringReader reader = new StringReader("1.2.3.4:1234\n2.3.4.5:\n 7.6.5.4:789004\n 1.2.3.5:80 "); + StringReader reader = new StringReader("1.2.3.4:1234\n2.3.4.5:\n 7.6.5.4:789004\n 1.2.3.5:80 1.2.3.5:3128 "); FileFeeder fileFeeder = new FileFeeder(reader); - assertEquals(1234, fileFeeder.next().getRequestedPort()); - assertNull(fileFeeder.next().getRequestedPort()); - assertNull(fileFeeder.next().getRequestedPort()); - assertEquals(80, fileFeeder.next().getRequestedPort()); + assertEquals(1234, fileFeeder.next().requestedPortsIterator().next()); + assertFalse(fileFeeder.next().isAnyPortRequested()); + assertFalse(fileFeeder.next().isAnyPortRequested()); + + ScanningSubject lastSubject = fileFeeder.next(); + assertEquals("1.2.3.5", lastSubject.getAddress().getHostAddress()); + Iterator portIterator = lastSubject.requestedPortsIterator(); + assertEquals(80, portIterator.next()); + assertEquals(3128, portIterator.next()); } private void assertAddressCount(String s, int addressCount) { diff --git a/test/net/azib/ipscan/fetchers/PortsFetcherTest.java b/test/net/azib/ipscan/fetchers/PortsFetcherTest.java index 4dc0d139..dda0497e 100755 --- a/test/net/azib/ipscan/fetchers/PortsFetcherTest.java +++ b/test/net/azib/ipscan/fetchers/PortsFetcherTest.java @@ -3,8 +3,11 @@ */ package net.azib.ipscan.fetchers; -import static org.easymock.classextension.EasyMock.*; -import static org.junit.Assert.*; +import static org.easymock.classextension.EasyMock.createMock; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.io.IOException; import java.net.InetAddress; @@ -13,7 +16,6 @@ import java.net.Socket; import net.azib.ipscan.config.ScannerConfig; import net.azib.ipscan.core.ScanningSubject; -import net.azib.ipscan.core.values.NotAvailable; import net.azib.ipscan.core.values.NumericRangeList; import org.junit.Before; @@ -36,11 +38,17 @@ public class PortsFetcherTest extends AbstractFetcherTestCase { @Test public void numberOfPortsInFullName() throws Exception { + config.useRequestedPorts = false; + config.portString = ""; - assertEquals(fetcher.getName() + " " + NotAvailable.VALUE, fetcher.getFullName()); + assertEquals(fetcher.getName() + " [0]", fetcher.getFullName()); config.portString = "1-3"; assertEquals(fetcher.getName() + " [3]", fetcher.getFullName()); + + config.useRequestedPorts = true; + config.portString = "21-29,40"; + assertEquals(fetcher.getName() + " [10+]", fetcher.getFullName()); } @Test diff --git a/test/net/azib/ipscan/util/SequenceIteratorTest.java b/test/net/azib/ipscan/util/SequenceIteratorTest.java new file mode 100644 index 00000000..50c86919 --- /dev/null +++ b/test/net/azib/ipscan/util/SequenceIteratorTest.java @@ -0,0 +1,50 @@ +/** + * This file is a part of Angry IP Scanner source code, + * see http://www.azib.net/ for more information. + * Licensed under GPLv2. + */ +package net.azib.ipscan.util; + +import static org.junit.Assert.*; + +import java.util.Arrays; +import java.util.Iterator; + +import org.junit.Test; + +/** + * SequenceIteratorTest + * + * @author Anton Keks + */ +@SuppressWarnings("unchecked") +public class SequenceIteratorTest { + + @Test + public void singleIterator() throws Exception { + Iterator i = new SequenceIterator(Arrays.asList(1).iterator()); + assertTrue(i.hasNext()); + assertEquals(1, i.next()); + assertFalse(i.hasNext()); + } + + @Test + public void twoIterators() throws Exception { + Iterator i = new SequenceIterator(Arrays.asList(1, 2).iterator(), Arrays.asList(3).iterator()); + assertTrue(i.hasNext()); + assertEquals(1, i.next()); + assertTrue(i.hasNext()); + assertEquals(2, i.next()); + assertTrue(i.hasNext()); + assertEquals(3, i.next()); + assertFalse(i.hasNext()); + } + + @Test + public void firstEmpty() throws Exception { + Iterator i = new SequenceIterator(Arrays.asList().iterator(), Arrays.asList(3).iterator()); + assertTrue(i.hasNext()); + assertEquals(3, i.next()); + assertFalse(i.hasNext()); + } +}