Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-3com-njack.c
blob06be8f4ea2150c3824f2ab954c6c700b1c182540
1 /* packet-3com-njack.c
2 * Routines for the disassembly of the 3com NetworkJack management protocol
4 * Copyright 2005 Joerg Mayer (see AUTHORS file)
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
14 TODO:
15 - Find out lots more values :-)
16 - Support for other 3com devices that use the same protocol
17 - Do any devices use TCP or different ports?
18 - Sanity checks for tlv_length depending on tlv_type
19 - Search and fix XXX comments in the code
20 - Proper descriptions in hf_ fields
22 Specs:
23 No specs available. All knowledge gained by looking at traffic dumps
24 Packets to Managementstation: PORT_NJACK_PC (5264)
25 Packets to Switch: PORT_NJACK_SWITCH (5265)
27 Type 0x00? (localquery): M -> BC, Magic, type, 'LOCALQUERY'?
28 Type 0x01 (query): M -> S, Magic, type, 'QUERY'
29 Type 0x02 (query resp): S -> M, Magic, type, tlv-list (end: ffxx)
30 Type 0x04 ??? (after query resp): M -> S, Magic, type, 0x43AAD406
31 Type 0x07 (set): M -> S, Magic, type, length (16 bit be)
32 Type 0x08 (set resp): S -> M, Magic, type, net length (8 bit), result status
33 Type 0x0b (get): M -> S, Magic, type, 00 00 63 ff
34 Type 0x0c (get resp): S -> M, Magic, type, T(8 bit) L(8 bit) V(L bytes)
35 Type 0x0d (dhcpinfo): S -> M, Magic, type, tlv, t=00 = last (no length)
36 Type 0x10 (clear counters): M -> S, Magic, type, 0400
37 Type 0x10 (clear counters resp): M -> S, Magic, type, 00
40 #include "config.h"
42 #include <epan/packet.h>
44 /* Forward declarations */
45 void proto_register_njack(void);
46 void proto_reg_handoff_njack(void);
48 static dissector_handle_t njack_handle;
50 /* protocol handles */
51 static int proto_njack;
53 /* ett handles */
54 static int ett_njack;
55 static int ett_njack_tlv_header;
57 /* hf elements */
58 static int hf_njack_magic;
59 static int hf_njack_type;
60 /* type set/get response */
61 static int hf_njack_tlv_length;
62 static int hf_njack_tlv_data;
63 static int hf_njack_tlv_version;
64 static int hf_njack_tlv_type;
65 static int hf_njack_tlv_typeip;
66 static int hf_njack_tlv_devicemac;
67 static int hf_njack_tlv_snmpwrite;
68 static int hf_njack_tlv_dhcpcontrol;
69 static int hf_njack_tlv_typestring;
70 /* 1st TAB */
71 static int hf_njack_tlv_countermode;
72 static int hf_njack_tlv_scheduling;
73 static int hf_njack_tlv_addtagscheme;
74 static int hf_njack_tlv_portingressmode;
75 static int hf_njack_tlv_maxframesize;
76 static int hf_njack_tlv_powerforwarding;
77 /* type 07: set */
78 static int hf_njack_set_length;
79 static int hf_njack_set_salt;
80 static int hf_njack_set_authdata;
81 /* type 08: set result */
82 static int hf_njack_setresult;
83 /* type 0b: get */
84 /* type 0c: get response */
85 static int hf_njack_getresp_unknown1;
87 #define PROTO_SHORT_NAME "NJACK"
88 #define PROTO_LONG_NAME "3com Network Jack"
90 #define NJACK_PORT_RANGE "5264-5265"
91 #define PORT_NJACK_PC 5264
92 #define PORT_NJACK_SWITCH 5265
94 typedef enum {
95 NJACK_TYPE_QUERY = 0x01,
96 NJACK_TYPE_QUERYRESP = 0x02,
97 /* type 0x04 exists - see specs sections */
98 NJACK_TYPE_SET = 0x07,
99 NJACK_TYPE_SETRESULT = 0x08,
101 NJACK_TYPE_GET = 0x0b,
102 NJACK_TYPE_GETRESP = 0x0c,
104 NJACK_TYPE_DHCPINFO = 0x0d,
106 NJACK_TYPE_CLEARCOUNTER = 0x10,
107 NJACK_TYPE_COUNTERRESP = 0x11
108 } njack_type_t;
110 static const value_string njack_type_vals[] = {
111 { NJACK_TYPE_SET, "Set"},
112 { NJACK_TYPE_SETRESULT, "Set result"},
113 { NJACK_TYPE_QUERY, "Query (discovery)"},
114 { NJACK_TYPE_QUERYRESP, "Query response"},
115 { NJACK_TYPE_GET, "Get"},
116 { NJACK_TYPE_GETRESP, "Get response"},
117 { NJACK_TYPE_DHCPINFO, "DHCP info\?\?"},
118 { NJACK_TYPE_CLEARCOUNTER, "Clear counters\?\?"},
119 { NJACK_TYPE_COUNTERRESP, "Clear counters response\?\?"},
121 { 0, NULL }
124 typedef enum {
125 NJACK_CMD_STARTOFPARAMS = 0x00,
126 NJACK_CMD_MACADDRESS = 0x01,
127 NJACK_CMD_IPADDRESS = 0x02,
128 NJACK_CMD_NETWORK = 0x03,
129 NJACK_CMD_MASK = 0x04,
130 NJACK_CMD_MAXFRAMESIZE = 0x05,
131 NJACK_CMD_COUNTERMODE = 0x06,
132 NJACK_CMD_QUEUEING = 0x0a,
133 NJACK_CMD_ADDTAGSCHEME = 0x0b,
134 NJACK_CMD_REMOVETAG = 0x0c,
135 NJACK_CMD_GROUP = 0x0d,
136 NJACK_CMD_LOCATION = 0x0e,
137 NJACK_CMD_VERSION = 0x0f,
138 NJACK_CMD_PORT1 = 0x13,
139 NJACK_CMD_PORT2 = 0x14,
140 NJACK_CMD_PORT3 = 0x15,
141 NJACK_CMD_PORT4 = 0x16,
142 NJACK_CMD_PASSWORD = 0x19,
143 NJACK_CMD_ENABLESNMPWRITE = 0x1a,
144 NJACK_CMD_ROCOMMUNITY = 0x1b,
145 NJACK_CMD_RWCOMMUNITY = 0x1c,
146 NJACK_CMD_POWERFORWARDING = 0x1e,
147 NJACK_CMD_DHCPCONTROL = 0x1f,
148 NJACK_CMD_IPGATEWAY = 0x20,
149 NJACK_CMD_SNMPTRAP = 0x23,
150 NJACK_CMD_COLDSTARTTRAP = 0x26,
151 NJACK_CMD_LINKDOWNTRAP = 0x27,
152 NJACK_CMD_LINKUPTRAP = 0x28,
153 NJACK_CMD_AUTHFAILTRAP = 0x29,
154 NJACK_CMD_PRODUCTNAME = 0x2a,
155 NJACK_CMD_SERIALNO = 0x2b,
156 NJACK_CMD_GETALLPARMAMS = 0x63,
157 NJACK_CMD_ENDOFPACKET = 0xff
158 } njack_cmd_type_t;
160 static const value_string njack_cmd_vals[] = {
161 { NJACK_CMD_STARTOFPARAMS, "Start of Parameters" },
162 { NJACK_CMD_MACADDRESS, "MAC address" },
163 { NJACK_CMD_IPADDRESS, "IP address" },
164 { NJACK_CMD_NETWORK, "IP network" },
165 { NJACK_CMD_MASK, "IP netmask" },
166 { NJACK_CMD_MAXFRAMESIZE, "Max frame size" },
167 { NJACK_CMD_COUNTERMODE, "Countermode" },
168 { NJACK_CMD_QUEUEING, "Priority scheduling policy" },
169 { NJACK_CMD_ADDTAGSCHEME, "Add tag scheme" },
170 { NJACK_CMD_REMOVETAG, "Remove tag" },
171 { NJACK_CMD_GROUP, "Device group" },
172 { NJACK_CMD_LOCATION, "Location" },
173 { NJACK_CMD_VERSION, "Firmware version" },
174 { NJACK_CMD_PORT1, "Port 1" },
175 { NJACK_CMD_PORT2, "Port 2" },
176 { NJACK_CMD_PORT3, "Port 3" },
177 { NJACK_CMD_PORT4, "Port 4" },
178 { NJACK_CMD_PASSWORD, "Device password" },
179 { NJACK_CMD_ENABLESNMPWRITE, "SNMP write enable" },
180 { NJACK_CMD_ROCOMMUNITY, "RO community" },
181 { NJACK_CMD_RWCOMMUNITY, "RW community" },
182 { NJACK_CMD_POWERFORWARDING, "Port power forwarding" },
183 { NJACK_CMD_DHCPCONTROL, "DHCP control" },
184 { NJACK_CMD_IPGATEWAY, "IP gateway" },
185 { NJACK_CMD_SNMPTRAP, "SNMP trap" },
186 { NJACK_CMD_COLDSTARTTRAP, "Coldstart trap" },
187 { NJACK_CMD_LINKDOWNTRAP, "Linkdown trap" },
188 { NJACK_CMD_LINKUPTRAP, "Linkup trap" },
189 { NJACK_CMD_AUTHFAILTRAP, "Auth fail trap" },
190 { NJACK_CMD_PRODUCTNAME, "Product name" },
191 { NJACK_CMD_SERIALNO, "Serial no" },
192 { NJACK_CMD_GETALLPARMAMS, "Get all parameters" },
193 { NJACK_CMD_ENDOFPACKET, "End of packet" },
195 { 0, NULL }
197 static value_string_ext njack_cmd_vals_ext = VALUE_STRING_EXT_INIT(njack_cmd_vals);
199 typedef enum {
200 NJACK_SETRESULT_SUCCESS = 0x01,
201 NJACK_SETRESULT_FAILAUTH = 0xFD
202 } njack_setresult_t;
204 static const value_string njack_setresult_vals[] = {
205 { NJACK_SETRESULT_SUCCESS, "Success" },
206 { NJACK_SETRESULT_FAILAUTH, "Failauth" },
208 { 0, NULL }
211 /* General settings TAB */
212 static const value_string njack_dhcpcontrol[] = {
213 { 0, "Disable" },
214 { 1, "Enable" },
216 { 0, NULL }
218 /* End General settings TAB */
220 /* Port settings TAB */
221 #if 0
222 static const true_false_string tfs_port_state = {
223 "Disable",
224 "Enable"
227 static const true_false_string tfs_port_autoneg = {
228 "Manual",
229 "Auto negotiation"
232 static const true_false_string tfs_port_speed = {
233 "10Mbps",
234 "100Mbps"
237 static const true_false_string tfs_port_duplex = {
238 "halfduplex",
239 "duplex"
242 #endif
243 /* End Port settings TAB */
245 /* Hardware Settings TAB */
246 static const value_string njack_scheduling[] = {
247 { 0, "Weighted fair" },
248 { 1, "Strict priority" },
250 { 0, NULL }
253 static const value_string njack_addtagscheme[] = {
254 { 0, "Frames transmitted unmodified" },
255 { 1, "Add tag to untagged frame" },
257 { 0, NULL }
260 static const value_string njack_portingressmode[] = {
261 { 0, "Receive unmodified" },
262 { 1, "Remove tag if present" },
264 { 0, NULL }
267 static const value_string njack_maxframesize[] = {
268 { 0, "1522 tagged, 1518 untagged" },
269 { 1, "1535" },
271 { 0, NULL }
274 static const value_string njack_countermode[] = {
275 { 0, "Count Rx, Tx Good frames" },
276 { 1, "RX errors, TX collisions" },
278 { 0, NULL }
281 static const value_string njack_powerforwarding[] = {
282 { 1, "OFF" },
283 { 2, "ON" },
284 /* XXX find out correct value */
285 { 3, "802.3af" },
287 { 0, NULL }
289 /* End Hardware Settings TAB */
291 /* SNMP TAB */
292 static const value_string njack_snmpwrite[] = {
293 { 0, "Disable" },
294 { 1, "Enable" },
296 { 0, NULL }
299 #if 0
300 static const value_string njack_snmptrap[] = {
301 { 0, "Disable" },
302 { 1, "Enable" },
304 { 0, NULL }
307 static const value_string njack_coldstarttrap[] = {
308 { 0, "Disable" },
309 { 1, "Enable" },
311 { 0, NULL }
314 static const value_string njack_linkdowntrap[] = {
315 { 0, "Disable" },
316 { 1, "Enable" },
318 { 0, NULL }
321 static const value_string njack_linkuptrap[] = {
322 { 0, "Disable" },
323 { 1, "Enable" },
325 { 0, NULL }
328 static const value_string njack_authfailtrap[] = {
329 { 0, "Disable" },
330 { 1, "Enable" },
332 { 0, NULL }
334 #endif
335 /* End SNMP TAB */
337 static int
338 dissect_portsettings(tvbuff_t *tvb, proto_tree *port_tree, uint32_t offset)
340 /* XXX This is still work in progress, the information here
341 * may be wrong and is obviously incomplete
342 * Structure: 8 bytes, total 64 bits.
344 * Bytes 0-1: select feature
345 * 2-7: feature values
346 * Feature Indicator Valuebit(s)
347 * ------------------------------------------------------------
348 * Port Vlan 0x8000 0x0000 0078 0000 (bits: port 4 ... 1)
349 * Prio (hw queue) 0x4000 0x0000 0006 0000
350 * MC rate limit 0x1000 0x0000 6000 0000 (0:3, 1:6, 2:12, 3:100%)
351 * Speed/Duplex 0x0c00 XXX don't know which bit is speed / duplex
352 * 0x0000 0800 0000 (duplex 0 half, 1 full)
353 * 0x0000 1000 0000 (speed 0 10M, 1 100M)
354 * Port Ena 0x0100 0x0000 0300 0000 (1 dis, 3 ena)
355 * Auto neg 0x0008 0x0000 0000 0800 (0 man, 1 auto)
356 * Vlan number 0x0004 0xff0f 0000 0000 (le)
357 * XXX evaluate the following stuff:
358 * Flowcontrol 0x0001 0x0000 0000 0200 ???
359 * Flowcontrol 0x0001 0x0100 83f1 0a00 <- recorded
360 * Auto Mdi 0x0002 0x0000 0000 0300 (1 man, 2 auto)
361 * Manual MDI 0x0002 0x0100 8371 0900 <- recorded
362 * Manual MDI-X 0x0002 0x0100 8371 0800 <- recorded
363 * Auto MDI-X
365 proto_tree_add_item(port_tree, hf_njack_tlv_data,
366 tvb, offset, 8, ENC_NA);
367 return offset;
370 static int
371 dissect_tlvs(tvbuff_t *tvb, proto_tree *njack_tree, uint32_t offset)
373 uint8_t tlv_type;
374 uint8_t tlv_length;
375 proto_item *tlv_tree;
377 for (;;) {
378 tlv_type = tvb_get_uint8(tvb, offset);
379 /* Special cases that don't have a length field */
380 if (tlv_type == NJACK_CMD_ENDOFPACKET) {
381 proto_tree_add_item(njack_tree, hf_njack_tlv_type,
382 tvb, offset, 1, ENC_BIG_ENDIAN);
383 offset += 1;
384 break;
386 if (tlv_type == NJACK_CMD_GETALLPARMAMS) {
387 proto_tree_add_item(njack_tree, hf_njack_tlv_type,
388 tvb, offset, 1, ENC_BIG_ENDIAN);
389 offset += 1;
390 continue;
392 tlv_length = tvb_get_uint8(tvb, offset + 1);
393 tlv_tree = proto_tree_add_subtree_format(njack_tree, tvb,
394 offset, tlv_length + 2, ett_njack_tlv_header, NULL,
395 "T %02x, L %02x: %s",
396 tlv_type,
397 tlv_length,
398 val_to_str_ext_const(tlv_type, &njack_cmd_vals_ext, "Unknown"));
399 proto_tree_add_item(tlv_tree, hf_njack_tlv_type,
400 tvb, offset, 1, ENC_BIG_ENDIAN);
401 offset += 1;
402 proto_tree_add_item(tlv_tree, hf_njack_tlv_length,
403 tvb, offset, 1, ENC_BIG_ENDIAN);
404 offset += 1;
405 switch (tlv_type) {
406 case NJACK_CMD_STARTOFPARAMS:
407 break;
408 case NJACK_CMD_COUNTERMODE:
409 proto_tree_add_item(tlv_tree, hf_njack_tlv_countermode,
410 tvb, offset, 1, ENC_BIG_ENDIAN);
411 offset += 1;
412 break;
413 case NJACK_CMD_QUEUEING:
414 proto_tree_add_item(tlv_tree, hf_njack_tlv_scheduling,
415 tvb, offset, 1, ENC_BIG_ENDIAN);
416 offset += 1;
417 break;
418 case NJACK_CMD_ADDTAGSCHEME:
419 proto_tree_add_item(tlv_tree, hf_njack_tlv_addtagscheme,
420 tvb, offset, 1, ENC_BIG_ENDIAN);
421 offset += 1;
422 break;
423 case NJACK_CMD_REMOVETAG:
424 proto_tree_add_item(tlv_tree, hf_njack_tlv_portingressmode,
425 tvb, offset, 1, ENC_BIG_ENDIAN);
426 offset += 1;
427 break;
428 case NJACK_CMD_MAXFRAMESIZE:
429 proto_tree_add_item(tlv_tree, hf_njack_tlv_maxframesize,
430 tvb, offset, 1, ENC_BIG_ENDIAN);
431 offset += 1;
432 break;
433 case NJACK_CMD_ENABLESNMPWRITE:
434 proto_tree_add_item(tlv_tree, hf_njack_tlv_snmpwrite,
435 tvb, offset, 1, ENC_BIG_ENDIAN);
436 offset += 1;
437 break;
438 case NJACK_CMD_POWERFORWARDING:
439 proto_tree_add_item(tlv_tree, hf_njack_tlv_powerforwarding,
440 tvb, offset, 1, ENC_BIG_ENDIAN);
441 offset += 1;
442 break;
443 case NJACK_CMD_DHCPCONTROL:
444 proto_tree_add_item(tlv_tree, hf_njack_tlv_dhcpcontrol,
445 tvb, offset, 1, ENC_BIG_ENDIAN);
446 offset += 1;
447 break;
448 case NJACK_CMD_MACADDRESS:
449 proto_tree_add_item(tlv_tree, hf_njack_tlv_devicemac,
450 tvb, offset, 6, ENC_NA);
451 offset += 6;
452 break;
453 case NJACK_CMD_VERSION:
454 /* XXX Don't misuse ip address printing here */
455 proto_tree_add_item(tlv_tree, hf_njack_tlv_version,
456 tvb, offset, 4, ENC_LITTLE_ENDIAN);
457 offset += 4;
458 break;
459 case NJACK_CMD_IPADDRESS:
460 case NJACK_CMD_NETWORK:
461 case NJACK_CMD_MASK:
462 case NJACK_CMD_IPGATEWAY:
463 proto_tree_add_item(tlv_tree, hf_njack_tlv_typeip,
464 tvb, offset, 4, ENC_BIG_ENDIAN);
465 offset += 4;
466 break;
467 case NJACK_CMD_GROUP:
468 case NJACK_CMD_LOCATION:
469 case NJACK_CMD_PASSWORD:
470 case NJACK_CMD_ROCOMMUNITY:
471 case NJACK_CMD_RWCOMMUNITY:
472 case 0x25: /* ? */
473 case NJACK_CMD_PRODUCTNAME:
474 case NJACK_CMD_SERIALNO:
475 proto_tree_add_item(tlv_tree, hf_njack_tlv_typestring,
476 tvb, offset, tlv_length, ENC_ASCII);
477 offset += tlv_length;
478 break;
479 case NJACK_CMD_PORT1:
480 case NJACK_CMD_PORT2:
481 case NJACK_CMD_PORT3:
482 case NJACK_CMD_PORT4:
483 if (tlv_length == 8) {
484 dissect_portsettings(tvb, tlv_tree, offset);
486 offset += tlv_length;
487 break;
488 default:
489 if (tlv_length != 0) {
490 proto_tree_add_item(tlv_tree, hf_njack_tlv_data,
491 tvb, offset, tlv_length, ENC_NA);
492 offset += tlv_length;
494 break;
497 return offset;
500 #if 0
501 #include <wsutil/wsgcrypt.h>
503 static bool
504 verify_password(tvbuff_t *tvb, const char *password)
506 /* 1. pad non-terminated password-string to a length of 32 bytes
507 * (padding: 0x01, 0x02, 0x03...)
508 * 2. Calculate MD5 of padded password and write it to offset 12 of packet
509 * 3. Calculate MD5 of resulting packet and write it to offset 12 of packet
512 bool is_valid = true;
513 const uint8_t *packetdata;
514 uint32_t length;
515 uint8_t *workbuffer;
516 unsigned i;
517 uint8_t byte;
518 gcry_md_hd_t md5_handle;
519 uint8_t *digest;
521 workbuffer=wmem_alloc(pinfo->pool, 32);
522 digest=wmem_alloc(pinfo->pool, 16);
524 length = tvb_get_ntohs(tvb, 6);
525 packetdata = tvb_get_ptr(tvb, 0, length);
526 for (i = 0; i<32 && *password; i++, password++) {
527 workbuffer[i] = *password;
529 for (byte = 1; i<32; i++, byte++) {
530 workbuffer[i] = byte;
533 if (gcry_md_open (&md5_handle, GCRY_MD_MD5, 0)) {
534 return false;
536 gcry_md_write(md5_handle, workbuffer, 32);
537 memcpy(digest, gcry_md_read(md5_handle, 0), 16);
538 gcry_md_reset(md5_handle);
540 gcry_md_write(md5_handle, packetdata, 12);
541 gcry_md_write(md5_handle, digest, 16);
542 gcry_md_write(md5_handle, packetdata + 28, length - 28);
543 memcpy(digest, gcry_md_read(md5_handle, 0), 16);
544 gcry_md_close(md5_handle);
546 fprintf(stderr, "Calculated digest: "); /* debugging */
547 for (i = 0; i < 16; i++) {
548 fprintf(stderr, "%02X", digest[i]); /* debugging */
549 if (digest[i] != *(packetdata + 12 + i)) {
550 is_valid = false;
551 break;
554 fprintf(stderr, " (%d)\n", is_valid); /* debugging */
556 return is_valid;
558 #endif
560 static int
561 dissect_njack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
563 proto_item *ti;
564 proto_tree *njack_tree;
565 uint32_t offset = 0;
566 uint8_t packet_type;
567 uint8_t setresult;
568 int remaining;
570 packet_type = tvb_get_uint8(tvb, 5);
571 col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_SHORT_NAME);
572 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type, njack_type_vals, "Type 0x%02x"));
574 ti = proto_tree_add_item(tree, proto_njack, tvb, offset, -1,
575 ENC_NA);
576 njack_tree = proto_item_add_subtree(ti, ett_njack);
578 proto_tree_add_item(njack_tree, hf_njack_magic, tvb, offset, 5,
579 ENC_ASCII);
580 offset += 5;
582 proto_tree_add_item(njack_tree, hf_njack_type, tvb, offset, 1,
583 ENC_BIG_ENDIAN);
584 offset += 1;
585 switch (packet_type) {
586 case NJACK_TYPE_SET:
587 /* Type 0x07: S -> M, Magic, type, length (16 bit be) */
588 proto_tree_add_item(njack_tree, hf_njack_set_length, tvb, offset,
589 2, ENC_BIG_ENDIAN);
590 offset += 2;
591 proto_tree_add_item(njack_tree, hf_njack_set_salt, tvb, offset,
592 4, ENC_LITTLE_ENDIAN);
593 offset += 4;
594 proto_tree_add_item(njack_tree, hf_njack_set_authdata, tvb, offset,
595 16, ENC_NA);
596 offset += 16;
597 offset = dissect_tlvs(tvb, njack_tree, offset);
598 break;
599 case NJACK_TYPE_SETRESULT:
600 /* Type 0x08: M -> S, Magic, type, setresult (8 bit) */
601 setresult = tvb_get_uint8(tvb, offset);
602 proto_tree_add_item(njack_tree, hf_njack_setresult, tvb, offset,
603 1, ENC_BIG_ENDIAN);
604 offset += 1;
605 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s",
606 val_to_str(setresult, njack_setresult_vals, "[0x%02x]"));
607 break;
608 case NJACK_TYPE_GET:
609 /* Type 0x0b: S -> M, Magic, type, 00 00 63 ff */
610 offset = dissect_tlvs(tvb, njack_tree, offset);
611 break;
612 case NJACK_TYPE_QUERYRESP:
613 /* Type 0x02: M -> S, Magic, type, T(8 bit) L(8 bit) V(L bytes) */
614 case NJACK_TYPE_GETRESP:
615 /* Type 0x0c: M -> S, Magic, type, T(8 bit) L(8 bit) V(L bytes) */
616 offset = dissect_tlvs(tvb, njack_tree, offset);
617 proto_tree_add_item(njack_tree, hf_njack_getresp_unknown1, tvb, offset,
618 1, ENC_BIG_ENDIAN);
619 offset += 1;
620 break;
621 case NJACK_TYPE_DHCPINFO: /* not completely understood */
622 default:
623 /* Unknown type */
624 remaining = tvb_reported_length_remaining(tvb, offset);
625 if (remaining > 0) {
626 proto_tree_add_item(njack_tree, hf_njack_tlv_data,
627 tvb, offset, remaining, ENC_NA);
628 offset += remaining;
630 break;
632 return offset;
635 static bool
636 test_njack(tvbuff_t *tvb)
638 /* We need at least 'NJ200' + 1 Byte packet type */
639 if ( (tvb_captured_length(tvb) < 6) ||
640 (tvb_strncaseeql(tvb, 0, "NJ200", 5) != 0) ) {
641 return false;
643 return true;
646 static bool
647 dissect_njack_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
649 if ( !test_njack(tvb) ) {
650 return false;
652 dissect_njack(tvb, pinfo, tree, data);
653 return true;
656 static int
657 dissect_njack_static(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
659 if ( !test_njack(tvb) ) {
660 return 0;
662 return dissect_njack(tvb, pinfo, tree, NULL);
665 void
666 proto_register_njack(void)
668 static hf_register_info hf[] = {
670 /* NJACK header */
671 { &hf_njack_magic,
672 { "Magic", "njack.magic", FT_STRING, BASE_NONE, NULL,
673 0x0, NULL, HFILL }},
675 { &hf_njack_type,
676 { "Type", "njack.type", FT_UINT8, BASE_HEX, NULL,
677 0x0, NULL, HFILL }},
679 /* TLV fields */
680 { &hf_njack_tlv_type,
681 { "TlvType", "njack.tlv.type", FT_UINT8, BASE_HEX | BASE_EXT_STRING, &njack_cmd_vals_ext,
682 0x0, NULL, HFILL }},
684 { &hf_njack_tlv_length,
685 { "TlvLength", "njack.tlv.length", FT_UINT8, BASE_HEX, NULL,
686 0x0, NULL, HFILL }},
688 { &hf_njack_tlv_data,
689 { "TlvData", "njack.tlv.data", FT_BYTES, BASE_NONE, NULL,
690 0x0, NULL, HFILL }},
692 { &hf_njack_tlv_version,
693 { "TlvFwVersion", "njack.tlv.version", FT_IPv4, BASE_NONE, NULL,
694 0x0, NULL, HFILL }},
696 { &hf_njack_tlv_snmpwrite,
697 { "TlvTypeSnmpwrite", "njack.tlv.snmpwrite", FT_UINT8, BASE_DEC, VALS(njack_snmpwrite),
698 0x0, NULL, HFILL }},
700 { &hf_njack_tlv_dhcpcontrol,
701 { "TlvTypeDhcpControl", "njack.tlv.dhcpcontrol", FT_UINT8, BASE_DEC, VALS(njack_dhcpcontrol),
702 0x0, NULL, HFILL }},
704 { &hf_njack_tlv_devicemac,
705 { "TlvTypeDeviceMAC", "njack.tlv.devicemac", FT_ETHER, BASE_NONE, NULL,
706 0x0, NULL, HFILL }},
708 /* XXX dummy entries, to be replaced */
709 { &hf_njack_tlv_typeip,
710 { "TlvTypeIP", "njack.tlv.typeip", FT_IPv4, BASE_NONE, NULL,
711 0x0, NULL, HFILL }},
713 { &hf_njack_tlv_typestring,
714 { "TlvTypeString", "njack.tlv.typestring", FT_STRING, BASE_NONE, NULL,
715 0x0, NULL, HFILL }},
717 /* 1st tab */
718 { &hf_njack_tlv_scheduling,
719 { "TlvTypeScheduling", "njack.tlv.scheduling", FT_UINT8, BASE_DEC, VALS(njack_scheduling),
720 0x0, NULL, HFILL }},
722 { &hf_njack_tlv_addtagscheme,
723 { "TlvAddTagScheme", "njack.tlv.addtagscheme", FT_UINT8, BASE_DEC, VALS(njack_addtagscheme),
724 0x0, NULL, HFILL }},
726 { &hf_njack_tlv_portingressmode,
727 { "TlvTypePortingressmode", "njack.tlv.portingressmode", FT_UINT8, BASE_DEC, VALS(njack_portingressmode),
728 0x0, NULL, HFILL }},
730 { &hf_njack_tlv_maxframesize,
731 { "TlvTypeMaxframesize", "njack.tlv.maxframesize", FT_UINT8, BASE_DEC, VALS(njack_maxframesize),
732 0x0, NULL, HFILL }},
734 { &hf_njack_tlv_countermode,
735 { "TlvTypeCountermode", "njack.tlv.countermode", FT_UINT8, BASE_DEC, VALS(njack_countermode),
736 0x0, NULL, HFILL }},
738 { &hf_njack_tlv_powerforwarding,
739 { "TlvTypePowerforwarding", "njack.tlv.powerforwarding", FT_UINT8, BASE_DEC, VALS(njack_powerforwarding),
740 0x0, NULL, HFILL }},
742 /* Type 0x07: set */
743 { &hf_njack_set_length,
744 { "SetLength", "njack.set.length", FT_UINT16, BASE_HEX, NULL,
745 0x0, NULL, HFILL }},
747 { &hf_njack_set_salt,
748 { "Salt", "njack.set.salt", FT_UINT32, BASE_HEX, NULL,
749 0x0, NULL, HFILL }},
751 { &hf_njack_set_authdata,
752 { "Authdata", "njack.tlv.authdata", FT_BYTES, BASE_NONE, NULL,
753 0x0, NULL, HFILL }},
755 /* Type 0x08: set result */
756 { &hf_njack_setresult,
757 { "SetResult", "njack.setresult", FT_UINT8, BASE_HEX, VALS(njack_setresult_vals),
758 0x0, NULL, HFILL }},
760 /* Type 0x0b get */
762 /* Type 0x0c get response */
763 { &hf_njack_getresp_unknown1,
764 { "Unknown1", "njack.getresp.unknown1", FT_UINT8, BASE_HEX, NULL,
765 0x0, NULL, HFILL }},
768 static int *ett[] = {
769 &ett_njack,
770 &ett_njack_tlv_header,
773 proto_njack = proto_register_protocol(PROTO_LONG_NAME, PROTO_SHORT_NAME, "njack");
774 proto_register_field_array(proto_njack, hf, array_length(hf));
775 proto_register_subtree_array(ett, array_length(ett));
777 njack_handle = register_dissector("njack", dissect_njack_static, proto_njack);
780 void
781 proto_reg_handoff_njack(void)
783 dissector_add_uint_range_with_preference("udp.port", NJACK_PORT_RANGE, njack_handle);
784 /* dissector_add_uint_with_preference("tcp.port", PORT_NJACK_PC, njack_handle); */
785 /* dissector_add_uint_with_preference("tcp.port", PORT_NJACK_SWITCH, njack_handle); */
787 heur_dissector_add("udp", dissect_njack_heur, "NJACK over UDP", "njack_udp", proto_njack, HEURISTIC_ENABLE);
788 heur_dissector_add("tcp", dissect_njack_heur, "NJACK over TCP", "njack_tcp", proto_njack, HEURISTIC_DISABLE);
792 * Editor modelines - https://www.wireshark.org/tools/modelines.html
794 * Local variables:
795 * c-basic-offset: 8
796 * tab-width: 8
797 * indent-tabs-mode: t
798 * End:
800 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
801 * :indentSize=8:tabSize=8:noTabs=false: