All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.filesys.netbios.NetBIOSPacket Maven / Gradle / Ivy

Go to download

Java file server with SMB, FTP/FTPS and NFS support, virtual filesystems, database filesystems

There is a newer version: 1.4.0
Show newest version
/*
 * Copyright (C) 2006-2010 Alfresco Software Limited.
 *
 * This file is part of Alfresco
 *
 * Alfresco is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Alfresco is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Alfresco. If not, see .
 */

package org.filesys.netbios;

import org.filesys.debug.Debug;
import org.filesys.util.DataPacker;
import org.filesys.util.HexDump;

/**
 * NetBIOS Packet Class
 *
 * 

* A NetBIOSPacket holds a single NetBIOS request or response. Contains methods for building the * main NetBIOS request types (add name, delete name, name query, refresh and session setup). * * @author gkspencer */ public class NetBIOSPacket { // Minimum valid receive length public static final int MIN_RXLEN = 4; // NetBIOS opcodes public static final int NAME_QUERY = 0x00; public static final int NAME_REGISTER = 0x05; public static final int NAME_RELEASE = 0x06; public static final int WACK = 0x07; public static final int REFRESH = 0x08; public static final int NAME_REGISTER_MULTI = 0x0F; public static final int RESP_QUERY = 0x10; public static final int RESP_REGISTER = 0x15; public static final int RESP_RELEASE = 0x16; // NetBIOS opcode masks public static final int MASK_OPCODE = 0xF800; public static final int MASK_NMFLAGS = 0x07F0; public static final int MASK_RCODE = 0x000F; public static final int MASK_NOOPCODE = 0x07FF; public static final int MASK_NOFLAGS = 0xF80F; public static final int MASK_NORCODE = 0xFFF0; public static final int MASK_RESPONSE = 0x0010; // Flags bit values public static final int FLG_BROADCAST = 0x0001; public static final int FLG_RECURSION = 0x0008; public static final int FLG_RECURSDES = 0x0010; public static final int FLG_TRUNCATION = 0x0020; public static final int FLG_AUTHANSWER = 0x0040; // NetBIOS name lookup types public static final int NAME_TYPE_NB = 0x0020; public static final int NAME_TYPE_NBSTAT = 0x0021; // RFC NetBIOS encoded name length public static final int NAME_LEN = 32; // NetBIOS name classes public static final int NAME_CLASS_IN = 0x0001; // Bit shifts for opcode/flags values private static final int SHIFT_FLAGS = 4; private static final int SHIFT_OPCODE = 11; // Default NetBIOS buffer size to allocate public static final int DEFAULT_BUFSIZE = 1024; // NetBIOS packet offsets private static final int NB_TRANSID = 0; private static final int NB_OPCODE = 2; private static final int NB_QDCOUNT = 4; private static final int NB_ANCOUNT = 6; private static final int NB_NSCOUNT = 8; private static final int NB_ARCOUNT = 10; private static final int NB_DATA = 12; // NetBIOS name registration error reponse codes (RCODE field) public static final int FMT_ERR = 0x01; public static final int SRV_ERR = 0x02; public static final int IMP_ERR = 0x04; public static final int RFS_ERR = 0x05; public static final int ACT_ERR = 0x06; public static final int CFT_ERR = 0x07; // Name flags public static final int NAME_PERM = 0x0200; public static final int NAME_ACTIVE = 0x0400; public static final int NAME_CONFLICT = 0x0800; public static final int NAME_DEREG = 0x1000; public static final int NAME_GROUP = 0x8000; public static final int NAME_TYPE_BNODE = 0x0000; public static final int NAME_TYPE_PNODE = 0x2000; public static final int NAME_TYPE_MNODE = 0x4000; public static final int NAME_TYPE_RESVD = 0x6000; // Adapter status name in encoded format private static final String AdapterStatusNBName = "CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; // NetBIOS packet buffer private byte[] m_nbbuf; // Actual used packet length private int m_datalen; /** * Default constructor */ public NetBIOSPacket() { m_nbbuf = new byte[DEFAULT_BUFSIZE]; m_datalen = NB_DATA; } /** * Create a NetBIOS packet with the specified buffer. * * @param buf byte[] */ public NetBIOSPacket(byte[] buf) { m_nbbuf = buf; m_datalen = NB_DATA; } /** * Create a NetBIOS packet with the specified buffer size. * * @param siz int */ public NetBIOSPacket(int siz) { m_nbbuf = new byte[siz]; m_datalen = NB_DATA; } /** * Dump the packet structure to the console. * * @param sessPkt True if this is a NetBIOS session packet, else false. */ public void DumpPacket(boolean sessPkt) { // Display the transaction id Debug.println("NetBIOS Packet Dump :-"); // Determine the packet type if (sessPkt == true) { switch (getPacketType()) { // NetBIOS session request case REQUEST: StringBuffer name = new StringBuffer(); for (int i = 0; i < 32; i++) name.append((char) m_nbbuf[39 + i]); Debug.println("Session request from " + NetBIOSSession.DecodeName(name.toString())); break; // NetBIOS message case MESSAGE: break; } } else { // Display the packet type Debug.println(" Transaction Id : " + getTransactionId()); Debug.print(" Opcode : "); switch (getOpcode()) { case NAME_QUERY: Debug.println("QUERY"); break; case RESP_QUERY: Debug.println("QUERY (Response)"); break; case NAME_REGISTER: Debug.println("NAME REGISTER"); break; case RESP_REGISTER: Debug.println("NAME REGISTER (Response)"); break; case NAME_RELEASE: Debug.println("NAME RELEASE"); break; case RESP_RELEASE: Debug.println("NAME RELEASE (Response)"); break; case WACK: Debug.println("WACK"); break; case REFRESH: Debug.println("REFRESH"); break; default: Debug.println(Integer.toHexString(getOpcode())); break; } // Display the flags Debug.println(" Flags : " + Integer.toHexString(getFlags())); // Display the name counts Debug.println(" QDCount : " + getQuestionCount()); Debug.println(" ANCount : " + getAnswerCount()); Debug.println(" NSCount : " + getNameServiceCount()); Debug.println(" ARCount : " + getAdditionalCount()); // Dump the question name, if there is one if (getQuestionCount() > 0) { Debug.print(" QName : "); // Get the encoded name string StringBuffer encName = new StringBuffer(); for (int i = 1; i <= 32; i++) encName.append((char) m_nbbuf[NB_DATA + i]); // Decode the name String name = NetBIOSSession.DecodeName(encName.toString()); Debug.println(name + " <" + NetBIOSName.TypeAsString(name.charAt(15)) + ">"); } } // Dump the raw data Debug.println("********** Raw NetBIOS Data Dump **********"); HexDump.Dump(getBuffer(), getLength(), 0); } /** * Get the additional byte count. * * @return int */ public final int getAdditionalCount() { return DataPacker.getShort(m_nbbuf, NB_ARCOUNT); } /** * Get the answer name details * * @return String */ public final String getAnswerName() { // Pack the encoded name into the NetBIOS packet return NetBIOSSession.DecodeName(m_nbbuf, NB_DATA + 1); } /** * Get the answer count. * * @return int */ public final int getAnswerCount() { return DataPacker.getShort(m_nbbuf, NB_ANCOUNT); } /** * Get the answer name list * * @return NetBIOSNameList */ public final NetBIOSNameList getAnswerNameList() { // Check if there are any answer names int cnt = getAnswerCount(); if (cnt == 0) return null; NetBIOSNameList nameList = new NetBIOSNameList(); int pos = NB_DATA; while (cnt-- > 0) { // Get a NetBIOS name from the buffer int nameLen = NetBIOSName.decodeNetBIOSNameLength(m_nbbuf, pos); NetBIOSName name = NetBIOSName.decodeNetBIOSName(m_nbbuf, pos); // Skip the type, class and TTL pos += nameLen; pos += 8; // Get the count of data bytes int dataCnt = DataPacker.getShort(m_nbbuf, pos); pos += 2; while (dataCnt > 0) { // Get the flags, check if the name is a unique or group name int flags = DataPacker.getShort(m_nbbuf, pos); pos += 2; if ((flags & NAME_GROUP) != 0) name.setGroup(true); // Get the IP address and add to the list of addresses for the current name byte[] ipaddr = new byte[4]; for (int i = 0; i < 4; i++) ipaddr[i] = m_nbbuf[pos++]; name.addIPAddress(ipaddr); // Update the data count dataCnt -= 6; } // Add the name to the name list nameList.addName(name); } // Set the MAC address of the server setMACAddress(nameList, pos); // Return the name list return nameList; } /** * Get the answer name list from an adapter status reply * * @return NetBIOSNameList */ public final NetBIOSNameList getAdapterStatusNameList() { // Check if there are any answer names int cnt = getAnswerCount(); if (cnt == 0) return null; NetBIOSNameList nameList = new NetBIOSNameList(); int pos = NB_DATA; // Skip the initial name int nameLen = (int) (m_nbbuf[pos++] & 0xFF); pos += nameLen; pos = DataPacker.wordAlign(pos); pos += 8; // Get the count of data bytes and name count int dataCnt = DataPacker.getShort(m_nbbuf, pos); pos += 2; int nameCnt = (int) (m_nbbuf[pos++] & 0xFF); while (nameCnt > 0 && dataCnt > 0) { // Check that there is enough buffer space for the next name record if ((pos + 18) > m_nbbuf.length) throw new ArrayIndexOutOfBoundsException("NetBIOS packet length " + m_nbbuf.length); // Get the NetBIOS name/type NetBIOSName nbName = new NetBIOSName(m_nbbuf, pos); pos += 16; // Get the name type flags, check if this is a unique or group name int typ = DataPacker.getShort(m_nbbuf, pos); pos += 2; if ((typ & NAME_GROUP) != 0) nbName.setGroup(true); // Add the name to the list nameList.addName(nbName); // Update the data count and name count dataCnt -= 18; nameCnt--; } // Set the MAC address of the server setMACAddress(nameList, pos); // Return the name list return nameList; } /** * Set the MAC address of the server * * @param nameList NetBIOSNameList * @param pos int */ private void setMACAddress(NetBIOSNameList nameList, int pos) { if ((pos + 6) > m_nbbuf.length) return; byte[] mac = new byte[6]; System.arraycopy(m_nbbuf, pos, mac, 0, 6); nameList.setMACAddress(mac); } /** * Return the NetBIOS buffer. * * @return byte[] */ public final byte[] getBuffer() { return m_nbbuf; } /** * Get the flags from the received NetBIOS packet. * * @return int */ public final int getFlags() { int flags = DataPacker.getShort(m_nbbuf, NB_QDCOUNT) & MASK_NMFLAGS; flags = flags >> SHIFT_FLAGS; return flags; } /** * Return the NetBIOS header flags value. * * @return int */ public final int getHeaderFlags() { return m_nbbuf[1] & 0x00FF; } /** * Return the NetBIOS header data length value. * * @return int */ public final int getHeaderLength() { return DataPacker.getIntelShort(m_nbbuf, 2) & 0xFFFF; } /** * Return the NetBIOS header message type. * * @return int */ public final int getHeaderType() { return m_nbbuf[0] & 0x00FF; } /** * Return the received packet length. * * @return int */ public final int getLength() { return m_datalen; } /** * Return the name service count. * * @return int */ public final int getNameServiceCount() { return DataPacker.getShort(m_nbbuf, NB_NSCOUNT); } /** * Return the NetBIOS opcode. * * @return int */ public final int getOpcode() { int op = DataPacker.getShort(m_nbbuf, NB_OPCODE) & MASK_OPCODE; op = op >> SHIFT_OPCODE; return op; } /** * Return the NetBIOS packet type. * * @return RFCNetBIOSProtocol.MsgType */ public final RFCNetBIOSProtocol.MsgType getPacketType() { return RFCNetBIOSProtocol.MsgType.fromInt((int) (m_nbbuf[0] & 0xFF)); } /** * Return the question count. * * @return int */ public final int getQuestionCount() { return DataPacker.getShort(m_nbbuf, NB_QDCOUNT); } /** * Get the question name. * * @return String */ public final String getQuestionName() { // Pack the encoded name into the NetBIOS packet return NetBIOSSession.DecodeName(m_nbbuf, NB_DATA + 1); } /** * Get the question name length. * * @return int */ public final int getQuestionNameLength() { // Pack the encoded name into the NetBIOS packet return (int) m_nbbuf[NB_DATA] & 0xFF; } /** * Return the result code for the received packet. * * @return int */ public final int getResultCode() { int res = DataPacker.getShort(m_nbbuf, NB_OPCODE) & MASK_RCODE; return res; } /** * Return the NetBIOS transaction id. * * @return int */ public final int getTransactionId() { return DataPacker.getShort(m_nbbuf, NB_TRANSID); } /** * Determine if the received packet is a repsonse packet. * * @return boolean */ public final boolean isResponse() { if ((getOpcode() & MASK_RESPONSE) != 0) return true; return false; } /** * Set the additional byte count. * * @param cnt int */ public final void setAdditionalCount(int cnt) { DataPacker.putShort((short) cnt, m_nbbuf, NB_ARCOUNT); } /** * Set the answer byte count. * * @param cnt int */ public final void setAnswerCount(int cnt) { DataPacker.putShort((short) cnt, m_nbbuf, NB_ANCOUNT); } /** * Set the answer name. * * @param name String * @param ntyp char * @param qtyp int * @param qcls int * @return int */ public final int setAnswerName(String name, char ntyp, int qtyp, int qcls) { // RFC encode the NetBIOS name string String encName = NetBIOSSession.ConvertName(name, ntyp); byte[] nameByts = encName.getBytes(); // Pack the encoded name into the NetBIOS packet int pos = NB_DATA; m_nbbuf[pos++] = (byte) NAME_LEN; for (int i = 0; i < 32; i++) m_nbbuf[pos++] = nameByts[i]; m_nbbuf[pos++] = 0x00; // Set the name type and class DataPacker.putShort((short) qtyp, m_nbbuf, pos); pos += 2; DataPacker.putShort((short) qcls, m_nbbuf, pos); pos += 2; // Set the packet length if (pos > m_datalen) setLength(pos); return pos; } /** * Set the flags. * * @param flg int */ public final void setFlags(int flg) { int val = DataPacker.getShort(m_nbbuf, NB_OPCODE) & MASK_NOFLAGS; val += (flg << SHIFT_FLAGS); DataPacker.putShort((short) val, m_nbbuf, NB_OPCODE); } /** * Set the NetBIOS packet header flags value. * * @param flg int */ public final void setHeaderFlags(int flg) { m_nbbuf[1] = (byte) (flg & 0x00FF); } /** * Set the NetBIOS packet data length in the packet header. * * @param len int */ public final void setHeaderLength(int len) { DataPacker.putIntelShort(len, m_nbbuf, 2); } /** * Set the NetBIOS packet type in the packet header. * * @param typ int */ public final void setHeaderType(int typ) { m_nbbuf[0] = (byte) (typ & 0x00FF); } /** * Set the IP address. * * @param off int * @param ipaddr byte[] * @return int */ public final int setIPAddress(int off, byte[] ipaddr) { // Pack the IP address for (int i = 0; i < 4; i++) m_nbbuf[off + i] = ipaddr[i]; // Set the packet length int pos = off + 4; if (pos > m_datalen) setLength(pos); // Return the new packet offset return pos; } /** * Set the packet data length. * * @param len int */ public final void setLength(int len) { m_datalen = len; } /** * Set the name registration flags. * * @param off int * @param flg int * @return int */ public final int setNameRegistrationFlags(int off, int flg) { // Set the name registration flags DataPacker.putShort((short) 0x0006, m_nbbuf, off); DataPacker.putShort((short) flg, m_nbbuf, off + 2); // Set the packet length int pos = off + 4; if (pos > m_datalen) setLength(pos); // Return the new packet offset return pos; } /** * Set the name service count. * * @param cnt int */ public final void setNameServiceCount(int cnt) { DataPacker.putShort((short) cnt, m_nbbuf, NB_NSCOUNT); } /** * Set the NetBIOS opcode. * * @param op int */ public final void setOpcode(int op) { int val = DataPacker.getShort(m_nbbuf, NB_OPCODE) & MASK_NOOPCODE; val = val + (op << SHIFT_OPCODE); DataPacker.putShort((short) val, m_nbbuf, NB_OPCODE); } /** * Set the question count. * * @param cnt int */ public final void setQuestionCount(int cnt) { DataPacker.putShort((short) cnt, m_nbbuf, NB_QDCOUNT); } /** * Set the question name. * * @param name NetBIOSName * @param qtyp int * @param qcls int * @return int */ public final int setQuestionName(NetBIOSName name, int qtyp, int qcls) { // Encode the NetBIOS name byte[] nameByts = name.encodeName(); // Pack the encoded name into the NetBIOS packet int pos = NB_DATA; System.arraycopy(nameByts, 0, m_nbbuf, pos, nameByts.length); pos += nameByts.length; // Set the name type and class DataPacker.putShort((short) qtyp, m_nbbuf, pos); pos += 2; DataPacker.putShort((short) qcls, m_nbbuf, pos); pos += 2; // Set the packet length if (pos > m_datalen) setLength(pos); return pos; } /** * Set the question name. * * @param name String * @param ntyp char * @param qtyp int * @param qcls int * @return int */ public final int setQuestionName(String name, char ntyp, int qtyp, int qcls) { // RFC encode the NetBIOS name string String encName = NetBIOSSession.ConvertName(name, ntyp); byte[] nameByts = encName.getBytes(); // Pack the encoded name into the NetBIOS packet int pos = NB_DATA; m_nbbuf[pos++] = (byte) NAME_LEN; for (int i = 0; i < 32; i++) m_nbbuf[pos++] = nameByts[i]; m_nbbuf[pos++] = 0x00; // Set the name type and class DataPacker.putShort((short) qtyp, m_nbbuf, pos); pos += 2; DataPacker.putShort((short) qcls, m_nbbuf, pos); pos += 2; // Set the packet length if (pos > m_datalen) setLength(pos); return pos; } /** * Pack the resource data into the packet. * * @param off int * @param flg int * @param data byte[] * @param len int * @return int */ public final int setResourceData(int off, int flg, byte[] data, int len) { // Set the resource data type DataPacker.putShort((short) flg, m_nbbuf, off); // Pack the data int pos = off + 2; for (int i = 0; i < len; i++) m_nbbuf[pos++] = data[i]; // Set the packet length if (pos > m_datalen) setLength(pos); return pos; } /** * Set the resource data length in the NetBIOS packet. * * @param off int * @param len int * @return int */ public final int setResourceDataLength(int off, int len) { // Set the resource data length DataPacker.putShort((short) len, m_nbbuf, off); // Set the packet length int pos = off + 2; if (pos > m_datalen) setLength(pos); // Return the new packet offset return pos; } /** * Set the resource record. * * @param pktoff Packet offset to pack the resource record. * @param rroff Offset to name. * @param qtyp int * @param qcls int * @return int */ public final int setResourceRecord(int pktoff, int rroff, int qtyp, int qcls) { // Pack the resource record details DataPacker.putShort((short) (0xC000 + rroff), m_nbbuf, pktoff); DataPacker.putShort((short) qtyp, m_nbbuf, pktoff + 2); DataPacker.putShort((short) qcls, m_nbbuf, pktoff + 4); // Set the packet length int pos = pktoff + 6; if (pos > m_datalen) setLength(pos); // Return the new packet offset return pos; } /** * Set the transaction id. * * @param id int */ public final void setTransactionId(int id) { DataPacker.putShort((short) id, m_nbbuf, NB_TRANSID); } /** * Set the time to live for the packet. * * @param off int * @param ttl int * @return int */ public final int setTTL(int off, int ttl) { // Set the time to live value for the packet DataPacker.putInt(ttl, m_nbbuf, off); // Set the packet length int pos = off + 4; if (pos > m_datalen) setLength(pos); // Return the new packet offset return pos; } /** * Build a name query response packet for the specified NetBIOS name * * @param name NetBIOSName * @return int */ public final int buildNameQueryResponse(NetBIOSName name) { // Fill in the header setOpcode(NetBIOSPacket.RESP_QUERY); setFlags(NetBIOSPacket.FLG_RECURSDES + NetBIOSPacket.FLG_AUTHANSWER); setQuestionCount(0); setAnswerCount(1); setAdditionalCount(0); setNameServiceCount(0); int pos = setAnswerName(name.getName(), name.getType(), 0x20, 0x01); pos = setTTL(pos, 10000); pos = setResourceDataLength(pos, name.numberOfAddresses() * 6); // Pack the IP address(es) for this name for (int i = 0; i < name.numberOfAddresses(); i++) { // Get the current IP address byte[] ipaddr = name.getIPAddress(i); // Pack the NetBIOS flags and IP address DataPacker.putShort((short) 0x00, m_nbbuf, pos); pos += 2; for (int j = 0; j < 4; j++) m_nbbuf[pos++] = ipaddr[j]; } // Set the packet length, and return the length setLength(pos); return getLength(); } /** * Build an add name request packet for the specified NetBIOS name * * @param name NetBIOSName * @param addrIdx int * @param tranId int * @return int */ public final int buildAddNameRequest(NetBIOSName name, int addrIdx, int tranId) { // Initialize an add name NetBIOS packet setTransactionId(tranId); setOpcode(NetBIOSPacket.NAME_REGISTER); setFlags(NetBIOSPacket.FLG_BROADCAST + NetBIOSPacket.FLG_RECURSION); setQuestionCount(1); setAnswerCount(0); setNameServiceCount(0); setAdditionalCount(1); int pos = setQuestionName(name.getName(), name.getType(), 0x20, 0x01); pos = setResourceRecord(pos, 12, 0x20, 0x01); if (name.getTimeToLive() == 0) pos = setTTL(pos, NetBIOSName.DefaultTTL); else pos = setTTL(pos, name.getTimeToLive()); short flg = 0; if (name.isGroupName()) flg = (short) 0x8000; pos = setNameRegistrationFlags(pos, flg); pos = setIPAddress(pos, name.getIPAddress(addrIdx)); // Return the packet length setLength(pos); return pos; } /** * Build a refresh name request packet for the specified NetBIOS name * * @param name NetBIOSName * @param addrIdx int * @param tranId int * @return int */ public final int buildRefreshNameRequest(NetBIOSName name, int addrIdx, int tranId) { // Initialize an add name NetBIOS packet setTransactionId(tranId); setOpcode(NetBIOSPacket.REFRESH); setFlags(NetBIOSPacket.FLG_BROADCAST + NetBIOSPacket.FLG_RECURSION); setQuestionCount(1); setAnswerCount(0); setNameServiceCount(0); setAdditionalCount(1); int pos = setQuestionName(name.getName(), name.getType(), 0x20, 0x01); pos = setResourceRecord(pos, 12, 0x20, 0x01); if (name.getTimeToLive() == 0) pos = setTTL(pos, NetBIOSName.DefaultTTL); else pos = setTTL(pos, name.getTimeToLive()); short flg = 0; if (name.isGroupName()) flg = (short) 0x8000; pos = setNameRegistrationFlags(pos, flg); pos = setIPAddress(pos, name.getIPAddress(addrIdx)); // Return the packet length setLength(pos); return pos; } /** * Build a delete name request packet for the specified NetBIOS name * * @param name NetBIOSName * @param addrIdx int * @param tranId int * @return int */ public final int buildDeleteNameRequest(NetBIOSName name, int addrIdx, int tranId) { // Initialize a delete name NetBIOS packet setTransactionId(tranId); setOpcode(NetBIOSPacket.NAME_RELEASE); setFlags(NetBIOSPacket.FLG_BROADCAST + NetBIOSPacket.FLG_RECURSION); setQuestionCount(1); setAnswerCount(0); setNameServiceCount(0); setAdditionalCount(1); int pos = setQuestionName(name.getName(), name.getType(), 0x20, 0x01); pos = setResourceRecord(pos, 12, 0x20, 0x01); pos = setTTL(pos, 30000); short flg = 0; if (name.isGroupName()) flg = (short) 0x8000; pos = setNameRegistrationFlags(pos, flg); pos = setIPAddress(pos, name.getIPAddress(addrIdx)); // Return the packet length setLength(pos); return pos; } /** * Build a name query request packet for the specified NetBIOS name * * @param name NetBIOSName * @param tranId int * @param wins boolean * @return int */ public final int buildNameQueryRequest(NetBIOSName name, int tranId, boolean wins) { // Initialize a name query NetBIOS packet setTransactionId(tranId); setOpcode(NetBIOSPacket.NAME_QUERY); int flags = NetBIOSPacket.FLG_RECURSDES; if (wins == false) flags += NetBIOSPacket.FLG_BROADCAST; setFlags(flags); setQuestionCount(1); return setQuestionName(name, NetBIOSPacket.NAME_TYPE_NB, NetBIOSPacket.NAME_CLASS_IN); } /** * Build a session setup request packet * * @param fromName NetBIOSName * @param toName NetBIOSName * @return int */ public final int buildSessionSetupRequest(NetBIOSName fromName, NetBIOSName toName) { // Initialize the session setup packet header m_nbbuf[0] = (byte) RFCNetBIOSProtocol.MsgType.REQUEST.intValue(); m_nbbuf[1] = (byte) 0; // flags // Set the remote NetBIOS name int pos = 4; byte[] encToName = toName.encodeName(); System.arraycopy(encToName, 0, m_nbbuf, pos, encToName.length); pos += encToName.length; // Set the local NetBIOS name byte[] encFromName = fromName.encodeName(); System.arraycopy(encFromName, 0, m_nbbuf, pos, encFromName.length); pos += encFromName.length; // Set the packet length setLength(pos); // Set the length in the session request header DataPacker.putShort((short) (pos - RFCNetBIOSProtocol.HEADER_LEN), m_nbbuf, 2); // Return the packet length return pos; } /** * Build an adapter status response * * @param nameList NetBIOSNameList * @param nodeType int * @return int */ public final int buildAdapterStatusResponse(NetBIOSNameList nameList, int nodeType) { // Fill in the header setOpcode(NetBIOSPacket.RESP_QUERY); setFlags(NetBIOSPacket.FLG_RECURSDES + NetBIOSPacket.FLG_AUTHANSWER); setQuestionCount(0); setAnswerCount(1); setAdditionalCount(0); setNameServiceCount(0); // Pack the encoded adapter status name into the NetBIOS packet int pos = NB_DATA; m_nbbuf[pos++] = (byte) NAME_LEN; pos = DataPacker.putString(AdapterStatusNBName, m_nbbuf, pos, true); // Set the name type and class DataPacker.putShort((short) 0x21, m_nbbuf, pos); pos += 2; DataPacker.putShort((short) 0x01, m_nbbuf, pos); pos += 2; pos = setTTL(pos, 10000); pos = setResourceDataLength(pos, (nameList.numberOfNames() * 18) + 42); // Pack the names m_nbbuf[pos++] = (byte) nameList.numberOfNames(); for (int i = 0; i < nameList.numberOfNames(); i++) { // Get the current name NetBIOSName nbName = nameList.getName(i); // Pack the NetBIOS name and flags System.arraycopy(nbName.getNetBIOSName(), 0, m_nbbuf, pos, NetBIOSName.NameLength); pos += NetBIOSName.NameLength; int flags = nodeType + NAME_ACTIVE; if (nbName.isGroupName()) flags += NAME_GROUP; DataPacker.putShort((short) flags, m_nbbuf, pos); pos += 2; } // Zero out the statistics, MAC address area for (int i = 0; i < 42; i++) m_nbbuf[pos++] = (byte) 0; // Set the packet length, and return the length setLength(pos); return getLength(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy