2 * Routines for PCNFSD dissection
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * Copied from packet-ypbind.c
10 * SPDX-License-Identifier: GPL-2.0-or-later
15 Protocol information comes from the book
16 "NFS Illustrated" by Brent Callaghan, ISBN 0-201-32570-5
23 #include "packet-rpc.h"
24 #include "packet-pcnfsd.h"
26 void proto_register_pcnfsd(void);
27 void proto_reg_handoff_pcnfsd(void);
29 static int proto_pcnfsd
;
30 static int hf_pcnfsd_procedure_v1
;
31 static int hf_pcnfsd_procedure_v2
;
32 static int hf_pcnfsd_auth_client
;
33 static int hf_pcnfsd_auth_ident_obscure
;
34 static int hf_pcnfsd_auth_ident_clear
;
35 static int hf_pcnfsd_auth_password
;
36 static int hf_pcnfsd_auth_password_obscure
;
37 static int hf_pcnfsd_auth_password_clear
;
38 static int hf_pcnfsd_comment
;
39 static int hf_pcnfsd_status
;
40 static int hf_pcnfsd_uid
;
41 static int hf_pcnfsd_gid
;
42 static int hf_pcnfsd_gids_count
;
43 static int hf_pcnfsd_homedir
;
44 static int hf_pcnfsd_def_umask
;
45 static int hf_pcnfsd_mapreq
;
46 static int hf_pcnfsd_mapreq_status
;
47 static int hf_pcnfsd_username
;
50 static int ett_pcnfsd
;
51 static int ett_pcnfsd_auth_ident
;
52 static int ett_pcnfsd_auth_password
;
53 static int ett_pcnfsd_gids
;
56 dissect_pcnfsd_username(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
58 return dissect_rpc_string(tvb
, tree
, hf_pcnfsd_username
, offset
, NULL
);
63 #define MAP_REQ_UNAME 2
64 #define MAP_REQ_GNAME 3
66 static const value_string names_mapreq
[] =
68 { MAP_REQ_UID
, "MAP_REQ_UID" },
69 { MAP_REQ_GID
, "MAP_REQ_GID" },
70 { MAP_REQ_UNAME
, "MAP_REQ_UNAME" },
71 { MAP_REQ_GNAME
, "MAP_REQ_GNAME" },
76 dissect_pcnfsd2_dissect_mapreq_arg_item(tvbuff_t
*tvb
, int offset
,
77 packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
79 proto_tree_add_item(tree
, hf_pcnfsd_mapreq
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
82 offset
= dissect_rpc_uint32(tvb
, tree
, hf_pcnfsd_uid
, offset
);
84 offset
= dissect_pcnfsd_username(tvb
, offset
, tree
);
90 dissect_pcnfsd2_mapid_call(tvbuff_t
*tvb
, packet_info
*pinfo
,
91 proto_tree
*tree
, void* data _U_
)
94 offset
= dissect_rpc_string(tvb
, tree
, hf_pcnfsd_comment
, offset
, NULL
);
96 offset
= dissect_rpc_list(tvb
, pinfo
, tree
, offset
,
97 dissect_pcnfsd2_dissect_mapreq_arg_item
, NULL
);
103 #define MAP_RES_UNKNOWN 1
104 #define MAP_RES_DENIED 2
106 static const value_string names_maprstat
[] =
108 { MAP_RES_OK
, "MAP_RES_OK" },
109 { MAP_RES_UNKNOWN
, "MAP_RES_UNKNOWN" },
110 { MAP_RES_DENIED
, "MAP_RES_DENIED" },
115 dissect_pcnfsd2_dissect_mapreq_res_item(tvbuff_t
*tvb
, int offset
,
116 packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
118 proto_tree_add_item(tree
, hf_pcnfsd_mapreq
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
121 proto_tree_add_item(tree
, hf_pcnfsd_mapreq_status
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
124 offset
= dissect_rpc_uint32(tvb
, tree
, hf_pcnfsd_uid
, offset
);
126 offset
= dissect_pcnfsd_username(tvb
, offset
, tree
);
132 dissect_pcnfsd2_mapid_reply(tvbuff_t
*tvb
, packet_info
*pinfo
,
133 proto_tree
*tree
, void* data _U_
)
136 offset
= dissect_rpc_string(tvb
, tree
, hf_pcnfsd_comment
, offset
, NULL
);
138 offset
= dissect_rpc_list(tvb
, pinfo
, tree
, offset
,
139 dissect_pcnfsd2_dissect_mapreq_res_item
, NULL
);
144 /* "NFS Illustrated 14.7.13 */
146 pcnfsd_decode_obscure(wmem_allocator_t
*pool
, const char* data
, int len
)
151 decoded_buf
= (char *)wmem_alloc(pool
, len
);
152 decoded_data
= decoded_buf
;
153 for ( ; len
>0 ; len
--, data
++, decoded_data
++) {
154 *decoded_data
= (*data
^ 0x5b) & 0x7f;
160 /* "NFS Illustrated" 14.7.13 */
162 dissect_pcnfsd2_auth_call(tvbuff_t
*tvb
, packet_info
*pinfo
,
163 proto_tree
*tree
, void* data _U_
)
166 const char *ident
= NULL
;
167 const char *ident_decoded
;
168 proto_item
*ident_item
;
169 proto_tree
*ident_tree
;
170 const char *password
= NULL
;
171 proto_item
*password_item
= NULL
;
172 proto_tree
*password_tree
= NULL
;
175 offset
= dissect_rpc_string(tvb
, tree
,
176 hf_pcnfsd_auth_client
, offset
, NULL
);
178 ident_tree
= proto_tree_add_subtree(tree
, tvb
,
179 offset
, -1, ett_pcnfsd_auth_ident
, &ident_item
, "Authentication Ident");
181 newoffset
= dissect_rpc_string(tvb
, ident_tree
,
182 hf_pcnfsd_auth_ident_obscure
, offset
, &ident
);
183 proto_item_set_len(ident_item
, newoffset
-offset
);
186 /* Only attempt to decode the ident if it has been specified */
187 if (strcmp(ident
, RPC_STRING_EMPTY
) != 0)
188 ident_decoded
= pcnfsd_decode_obscure(pinfo
->pool
, ident
, (int)strlen(ident
));
190 ident_decoded
= ident
;
193 proto_tree_add_string(ident_tree
,
194 hf_pcnfsd_auth_ident_clear
,
195 tvb
, offset
+4, (int)strlen(ident_decoded
), ident_decoded
);
198 proto_item_set_text(ident_item
, "Authentication Ident: %s",
204 password_item
= proto_tree_add_string_format(tree
, hf_pcnfsd_auth_password
,
205 tvb
, 0, 0, "", "Authentication Password");
206 password_tree
= proto_item_add_subtree(password_item
, ett_pcnfsd_auth_password
);
208 newoffset
= dissect_rpc_string(tvb
, password_tree
,
209 hf_pcnfsd_auth_password_obscure
, offset
, &password
);
211 proto_item_set_len(password_item
, newoffset
-offset
);
215 /* Only attempt to decode the password if it has been specified */
216 if (strcmp(password
, RPC_STRING_EMPTY
))
217 pcnfsd_decode_obscure(pinfo
->pool
, password
, (int)strlen(password
));
220 proto_tree_add_string(password_tree
,
221 hf_pcnfsd_auth_password_clear
,
222 tvb
, offset
+4, (int)strlen(password
), password
);
225 proto_item_set_text(password_item
, "Authentication Password: %s",
231 offset
= dissect_rpc_string(tvb
, tree
,
232 hf_pcnfsd_comment
, offset
, NULL
);
238 /* "NFS Illustrated" 14.7.13 */
240 dissect_pcnfsd2_auth_reply(tvbuff_t
*tvb
, packet_info
*pinfo _U_
,
241 proto_tree
*tree
, void* data _U_
)
248 offset
= dissect_rpc_uint32(tvb
, tree
, hf_pcnfsd_status
, offset
);
249 offset
= dissect_rpc_uint32(tvb
, tree
, hf_pcnfsd_uid
, offset
);
250 offset
= dissect_rpc_uint32(tvb
, tree
, hf_pcnfsd_gid
, offset
);
251 gids_count
= tvb_get_ntohl(tvb
,offset
+0);
252 gtree
= proto_tree_add_subtree_format(tree
, tvb
,
253 offset
, 4+gids_count
*4, ett_pcnfsd_gids
, NULL
, "Group IDs: %d", gids_count
);
255 proto_tree_add_item(gtree
, hf_pcnfsd_gids_count
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
258 for (gids_i
= 0 ; gids_i
< gids_count
; gids_i
++) {
259 offset
= dissect_rpc_uint32(tvb
, gtree
,
260 hf_pcnfsd_gid
, offset
);
262 offset
= dissect_rpc_string(tvb
, tree
,
263 hf_pcnfsd_homedir
, offset
, NULL
);
264 /* should be signed int32 */
265 offset
= dissect_rpc_uint32(tvb
, tree
, hf_pcnfsd_def_umask
, offset
);
266 offset
= dissect_rpc_string(tvb
, tree
,
267 hf_pcnfsd_comment
, offset
, NULL
);
273 /* "NFS Illustrated", 14.6 */
274 /* proc number, "proc name", dissect_request, dissect_reply */
275 static const vsff pcnfsd1_proc
[] = {
276 { 0, "NULL", dissect_rpc_void
, dissect_rpc_void
},
277 { 1, "AUTH", dissect_rpc_unknown
, dissect_rpc_unknown
},
278 { 2, "PR_INIT", dissect_rpc_unknown
, dissect_rpc_unknown
},
279 { 3, "PR_START", dissect_rpc_unknown
, dissect_rpc_unknown
},
280 { 0, NULL
, NULL
, NULL
}
282 static const value_string pcnfsd1_proc_vals
[] = {
289 /* end of PCNFS version 1 */
292 /* "NFS Illustrated", 14.7 */
293 static const vsff pcnfsd2_proc
[] = {
295 dissect_rpc_void
, dissect_rpc_void
},
296 { 1, "INFO", dissect_rpc_unknown
, dissect_rpc_unknown
},
297 { 2, "PR_INIT", dissect_rpc_unknown
, dissect_rpc_unknown
},
298 { 3, "PR_START", dissect_rpc_unknown
, dissect_rpc_unknown
},
299 { 4, "PR_LIST", dissect_rpc_unknown
, dissect_rpc_unknown
},
300 { 5, "PR_QUEUE", dissect_rpc_unknown
, dissect_rpc_unknown
},
301 { 6, "PR_STATUS", dissect_rpc_unknown
, dissect_rpc_unknown
},
302 { 7, "PR_CANCEL", dissect_rpc_unknown
, dissect_rpc_unknown
},
303 { 8, "PR_ADMIN", dissect_rpc_unknown
, dissect_rpc_unknown
},
304 { 9, "PR_REQUEUE", dissect_rpc_unknown
, dissect_rpc_unknown
},
305 { 10, "PR_HOLD", dissect_rpc_unknown
, dissect_rpc_unknown
},
306 { 11, "PR_RELEASE", dissect_rpc_unknown
, dissect_rpc_unknown
},
308 dissect_pcnfsd2_mapid_call
, dissect_pcnfsd2_mapid_reply
},
310 dissect_pcnfsd2_auth_call
, dissect_pcnfsd2_auth_reply
},
311 { 14, "ALERT", dissect_rpc_unknown
, dissect_rpc_unknown
},
312 { 0, NULL
, NULL
, NULL
}
314 static const value_string pcnfsd2_proc_vals
[] = {
326 { 11, "PR_RELEASE" },
332 /* end of PCNFS version 2 */
334 static const rpc_prog_vers_info pcnfsd_vers_info
[] = {
335 { 1, pcnfsd1_proc
, &hf_pcnfsd_procedure_v1
},
336 { 2, pcnfsd2_proc
, &hf_pcnfsd_procedure_v2
},
340 proto_register_pcnfsd(void)
342 static hf_register_info hf
[] = {
343 { &hf_pcnfsd_procedure_v1
, {
344 "V1 Procedure", "pcnfsd.procedure_v1", FT_UINT32
, BASE_DEC
,
345 VALS(pcnfsd1_proc_vals
), 0, NULL
, HFILL
}},
346 { &hf_pcnfsd_procedure_v2
, {
347 "V2 Procedure", "pcnfsd.procedure_v2", FT_UINT32
, BASE_DEC
,
348 VALS(pcnfsd2_proc_vals
), 0, NULL
, HFILL
}},
349 { &hf_pcnfsd_auth_client
, {
350 "Authentication Client", "pcnfsd.auth.client", FT_STRING
, BASE_NONE
,
351 NULL
, 0, NULL
, HFILL
}},
352 { &hf_pcnfsd_auth_ident_obscure
, {
353 "Obscure Ident", "pcnfsd.auth.ident.obscure", FT_STRING
, BASE_NONE
,
354 NULL
, 0, "Authentication Obscure Ident", HFILL
}},
355 { &hf_pcnfsd_auth_ident_clear
, {
356 "Clear Ident", "pcnfsd.auth.ident.clear", FT_STRING
, BASE_NONE
,
357 NULL
, 0, "Authentication Clear Ident", HFILL
}},
358 { &hf_pcnfsd_auth_password
, {
359 "Password", "pcnfsd.auth.password", FT_STRING
, BASE_NONE
,
360 NULL
, 0, NULL
, HFILL
}},
361 { &hf_pcnfsd_auth_password_obscure
, {
362 "Obscure Password", "pcnfsd.auth.password.obscure", FT_STRING
, BASE_NONE
,
363 NULL
, 0, "Authentication Obscure Password", HFILL
}},
364 { &hf_pcnfsd_auth_password_clear
, {
365 "Clear Password", "pcnfsd.auth.password.clear", FT_STRING
, BASE_NONE
,
366 NULL
, 0, "Authentication Clear Password", HFILL
}},
367 { &hf_pcnfsd_comment
, {
368 "Comment", "pcnfsd.comment", FT_STRING
, BASE_NONE
,
369 NULL
, 0, NULL
, HFILL
}},
370 { &hf_pcnfsd_status
, {
371 "Reply Status", "pcnfsd.status", FT_UINT32
, BASE_DEC
,
372 NULL
, 0, NULL
, HFILL
}},
374 "User ID", "pcnfsd.uid", FT_UINT32
, BASE_DEC
,
375 NULL
, 0, NULL
, HFILL
}},
377 "Group ID", "pcnfsd.gid", FT_UINT32
, BASE_DEC
,
378 NULL
, 0, NULL
, HFILL
}},
379 { &hf_pcnfsd_gids_count
, {
380 "Group ID Count", "pcnfsd.gids.count", FT_UINT32
, BASE_DEC
,
381 NULL
, 0, NULL
, HFILL
}},
382 { &hf_pcnfsd_homedir
, {
383 "Home Directory", "pcnfsd.homedir", FT_STRING
, BASE_NONE
,
384 NULL
, 0, NULL
, HFILL
}},
385 { &hf_pcnfsd_def_umask
, {
386 "def_umask", "pcnfsd.def_umask", FT_UINT32
, BASE_OCT
,
387 NULL
, 0, NULL
, HFILL
}},
388 { &hf_pcnfsd_mapreq
, {
389 "Request", "pcnfsd.mapreq", FT_UINT32
, BASE_DEC
,
390 VALS(names_mapreq
), 0, NULL
, HFILL
}},
391 { &hf_pcnfsd_mapreq_status
, {
392 "Status", "pcnfsd.mapreq_status", FT_UINT32
, BASE_DEC
,
393 VALS(names_maprstat
), 0, NULL
, HFILL
}},
394 { &hf_pcnfsd_username
, {
395 "User name", "pcnfsd.username", FT_STRING
, BASE_NONE
,
396 NULL
, 0, "pcnfsd.username", HFILL
}},
399 static int *ett
[] = {
401 &ett_pcnfsd_auth_ident
,
402 &ett_pcnfsd_auth_password
,
406 proto_pcnfsd
= proto_register_protocol("PC NFS", "PCNFSD", "pcnfsd");
407 proto_register_field_array(proto_pcnfsd
, hf
, array_length(hf
));
408 proto_register_subtree_array(ett
, array_length(ett
));
412 proto_reg_handoff_pcnfsd(void)
414 /* Register the protocol as RPC */
415 rpc_init_prog(proto_pcnfsd
, PCNFSD_PROGRAM
, ett_pcnfsd
,
416 G_N_ELEMENTS(pcnfsd_vers_info
), pcnfsd_vers_info
);
420 * Editor modelines - https://www.wireshark.org/tools/modelines.html
425 * indent-tabs-mode: nil
428 * vi: set shiftwidth=4 tabstop=8 expandtab:
429 * :indentSize=4:tabSize=8:noTabs=true: