Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-usb-printer.c
blobdda82ea748442db1e6d1eaa7917daea080d17bf2
1 /* packet-usb-printer.c
3 * Copyright 2020, Martin Kaiser <martin@kaiser.cx>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
13 * References:
15 * USB printer class specification
16 * https://www.usb.org/sites/default/files/usbprint11a021811.pdf
18 * IEEE 1284 (parallel peripheral interface for personal computers)
19 * http://kazus.ru/nuke/modules/Downloads/pub/148/0/IEEE%201284-2000.pdf
22 #include "config.h"
23 #include <epan/packet.h>
24 #include <epan/proto.h>
25 #include "packet-usb.h"
26 #include <epan/value_string.h>
28 static dissector_handle_t usb_printer_ctl_handle;
30 static int proto_usb_printer;
32 static int hf_usb_printer_req;
33 static int hf_usb_printer_cfg_idx;
34 static int hf_usb_printer_intf;
35 static int hf_usb_printer_alt_set;
36 static int hf_usb_printer_max_len;
37 static int hf_usb_printer_dev_id_len;
38 static int hf_usb_printer_dev_id;
40 static int ett_usb_printer;
42 void proto_register_usb_printer(void);
43 void proto_reg_handoff_usb_printer(void);
45 #define REQ_GET_DEV_ID 0
46 #define REQ_GET_PORT_STAT 1
47 #define REQ_GET_SOFT_RST 2
49 static const value_string usb_printer_req[] = {
50 { REQ_GET_DEV_ID, "GET_DEVICE_ID" },
51 { REQ_GET_PORT_STAT, "GET_PORT_STATUS" },
52 { REQ_GET_SOFT_RST, "SOFT_RESET" },
53 { 0, NULL }
56 static int dissect_usb_printer_ctl(
57 tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
59 bool is_request = (pinfo->srcport == NO_ENDPOINT);
60 urb_info_t *urb = (urb_info_t *)data;
61 usb_trans_info_t *usb_trans_info;
62 int offset = 0;
63 uint8_t bReq;
64 uint32_t dev_id_len;
66 if (!urb)
67 return 0;
69 usb_trans_info = urb->usb_trans_info;
70 if (!usb_trans_info)
71 return 0;
73 col_set_str(pinfo->cinfo, COL_PROTOCOL, "USBPRINTER");
74 col_set_str(pinfo->cinfo, COL_INFO,
75 val_to_str_const(usb_trans_info->setup.request,
76 usb_printer_req, "Invalid"));
78 if (is_request) {
79 col_append_str(pinfo->cinfo, COL_INFO, " request");
81 bReq = tvb_get_uint8(tvb, offset);
82 proto_tree_add_item(tree, hf_usb_printer_req,
83 tvb, offset, 1, ENC_LITTLE_ENDIAN);
84 offset++;
86 if (bReq == REQ_GET_DEV_ID) {
87 /* Generally, fields in USB messages are little endian. */
88 proto_tree_add_item(tree, hf_usb_printer_cfg_idx,
89 tvb, offset, 2, ENC_LITTLE_ENDIAN);
90 offset += 2;
91 proto_tree_add_item(tree, hf_usb_printer_intf,
92 tvb, offset, 2, ENC_LITTLE_ENDIAN);
93 proto_tree_add_item(tree, hf_usb_printer_alt_set,
94 tvb, offset, 2, ENC_LITTLE_ENDIAN);
95 offset += 2;
96 proto_tree_add_item(tree, hf_usb_printer_max_len,
97 tvb, offset, 2, ENC_LITTLE_ENDIAN);
98 offset += 2;
101 else {
102 col_append_str(pinfo->cinfo, COL_INFO, " response");
104 if (usb_trans_info->setup.request == REQ_GET_DEV_ID) {
106 * A printer's Device ID is defined in IEEE 1284, section 7.6.
107 * It starts with a 16-bit length field in big endian encoding.
108 * The length field includes the two bytes for itself. Therefore,
109 * we can't use an FT_UINT_STRING for the entire Device ID.
110 * The actual Device ID string consists of ASCII characters.
112 proto_tree_add_item_ret_uint(tree, hf_usb_printer_dev_id_len,
113 tvb, offset, 2, ENC_BIG_ENDIAN, &dev_id_len);
114 offset += 2;
115 if (dev_id_len > 2) {
116 proto_tree_add_item(tree, hf_usb_printer_dev_id,
117 tvb, offset, dev_id_len-2, ENC_ASCII);
118 offset += dev_id_len-2;
120 /* XXX - expert info for invalid dev_id_len */
124 return offset;
127 void proto_register_usb_printer(void)
129 static hf_register_info hf[] = {
130 { &hf_usb_printer_req,
131 { "bRequest", "usbprinter.bRequest", FT_UINT8, BASE_HEX,
132 VALS(usb_printer_req), 0x0, NULL, HFILL }
134 { &hf_usb_printer_cfg_idx,
135 { "Config index", "usbprinter.config_index", FT_UINT16, BASE_HEX,
136 NULL, 0x0, NULL, HFILL }
138 { &hf_usb_printer_intf,
139 { "Interface", "usbprinter.interface", FT_UINT16, BASE_HEX,
140 NULL, 0xFF00, NULL, HFILL }
142 { &hf_usb_printer_alt_set,
143 { "Alternate setting", "usbprinter.alt_set", FT_UINT16, BASE_HEX,
144 NULL, 0x00FF, NULL, HFILL }
146 { &hf_usb_printer_max_len,
147 { "Maximum length", "usbprinter.max_len", FT_UINT16, BASE_HEX,
148 NULL, 0, NULL, HFILL }
150 { &hf_usb_printer_dev_id_len,
151 { "Device ID length", "usbprinter.device_id_len", FT_UINT16,
152 BASE_HEX, NULL, 0, NULL, HFILL }
154 { &hf_usb_printer_dev_id,
155 { "Device ID", "usbprinter.device_id", FT_STRING, BASE_NONE,
156 NULL, 0, NULL, HFILL }
160 static int *ett[] = {
161 &ett_usb_printer
164 proto_usb_printer = proto_register_protocol("USB Printer", "USBPRINTER", "usbprinter");
165 proto_register_field_array(proto_usb_printer, hf, array_length(hf));
166 proto_register_subtree_array(ett, array_length(ett));
167 usb_printer_ctl_handle = register_dissector("usbprinter", dissect_usb_printer_ctl, proto_usb_printer);
170 void
171 proto_reg_handoff_usb_printer(void)
173 dissector_add_uint("usb.control", IF_CLASS_PRINTER, usb_printer_ctl_handle);
177 * Editor modelines - https://www.wireshark.org/tools/modelines.html
179 * Local variables:
180 * c-basic-offset: 4
181 * tab-width: 8
182 * indent-tabs-mode: nil
183 * End:
185 * ex: set shiftwidth=4 tabstop=8 expandtab:
186 * :indentSize=4:tabSize=8:noTabs=true: