2 * Routines for ypserv dissection
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * Copied from packet-smb.c
10 * 2001 Ronnie Sahlberg <See AUTHORS for email>
11 * Added all remaining dissectors for this protocol
13 * SPDX-License-Identifier: GPL-2.0-or-later
18 #include <epan/packet.h>
20 #include <wsutil/array.h>
21 #include "packet-rpc.h"
22 #include "packet-ypserv.h"
24 void proto_register_ypserv(void);
25 void proto_reg_handoff_ypserv(void);
27 static int proto_ypserv
;
28 static int hf_ypserv_procedure_v1
;
29 static int hf_ypserv_procedure_v2
;
30 static int hf_ypserv_domain
;
31 static int hf_ypserv_servesdomain
;
32 static int hf_ypserv_map
;
33 static int hf_ypserv_key
;
34 static int hf_ypserv_peer
;
35 static int hf_ypserv_more
;
36 static int hf_ypserv_ordernum
;
37 static int hf_ypserv_transid
;
38 static int hf_ypserv_prog
;
39 static int hf_ypserv_port
;
40 static int hf_ypserv_value
;
41 static int hf_ypserv_status
;
42 static int hf_ypserv_map_parms
;
43 static int hf_ypserv_xfrstat
;
45 static int ett_ypserv
;
46 static int ett_ypserv_map_parms
;
48 static const value_string ypstat
[] =
64 static const value_string xfrstat
[] =
68 { -1, "YPXFR_NOMAP" },
69 { -2, "YPXFR_NODOM" },
72 { -5, "YPXFR_MADDR" },
73 { -6, "YPXFR_YPERR" },
74 { -7, "YPXFR_BADARGS" },
77 { -10, "YPXFR_SKEW" },
78 { -11, "YPXFR_CLEAR" },
79 { -12, "YPXFR_FORCE" },
80 { -13, "YPXFR_XFRERR" },
81 { -14, "YPXFR_REFUSED" },
86 dissect_ypserv_status(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, int32_t *rstatus
)
91 status
=tvb_get_ntohl(tvb
, offset
);
95 offset
= dissect_rpc_uint32(tvb
, tree
, hf_ypserv_status
, offset
);
98 err
=val_to_str(status
, ypstat
, "Unknown error:%u");
99 col_append_fstr(pinfo
->cinfo
, COL_INFO
," %s", err
);
101 proto_item_append_text(tree
, " Error:%s", err
);
108 dissect_domain_call(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
110 proto_item_append_text(tree
, " DOMAIN call");
112 return dissect_rpc_string(tvb
,tree
,hf_ypserv_domain
,0,NULL
);
116 dissect_domain_nonack_call(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
118 proto_item_append_text(tree
, " DOMAIN_NONACK call");
120 return dissect_rpc_string(tvb
,tree
,hf_ypserv_domain
,0,NULL
);
124 dissect_maplist_call(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
126 proto_item_append_text(tree
, " MAPLIST call");
128 return dissect_rpc_string(tvb
,tree
,hf_ypserv_domain
,0,NULL
);
132 dissect_domain_reply(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
135 proto_item_append_text(tree
, " DOMAIN reply");
137 proto_tree_add_item(tree
, hf_ypserv_servesdomain
, tvb
,
138 offset
, 4, ENC_BIG_ENDIAN
);
145 dissect_domain_nonack_reply(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
148 proto_item_append_text(tree
, " DOMAIN_NONACK reply");
150 proto_tree_add_item(tree
, hf_ypserv_servesdomain
, tvb
,
151 offset
, 4, ENC_BIG_ENDIAN
);
158 dissect_match_call(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
163 proto_item_append_text(tree
, " MATCH call");
166 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_domain
, offset
, &str
);
167 col_append_fstr(pinfo
->cinfo
, COL_INFO
," %s/", str
);
168 proto_item_append_text(tree
, " %s/", str
);
171 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_map
, offset
, &str
);
172 col_append_fstr(pinfo
->cinfo
, COL_INFO
,"%s/", str
);
173 proto_item_append_text(tree
, "%s/", str
);
176 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_key
, offset
, &str
);
177 col_append_str(pinfo
->cinfo
, COL_INFO
, str
);
178 proto_item_append_text(tree
, "%s", str
);
184 dissect_match_reply(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
190 proto_item_append_text(tree
, " MATCH reply");
192 offset
= dissect_ypserv_status(tvb
, offset
, pinfo
, tree
, &status
);
195 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_value
,offset
, &str
);
196 col_append_fstr(pinfo
->cinfo
, COL_INFO
," %s", str
);
197 proto_item_append_text(tree
, " %s", str
);
200 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_value
,offset
, NULL
);
208 dissect_first_call(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
211 proto_item_append_text(tree
, " FIRST call");
214 * XXX - does Sun's "yp.x" lie, and claim that the argument to a
215 * FIRST call is a "ypreq_key" rather than a "ypreq_nokey"?
216 * You presumably need the key for NEXT, as "next" is "next
217 * after some entry", and the key tells you which entry, but
218 * you don't need a key for FIRST, as there's only one entry that
219 * is the first entry.
221 * The NIS server originally used DBM, which has a "firstkey()"
222 * call, with no argument, and a "nextkey()" argument, with
223 * a key argument. (Heck, it might *still* use DBM.)
225 * Given that, and given that at least one FIRST call from a Sun
226 * running Solaris 8 (the Sun on which I'm typing this, in fact)
227 * had a "ypreq_nokey" as the argument, I'm assuming that "yp.x"
231 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_domain
, offset
, NULL
);
232 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_map
, offset
, NULL
);
239 dissect_first_reply(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
242 proto_item_append_text(tree
, " FIRST reply");
244 offset
= dissect_ypserv_status(tvb
, offset
, pinfo
, tree
, NULL
);
246 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_value
, offset
, NULL
);
247 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_key
, offset
, NULL
);
253 dissect_next_reply(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
256 proto_item_append_text(tree
, " NEXT reply");
258 offset
= dissect_ypserv_status(tvb
, offset
, pinfo
, tree
, NULL
);
260 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_value
, offset
, NULL
);
261 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_key
, offset
, NULL
);
268 dissect_next_call(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
271 proto_item_append_text(tree
, " NEXT call");
273 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_domain
, offset
, NULL
);
274 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_map
, offset
, NULL
);
275 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_key
, offset
, NULL
);
281 dissect_xfr_call(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
283 proto_item
*sub_item
=NULL
;
284 proto_tree
*sub_tree
=NULL
;
286 int start_offset
= offset
;
288 proto_item_append_text(tree
, " XFR call");
291 sub_item
= proto_tree_add_item(tree
, hf_ypserv_map_parms
, tvb
,
294 sub_tree
= proto_item_add_subtree(sub_item
, ett_ypserv_map_parms
);
297 offset
= dissect_rpc_string(tvb
, sub_tree
, hf_ypserv_domain
, offset
, NULL
);
299 offset
= dissect_rpc_string(tvb
, sub_tree
, hf_ypserv_map
, offset
, NULL
);
301 offset
= dissect_rpc_uint32(tvb
, sub_tree
, hf_ypserv_ordernum
, offset
);
303 offset
= dissect_rpc_string(tvb
, sub_tree
, hf_ypserv_peer
, offset
, NULL
);
305 proto_tree_add_item(tree
, hf_ypserv_transid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
308 offset
= dissect_rpc_uint32(tvb
, tree
, hf_ypserv_prog
, offset
);
309 offset
= dissect_rpc_uint32(tvb
, tree
, hf_ypserv_port
, offset
);
312 proto_item_set_len(sub_item
, offset
- start_offset
);
318 dissect_clear_call(tvbuff_t
*tvb _U_
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
321 proto_item_append_text(tree
, " CLEAR call");
327 dissect_clear_reply(tvbuff_t
*tvb _U_
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
329 proto_item_append_text(tree
, " CLEAR reply");
335 dissect_xfr_reply(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
338 proto_item_append_text(tree
, " XFR reply");
340 proto_tree_add_item(tree
, hf_ypserv_transid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
343 offset
= dissect_rpc_uint32(tvb
, tree
, hf_ypserv_xfrstat
, offset
);
349 dissect_order_call(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
354 proto_item_append_text(tree
, " ORDER call");
357 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_domain
, offset
, &str
);
358 col_append_fstr(pinfo
->cinfo
, COL_INFO
," %s/", str
);
359 proto_item_append_text(tree
, " %s/", str
);
362 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_map
, offset
, &str
);
363 col_append_str(pinfo
->cinfo
, COL_INFO
, str
);
364 proto_item_append_text(tree
, "%s", str
);
370 dissect_all_call(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
373 proto_item_append_text(tree
, " ALL call");
375 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_domain
, offset
, NULL
);
377 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_map
, offset
, NULL
);
383 dissect_master_call(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
386 proto_item_append_text(tree
, " MASTER call");
388 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_domain
, offset
, NULL
);
390 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_map
, offset
, NULL
);
396 dissect_all_reply(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
401 proto_item_append_text(tree
, " ALL reply");
404 more
= tvb_get_ntohl(tvb
, offset
);
406 offset
= dissect_rpc_uint32(tvb
, tree
, hf_ypserv_more
, offset
);
409 offset
= dissect_ypserv_status(tvb
, offset
, pinfo
, tree
, NULL
);
411 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_value
, offset
, NULL
);
412 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_key
, offset
, NULL
);
419 dissect_master_reply(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
422 proto_item_append_text(tree
, " MASTER reply");
424 offset
= dissect_ypserv_status(tvb
, offset
, pinfo
, tree
, NULL
);
426 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_peer
, offset
, NULL
);
433 dissect_order_reply(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
438 proto_item_append_text(tree
, " ORDER reply");
440 offset
= dissect_ypserv_status(tvb
, offset
, pinfo
, tree
, NULL
);
443 num
=tvb_get_ntohl(tvb
, offset
);
444 offset
= dissect_rpc_uint32(tvb
, tree
, hf_ypserv_ordernum
, offset
);
445 col_append_fstr(pinfo
->cinfo
, COL_INFO
," 0x%08x", num
);
446 proto_item_append_text(tree
, " 0x%08x", num
);
453 dissect_maplist_reply(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
456 proto_item_append_text(tree
, " MAPLIST reply");
458 offset
= dissect_ypserv_status(tvb
, offset
, pinfo
, tree
, NULL
);
459 while(tvb_get_ntohl(tvb
,offset
)){
460 offset
= dissect_rpc_uint32(tvb
, tree
, hf_ypserv_more
, offset
);
461 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_map
, offset
, NULL
);
464 offset
= dissect_rpc_uint32(tvb
, tree
, hf_ypserv_more
, offset
);
469 /* proc number, "proc name", dissect_request, dissect_reply */
471 /* someone please get me a version 1 trace */
473 static const vsff ypserv1_proc
[] = {
475 dissect_rpc_void
, dissect_rpc_void
},
476 { YPPROC_DOMAIN
, "DOMAIN",
477 dissect_rpc_unknown
, dissect_rpc_unknown
},
478 { YPPROC_DOMAIN_NONACK
, "DOMAIN_NONACK",
479 dissect_rpc_unknown
, dissect_rpc_unknown
},
480 { YPPROC_MATCH
, "MATCH",
481 dissect_rpc_unknown
, dissect_rpc_unknown
},
482 { YPPROC_FIRST
, "FIRST",
483 dissect_rpc_unknown
, dissect_rpc_unknown
},
484 { YPPROC_NEXT
, "NEXT",
485 dissect_rpc_unknown
, dissect_rpc_unknown
},
487 dissect_rpc_unknown
, dissect_rpc_unknown
},
488 { YPPROC_CLEAR
, "CLEAR",
489 dissect_rpc_unknown
, dissect_rpc_unknown
},
491 dissect_rpc_unknown
, dissect_rpc_unknown
},
492 { YPPROC_MASTER
, "MASTER",
493 dissect_rpc_unknown
, dissect_rpc_unknown
},
494 { YPPROC_ORDER
, "ORDER",
495 dissect_rpc_unknown
, dissect_rpc_unknown
},
496 { YPPROC_MAPLIST
, "MAPLIST",
497 dissect_rpc_unknown
, dissect_rpc_unknown
},
498 { 0, NULL
, NULL
, NULL
}
501 static const value_string ypserv1_proc_vals
[] = {
502 { YPPROC_DOMAIN
, "DOMAIN" },
503 { YPPROC_DOMAIN_NONACK
, "DOMAIN_NONACK" },
504 { YPPROC_MATCH
, "MATCH" },
505 { YPPROC_FIRST
, "FIRST" },
506 { YPPROC_NEXT
, "NEXT" },
507 { YPPROC_XFR
, "XFR" },
508 { YPPROC_CLEAR
, "CLEAR" },
509 { YPPROC_ALL
, "ALL" },
510 { YPPROC_MASTER
, "MASTER" },
511 { YPPROC_ORDER
, "ORDER" },
512 { YPPROC_MAPLIST
, "MAPLIST" },
516 /* end of YPServ version 1 */
518 /* proc number, "proc name", dissect_request, dissect_reply */
520 static const vsff ypserv2_proc
[] = {
522 dissect_rpc_void
, dissect_rpc_void
},
523 { YPPROC_DOMAIN
, "DOMAIN",
524 dissect_domain_call
, dissect_domain_reply
},
525 { YPPROC_DOMAIN_NONACK
, "DOMAIN_NONACK",
526 dissect_domain_nonack_call
, dissect_domain_nonack_reply
},
527 { YPPROC_MATCH
, "MATCH",
528 dissect_match_call
, dissect_match_reply
},
529 { YPPROC_FIRST
, "FIRST",
530 dissect_first_call
, dissect_first_reply
},
531 { YPPROC_NEXT
, "NEXT",
532 dissect_next_call
, dissect_next_reply
},
534 dissect_xfr_call
, dissect_xfr_reply
},
535 { YPPROC_CLEAR
, "CLEAR",
536 dissect_clear_call
, dissect_clear_reply
},
538 dissect_all_call
, dissect_all_reply
},
539 { YPPROC_MASTER
, "MASTER",
540 dissect_master_call
, dissect_master_reply
},
541 { YPPROC_ORDER
, "ORDER",
542 dissect_order_call
, dissect_order_reply
},
543 { YPPROC_MAPLIST
, "MAPLIST",
544 dissect_maplist_call
, dissect_maplist_reply
},
545 { 0, NULL
, NULL
, NULL
}
548 static const value_string ypserv2_proc_vals
[] = {
549 { YPPROC_DOMAIN
, "DOMAIN" },
550 { YPPROC_DOMAIN_NONACK
, "DOMAIN_NONACK" },
551 { YPPROC_MATCH
, "MATCH" },
552 { YPPROC_FIRST
, "FIRST" },
553 { YPPROC_NEXT
, "NEXT" },
554 { YPPROC_XFR
, "XFR" },
555 { YPPROC_CLEAR
, "CLEAR" },
556 { YPPROC_ALL
, "ALL" },
557 { YPPROC_MASTER
, "MASTER" },
558 { YPPROC_ORDER
, "ORDER" },
559 { YPPROC_MAPLIST
, "MAPLIST" },
563 /* end of YPServ version 2 */
566 static const rpc_prog_vers_info ypserv_vers_info
[] = {
567 { 1, ypserv1_proc
, &hf_ypserv_procedure_v1
},
568 { 2, ypserv2_proc
, &hf_ypserv_procedure_v2
},
572 proto_register_ypserv(void)
574 static hf_register_info hf
[] = {
575 { &hf_ypserv_procedure_v1
, {
576 "V1 Procedure", "ypserv.procedure_v1", FT_UINT32
, BASE_DEC
,
577 VALS(ypserv1_proc_vals
), 0, NULL
, HFILL
}},
578 { &hf_ypserv_procedure_v2
, {
579 "V2 Procedure", "ypserv.procedure_v2", FT_UINT32
, BASE_DEC
,
580 VALS(ypserv2_proc_vals
), 0, NULL
, HFILL
}},
581 { &hf_ypserv_domain
, {
582 "Domain", "ypserv.domain", FT_STRING
, BASE_NONE
,
583 NULL
, 0, NULL
, HFILL
}},
584 { &hf_ypserv_servesdomain
, {
585 "Serves Domain", "ypserv.servesdomain", FT_BOOLEAN
, BASE_NONE
,
586 TFS(&tfs_yes_no
), 0x0, NULL
, HFILL
}},
588 "Map Name", "ypserv.map", FT_STRING
, BASE_NONE
,
589 NULL
, 0, NULL
, HFILL
}},
591 "Peer Name", "ypserv.peer", FT_STRING
, BASE_NONE
,
592 NULL
, 0, NULL
, HFILL
}},
594 "More", "ypserv.more", FT_BOOLEAN
, BASE_NONE
,
595 TFS(&tfs_yes_no
), 0x0, NULL
, HFILL
}},
596 { &hf_ypserv_ordernum
, {
597 "Order Number", "ypserv.ordernum", FT_UINT32
, BASE_DEC
,
598 NULL
, 0, "Order Number for XFR", HFILL
}},
599 { &hf_ypserv_transid
, {
600 "Host Transport ID", "ypserv.transid", FT_IPv4
, BASE_NONE
,
601 NULL
, 0, "Host Transport ID to use for XFR Callback", HFILL
}},
603 "Program Number", "ypserv.prog", FT_UINT32
, BASE_DEC
,
604 NULL
, 0, "Program Number to use for XFR Callback", HFILL
}},
606 "Port", "ypserv.port", FT_UINT32
, BASE_DEC
,
607 NULL
, 0, "Port to use for XFR Callback", HFILL
}},
609 "Key", "ypserv.key", FT_STRING
, BASE_NONE
,
610 NULL
, 0, NULL
, HFILL
}},
611 { &hf_ypserv_value
, {
612 "Value", "ypserv.value", FT_STRING
, BASE_NONE
,
613 NULL
, 0, NULL
, HFILL
}},
614 { &hf_ypserv_status
, {
615 "Status", "ypserv.status", FT_INT32
, BASE_DEC
,
616 VALS(ypstat
) , 0, NULL
, HFILL
}},
617 { &hf_ypserv_map_parms
, {
618 "YP Map Parameters", "ypserv.map_parms", FT_NONE
, BASE_NONE
,
619 NULL
, 0, NULL
, HFILL
}},
620 { &hf_ypserv_xfrstat
, {
621 "Xfrstat", "ypserv.xfrstat", FT_INT32
, BASE_DEC
,
622 VALS(xfrstat
), 0, NULL
, HFILL
}},
624 static int *ett
[] = {
626 &ett_ypserv_map_parms
,
629 proto_ypserv
= proto_register_protocol("Yellow Pages Service",
631 proto_register_field_array(proto_ypserv
, hf
, array_length(hf
));
632 proto_register_subtree_array(ett
, array_length(ett
));
636 proto_reg_handoff_ypserv(void)
638 /* Register the protocol as RPC */
639 rpc_init_prog(proto_ypserv
, YPSERV_PROGRAM
, ett_ypserv
,
640 G_N_ELEMENTS(ypserv_vers_info
), ypserv_vers_info
);
644 * Editor modelines - https://www.wireshark.org/tools/modelines.html
649 * indent-tabs-mode: t
652 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
653 * :indentSize=8:tabSize=8:noTabs=false: