/src/wireshark/epan/dissectors/packet-bjnp.c
Line | Count | Source |
1 | | /* packet-bjnp.c |
2 | | * Routines for Canon BJNP packet disassembly. |
3 | | * |
4 | | * Copyright 2009, Stig Bjorlykke <stig@bjorlykke.org> |
5 | | * |
6 | | * Wireshark - Network traffic analyzer |
7 | | * By Gerald Combs <gerald@wireshark.org> |
8 | | * Copyright 1998 Gerald Combs |
9 | | * |
10 | | * SPDX-License-Identifier: GPL-2.0-or-later |
11 | | */ |
12 | | |
13 | | #include "config.h" |
14 | | |
15 | | #include <epan/packet.h> |
16 | 14 | #define PNAME "Canon BJNP" |
17 | 15 | #define PSNAME "BJNP" |
18 | 28 | #define PFNAME "bjnp" |
19 | | |
20 | 14 | #define BJNP_PORT_RANGE "8611-8614" |
21 | | |
22 | | /* dev_type */ |
23 | | #define PRINTER_COMMAND 0x01 |
24 | | #define SCANNER_COMMAND 0x02 |
25 | | #define PRINTER_RESPONSE 0x81 |
26 | | #define SCANNER_RESPONSE 0x82 |
27 | | |
28 | | /* cmd_code */ |
29 | | #define CMD_DISCOVER 0x01 |
30 | | #define CMD_PRINT_JOB_DET 0x10 |
31 | | #define CMD_CLOSE 0x11 |
32 | | #define CMD_GET_STATUS 0x20 |
33 | | #define CMD_PRINT 0x21 |
34 | | #define CMD_GET_ID 0x30 |
35 | | #define CMD_SCAN_JOB 0x32 |
36 | | |
37 | | void proto_register_bjnp(void); |
38 | | void proto_reg_handoff_bjnp(void); |
39 | | |
40 | | static int proto_bjnp; |
41 | | |
42 | | static int hf_bjnp_id; |
43 | | static int hf_dev_type; |
44 | | static int hf_cmd_code; |
45 | | static int hf_seq_no; |
46 | | static int hf_session_id; |
47 | | static int hf_payload_len; |
48 | | static int hf_payload; |
49 | | |
50 | | static int ett_bjnp; |
51 | | |
52 | | static dissector_handle_t bjnp_handle; |
53 | | |
54 | | static const value_string dev_type_vals[] = { |
55 | | { PRINTER_COMMAND, "Printer Command" }, |
56 | | { SCANNER_COMMAND, "Scanner Command" }, |
57 | | { PRINTER_RESPONSE, "Printer Response" }, |
58 | | { SCANNER_RESPONSE, "Scanner Response" }, |
59 | | { 0, NULL } |
60 | | }; |
61 | | |
62 | | static const value_string cmd_code_vals[] = { |
63 | | { CMD_DISCOVER, "Discover" }, |
64 | | { CMD_PRINT_JOB_DET, "Print Job Details" }, |
65 | | { CMD_CLOSE, "Request Closure" }, |
66 | | { CMD_GET_STATUS, "Get Printer Status" }, |
67 | | { CMD_PRINT, "Print" }, |
68 | | { CMD_GET_ID, "Get Printer Identity" }, |
69 | | { CMD_SCAN_JOB, "Scan Job Details" }, |
70 | | { 0, NULL } |
71 | | }; |
72 | | |
73 | | static int dissect_bjnp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
74 | 2 | { |
75 | 2 | proto_tree *bjnp_tree; |
76 | 2 | proto_item *ti; |
77 | 2 | int offset = 0; |
78 | 2 | uint32_t payload_len; |
79 | 2 | uint8_t dev_type, cmd_code; |
80 | 2 | char *info; |
81 | | |
82 | | /* If it does not start with a printable character it's not BJNP */ |
83 | 2 | if(!g_ascii_isprint(tvb_get_uint8(tvb, 0))) |
84 | 1 | return 0; |
85 | | |
86 | 1 | col_set_str (pinfo->cinfo, COL_PROTOCOL, PSNAME); |
87 | 1 | col_clear (pinfo->cinfo, COL_INFO); |
88 | | |
89 | 1 | ti = proto_tree_add_item (tree, proto_bjnp, tvb, offset, -1, ENC_NA); |
90 | 1 | bjnp_tree = proto_item_add_subtree (ti, ett_bjnp); |
91 | | |
92 | 1 | proto_tree_add_item (bjnp_tree, hf_bjnp_id, tvb, offset, 4, ENC_ASCII); |
93 | 1 | offset += 4; |
94 | | |
95 | 1 | dev_type = tvb_get_uint8 (tvb, offset); |
96 | 1 | proto_tree_add_item (bjnp_tree, hf_dev_type, tvb, offset, 1, ENC_BIG_ENDIAN); |
97 | 1 | offset++; |
98 | | |
99 | 1 | cmd_code = tvb_get_uint8 (tvb, offset); |
100 | 1 | proto_tree_add_item (bjnp_tree, hf_cmd_code, tvb, offset, 1, ENC_BIG_ENDIAN); |
101 | 1 | offset++; |
102 | | |
103 | 1 | info = wmem_strdup_printf(pinfo->pool, "%s: %s", |
104 | 1 | val_to_str(pinfo->pool, dev_type, dev_type_vals, "Unknown type (%d)"), |
105 | 1 | val_to_str(pinfo->pool, cmd_code, cmd_code_vals, "Unknown code (%d)")); |
106 | | |
107 | 1 | proto_item_append_text (ti, ", %s", info); |
108 | 1 | col_add_str (pinfo->cinfo, COL_INFO, info); |
109 | | |
110 | 1 | proto_tree_add_item (bjnp_tree, hf_seq_no, tvb, offset, 4, ENC_BIG_ENDIAN); |
111 | 1 | offset += 4; |
112 | | |
113 | 1 | proto_tree_add_item (bjnp_tree, hf_session_id, tvb, offset, 2, ENC_BIG_ENDIAN); |
114 | 1 | offset += 2; |
115 | | |
116 | 1 | payload_len = tvb_get_ntohl (tvb, offset); |
117 | 1 | proto_tree_add_item (bjnp_tree, hf_payload_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
118 | 1 | offset += 4; |
119 | | |
120 | 1 | if (payload_len > 0) { |
121 | | /* TBD: Dissect various commands */ |
122 | 1 | proto_tree_add_item (bjnp_tree, hf_payload, tvb, offset, payload_len, ENC_NA); |
123 | 1 | offset += payload_len; |
124 | 1 | } |
125 | 1 | return offset; |
126 | 2 | } |
127 | | |
128 | | void proto_register_bjnp (void) |
129 | 14 | { |
130 | 14 | static hf_register_info hf[] = { |
131 | 14 | { &hf_bjnp_id, |
132 | 14 | { "Id", "bjnp.id", FT_STRING, BASE_NONE, |
133 | 14 | NULL, 0x0, NULL, HFILL } }, |
134 | 14 | { &hf_dev_type, |
135 | 14 | { "Type", "bjnp.type", FT_UINT8, BASE_DEC, |
136 | 14 | VALS(dev_type_vals), 0x0, NULL, HFILL } }, |
137 | 14 | { &hf_cmd_code, |
138 | 14 | { "Code", "bjnp.code", FT_UINT8, BASE_DEC, |
139 | 14 | VALS(cmd_code_vals), 0x0, NULL, HFILL } }, |
140 | 14 | { &hf_seq_no, |
141 | 14 | { "Sequence Number", "bjnp.seq_no", FT_UINT32, BASE_DEC, |
142 | 14 | NULL, 0x0, NULL, HFILL } }, |
143 | 14 | { &hf_session_id, |
144 | 14 | { "Session Id", "bjnp.session_id", FT_UINT16, BASE_DEC, |
145 | 14 | NULL, 0x0, NULL, HFILL } }, |
146 | 14 | { &hf_payload_len, |
147 | 14 | { "Payload Length", "bjnp.payload_len", FT_UINT32, BASE_DEC, |
148 | 14 | NULL, 0x0, NULL, HFILL } }, |
149 | 14 | { &hf_payload, |
150 | 14 | { "Payload", "bjnp.payload", FT_BYTES, BASE_NONE, |
151 | 14 | NULL, 0x0, NULL, HFILL } }, |
152 | 14 | }; |
153 | | |
154 | 14 | static int *ett[] = { |
155 | 14 | &ett_bjnp |
156 | 14 | }; |
157 | | |
158 | 14 | proto_bjnp = proto_register_protocol (PNAME, PSNAME, PFNAME); |
159 | | |
160 | 14 | bjnp_handle = register_dissector (PFNAME, dissect_bjnp, proto_bjnp); |
161 | | |
162 | 14 | proto_register_field_array (proto_bjnp, hf, array_length (hf)); |
163 | 14 | proto_register_subtree_array (ett, array_length (ett)); |
164 | 14 | } |
165 | | |
166 | | void proto_reg_handoff_bjnp (void) |
167 | 14 | { |
168 | 14 | dissector_add_uint_range_with_preference("udp.port", BJNP_PORT_RANGE, bjnp_handle); |
169 | 14 | } |
170 | | |
171 | | /* |
172 | | * Editor modelines |
173 | | * |
174 | | * Local Variables: |
175 | | * c-basic-offset: 2 |
176 | | * tab-width: 8 |
177 | | * indent-tabs-mode: nil |
178 | | * End: |
179 | | * |
180 | | * ex: set shiftwidth=2 tabstop=8 expandtab: |
181 | | * :indentSize=2:tabSize=8:noTabs=true: |
182 | | */ |