|
@@ -4,11 +4,17 @@ import java.io.IOException;
|
|
import java.net.DatagramPacket;
|
|
import java.net.DatagramPacket;
|
|
import java.net.DatagramSocket;
|
|
import java.net.DatagramSocket;
|
|
import java.net.InetAddress;
|
|
import java.net.InetAddress;
|
|
|
|
+import java.net.SocketException;
|
|
import java.net.SocketTimeoutException;
|
|
import java.net.SocketTimeoutException;
|
|
import java.net.UnknownHostException;
|
|
import java.net.UnknownHostException;
|
|
|
|
|
|
-import de.tudarmstadt.informatik.hostage.net.MyDatagramSocketFactory;
|
|
+import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
|
|
|
|
|
|
|
|
+
|
|
|
|
+ * NetBIOS.
|
|
|
|
+ * Used to registrate computers and workgroups in a windows network.
|
|
|
|
+ * @author Wulf Pfeiffer
|
|
|
|
+ */
|
|
public class NMB extends Thread {
|
|
public class NMB extends Thread {
|
|
|
|
|
|
private DatagramSocket nbnsSocket;
|
|
private DatagramSocket nbnsSocket;
|
|
@@ -23,23 +29,46 @@ public class NMB extends Thread {
|
|
private String workgroup;
|
|
private String workgroup;
|
|
private NBNS nbns;
|
|
private NBNS nbns;
|
|
private NBDS nbds;
|
|
private NBDS nbds;
|
|
- private volatile boolean smbRunning;
|
|
+ private boolean isMaster;
|
|
- private Receiver receiver;
|
|
+ private byte[] addr = new byte[4];
|
|
|
|
+ private static byte[] transactID = HelperUtils.randomBytes(2);
|
|
|
|
|
|
public NMB(String ip, String username, String workgroup) {
|
|
public NMB(String ip, String username, String workgroup) {
|
|
try {
|
|
try {
|
|
- smbRunning = true;
|
|
+ isMaster = false;
|
|
this.username = username;
|
|
this.username = username;
|
|
this.workgroup = workgroup;
|
|
this.workgroup = workgroup;
|
|
this.ip = ip;
|
|
this.ip = ip;
|
|
ipParts = ip.split("\\.");
|
|
ipParts = ip.split("\\.");
|
|
String newHostAddr = ipParts[0] + "." + ipParts[1] + "." + ipParts[2] + ".255";
|
|
String newHostAddr = ipParts[0] + "." + ipParts[1] + "." + ipParts[2] + ".255";
|
|
dst = InetAddress.getByName(newHostAddr);
|
|
dst = InetAddress.getByName(newHostAddr);
|
|
|
|
+ addr = addressToBytes(ip);
|
|
|
|
+ nbns = new NBNS(addr);
|
|
|
|
+ nbds = new NBDS(addr, username, workgroup);
|
|
} catch (UnknownHostException e) {
|
|
} catch (UnknownHostException e) {
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ * Converts an ip address string into a byte array of length 4.
|
|
|
|
+ * @param addrString ip address.
|
|
|
|
+ * @return 4 byte ip address.
|
|
|
|
+ */
|
|
|
|
+ private byte[] addressToBytes(String addrString) {
|
|
|
|
+ String[] addrParts = addrString.split("\\.");
|
|
|
|
+ byte[] newAddr = new byte[4];
|
|
|
|
+ newAddr[0] = (byte)Integer.parseInt(addrParts[0]);
|
|
|
|
+ newAddr[1] = (byte)Integer.parseInt(addrParts[1]);
|
|
|
|
+ newAddr[2] = (byte)Integer.parseInt(addrParts[2]);
|
|
|
|
+ newAddr[3] = (byte)Integer.parseInt(addrParts[3]);
|
|
|
|
+ return newAddr;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ * Sends a NBNS packet.
|
|
|
|
+ * @param nbns packet.
|
|
|
|
+ */
|
|
private void sendPacket(NBNS nbns) {
|
|
private void sendPacket(NBNS nbns) {
|
|
try {
|
|
try {
|
|
byte[] packetBytes = nbns.getNextPacket();
|
|
byte[] packetBytes = nbns.getNextPacket();
|
|
@@ -50,9 +79,13 @@ public class NMB extends Thread {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ * Sends a NBDS packet.
|
|
|
|
+ * @param nbds packet.
|
|
|
|
+ */
|
|
private void sendPacket(NBDS nbds) {
|
|
private void sendPacket(NBDS nbds) {
|
|
try {
|
|
try {
|
|
- byte[] packetBytes = nbds.getBytes();
|
|
+ byte[] packetBytes = nbds.getNextPacket();
|
|
packet = new DatagramPacket(packetBytes, packetBytes.length, dst, nbdsPort);
|
|
packet = new DatagramPacket(packetBytes, packetBytes.length, dst, nbdsPort);
|
|
nbdsSocket.send(packet);
|
|
nbdsSocket.send(packet);
|
|
} catch (IOException e) {
|
|
} catch (IOException e) {
|
|
@@ -60,13 +93,21 @@ public class NMB extends Thread {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ * Sends the required packets for user and workgroup registration.
|
|
|
|
+ */
|
|
private void registrate() {
|
|
private void registrate() {
|
|
registrateUser();
|
|
registrateUser();
|
|
registrateGroup();
|
|
registrateGroup();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ * Sends the required packets for user registration.
|
|
|
|
+ */
|
|
private void registrateUser() {
|
|
private void registrateUser() {
|
|
- nbns = new NBNS(new byte[]{0x50, 0x00}, NBNSType.REGISTRATION_UNIQUE, NBNSService.SERVER, username, ip);
|
|
+ nbns.setType(NBNSType.REGISTRATION_UNIQUE);
|
|
|
|
+ nbns.setService(NBNSService.SERVER);
|
|
|
|
+ nbns.setName(username);
|
|
sendPacket(nbns);
|
|
sendPacket(nbns);
|
|
|
|
|
|
nbns.setService(NBNSService.MESSENGER);
|
|
nbns.setService(NBNSService.MESSENGER);
|
|
@@ -76,6 +117,9 @@ public class NMB extends Thread {
|
|
sendPacket(nbns);
|
|
sendPacket(nbns);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ * Sends the required packets for workgroup registration.
|
|
|
|
+ */
|
|
private void registrateGroup() {
|
|
private void registrateGroup() {
|
|
nbns.setName(workgroup);
|
|
nbns.setName(workgroup);
|
|
nbns.setType(NBNSType.REGISTRATION_GROUP);
|
|
nbns.setType(NBNSType.REGISTRATION_GROUP);
|
|
@@ -85,11 +129,17 @@ public class NMB extends Thread {
|
|
sendPacket(nbns);
|
|
sendPacket(nbns);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ * Sends the browser election request.
|
|
|
|
+ */
|
|
private void browserElection() {
|
|
private void browserElection() {
|
|
- nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.BROWSER);
|
|
+ nbds.setNbdstype(NBDSType.BROWSER);
|
|
sendPacket(nbds);
|
|
sendPacket(nbds);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ * Sends the required packets for MSBROWSE registration.
|
|
|
|
+ */
|
|
private void registrateMsBrowse() {
|
|
private void registrateMsBrowse() {
|
|
nbns.setName("__MSBROWSE__");
|
|
nbns.setName("__MSBROWSE__");
|
|
nbns.setType(NBNSType.REGISTRATION_MSBROWSE);
|
|
nbns.setType(NBNSType.REGISTRATION_MSBROWSE);
|
|
@@ -97,6 +147,9 @@ public class NMB extends Thread {
|
|
sendPacket(nbns);
|
|
sendPacket(nbns);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ * Sends the required packets for local master registration.
|
|
|
|
+ */
|
|
private void registrateLocalMaster() {
|
|
private void registrateLocalMaster() {
|
|
nbns.setName(workgroup);
|
|
nbns.setName(workgroup);
|
|
nbns.setType(NBNSType.REGISTRATION_UNIQUE);
|
|
nbns.setType(NBNSType.REGISTRATION_UNIQUE);
|
|
@@ -104,122 +157,169 @@ public class NMB extends Thread {
|
|
sendPacket(nbns);
|
|
sendPacket(nbns);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ * Sends the required packets for host announcement with services.
|
|
|
|
+ */
|
|
private void announceHost() {
|
|
private void announceHost() {
|
|
- nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.HOST_ANNOUNCEMENT_WITH_SERVICES);
|
|
+ nbds.setNbdstype(NBDSType.HOST_ANNOUNCEMENT_WITH_SERVICES);
|
|
sendPacket(nbds);
|
|
sendPacket(nbds);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ * Sends the required packets for a name query.
|
|
|
|
+ */
|
|
private void queryName() {
|
|
private void queryName() {
|
|
nbns.setType(NBNSType.NAME_QUERY);
|
|
nbns.setType(NBNSType.NAME_QUERY);
|
|
nbns.setService(NBNSService.LOCAL_MASTER_BROWSER);
|
|
nbns.setService(NBNSService.LOCAL_MASTER_BROWSER);
|
|
sendPacket(nbns);
|
|
sendPacket(nbns);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ * Sends the required packets for a request announcement
|
|
|
|
+ */
|
|
private void requestAnnouncement() {
|
|
private void requestAnnouncement() {
|
|
- nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.REQUEST_ANNOUNCEMENT);
|
|
+ nbds.setNbdstype(NBDSType.REQUEST_ANNOUNCEMENT);
|
|
sendPacket(nbds);
|
|
sendPacket(nbds);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ * Sends the required packets for a local master announcement to all.
|
|
|
|
+ */
|
|
private void localMasterAnnouncementAll() {
|
|
private void localMasterAnnouncementAll() {
|
|
- nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL);
|
|
+ nbds.setNbdstype(NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL);
|
|
sendPacket(nbds);
|
|
sendPacket(nbds);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ * Sends the required packets for a domain announcement.
|
|
|
|
+ */
|
|
private void domainAnnouncement() {
|
|
private void domainAnnouncement() {
|
|
- nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.DOMAIN_ANNOUNCEMENT);
|
|
+ nbds.setNbdstype(NBDSType.DOMAIN_ANNOUNCEMENT);
|
|
sendPacket(nbds);
|
|
sendPacket(nbds);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ * Sends the required packets for a local master announcement.
|
|
|
|
+ */
|
|
private void localMasterAnnouncement() {
|
|
private void localMasterAnnouncement() {
|
|
- nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.LOCAL_MASTER_ANNOUNCEMENT);
|
|
+ nbds.setNbdstype(NBDSType.LOCAL_MASTER_ANNOUNCEMENT);
|
|
sendPacket(nbds);
|
|
sendPacket(nbds);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
- public void run() {
|
|
+ public void run() {
|
|
|
|
+ NBSS nbss = new NBSS();
|
|
|
|
+ nbss.start();
|
|
try {
|
|
try {
|
|
- nbnsSocket = new MyDatagramSocketFactory().createDatagramSocket(nbnsPort);
|
|
+ nbnsSocket = new DatagramSocket(nbnsPort);
|
|
- nbnsSocket.connect(dst, nbnsPort);
|
|
+ nbdsSocket = new DatagramSocket(nbdsPort);
|
|
- nbdsSocket = new MyDatagramSocketFactory().createDatagramSocket(nbdsPort);
|
|
+ } catch (SocketException e) {
|
|
- nbdsSocket.connect(dst, nbdsPort);
|
|
|
|
- } catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
|
|
registrate();
|
|
registrate();
|
|
- receiver = new Receiver();
|
|
|
|
- receiver.start();
|
|
|
|
announceHost();
|
|
announceHost();
|
|
queryName();
|
|
queryName();
|
|
|
|
+ checkForAnswers();
|
|
|
|
|
|
- registrate();
|
|
+ if (isMaster) {
|
|
- queryName();
|
|
+ registrate();
|
|
-
|
|
+ queryName();
|
|
- registrate();
|
|
+
|
|
- queryName();
|
|
+ registrate();
|
|
-
|
|
+ queryName();
|
|
- registrate();
|
|
+
|
|
- queryName();
|
|
+ registrate();
|
|
-
|
|
+ queryName();
|
|
- browserElection();
|
|
+
|
|
- browserElection();
|
|
+ browserElection();
|
|
- browserElection();
|
|
+ browserElection();
|
|
- browserElection();
|
|
+ browserElection();
|
|
-
|
|
+ browserElection();
|
|
- registrateMsBrowse();
|
|
+
|
|
- registrateMsBrowse();
|
|
+ registrateMsBrowse();
|
|
- registrateMsBrowse();
|
|
+ registrateMsBrowse();
|
|
- registrateMsBrowse();
|
|
+ registrateMsBrowse();
|
|
-
|
|
+ registrateMsBrowse();
|
|
- registrateLocalMaster();
|
|
+
|
|
- registrateLocalMaster();
|
|
+ registrateLocalMaster();
|
|
- registrateLocalMaster();
|
|
+ registrateLocalMaster();
|
|
- registrateLocalMaster();
|
|
+ registrateLocalMaster();
|
|
-
|
|
+ registrateLocalMaster();
|
|
- requestAnnouncement();
|
|
+
|
|
- localMasterAnnouncementAll();
|
|
+ requestAnnouncement();
|
|
- domainAnnouncement();
|
|
+ localMasterAnnouncementAll();
|
|
-
|
|
+ domainAnnouncement();
|
|
-
|
|
+ localMasterAnnouncement();
|
|
-
|
|
+ }
|
|
|
|
|
|
announceHost();
|
|
announceHost();
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
nbnsSocket.close();
|
|
nbnsSocket.close();
|
|
nbdsSocket.close();
|
|
nbdsSocket.close();
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ private byte[] buffer = new byte[2048];
|
|
|
|
+ private boolean masterAnswered = false;
|
|
|
|
+ private DatagramPacket receive = new DatagramPacket(buffer, buffer.length);
|
|
|
|
|
|
- public synchronized void setSmbRunning(boolean smbRunning) {
|
|
+
|
|
- this.smbRunning = smbRunning;
|
|
+ * Check if the specified workgroup is already existing.
|
|
|
|
+ * If someone answers on your register messages there is already a master.
|
|
|
|
+ */
|
|
|
|
+ private void checkForAnswers() {
|
|
|
|
+ try {
|
|
|
|
+ nbnsSocket.setSoTimeout(1000);
|
|
|
|
+ try {
|
|
|
|
+ while (!masterAnswered) {
|
|
|
|
+ nbnsSocket.receive(receive);
|
|
|
|
+ if (!(receive.getAddress().toString().equals("/"+ip))) {
|
|
|
|
+ masterAnswered = true;
|
|
|
|
+ isMaster = false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ } catch (SocketTimeoutException e) {
|
|
|
|
+ isMaster = true;
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ isMaster = true;
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ * Returns the current transactID and increases it by one.
|
|
|
|
+ * @return transactID.
|
|
|
|
+ */
|
|
|
|
+ public static byte[] getAndIncTransactID() {
|
|
|
|
+ transactID[1]++;
|
|
|
|
+ if (transactID[1] == 0x00) {
|
|
|
|
+ transactID[0]++;
|
|
|
|
+ }
|
|
|
|
+ return transactID;
|
|
}
|
|
}
|
|
|
|
|
|
- private class Receiver extends Thread {
|
|
+
|
|
-
|
|
+ * Handling requests after initial registration
|
|
- private DatagramPacket packet;
|
|
+ */
|
|
- private byte[] buffer;
|
|
+ private void talk() {
|
|
- private boolean masterAnswered = false;
|
|
+ try {
|
|
-
|
|
+ nbnsSocket.setSoTimeout(0);
|
|
- public Receiver() {
|
|
+ } catch (SocketException e) {
|
|
- buffer = new byte[2048];
|
|
+ e.printStackTrace();
|
|
- packet = new DatagramPacket(buffer, buffer.length);
|
|
|
|
}
|
|
}
|
|
-
|
|
+ DatagramPacket request = new DatagramPacket(buffer, buffer.length);
|
|
- @Override
|
|
+ DatagramPacket response = new DatagramPacket(buffer, buffer.length);
|
|
- public void run() {
|
|
+ while (true) {
|
|
try {
|
|
try {
|
|
- nbnsSocket.setSoTimeout(1000);
|
|
+ nbnsSocket.receive(request);
|
|
- try {
|
|
+ byte[] resp = nbns.getNextResponse(request.getData(), addressToBytes(ip));
|
|
- while (!masterAnswered) {
|
|
+ response = new DatagramPacket(resp, resp.length, request.getAddress(), nbnsPort);
|
|
- nbnsSocket.receive(packet);
|
|
+ nbnsSocket.send(response);
|
|
- if (!(packet.getAddress().toString().equals("/"+ip))) {
|
|
|
|
- masterAnswered = true;
|
|
|
|
- setSmbRunning(false);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- } catch (SocketTimeoutException e) {
|
|
|
|
- setSmbRunning(false);
|
|
|
|
- e.printStackTrace();
|
|
|
|
- }
|
|
|
|
} catch (IOException e) {
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
}
|
|
}
|