1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package it.jnrpe.net;
17
18 import java.io.ByteArrayOutputStream;
19 import java.io.DataInputStream;
20 import java.io.DataOutputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.nio.charset.Charset;
24 import java.util.Arrays;
25 import java.util.Random;
26 import java.util.zip.CRC32;
27
28 import org.apache.commons.lang.ArrayUtils;
29
30
31
32
33
34
35 class JNRPEProtocolPacket {
36
37
38
39
40 private static final int MAX_PACKETBUFFER_LENGTH = 1024;
41
42
43
44
45 private Charset charset = Charset.forName("UTF-8");
46
47
48
49
50 private int crcValue;
51
52
53
54
55 private int packetTypeCode;
56
57
58
59
60 private int packetVersion;
61
62
63
64
65 private int resultCode;
66
67
68
69
70 private byte[] byteBufferAry = new byte[MAX_PACKETBUFFER_LENGTH];
71
72
73
74
75 private final byte[] dummyBytesAry = new byte[2];
76
77
78
79
80
81
82 int getCRC() {
83 return crcValue;
84 }
85
86
87
88
89
90
91 PacketType getPacketType() {
92 return PacketType.fromIntValue(packetTypeCode);
93 }
94
95
96
97
98
99
100 public PacketVersion getPacketVersion() {
101 return PacketVersion.fromIntValue(packetVersion);
102 }
103
104
105
106
107
108
109
110 void setCRC(final int crc) {
111 crcValue = crc;
112 }
113
114
115
116
117
118
119
120 protected void setPacketType(final PacketType packetType) {
121 packetTypeCode = packetType.intValue();
122 }
123
124
125
126
127
128
129
130 public void setPacketVersion(final PacketVersion version) {
131 packetVersion = version.intValue();
132 }
133
134
135
136
137
138
139
140 public void setCharset(final Charset newCharset) {
141 this.charset = newCharset;
142 }
143
144
145
146
147
148
149 public int getResultCode() {
150 return resultCode;
151 }
152
153
154
155
156
157
158
159 public void setResultCode(final int status) {
160 resultCode = status;
161 }
162
163
164
165
166
167
168
169 public void validate() throws BadCRCException {
170 ByteArrayOutputStream bout = new ByteArrayOutputStream();
171 DataOutputStream dout = new DataOutputStream(bout);
172
173 try {
174 dout.writeShort(packetVersion);
175 dout.writeShort(packetTypeCode);
176 dout.writeInt(0);
177 dout.writeShort(resultCode);
178 dout.write(byteBufferAry);
179 dout.write(dummyBytesAry);
180
181 dout.close();
182
183 byte[] vBytes = bout.toByteArray();
184
185 CRC32 crcAlg = new CRC32();
186 crcAlg.update(vBytes);
187
188 if (!(((int) crcAlg.getValue()) == crcValue)) {
189 throw new BadCRCException("Bad CRC");
190 }
191 } catch (IOException e) {
192 throw new IllegalStateException(e);
193 }
194 }
195
196 protected byte[] getBuffer() {
197 return byteBufferAry;
198 }
199
200 protected String getPacketString() {
201 byte[] buffer = getBuffer();
202 int zeroIndex = ArrayUtils.indexOf(buffer, (byte) 0);
203
204 if (zeroIndex == ArrayUtils.INDEX_NOT_FOUND) {
205 return new String(buffer);
206 } else {
207 return new String(buffer, 0, zeroIndex);
208 }
209 }
210
211
212
213
214 private void initRandomBuffer() {
215 Random r = new Random(System.currentTimeMillis());
216
217 r.nextBytes(byteBufferAry);
218 r.nextBytes(dummyBytesAry);
219 }
220
221 protected void setBuffer(final String buffer) {
222 initRandomBuffer();
223 byteBufferAry = Arrays.copyOf(buffer.getBytes(charset),
224 MAX_PACKETBUFFER_LENGTH);
225 }
226
227 void setDummy(final byte[] dummyBytes) {
228 if (dummyBytes == null || dummyBytes.length != 2) {
229 throw new IllegalArgumentException(
230 "Dummy bytes array must have exactly two elements");
231 }
232
233 System.arraycopy(dummyBytes, 0, this.dummyBytesAry, 0, 2);
234 }
235
236 byte[] getDummy() {
237 return dummyBytesAry;
238 }
239
240 void updateCRC() {
241 setCRC(0);
242 CRC32 crcAlg = new CRC32();
243 crcAlg.update(toByteArray());
244
245 setCRC((int) crcAlg.getValue());
246 }
247
248
249
250
251
252
253 public byte[] toByteArray() {
254 ByteArrayOutputStream bout = new ByteArrayOutputStream();
255 DataOutputStream dout = new DataOutputStream(bout);
256
257 try {
258 dout.writeShort(packetVersion);
259 dout.writeShort(packetTypeCode);
260 dout.writeInt(crcValue);
261 dout.writeShort(resultCode);
262 dout.write(byteBufferAry);
263 dout.write(dummyBytesAry);
264
265 dout.close();
266 } catch (IOException e) {
267 throw new IllegalStateException(e);
268 }
269 return bout.toByteArray();
270 }
271
272 protected void fromInputStream(final InputStream in) throws IOException {
273 DataInputStream din = new DataInputStream(in);
274 packetVersion = din.readShort();
275 packetTypeCode = din.readShort();
276 crcValue = din.readInt();
277 resultCode = din.readShort();
278 din.readFully(byteBufferAry);
279 din.readFully(dummyBytesAry);
280 }
281 }