Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-who.c
blob49c44c97fdaf15ca84ae0ee67599cbd4707ec823
1 /* packet-who.c
2 * Routines for who protocol (see man rwhod)
3 * Gilbert Ramirez <gram@alumni.rice.edu>
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
12 #include "config.h"
14 #include <epan/packet.h>
15 #include <epan/to_str.h>
20 RWHOD(8) UNIX System Manager's Manual RWHOD(8)
23 The messages sent and received, are of the form:
25 struct outmp {
26 0 char out_line[8]; tty name
27 8 char out_name[8]; user id
28 16 long out_time; time on
31 struct whod {
32 0 char wd_vers;
33 1 char wd_type;
34 2 char wd_fill[2];
35 4 int wd_sendtime;
36 8 int wd_recvtime;
37 12 char wd_hostname[32];
38 44 int wd_loadav[3];
39 56 int wd_boottime;
40 60 struct whoent {
41 struct outmp we_utmp;
42 (20 each) int we_idle;
43 } wd_we[1024 / sizeof (struct whoent)];
48 void proto_register_who(void);
49 void proto_reg_handoff_who(void);
51 static dissector_handle_t who_handle;
53 static int proto_who;
54 static int hf_who_vers;
55 static int hf_who_type;
56 static int hf_who_sendtime;
57 static int hf_who_recvtime;
58 static int hf_who_hostname;
59 static int hf_who_loadav_5;
60 static int hf_who_loadav_10;
61 static int hf_who_loadav_15;
62 static int hf_who_boottime;
63 static int hf_who_whoent;
64 static int hf_who_tty;
65 static int hf_who_uid;
66 static int hf_who_timeon;
67 static int hf_who_idle;
69 static int ett_who;
70 static int ett_whoent;
72 #define UDP_PORT_WHO 513
74 static void dissect_whoent(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree);
76 static int
77 dissect_who(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
79 int offset = 0;
80 proto_tree *who_tree;
81 proto_item *who_ti;
82 uint8_t *server_name;
83 double loadav_5 = 0.0, loadav_10 = 0.0, loadav_15 = 0.0;
85 /* Summary information */
86 col_set_str(pinfo->cinfo, COL_PROTOCOL, "WHO");
87 col_clear(pinfo->cinfo, COL_INFO);
89 who_ti = proto_tree_add_item(tree, proto_who, tvb, offset, -1, ENC_NA);
90 who_tree = proto_item_add_subtree(who_ti, ett_who);
92 proto_tree_add_item(who_tree, hf_who_vers, tvb, offset, 1, ENC_BIG_ENDIAN);
93 offset += 1;
95 proto_tree_add_item(who_tree, hf_who_type, tvb, offset, 1, ENC_BIG_ENDIAN);
96 offset += 1;
98 /* 2 filler bytes */
99 offset += 2;
101 if (tree) {
102 proto_tree_add_item(who_tree, hf_who_sendtime, tvb, offset, 4,
103 ENC_TIME_SECS|ENC_BIG_ENDIAN);
105 offset += 4;
107 if (tree) {
108 proto_tree_add_item(who_tree, hf_who_recvtime, tvb, offset, 4,
109 ENC_TIME_SECS|ENC_BIG_ENDIAN);
111 offset += 4;
113 server_name = tvb_get_stringzpad(pinfo->pool, tvb, offset, 32, ENC_ASCII|ENC_NA);
114 proto_tree_add_string(who_tree, hf_who_hostname, tvb, offset, 32, server_name);
115 offset += 32;
117 loadav_5 = tvb_get_ntohl(tvb, offset) / 100.0;
118 proto_tree_add_double(who_tree, hf_who_loadav_5, tvb, offset,
119 4, loadav_5);
120 offset += 4;
122 loadav_10 = tvb_get_ntohl(tvb, offset) / 100.0;
123 proto_tree_add_double(who_tree, hf_who_loadav_10, tvb, offset,
124 4, loadav_10);
125 offset += 4;
127 loadav_15 = tvb_get_ntohl(tvb, offset) / 100.0;
128 proto_tree_add_double(who_tree, hf_who_loadav_15, tvb, offset,
129 4, loadav_15);
130 offset += 4;
132 /* Summary information */
133 col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %.02f %.02f %.02f",
134 server_name, loadav_5, loadav_10, loadav_15);
136 if (tree) {
137 proto_tree_add_item(who_tree, hf_who_boottime, tvb, offset, 4,
138 ENC_TIME_SECS|ENC_BIG_ENDIAN);
139 offset += 4;
141 dissect_whoent(pinfo, tvb, offset, who_tree);
144 return tvb_captured_length(tvb);
147 /* The man page says that (1024 / sizeof(struct whoent)) is the maximum number
148 * of whoent structures in the packet. */
149 #define SIZE_OF_WHOENT 24
150 #define MAX_NUM_WHOENTS (1024 / SIZE_OF_WHOENT)
152 static void
153 dissect_whoent(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree)
155 proto_tree *whoent_tree = NULL;
156 proto_item *whoent_ti = NULL;
157 int line_offset = offset;
158 uint8_t *out_line;
159 uint8_t *out_name;
160 int whoent_num = 0;
161 uint32_t idle_secs; /* say that out loud... */
163 while (tvb_reported_length_remaining(tvb, line_offset) > 0
164 && whoent_num < MAX_NUM_WHOENTS) {
165 whoent_ti = proto_tree_add_item(tree, hf_who_whoent, tvb,
166 line_offset, SIZE_OF_WHOENT, ENC_NA);
167 whoent_tree = proto_item_add_subtree(whoent_ti, ett_whoent);
169 out_line = tvb_get_stringzpad(pinfo->pool, tvb, line_offset, 8, ENC_ASCII|ENC_NA);
170 proto_tree_add_string(whoent_tree, hf_who_tty, tvb, line_offset,
171 8, out_line);
172 line_offset += 8;
174 out_name = tvb_get_stringzpad(pinfo->pool, tvb, line_offset, 8, ENC_ASCII|ENC_NA);
175 proto_tree_add_string(whoent_tree, hf_who_uid, tvb, line_offset,
176 8, out_name);
177 line_offset += 8;
179 proto_tree_add_item(whoent_tree, hf_who_timeon, tvb,
180 line_offset, 4, ENC_TIME_SECS|ENC_BIG_ENDIAN);
181 line_offset += 4;
183 idle_secs = tvb_get_ntohl(tvb, line_offset);
184 proto_tree_add_uint_format(whoent_tree, hf_who_idle, tvb,
185 line_offset, 4, idle_secs, "Idle: %s",
186 signed_time_secs_to_str(pinfo->pool, idle_secs));
187 line_offset += 4;
189 whoent_num++;
193 void
194 proto_register_who(void)
196 static hf_register_info hf[] = {
197 { &hf_who_vers,
198 { "Version", "who.vers", FT_UINT8, BASE_DEC, NULL, 0x0,
199 NULL, HFILL }},
201 { &hf_who_type,
202 { "Type", "who.type", FT_UINT8, BASE_DEC, NULL, 0x0,
203 NULL, HFILL }},
205 { &hf_who_sendtime,
206 { "Send Time", "who.sendtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
207 NULL, HFILL }},
209 { &hf_who_recvtime,
210 { "Receive Time", "who.recvtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
211 NULL, HFILL }},
213 { &hf_who_hostname,
214 { "Hostname", "who.hostname", FT_STRING, BASE_NONE, NULL, 0x0,
215 NULL, HFILL }},
217 { &hf_who_loadav_5,
218 { "Load Average Over Past 5 Minutes", "who.loadav_5", FT_DOUBLE, BASE_NONE, NULL, 0x0,
219 NULL, HFILL }},
221 { &hf_who_loadav_10,
222 { "Load Average Over Past 10 Minutes", "who.loadav_10", FT_DOUBLE, BASE_NONE, NULL, 0x0,
223 NULL, HFILL }},
225 { &hf_who_loadav_15,
226 { "Load Average Over Past 15 Minutes", "who.loadav_15", FT_DOUBLE, BASE_NONE, NULL, 0x0,
227 NULL, HFILL }},
229 { &hf_who_boottime,
230 { "Boot Time", "who.boottime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
231 NULL, HFILL }},
233 { &hf_who_whoent,
234 { "Who utmp Entry", "who.entry", FT_NONE, BASE_NONE, NULL, 0x0,
235 NULL, HFILL }},
237 { &hf_who_tty,
238 { "TTY Name", "who.tty", FT_STRING, BASE_NONE, NULL, 0x0,
239 NULL, HFILL }},
241 { &hf_who_uid,
242 { "User ID", "who.uid", FT_STRING, BASE_NONE, NULL, 0x0,
243 NULL, HFILL }},
245 { &hf_who_timeon,
246 { "Time On", "who.timeon", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
247 NULL, HFILL }},
249 { &hf_who_idle,
250 { "Time Idle", "who.idle", FT_UINT32, BASE_DEC, NULL, 0x0,
251 NULL, HFILL }},
254 static int *ett[] = {
255 &ett_who,
256 &ett_whoent,
259 proto_who = proto_register_protocol("Who", "WHO", "who");
260 who_handle = register_dissector("who", dissect_who, proto_who);
261 proto_register_field_array(proto_who, hf, array_length(hf));
262 proto_register_subtree_array(ett, array_length(ett));
265 void
266 proto_reg_handoff_who(void)
268 dissector_add_uint_with_preference("udp.port", UDP_PORT_WHO, who_handle);
272 * Editor modelines - https://www.wireshark.org/tools/modelines.html
274 * Local variables:
275 * c-basic-offset: 8
276 * tab-width: 8
277 * indent-tabs-mode: t
278 * End:
280 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
281 * :indentSize=8:tabSize=8:noTabs=false: