KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jcifs > netbios > NameServicePacket


1 /* jcifs smb client library in Java
2  * Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18
19 package jcifs.netbios;
20
21 import java.net.InetAddress JavaDoc;
22 import jcifs.util.Hexdump;
23
24 abstract class NameServicePacket {
25
26     // opcode
27
static final int QUERY = 0;
28     static final int WACK = 7;
29
30     // rcode
31
static final int FMT_ERR = 0x1;
32     static final int SRV_ERR = 0x2;
33     static final int IMP_ERR = 0x4;
34     static final int RFS_ERR = 0x5;
35     static final int ACT_ERR = 0x6;
36     static final int CFT_ERR = 0x7;
37
38     // type/class
39
static final int NB_IN = 0x00200001;
40     static final int NBSTAT_IN = 0x00210001;
41     static final int NB = 0x0020;
42     static final int NBSTAT = 0x0021;
43     static final int IN = 0x0001;
44     static final int A = 0x0001;
45     static final int NS = 0x0002;
46     static final int NULL = 0x000a;
47
48     static final int HEADER_LENGTH = 12;
49
50     // header field offsets
51
static final int OPCODE_OFFSET = 2;
52     static final int QUESTION_OFFSET = 4;
53     static final int ANSWER_OFFSET = 6;
54     static final int AUTHORITY_OFFSET = 8;
55     static final int ADDITIONAL_OFFSET = 10;
56
57     static void writeInt2( int val, byte[] dst, int dstIndex ) {
58         dst[dstIndex++] = (byte)(( val >> 8 ) & 0xFF );
59         dst[dstIndex] = (byte)( val & 0xFF );
60     }
61     static void writeInt4( int val, byte[] dst, int dstIndex ) {
62         dst[dstIndex++] = (byte)(( val >> 24 ) & 0xFF );
63         dst[dstIndex++] = (byte)(( val >> 16 ) & 0xFF );
64         dst[dstIndex++] = (byte)(( val >> 8 ) & 0xFF );
65         dst[dstIndex] = (byte)( val & 0xFF );
66     }
67     static int readInt2( byte[] src, int srcIndex ) {
68         return (( src[srcIndex] & 0xFF ) << 8 ) +
69                 ( src[srcIndex + 1] & 0xFF );
70     }
71     static int readInt4( byte[] src, int srcIndex ) {
72         return (( src[srcIndex] & 0xFF ) << 24 ) +
73                 (( src[srcIndex + 1] & 0xFF ) << 16 ) +
74                 (( src[srcIndex + 2] & 0xFF ) << 8 ) +
75                 ( src[srcIndex + 3] & 0xFF );
76     }
77
78     static int readNameTrnId( byte[] src, int srcIndex ) {
79         return readInt2( src, srcIndex );
80     }
81
82     int addrIndex;
83     NbtAddress[] addrEntry;
84
85     int nameTrnId;
86
87     int opCode,
88             resultCode,
89             questionCount,
90             answerCount,
91             authorityCount,
92             additionalCount;
93     boolean received,
94             isResponse,
95             isAuthAnswer,
96             isTruncated,
97             isRecurDesired,
98             isRecurAvailable,
99             isBroadcast;
100
101     Name questionName;
102     Name recordName;
103
104     int questionType,
105             questionClass,
106             recordType,
107             recordClass,
108             ttl,
109             rDataLength;
110
111     InetAddress JavaDoc addr;
112
113     NameServicePacket() {
114         isRecurDesired = true;
115         isBroadcast = true;
116         questionCount = 1;
117         questionClass = IN;
118     }
119
120     int writeWireFormat( byte[] dst, int dstIndex ) {
121         int start = dstIndex;
122         dstIndex += writeHeaderWireFormat( dst, dstIndex );
123         dstIndex += writeBodyWireFormat( dst, dstIndex );
124         return dstIndex - start;
125     }
126     int readWireFormat( byte[] src, int srcIndex ) {
127         int start = srcIndex;
128         srcIndex += readHeaderWireFormat( src, srcIndex );
129         srcIndex += readBodyWireFormat( src, srcIndex );
130         return srcIndex - start;
131     }
132
133     int writeHeaderWireFormat( byte[] dst, int dstIndex ) {
134         int start = dstIndex;
135         writeInt2( nameTrnId, dst, dstIndex );
136         dst[dstIndex + OPCODE_OFFSET] = (byte)(( isResponse ? 0x80 : 0x00 ) +
137                         (( opCode << 3 ) & 0x78 ) +
138                         ( isAuthAnswer ? 0x04 : 0x00 ) +
139                         ( isTruncated ? 0x02 : 0x00 ) +
140                         ( isRecurDesired ? 0x01 : 0x00 ));
141         dst[dstIndex + OPCODE_OFFSET + 1] = (byte)(( isRecurAvailable ? 0x80 : 0x00 ) +
142                         ( isBroadcast ? 0x10 : 0x00 ) +
143                         ( resultCode & 0x0F ));
144         writeInt2( questionCount, dst, start + QUESTION_OFFSET );
145         writeInt2( answerCount, dst, start + ANSWER_OFFSET );
146         writeInt2( authorityCount, dst, start + AUTHORITY_OFFSET );
147         writeInt2( additionalCount, dst, start + ADDITIONAL_OFFSET );
148         return HEADER_LENGTH;
149     }
150     int readHeaderWireFormat( byte[] src, int srcIndex ) {
151         nameTrnId = readInt2( src, srcIndex );
152         isResponse = (( src[srcIndex + OPCODE_OFFSET] & 0x80 ) == 0 ) ? false : true;
153         opCode = ( src[srcIndex + OPCODE_OFFSET] & 0x78 ) >> 3;
154         isAuthAnswer = (( src[srcIndex + OPCODE_OFFSET] & 0x04 ) == 0 ) ? false : true;
155         isTruncated = (( src[srcIndex + OPCODE_OFFSET] & 0x02 ) == 0 ) ? false : true;
156         isRecurDesired = (( src[srcIndex + OPCODE_OFFSET] & 0x01 ) == 0 ) ? false : true;
157         isRecurAvailable =
158                         (( src[srcIndex + OPCODE_OFFSET + 1] & 0x80 ) == 0 ) ? false : true;
159         isBroadcast = (( src[srcIndex + OPCODE_OFFSET + 1] & 0x10 ) == 0 ) ? false : true;
160         resultCode = src[srcIndex + OPCODE_OFFSET + 1] & 0x0F;
161         questionCount = readInt2( src, srcIndex + QUESTION_OFFSET );
162         answerCount = readInt2( src, srcIndex + ANSWER_OFFSET );
163         authorityCount = readInt2( src, srcIndex + AUTHORITY_OFFSET );
164         additionalCount = readInt2( src, srcIndex + ADDITIONAL_OFFSET );
165         return HEADER_LENGTH;
166     }
167     int writeQuestionSectionWireFormat( byte[] dst, int dstIndex ) {
168         int start = dstIndex;
169         dstIndex += questionName.writeWireFormat( dst, dstIndex );
170         writeInt2( questionType, dst, dstIndex );
171         dstIndex += 2;
172         writeInt2( questionClass, dst, dstIndex );
173         dstIndex += 2;
174         return dstIndex - start;
175     }
176     int readQuestionSectionWireFormat( byte[] src, int srcIndex ) {
177         int start = srcIndex;
178         srcIndex += questionName.readWireFormat( src, srcIndex );
179         questionType = readInt2( src, srcIndex );
180         srcIndex += 2;
181         questionClass = readInt2( src, srcIndex );
182         srcIndex += 2;
183         return srcIndex - start;
184     }
185     int writeResourceRecordWireFormat( byte[] dst, int dstIndex ) {
186         int start = dstIndex;
187         if( recordName == questionName ) {
188             dst[dstIndex++] = (byte)0xC0; // label string pointer to
189
dst[dstIndex++] = (byte)0x0C; // questionName (offset 12)
190
} else {
191             dstIndex += recordName.writeWireFormat( dst, dstIndex );
192         }
193         writeInt2( recordType, dst, dstIndex );
194         dstIndex += 2;
195         writeInt2( recordClass, dst, dstIndex );
196         dstIndex += 2;
197         writeInt4( ttl, dst, dstIndex );
198         dstIndex += 4;
199         rDataLength = writeRDataWireFormat( dst, dstIndex + 2 );
200         writeInt2( rDataLength, dst, dstIndex );
201         dstIndex += 2 + rDataLength;
202         return dstIndex - start;
203     }
204     int readResourceRecordWireFormat( byte[] src, int srcIndex ) {
205         int start = srcIndex;
206         int end;
207
208         if(( src[srcIndex] & 0xC0 ) == 0xC0 ) {
209             recordName = questionName; // label string pointer to questionName
210
srcIndex += 2;
211         } else {
212             srcIndex += recordName.readWireFormat( src, srcIndex );
213         }
214         recordType = readInt2( src, srcIndex );
215         srcIndex += 2;
216         recordClass = readInt2( src, srcIndex );
217         srcIndex += 2;
218         ttl = readInt4( src, srcIndex );
219         srcIndex += 4;
220         rDataLength = readInt2( src, srcIndex );
221         srcIndex += 2;
222
223         addrEntry = new NbtAddress[rDataLength / 6];
224         end = srcIndex + rDataLength;
225         for( addrIndex = 0; srcIndex < end; addrIndex++ ) {
226             srcIndex += readRDataWireFormat( src, srcIndex );
227         }
228
229         return srcIndex - start;
230     }
231
232     abstract int writeBodyWireFormat( byte[] dst, int dstIndex );
233     abstract int readBodyWireFormat( byte[] src, int srcIndex );
234     abstract int writeRDataWireFormat( byte[] dst, int dstIndex );
235     abstract int readRDataWireFormat( byte[] src, int srcIndex );
236
237     public String JavaDoc toString() {
238         String JavaDoc opCodeString,
239                 resultCodeString,
240                 questionTypeString,
241                 questionClassString,
242                 recordTypeString,
243                 recordClassString;
244
245         switch( opCode ) {
246             case QUERY:
247                 opCodeString = "QUERY";
248                 break;
249             case WACK:
250                 opCodeString = "WACK";
251                 break;
252             default:
253                 opCodeString = Integer.toString( opCode );
254         }
255         switch( resultCode ) {
256             case FMT_ERR:
257                 resultCodeString = "FMT_ERR";
258                 break;
259             case SRV_ERR:
260                 resultCodeString = "SRV_ERR";
261                 break;
262             case IMP_ERR:
263                 resultCodeString = "IMP_ERR";
264                 break;
265             case RFS_ERR:
266                 resultCodeString = "RFS_ERR";
267                 break;
268             case ACT_ERR:
269                 resultCodeString = "ACT_ERR";
270                 break;
271             case CFT_ERR:
272                 resultCodeString = "CFT_ERR";
273                 break;
274             default:
275                 resultCodeString = "0x" + Hexdump.toHexString( resultCode, 1 );
276         }
277         switch( questionType ) {
278             case NB:
279                 questionTypeString = "NB";
280             case NBSTAT:
281                 questionTypeString = "NBSTAT";
282             default:
283                 questionTypeString = "0x" + Hexdump.toHexString( questionType, 4 );
284         }
285         switch( recordType ) {
286             case A:
287                 recordTypeString = "A";
288                 break;
289             case NS:
290                 recordTypeString = "NS";
291                 break;
292             case NULL:
293                 recordTypeString = "NULL";
294                 break;
295             case NB:
296                 recordTypeString = "NB";
297             case NBSTAT:
298                 recordTypeString = "NBSTAT";
299             default:
300                 recordTypeString = "0x" + Hexdump.toHexString( recordType, 4 );
301         }
302
303         return new String JavaDoc(
304                 "nameTrnId=" + nameTrnId +
305                 ",isResponse=" + isResponse +
306                 ",opCode=" + opCodeString +
307                 ",isAuthAnswer=" + isAuthAnswer +
308                 ",isTruncated=" + isTruncated +
309                 ",isRecurAvailable=" + isRecurAvailable +
310                 ",isRecurDesired=" + isRecurDesired +
311                 ",isBroadcast=" + isBroadcast +
312                 ",resultCode=" + resultCode +
313                 ",questionCount=" + questionCount +
314                 ",answerCount=" + answerCount +
315                 ",authorityCount=" + authorityCount +
316                 ",additionalCount=" + additionalCount +
317                 ",questionName=" + questionName +
318                 ",questionType=" + questionTypeString +
319                 ",questionClass=" + ( questionClass == IN ? "IN" :
320                             "0x" + Hexdump.toHexString( questionClass, 4 )) +
321                 ",recordName=" + recordName +
322                 ",recordType=" + recordTypeString +
323                 ",recordClass=" + ( recordClass == IN ? "IN" :
324                             "0x" + Hexdump.toHexString( recordClass, 4 )) +
325                 ",ttl=" + ttl +
326                 ",rDataLength=" + rDataLength );
327     }
328 }
329
330
Popular Tags