KickJava   Java API By Example, From Geeks To Geeks.

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