Browse Source

-SMB: updated netbios service

Wulf Pfeiffer 10 years ago
parent
commit
01d61e569d

+ 9 - 9
src/de/tudarmstadt/informatik/hostage/protocol/SSH.java

@@ -305,7 +305,7 @@ public class SSH implements Protocol {
 		try {
 			TypesReader tr = new TypesReader(request, 6);
 			userName = tr.readString();
-			terminalPrefix = "[" + userName + "@" + serverName + "]$";
+			terminalPrefix = "[" + userName + "@" + serverName + " ~]$ ";
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
@@ -448,7 +448,7 @@ public class SSH implements Protocol {
 		if (request[5] != 0x14) {
 			position = 1;
 			for (int i = 0; i < request.length; i++, position++) {
-				if (request[i] == 0xa)
+				if (request[i] == 0x0a)
 					break;
 			}
 		}
@@ -583,24 +583,24 @@ public class SSH implements Protocol {
 	 */
 	private Packet terminalReply(byte[] request) {
 		TypesReader tr = new TypesReader(request, 6);
-		String messsage = "";
+		String message = "";
 		try {
 			tr.readUINT32();
-			messsage = tr.readString();
-			if (messsage.contains("\r")) {
+			message = tr.readString();
+			if (message.contains("\r")) {
 				if (command.toString().contains("exit")) {
 					state = STATE.CLOSED; // ugly style
 					return disconnectReply(2);
 				}
-				messsage = "\r\nbash: " + command + " :command not found\r\n"
+				message = "\r\nbash: " + command + " :command not found\r\n"
 						+ terminalPrefix;
 				command = new StringBuffer();
-			} else if (messsage.contains(new String(new char[] { '\u007F' }))
+			} else if (message.contains(new String(new char[] { '\u007F' }))
 					&& command.length() > 0) {
 				command = command
 						.delete(command.length() - 1, command.length());
 			} else {
-				command.append(messsage);
+				command.append(message);
 			}
 		} catch (IOException e) {
 			e.printStackTrace();
@@ -608,7 +608,7 @@ public class SSH implements Protocol {
 		TypesWriter tw = new TypesWriter();
 		tw.writeByte(0x5e); // msgcode
 		tw.writeUINT32(recipientChannel);
-		tw.writeString(messsage);
+		tw.writeString(message);
 		return wrapPacket(tw.getBytes());
 	}
 

+ 14 - 66
src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NBDS.java

@@ -17,24 +17,27 @@ public class NBDS {
 	private byte[] srcName;
 	private byte[] dstName;
 	private SMBPacket smb;
-	private SMBMailSlot smbMailSlot;
-	private MicrosoftWindowsBrowser microsoftWindowsBrowser;
 	
-	public NBDS(byte[] transactID, byte[] ip, byte[] addr, String src, String dst) {
-		type = new byte[]{0x11};
+	public NBDS(byte[] transactID, byte[] addr, String src, String dst, int nbdstype) {
+		this.type = new byte[]{0x11};
 		flags = new byte[]{0x0a};
 		id = transactID;
 		srcIP = addr;
 		srcPort = new byte[]{0x00, (byte) 0x8a};
 		offset = new byte[]{0x00, 0x00};
 		length = new byte[2];
-		srcName = NMBStringCoder.wrapNBNSName(NMBStringCoder.encodeNBNSName(src.getBytes()), Service.WORKSTATION);
-		dstName = NMBStringCoder.wrapNBNSName(NMBStringCoder.encodeNBNSName(dst.getBytes()), Service.LOCAL_MASTER_BROWSER);
+		srcName = NMBStringCoder.wrapNBNSName(NMBStringCoder.encodeNBNSName(src.getBytes()), NBNSService.WORKSTATION);
+		if (nbdstype == NBDSType.REQUEST_ANNOUNCEMENT || nbdstype == NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL) {
+			dstName = NMBStringCoder.wrapNBNSName(NMBStringCoder.encodeNBNSName(dst.getBytes()), NBNSService.BROWSER_ELECTION);
+		} else if (nbdstype == NBDSType.DOMAIN_ANNOUNCEMENT) {
+			dstName = HelperUtils.concat(new byte[]{0x20, 0x41, 0x42, 0x41, 0x43}, NMBStringCoder.encodeNBNSName("__MSBROWSE__".getBytes()),
+					new byte[]{0x41, 0x43, 0x41, 0x42, 0x00});
+		} else {
+			dstName = NMBStringCoder.wrapNBNSName(NMBStringCoder.encodeNBNSName(dst.getBytes()), NBNSService.LOCAL_MASTER_BROWSER);
+		}
 		smb = new SMBPacket(null);
-		smb.prepareNextResponse();
-		smbMailSlot = new SMBMailSlot();
-		microsoftWindowsBrowser = new MicrosoftWindowsBrowser(src);
-		byte[] buffer = HelperUtils.concat(srcName, dstName, smb.getTrans(), smbMailSlot.getBytes(), microsoftWindowsBrowser.getBytes());
+		smb.prepareNextResponse(nbdstype, src, dst);
+		byte[] buffer = HelperUtils.concat(srcName, dstName, smb.getTrans());
 		byte[] lengthBuffer = ByteBuffer.allocate(4).putInt(buffer.length).array();
 		length[0] = lengthBuffer[2];
 		length[1] = lengthBuffer[3];
@@ -42,62 +45,7 @@ public class NBDS {
 	
 	public byte[] getBytes() {
 		return HelperUtils.concat(type, flags, id, srcIP, srcPort, length,
-				offset, srcName, dstName, smb.getTrans(), smbMailSlot.getBytes(), microsoftWindowsBrowser.getBytes());
+				offset, srcName, dstName, smb.getTrans());
 	}
 
-	private class SMBMailSlot {
-		private byte[] opcode;
-		private byte[] priority;
-		private byte[] smbclass;
-		private byte[] size;
-		private byte[] name;
-		
-		public SMBMailSlot() {
-			opcode = new byte[]{0x01, 0x00};
-			priority = new byte[]{0x01, 0x00};
-			smbclass = new byte[]{0x02, 0x00};
-			size = new byte[]{0x3e, 0x00};
-			name = HelperUtils.concat("\\MAILSLOT\\BROWSE".getBytes(), new byte[]{0x00}); 
-		}
-		
-		public byte[] getBytes() {
-			return HelperUtils.concat(opcode, priority, smbclass, size, name);
-		}
-	}
-	
-	private class MicrosoftWindowsBrowser {
-		private byte[] command;
-		private byte[] updateCount;
-		private byte[] updatePeriodicity;
-		private byte[] hostName;
-		private byte[] osMajorVersion;
-		private byte[] osMinorVersion;
-		private byte[] serverType;
-		private byte[] browserProtocolMajorVer;
-		private byte[] browserProtocolMinorVer;
-		private byte[] signature;
-		private byte[] hostComment;
-		
-		public MicrosoftWindowsBrowser(String name) {
-			command = new byte[]{0x01};
-			updateCount = new byte[]{0x00};
-			updatePeriodicity = new byte[]{0x60, (byte) 0xea, 0x00, 0x00};
-			hostName = HelperUtils.concat(name.getBytes(),
-					new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
-			osMajorVersion = new byte[]{0x04};
-			osMinorVersion = new byte[]{0x09};
-			serverType = new byte[]{0x03, (byte) 0x9a, (byte) 0x81, 0x00};
-			browserProtocolMajorVer = new byte[]{0x0f};
-			browserProtocolMinorVer = new byte[]{0x01};
-			signature = new byte[]{0x55, (byte) 0xaa};
-			hostComment = HelperUtils.concat("Samba Server".getBytes(), new byte[]{0x00});
-		}
-		
-		public byte[] getBytes() {
-			return HelperUtils.concat(command, updateCount, updatePeriodicity,
-					hostName, osMajorVersion, osMinorVersion, serverType,
-					browserProtocolMajorVer, browserProtocolMinorVer,
-					signature, hostComment);
-		}
-	}
 }

+ 12 - 0
src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NBDSType.java

@@ -0,0 +1,12 @@
+package de.tudarmstadt.informatik.hostage.protocol.smbutils;
+
+public class NBDSType {
+	
+	public static final int HOST_ANNOUNCEMENT = 0;
+	public static final int HOST_ANNOUNCEMENT_WITH_SERVICES = 1;
+	public static final int BROWSER = 2;
+	public static final int REQUEST_ANNOUNCEMENT = 3;
+	public static final int LOCAL_MASTER_ANNOUNCEMENT_ALL = 4;
+	public static final int DOMAIN_ANNOUNCEMENT = 5;
+	public static final int LOCAL_MASTER_ANNOUNCEMENT = 6;
+}

+ 24 - 10
src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NBNS.java

@@ -58,15 +58,18 @@ public class NBNS {
 	
 	private void preparePacket() {
 		switch (type) {
-		case Type.REGISTRATION_UNIQUE:
+		case NBNSType.REGISTRATION_UNIQUE:
 			prepareRegistrationPacket();
 			break;
-		case Type.REGISTRATION_GROUP:
+		case NBNSType.REGISTRATION_GROUP:
 			prepareRegistrationPacket();
 			break;
-		case Type.NAME_QUERY:
+		case NBNSType.NAME_QUERY:
 			prepareNameQueryPacket();
 			break;
+		case NBNSType.REGISTRATION_MSBROWSE:
+			prepareRegistrationMsBrowse();
+			break;
 		default:
 		}
 	}
@@ -90,6 +93,17 @@ public class NBNS {
 		payload = getPayload();
 	}
 	
+	private void prepareRegistrationMsBrowse() {
+		flags = new byte[]{0x29, 0x10};
+		questions = new byte[]{0x00, 0x01};
+		answerRRs = new byte[]{0x00, 0x00};
+		authorityRRs = new byte[]{0x00, 0x00};
+		additionalRRs = new byte[]{0x00, 0x01};
+		payload = HelperUtils.concat(new byte[]{0x20, 0x41, 0x42, 0x41, 0x43}, name,
+				new byte[]{0x41, 0x43, 0x41, 0x42, 0x00, 0x00, 0x20, 0x00, 0x01});
+		additional = getAdditionalRecords();
+	}
+	
 	private byte[] getPayload() {
 		byte[] payload = NMBStringCoder.wrapNBNSName(this.name, service);
 		byte[] type = {0x00, 0x20};
@@ -108,15 +122,15 @@ public class NBNS {
 	
 	public static byte[] getServiceBytes(int service) {
 		switch (service) {
-		case Service.SERVER:
+		case NBNSService.SERVER:
 			return new byte[]{0x43, 0x41};
-		case Service.MESSENGER:
+		case NBNSService.MESSENGER:
 			return new byte[]{0x41, 0x44};
-		case Service.WORKSTATION:
+		case NBNSService.WORKSTATION:
 			return new byte[]{0x41, 0x41};
-		case Service.BROWSER_ELECTION:
+		case NBNSService.BROWSER_ELECTION:
 			return new byte[]{0x42, 0x4f};
-		case Service.LOCAL_MASTER_BROWSER:
+		case NBNSService.LOCAL_MASTER_BROWSER:
 			return new byte[]{0x42, 0x4e};
 		default:
 			return new byte[]{0x43, 0x41};
@@ -128,7 +142,7 @@ public class NBNS {
 		byte[] type = {0x00, 0x20};
 		byte[] nbnsclass = {0x00, 0x01};
 		byte[] timeToLive = {0x00, 0x00, 0x00, 0x00};
-		byte[] nameFlags = ((this.type == Type.REGISTRATION_UNIQUE) ? new byte[]{0x00, 0x00} : new byte[]{0x08, 0x00});
+		byte[] nameFlags = ((this.type == NBNSType.REGISTRATION_UNIQUE) ? new byte[]{0x00, 0x00} : new byte[]{(byte) 0x80, 0x00});
 		byte[] buffer = ByteBuffer.allocate(4).putInt(nameFlags.length + addr.length).array();
 		byte[] length = {buffer[2], buffer[3]};
 		return HelperUtils.concat(name, type, nbnsclass, timeToLive, length, nameFlags, addr);
@@ -157,7 +171,7 @@ public class NBNS {
 		this.service = service;
 	}
 
-	public byte[] getAndIncrementTransactID() {
+	public byte[] getAndIncTransactID() {
 		byte[] response = new byte[2];
 		response[0] = transactID[0];
 		response[1] = transactID[1];

+ 2 - 1
src/de/tudarmstadt/informatik/hostage/protocol/smbutils/Service.java → src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NBNSService.java

@@ -1,9 +1,10 @@
 package de.tudarmstadt.informatik.hostage.protocol.smbutils;
 
-public class Service {
+public class NBNSService {
 	public static final int SERVER = 0;
 	public static final int MESSENGER = 1;
 	public static final int WORKSTATION = 2;
 	public static final int BROWSER_ELECTION = 3;
 	public static final int LOCAL_MASTER_BROWSER = 4;
+	public static final int BROWSER = 5;
 }

+ 2 - 1
src/de/tudarmstadt/informatik/hostage/protocol/smbutils/Type.java → src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NBNSType.java

@@ -1,7 +1,8 @@
 package de.tudarmstadt.informatik.hostage.protocol.smbutils;
 
-public class Type {
+public class NBNSType {
 	public static final int REGISTRATION_UNIQUE = 0;
 	public static final int REGISTRATION_GROUP = 1;
 	public static final int NAME_QUERY = 2;
+	public static final int REGISTRATION_MSBROWSE = 3;
 }

+ 154 - 19
src/de/tudarmstadt/informatik/hostage/protocol/smbutils/NMB.java

@@ -4,6 +4,7 @@ import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
+import java.net.SocketTimeoutException;
 import java.net.UnknownHostException;
 
 import de.tudarmstadt.informatik.hostage.net.MyDatagramSocketFactory;
@@ -20,23 +21,22 @@ public class NMB extends Thread {
 	private int nbdsPort = 138;
 	private String username;
 	private String workgroup;
+	private NBNS nbns;
+	private NBDS nbds;
+	private volatile boolean smbRunning;
+	private Receiver receiver;
 	
 	public NMB(String ip, String username, String workgroup) {
 		try {
+			smbRunning = true;
 			this.username = username;
 			this.workgroup = workgroup;
 			this.ip = ip;
 			ipParts = ip.split("\\.");
 			String newHostAddr = ipParts[0] + "." + ipParts[1] + "." + ipParts[2] + ".255";
 			dst = InetAddress.getByName(newHostAddr);
-			nbnsSocket = new MyDatagramSocketFactory().createDatagramSocket(nbnsPort);
-			nbnsSocket.connect(dst, nbnsPort);
-			nbdsSocket = new MyDatagramSocketFactory().createDatagramSocket(nbdsPort);
-			nbnsSocket.connect(dst, nbdsPort);
 		} catch (UnknownHostException e) {
 			e.printStackTrace();
-		} catch (IOException e) {
-			e.printStackTrace();
 		}
 	}
 	
@@ -54,41 +54,176 @@ public class NMB extends Thread {
 		try {
 			byte[] packetBytes = nbds.getBytes();
 			packet = new DatagramPacket(packetBytes, packetBytes.length, dst, nbdsPort);
-			nbnsSocket.send(packet);
+			nbdsSocket.send(packet);
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
 	}
 	
 	private void registrate() {
-		NBNS nbns = new NBNS(new byte[]{0x50, 0x00}, Type.REGISTRATION_UNIQUE, Service.SERVER, username, ip);
+		registrateUser();
+		registrateGroup();
+	}
+	
+	private void registrateUser() {
+		nbns = new NBNS(new byte[]{0x50, 0x00}, NBNSType.REGISTRATION_UNIQUE, NBNSService.SERVER, username, ip);
 		sendPacket(nbns);
 		
-		nbns.setService(Service.MESSENGER);
+		nbns.setService(NBNSService.MESSENGER);
 		sendPacket(nbns);
 				
-		nbns.setService(Service.WORKSTATION);
+		nbns.setService(NBNSService.WORKSTATION);
 		sendPacket(nbns);
-			
+	}
+	
+	private void registrateGroup() {
 		nbns.setName(workgroup);
-		nbns.setType(Type.REGISTRATION_GROUP);
+		nbns.setType(NBNSType.REGISTRATION_GROUP);
 		sendPacket(nbns);
 		
-		nbns.setService(Service.BROWSER_ELECTION);
+		nbns.setService(NBNSService.BROWSER_ELECTION);
 		sendPacket(nbns);
-		
-		NBDS nbds = new NBDS(new byte[]{0x50, 0x06}, nbns.getAndIncrementTransactID(), nbns.getAddr(), username, workgroup);
+	}
+	
+	private void browserElection() {
+		nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.BROWSER);
 		sendPacket(nbds);
-		
-		nbns.setType(Type.NAME_QUERY);
-		nbns.setService(Service.LOCAL_MASTER_BROWSER);
+	}
+	
+	private void registrateMsBrowse() {
+		nbns.setName("__MSBROWSE__");
+		nbns.setType(NBNSType.REGISTRATION_MSBROWSE);
+		nbns.setService(NBNSService.BROWSER);
+		sendPacket(nbns);
+	}
+	
+	private void registrateLocalMaster() {
+		nbns.setName(workgroup);
+		nbns.setType(NBNSType.REGISTRATION_UNIQUE);
+		nbns.setService(NBNSService.LOCAL_MASTER_BROWSER);
+		sendPacket(nbns);
+	}
+	
+	private void announceHost() {
+		nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.HOST_ANNOUNCEMENT_WITH_SERVICES);
+		sendPacket(nbds);
+	}
+	
+	private void queryName() {
+		nbns.setType(NBNSType.NAME_QUERY);
+		nbns.setService(NBNSService.LOCAL_MASTER_BROWSER);
 		sendPacket(nbns);
 	}
+	
+	private void requestAnnouncement() {
+		nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.REQUEST_ANNOUNCEMENT);
+		sendPacket(nbds);
+	}
+	
+	private void localMasterAnnouncementAll() {
+		nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL);
+		sendPacket(nbds);
+	}
+	
+	private void domainAnnouncement() {
+		nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.DOMAIN_ANNOUNCEMENT);
+		sendPacket(nbds);
+	}
+	
+	private void localMasterAnnouncement() {
+		nbds = new NBDS(nbns.getAndIncTransactID(), nbns.getAddr(), username, workgroup, NBDSType.LOCAL_MASTER_ANNOUNCEMENT);
+		sendPacket(nbds);
+	}
 
-	public void run() {
+	@Override
+	public void run() {		
+		try {
+			nbnsSocket = new MyDatagramSocketFactory().createDatagramSocket(nbnsPort);
+			nbnsSocket.connect(dst, nbnsPort);
+			nbdsSocket = new MyDatagramSocketFactory().createDatagramSocket(nbdsPort);
+			nbdsSocket.connect(dst, nbdsPort);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		
+		registrate();
+		receiver = new Receiver();
+		receiver.start();
+		announceHost();
+		queryName();
+		
+		registrate();
+		queryName();
+		
+		registrate();
+		queryName();
+		
 		registrate();
+		queryName();	
+		
+		browserElection();
+		browserElection();
+		browserElection();
+		browserElection();
+		
+		registrateMsBrowse();
+		registrateMsBrowse();
+		registrateMsBrowse();
+		registrateMsBrowse();
+		
+		registrateLocalMaster();
+		registrateLocalMaster();
+		registrateLocalMaster();
+		registrateLocalMaster();
+		
+		requestAnnouncement();
+		localMasterAnnouncementAll();
+		domainAnnouncement();
+		
+//		// domain/workgroup announcement
+//		// local master announcmen
+		
+		announceHost();	
+		
 		nbnsSocket.close();
 		nbdsSocket.close();
 	}
+
+	public synchronized void setSmbRunning(boolean smbRunning) {
+		this.smbRunning = smbRunning;
+	}
+	
+	private class Receiver extends Thread {
+		
+		private DatagramPacket packet;
+		private byte[] buffer;
+		private boolean masterAnswered = false;
+		
+		public Receiver() {
+			buffer = new byte[2048];
+			packet = new DatagramPacket(buffer, buffer.length);
+		}
+		
+		@Override
+		public void run() {
+			try {
+				nbnsSocket.setSoTimeout(1000);
+				try {
+					while (!masterAnswered) {
+						nbnsSocket.receive(packet);
+						if (!(packet.getAddress().toString().equals("/"+ip))) {
+							masterAnswered = true;
+							setSmbRunning(false);
+						}
+					}
+				} catch (SocketTimeoutException e) {
+					setSmbRunning(false);
+					e.printStackTrace();
+				}	
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
 	
 }

+ 107 - 6
src/de/tudarmstadt/informatik/hostage/protocol/smbutils/SMBPacket.java

@@ -5,6 +5,8 @@ import java.util.Calendar;
 import java.util.GregorianCalendar;
 import java.util.TimeZone;
 
+import javax.net.ssl.HostnameVerifier;
+
 import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 
 /**
@@ -15,7 +17,7 @@ import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 public class SMBPacket {
 	
 	private String[] serverVersion;
-	private byte[] serverName = HelperUtils.fillWithZero(HelperUtils
+	private static byte[] serverName = HelperUtils.fillWithZero(HelperUtils
 			.getRandomString(16, true).getBytes());
 	private byte[] message = null;
 	private static final byte[] serverGUID = HelperUtils.randomBytes(16);
@@ -35,11 +37,15 @@ public class SMBPacket {
 	private byte[] userID = new byte[2];
 	private byte[] multiplexID = new byte[2];
 	
+	//special nbds stuff
+	private byte[] workgroup;
+	private int type;
+	
 	public SMBPacket(String[] serverVersion) {
 		this.serverVersion = serverVersion;
 	}
 	
-	public void prepareNextResponse() {
+	public void prepareNextResponse(int type, String serverName, String workgroup) {
 		serverComp = new byte[] { (byte) 0xff, 0x53, 0x4d, 0x42 };
 		smbCommand = new byte[] { 0x25 };
 		ntStat = new byte[] { 0x00, 0x00, 0x00, 0x00 };
@@ -53,6 +59,9 @@ public class SMBPacket {
 		processID = new byte[] { 0x00, 0x00 };
 		userID = new byte[] { 0x00, 0x00 };
 		multiplexID = new byte[] { 0x00, 0x00 };
+		this.workgroup = workgroup.getBytes();
+		this.type = type;
+		SMBPacket.serverName = serverName.getBytes();
 	}
 	
 	public void prepareNextResponse(byte[] message) {
@@ -438,10 +447,9 @@ public class SMBPacket {
 		byte[] response = null;
 		
 		if (transSub[0] == (byte) 0xff) { // for NMB in host announcement, NOT smb protocol
-			System.out.println("Hi");
 			byte[] wordCount = { 0x11 };
 			byte[] totalParamCount = { 0x00, 0x00 };
-			byte[] totalDataCount = { 0x2d, 0x00 };
+			byte[] totalDataCount = new byte[2]; //TODO
 			byte[] maxParamCount = { 0x00, 0x00 };
 			byte[] maxDataCount = { 0x00, 0x00 };
 			byte[] maxSetupCount = { 0x00 };
@@ -451,14 +459,46 @@ public class SMBPacket {
 			byte[] reserved2 = { 0x00, 0x00 };
 			byte[] paramCount = { 0x00, 0x00 };
 			byte[] paramOffset = { 0x00, 0x00 };
-			byte[] dataCount = { 0x2d, 0x00 };
+			byte[] dataCount = new byte[2]; //TODO
 			byte[] dataOffset = { 0x56, 0x00 };
 			byte[] setupCount = { 0x03 };
 			byte[] reserved3 = { 0x00 };
+			
+			//SMB MailSlot				
+			byte[] opcode = new byte[]{0x01, 0x00};
+			byte[] priority = new byte[]{0x01, 0x00};
+			byte[] smbclass = new byte[]{0x02, 0x00};
+			byte[] size = new byte[2]; //TODO
+			byte[] name = HelperUtils.concat("\\MAILSLOT\\BROWSE".getBytes(), new byte[]{0x00}); 
+			
+			byte[] windowsBrowser = null;
+			if (type == NBDSType.HOST_ANNOUNCEMENT_WITH_SERVICES || type == NBDSType.HOST_ANNOUNCEMENT
+					|| type == NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL || type == NBDSType.DOMAIN_ANNOUNCEMENT) {
+				windowsBrowser = getAnnouncement();
+			} else if (type == NBDSType.BROWSER) {
+				windowsBrowser = getBrowser();
+			} else if (type == NBDSType.REQUEST_ANNOUNCEMENT) {
+				byte[] command = {0x02};
+				byte[] unusedFlags = {0x01, 0x00};
+				byte[] responseCompName = serverName;
+				windowsBrowser = HelperUtils.concat(command, unusedFlags, responseCompName);
+			}
+
+			byte[] buffer = ByteBuffer.allocate(4).putInt(windowsBrowser.length).array();
+			totalDataCount[0] = buffer[3];
+			totalDataCount[1] = buffer[2];
+			dataCount = totalDataCount;
+			
+			buffer = ByteBuffer.allocate(4).putInt(name.length + windowsBrowser.length).array();
+			size[0] = buffer[3];
+			size[1] = buffer[2];
+			byte[] smbMailSlot = HelperUtils.concat(opcode, priority, smbclass, size, name);					
+
 			// no netbios header required for NMB!!
 			return wrapHeader(HelperUtils.concat(wordCount, totalParamCount, totalDataCount,
 					maxParamCount, maxDataCount, maxSetupCount, reserved, flags, timeout, reserved2,
-					paramCount, paramOffset, dataCount, dataOffset, setupCount, reserved3));
+					paramCount, paramOffset, dataCount, dataOffset, setupCount, reserved3, smbMailSlot,
+					windowsBrowser));
 		} else if (transSub[0] == 0x00 && transSub[1] == 0x0b) { // bind_ack
 			byte[] wordCount = { 0x0a };
 			byte[] totalParamCount = { 0x00, 0x00 };
@@ -588,6 +628,67 @@ public class SMBPacket {
 			transSub = new byte[] { 0x00, 0x00 };
 		return transSub;
 	}
+	
+	private byte[] getAnnouncement() {
+		//Microsoft Windows Browser
+		byte[] command = null;
+		if(type == NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL) {
+			command = new byte[]{0x0f};
+		} else if (type == NBDSType.DOMAIN_ANNOUNCEMENT) {
+			command = new byte[]{0x0c};
+		} else {
+			command = new byte[]{0x01};
+		}
+		byte[] updateCount = new byte[]{0x00};
+		byte[] updatePeriodicity = null;
+		if (type == NBDSType.HOST_ANNOUNCEMENT_WITH_SERVICES) {
+			updatePeriodicity = new byte[]{0x60, (byte) 0xea, 0x00, 0x00};
+		} else if (type == NBDSType.HOST_ANNOUNCEMENT) {
+			updatePeriodicity = new byte[]{0x00, 0x00, 0x00, 0x00};
+		} else if (type == NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL || type == NBDSType.DOMAIN_ANNOUNCEMENT) {
+			updatePeriodicity = new byte[]{(byte) 0xc0, (byte) 0xd4, 0x01, 0x00};
+		}
+		byte[] hostName = null;
+		if (type == NBDSType.DOMAIN_ANNOUNCEMENT) {
+			hostName = workgroup;
+		} else {
+			hostName = serverName;
+		}
+		for (int i = hostName.length; i < 16; i++) {
+			hostName = HelperUtils.concat(hostName, new byte[]{0x00});
+		}
+		byte[] osMajorVersion = new byte[]{0x04};
+		byte[] osMinorVersion = new byte[]{0x09};
+		byte[] serverType = null;
+		if (type == NBDSType.HOST_ANNOUNCEMENT_WITH_SERVICES || type == NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL) {
+			serverType = new byte[]{0x03, (byte) 0x9a, (byte) 0x81, 0x00};
+		} else if (type == NBDSType.HOST_ANNOUNCEMENT) {
+			serverType = new byte[]{0x00, 0x00, 0x00, 0x00};
+		} else if (type == NBDSType.DOMAIN_ANNOUNCEMENT) {
+			serverType = new byte[]{0x00, 0x10, 0x00, (byte) 0x80};
+		}
+		byte[] browserProtocolMajorVer = new byte[]{0x0f};
+		byte[] browserProtocolMinorVer = new byte[]{0x01};
+		byte[] signature = new byte[]{0x55, (byte) 0xaa};
+		byte[] hostComment = null;
+		if (type == NBDSType.DOMAIN_ANNOUNCEMENT) {
+			hostComment = HelperUtils.concat(serverName, new byte[]{0x00});
+		} else {
+			hostComment = HelperUtils.concat("".getBytes(), new byte[]{0x00});
+		}
+		
+		return HelperUtils.concat(command, updateCount, updatePeriodicity, hostName,
+				osMajorVersion, osMinorVersion, serverType, browserProtocolMajorVer, browserProtocolMinorVer,
+				signature, hostComment);
+	}
+	
+	private byte[] getBrowser() {
+		byte[] command = {0x08};
+		byte[] electionVersion = {0x01};
+		byte[] electionCriteria = {0x02, 0x0f, 0x01, 0x14};
+		byte[] uptime = {(byte) 0xb0, 0x36, 0x00, 0x00, 0x00, 0x00,0x00, 0x00};
+		return HelperUtils.concat(command, electionVersion, electionCriteria, uptime, serverName, new byte[]{0x00});
+	}
 
 	/**
 	 * Builds the tree connect packet