# UDP Port bestimmen | Windows, MAC, Linux...



## Dit_ (20. Feb 2011)

Hallo,

ist es möglich einen für UDP bestimmten Port festzustellen und zwar mit einer Methode die auf verschiedenen OS funktionieren würde?

Ich brauche das für eine ProjektArbeit, da muss man in einer XML-Datei den Port angeben, manchmal weiss aber der Benutzer nicht welcher port im Netz (einer Schule oder Organisation) freigegeben ist. Ich weiss man kann RZ fragen, aber vielleicht kann man einfach eine Suchfunktion anbieten 


Habe im Netz folgende Methode gefunden


```
public static void main(String[] args) {
		for (int port = 1024; port <= 65535; port++) {
			try {
				DatagramSocket server = new DatagramSocket(port);
				server.close();
				System.out.println("OK: " + port);
			} catch (SocketException ex) {
				System.out.println("There is a server on port " + port + ".");
			}
		}
	}
```

Was sagen die Profis? 

Danke schon mal


----------



## kay73 (20. Feb 2011)

Dit_ hat gesagt.:


> ist es möglich einen für UDP bestimmten Port festzustellen...


Nicht sehr sauber. Portscanner beschießen eine Zieladresse mit Paketen auf allen Ports und testen, ob eventuell eingehende Pakete zu einem versandten Paket passen. 

In Deinem Fall wäre das nicht besonders "höflich" und auch nicht 100%-ig sicher, da das "U" in UDP nun mal für unreliable steht. Wenn Du das Antwortverhalten und Format der Pakete kennst, ließe sich vielleicht was machen, was einigermaßen funktioniert. Der Code da unten scheint ganz nett zu klappen:


```
PortscanDemo
```
 kann einen laufenden DNS Server erkennen. Für Deine Zwecke kannst Du die Klasse 
	
	
	
	





```
DNSSinglePortScanner
```
 Vorlage zu verwenden; musst nur 
Den Konstruktor überladen


```
genUDPPayload()
```
 überladen; gibt die byte Vorlage für die UDP Pakete zurück.


```
verifyReturnedPayload()
```
 überladen; testet ob ein empfangenes Paket ein gültiges Antwortpaket sein kann.

Der Code der Basisklasse ist an etlichen Stellen verbesserungswürdig, z. B. kann man 

den/die Timeout(s) schöner implementieren 
Exceptions besser behandeln
das blocking fixen, da 
	
	
	
	





```
receive()
```
 ständig 
	
	
	
	





```
null
```
-s zutückliefert. (Keine Ahnung wieso...)
eine Abbruchfunktion für den Scan einbauen, anstatt nach 10 Sekunden automatisch zu sterben
intervallartiges Senden/Empfangen von Paketen, Z. B. nicht mehr als 100 auf einmal, damit die Firewalls nicht denken, man wolle eine DoS-Attacke starten, usw...


```
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

interface PortScanner {
	static final int INVALID_PORT = -1;
	int scan() throws IOException;
};

abstract class AbstractUDPSinglePortScanner implements PortScanner {

	private final int portMin;
	private final int portMax;
	private final InetAddress dest;
	
	private static final int TIMEOUT_SECONDS=10;

	protected abstract byte[] genUDPPayload();

	protected abstract boolean verifyReturnedPayload(byte[] payload);

	protected AbstractUDPSinglePortScanner(String hostName, int portMin, int portMax)
			throws IOException {

		this.portMin = Math.min(portMin, portMax);
		this.portMax = Math.max(portMin, portMax);

		dest = Inet4Address.getByName(hostName);
	}

	@Override
	public final int scan() throws IOException {

		final DatagramChannel ch = DatagramChannel.open();
		ch.configureBlocking(true);

		final ExecutorService exs = Executors.newSingleThreadExecutor(); 
		final Future<Integer> f = exs.submit(
			new Callable<Integer>() {

				@Override
				public Integer call() throws Exception {
					final byte[] buffer = new byte[1024];
					final ByteBuffer bb = ByteBuffer.wrap(buffer);
					
					while (true) {
						final SocketAddress soa = ch.receive(bb);

						if (soa != null) {
							bb.flip();

							if (soa instanceof InetSocketAddress) {
								final InetSocketAddress isa = (InetSocketAddress) soa;
								if (isa.getAddress().equals(dest)
										&& verifyReturnedPayload(buffer)) {
									return isa.getPort();
								}
							}
						}
					}
				}
			});
		exs.shutdown();
		
		for (int port = portMin; port <= portMax; port++) {
			ch.send(ByteBuffer.wrap(this.genUDPPayload()), 
				new InetSocketAddress(dest, port));
		}

		try {
			if(!exs.awaitTermination(TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
				f.cancel(true);
				return PortScanner.INVALID_PORT;
			} 
			
			return f.get();
		} catch (InterruptedException e) {
			return PortScanner.INVALID_PORT;
		} catch (ExecutionException e) {
			return PortScanner.INVALID_PORT;
		}
	}
}

class DNSSinglePortScanner extends AbstractUDPSinglePortScanner {
	
	private static final byte dns_google_de[] = { 
		0x7d, (byte) 0x9f, 0x01, 0x00, 0x00,
		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x03, 0x77, 0x77, 0x77, 0x06, 
		0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 
		0x02, 0x64, 0x65, 0x00, 0x00, 0x01, 
		0x00, 0x01 };

	public DNSSinglePortScanner(String hostName, int portMin, int portMax)
			throws IOException {
		super(hostName, portMin, portMax);
	}

	@Override
	protected byte[] genUDPPayload() {		
		return dns_google_de;
	}

	@Override
	protected boolean verifyReturnedPayload(byte[] payload) {
		return true;
	}	
}

public class PortscanDemo {

	public static void main(String[] args) throws IOException {
		
		final PortScanner ps = new DNSSinglePortScanner("208.67.222.222", 20, 70);
		final int port = ps.scan();
		System.out.println("DNS auf port: "+(port != PortScanner.INVALID_PORT ? port : "(nicht gefunden)"));
	}
}
```



Dit_ hat gesagt.:


> Habe im Netz folgende Methode gefunden


Das hilft Dir nicht weiter. Hier wird getestet, ob auf Deiner eigenen Maschine ein Prozess auf einem Port lauscht, wenn das berhaupt so klappt.


----------



## Dit_ (21. Feb 2011)

omg hast du das so auf schnelle eingetippt ? 

Danke, mache mich an die Arbeit


----------

