2 * Routines for ypserv dissection
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * Copied from packet-smb.c
12 * 2001 Ronnie Sahlberg <See AUTHORS for email>
13 * Added all remaining dissectors for this protocol
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 #include "packet-rpc.h"
35 #include "packet-ypserv.h"
37 static int proto_ypserv
= -1;
38 static int hf_ypserv_procedure_v1
= -1;
39 static int hf_ypserv_procedure_v2
= -1;
40 static int hf_ypserv_domain
= -1;
41 static int hf_ypserv_servesdomain
= -1;
42 static int hf_ypserv_map
= -1;
43 static int hf_ypserv_key
= -1;
44 static int hf_ypserv_peer
= -1;
45 static int hf_ypserv_more
= -1;
46 static int hf_ypserv_ordernum
= -1;
47 static int hf_ypserv_transid
= -1;
48 static int hf_ypserv_prog
= -1;
49 static int hf_ypserv_port
= -1;
50 static int hf_ypserv_value
= -1;
51 static int hf_ypserv_status
= -1;
52 static int hf_ypserv_map_parms
= -1;
53 static int hf_ypserv_xfrstat
= -1;
55 static gint ett_ypserv
= -1;
56 static gint ett_ypserv_map_parms
= -1;
58 static const value_string ypstat
[] =
74 static const value_string xfrstat
[] =
78 { -1, "YPXFR_NOMAP" },
79 { -2, "YPXFR_NODOM" },
82 { -5, "YPXFR_MADDR" },
83 { -6, "YPXFR_YPERR" },
84 { -7, "YPXFR_BADARGS" },
87 { -10, "YPXFR_SKEW" },
88 { -11, "YPXFR_CLEAR" },
89 { -12, "YPXFR_FORCE" },
90 { -13, "YPXFR_XFRERR" },
91 { -14, "YPXFR_REFUSED" },
96 dissect_ypserv_status(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, gint32
*rstatus
)
101 status
=tvb_get_ntohl(tvb
, offset
);
105 offset
= dissect_rpc_uint32(tvb
, tree
, hf_ypserv_status
, offset
);
108 err
=val_to_str(status
, ypstat
, "Unknown error:%u");
109 col_append_fstr(pinfo
->cinfo
, COL_INFO
," %s", err
);
111 proto_item_append_text(tree
, " Error:%s", err
);
118 dissect_domain_call(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
120 proto_item_append_text(tree
, " DOMAIN call");
124 offset
= dissect_rpc_string(tvb
,tree
,hf_ypserv_domain
,offset
,NULL
);
131 dissect_domain_nonack_call(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
133 proto_item_append_text(tree
, " DOMAIN_NONACK call");
137 offset
= dissect_rpc_string(tvb
,tree
,hf_ypserv_domain
,offset
,NULL
);
144 dissect_maplist_call(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
146 proto_item_append_text(tree
, " MAPLIST call");
150 offset
= dissect_rpc_string(tvb
,tree
,hf_ypserv_domain
,offset
,NULL
);
157 dissect_domain_reply(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
159 proto_item_append_text(tree
, " DOMAIN reply");
163 proto_tree_add_boolean(tree
, hf_ypserv_servesdomain
, tvb
,
164 offset
, 4, tvb_get_ntohl(tvb
,offset
));
172 dissect_domain_nonack_reply(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
174 proto_item_append_text(tree
, " DOMAIN_NONACK reply");
178 proto_tree_add_boolean(tree
, hf_ypserv_servesdomain
, tvb
,
179 offset
, 4, tvb_get_ntohl(tvb
,offset
));
187 dissect_match_call(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
191 proto_item_append_text(tree
, " MATCH call");
194 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_domain
, offset
, &str
);
195 col_append_fstr(pinfo
->cinfo
, COL_INFO
," %s/", str
);
196 proto_item_append_text(tree
, " %s/", str
);
199 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_map
, offset
, &str
);
200 col_append_fstr(pinfo
->cinfo
, COL_INFO
,"%s/", str
);
201 proto_item_append_text(tree
, "%s/", str
);
204 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_key
, offset
, &str
);
205 col_append_fstr(pinfo
->cinfo
, COL_INFO
,"%s", str
);
206 proto_item_append_text(tree
, "%s", str
);
212 dissect_match_reply(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
217 proto_item_append_text(tree
, " MATCH reply");
221 offset
= dissect_ypserv_status(tvb
, offset
, pinfo
, tree
, &status
);
224 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_value
,offset
, &str
);
225 col_append_fstr(pinfo
->cinfo
, COL_INFO
," %s", str
);
226 proto_item_append_text(tree
, " %s", str
);
229 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_value
,offset
, NULL
);
238 dissect_first_call(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
240 proto_item_append_text(tree
, " FIRST call");
243 * XXX - does Sun's "yp.x" lie, and claim that the argument to a
244 * FIRST call is a "ypreq_key" rather than a "ypreq_nokey"?
245 * You presumably need the key for NEXT, as "next" is "next
246 * after some entry", and the key tells you which entry, but
247 * you don't need a key for FIRST, as there's only one entry that
248 * is the first entry.
250 * The NIS server originally used DBM, which has a "firstkey()"
251 * call, with no argument, and a "nextkey()" argument, with
252 * a key argument. (Heck, it might *still* use DBM.)
254 * Given that, and given that at least one FIRST call from a Sun
255 * running Solaris 8 (the Sun on which I'm typing this, in fact)
256 * had a "ypreq_nokey" as the argument, I'm assuming that "yp.x"
262 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_domain
, offset
, NULL
);
263 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_map
, offset
, NULL
);
271 dissect_first_reply(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
273 proto_item_append_text(tree
, " FIRST reply");
277 offset
= dissect_ypserv_status(tvb
, offset
, pinfo
, tree
, NULL
);
279 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_value
, offset
, NULL
);
280 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_key
, offset
, NULL
);
287 dissect_next_reply(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
289 proto_item_append_text(tree
, " NEXT reply");
293 offset
= dissect_ypserv_status(tvb
, offset
, pinfo
, tree
, NULL
);
295 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_value
, offset
, NULL
);
296 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_key
, offset
, NULL
);
304 dissect_next_call(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
306 proto_item_append_text(tree
, " NEXT call");
310 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_domain
, offset
, NULL
);
311 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_map
, offset
, NULL
);
312 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_key
, offset
, NULL
);
319 dissect_xfr_call(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
321 proto_item
*sub_item
=NULL
;
322 proto_tree
*sub_tree
=NULL
;
323 int start_offset
= offset
;
325 proto_item_append_text(tree
, " XFR call");
328 sub_item
= proto_tree_add_item(tree
, hf_ypserv_map_parms
, tvb
,
331 sub_tree
= proto_item_add_subtree(sub_item
, ett_ypserv_map_parms
);
334 offset
= dissect_rpc_string(tvb
, sub_tree
, hf_ypserv_domain
, offset
, NULL
);
336 offset
= dissect_rpc_string(tvb
, sub_tree
, hf_ypserv_map
, offset
, NULL
);
338 offset
= dissect_rpc_uint32(tvb
, sub_tree
, hf_ypserv_ordernum
, offset
);
340 offset
= dissect_rpc_string(tvb
, sub_tree
, hf_ypserv_peer
, offset
, NULL
);
342 proto_tree_add_item(tree
, hf_ypserv_transid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
345 offset
= dissect_rpc_uint32(tvb
, tree
, hf_ypserv_prog
, offset
);
346 offset
= dissect_rpc_uint32(tvb
, tree
, hf_ypserv_port
, offset
);
349 proto_item_set_len(sub_item
, offset
- start_offset
);
355 dissect_clear_call(tvbuff_t
*tvb _U_
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
357 proto_item_append_text(tree
, " CLEAR call");
363 dissect_clear_reply(tvbuff_t
*tvb _U_
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
365 proto_item_append_text(tree
, " CLEAR reply");
371 dissect_xfr_reply(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
373 proto_item_append_text(tree
, " XFR reply");
375 proto_tree_add_item(tree
, hf_ypserv_transid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
378 offset
= dissect_rpc_uint32(tvb
, tree
, hf_ypserv_xfrstat
, offset
);
384 dissect_order_call(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
388 proto_item_append_text(tree
, " ORDER call");
391 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_domain
, offset
, &str
);
392 col_append_fstr(pinfo
->cinfo
, COL_INFO
," %s/", str
);
393 proto_item_append_text(tree
, " %s/", str
);
396 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_map
, offset
, &str
);
397 col_append_str(pinfo
->cinfo
, COL_INFO
, str
);
398 proto_item_append_text(tree
, "%s", str
);
404 dissect_all_call(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
406 proto_item_append_text(tree
, " ALL call");
408 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_domain
, offset
, NULL
);
410 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_map
, offset
, NULL
);
416 dissect_master_call(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
418 proto_item_append_text(tree
, " MASTER call");
420 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_domain
, offset
, NULL
);
422 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_map
, offset
, NULL
);
428 dissect_all_reply(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
432 proto_item_append_text(tree
, " ALL reply");
435 more
= tvb_get_ntohl(tvb
, offset
);
437 offset
= dissect_rpc_uint32(tvb
, tree
, hf_ypserv_more
, offset
);
440 offset
= dissect_ypserv_status(tvb
, offset
, pinfo
, tree
, NULL
);
442 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_value
, offset
, NULL
);
443 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_key
, offset
, NULL
);
450 dissect_master_reply(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
452 proto_item_append_text(tree
, " MASTER reply");
454 offset
= dissect_ypserv_status(tvb
, offset
, pinfo
, tree
, NULL
);
456 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_peer
, offset
, NULL
);
463 dissect_order_reply(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
467 proto_item_append_text(tree
, " ORDER reply");
469 offset
= dissect_ypserv_status(tvb
, offset
, pinfo
, tree
, NULL
);
472 num
=tvb_get_ntohl(tvb
, offset
);
473 offset
= dissect_rpc_uint32(tvb
, tree
, hf_ypserv_ordernum
, offset
);
474 col_append_fstr(pinfo
->cinfo
, COL_INFO
," 0x%08x", num
);
475 proto_item_append_text(tree
, " 0x%08x", num
);
482 dissect_maplist_reply(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
484 proto_item_append_text(tree
, " MAPLIST reply");
486 offset
= dissect_ypserv_status(tvb
, offset
, pinfo
, tree
, NULL
);
487 while(tvb_get_ntohl(tvb
,offset
)){
488 offset
= dissect_rpc_uint32(tvb
, tree
, hf_ypserv_more
, offset
);
489 offset
= dissect_rpc_string(tvb
, tree
, hf_ypserv_map
, offset
, NULL
);
492 offset
= dissect_rpc_uint32(tvb
, tree
, hf_ypserv_more
, offset
);
497 /* proc number, "proc name", dissect_request, dissect_reply */
498 /* NULL as function pointer means: type of arguments is "void". */
500 /* someone please get me a version 1 trace */
502 static const vsff ypserv1_proc
[] = {
503 { 0, "NULL", NULL
, NULL
},
504 { YPPROC_DOMAIN
, "DOMAIN",
506 { YPPROC_DOMAIN_NONACK
, "DOMAIN_NONACK",
508 { YPPROC_MATCH
, "MATCH",
510 { YPPROC_FIRST
, "FIRST",
512 { YPPROC_NEXT
, "NEXT",
516 { YPPROC_CLEAR
, "CLEAR",
520 { YPPROC_MASTER
, "MASTER",
522 { YPPROC_ORDER
, "ORDER",
524 { YPPROC_MAPLIST
, "MAPLIST",
526 { 0, NULL
, NULL
, NULL
}
529 static const value_string ypserv1_proc_vals
[] = {
530 { YPPROC_DOMAIN
, "DOMAIN" },
531 { YPPROC_DOMAIN_NONACK
, "DOMAIN_NONACK" },
532 { YPPROC_MATCH
, "MATCH" },
533 { YPPROC_FIRST
, "FIRST" },
534 { YPPROC_NEXT
, "NEXT" },
535 { YPPROC_XFR
, "XFR" },
536 { YPPROC_CLEAR
, "CLEAR" },
537 { YPPROC_ALL
, "ALL" },
538 { YPPROC_MASTER
, "MASTER" },
539 { YPPROC_ORDER
, "ORDER" },
540 { YPPROC_MAPLIST
, "MAPLIST" },
544 /* end of YPServ version 1 */
546 /* proc number, "proc name", dissect_request, dissect_reply */
547 /* NULL as function pointer means: type of arguments is "void". */
549 static const vsff ypserv2_proc
[] = {
550 { 0, "NULL", NULL
, NULL
},
551 { YPPROC_DOMAIN
, "DOMAIN",
552 dissect_domain_call
, dissect_domain_reply
},
553 { YPPROC_DOMAIN_NONACK
, "DOMAIN_NONACK",
554 dissect_domain_nonack_call
, dissect_domain_nonack_reply
},
555 { YPPROC_MATCH
, "MATCH",
556 dissect_match_call
, dissect_match_reply
},
557 { YPPROC_FIRST
, "FIRST",
558 dissect_first_call
, dissect_first_reply
},
559 { YPPROC_NEXT
, "NEXT",
560 dissect_next_call
, dissect_next_reply
},
562 dissect_xfr_call
, dissect_xfr_reply
},
563 { YPPROC_CLEAR
, "CLEAR",
564 dissect_clear_call
, dissect_clear_reply
},
566 dissect_all_call
, dissect_all_reply
},
567 { YPPROC_MASTER
, "MASTER",
568 dissect_master_call
, dissect_master_reply
},
569 { YPPROC_ORDER
, "ORDER",
570 dissect_order_call
, dissect_order_reply
},
571 { YPPROC_MAPLIST
, "MAPLIST",
572 dissect_maplist_call
, dissect_maplist_reply
},
573 { 0, NULL
, NULL
, NULL
}
576 static const value_string ypserv2_proc_vals
[] = {
577 { YPPROC_DOMAIN
, "DOMAIN" },
578 { YPPROC_DOMAIN_NONACK
, "DOMAIN_NONACK" },
579 { YPPROC_MATCH
, "MATCH" },
580 { YPPROC_FIRST
, "FIRST" },
581 { YPPROC_NEXT
, "NEXT" },
582 { YPPROC_XFR
, "XFR" },
583 { YPPROC_CLEAR
, "CLEAR" },
584 { YPPROC_ALL
, "ALL" },
585 { YPPROC_MASTER
, "MASTER" },
586 { YPPROC_ORDER
, "ORDER" },
587 { YPPROC_MAPLIST
, "MAPLIST" },
591 /* end of YPServ version 2 */
595 proto_register_ypserv(void)
597 static hf_register_info hf
[] = {
598 { &hf_ypserv_procedure_v1
, {
599 "V1 Procedure", "ypserv.procedure_v1", FT_UINT32
, BASE_DEC
,
600 VALS(ypserv1_proc_vals
), 0, NULL
, HFILL
}},
601 { &hf_ypserv_procedure_v2
, {
602 "V2 Procedure", "ypserv.procedure_v2", FT_UINT32
, BASE_DEC
,
603 VALS(ypserv2_proc_vals
), 0, NULL
, HFILL
}},
604 { &hf_ypserv_domain
, {
605 "Domain", "ypserv.domain", FT_STRING
, BASE_NONE
,
606 NULL
, 0, NULL
, HFILL
}},
607 { &hf_ypserv_servesdomain
, {
608 "Serves Domain", "ypserv.servesdomain", FT_BOOLEAN
, BASE_NONE
,
609 TFS(&tfs_yes_no
), 0x0, NULL
, HFILL
}},
611 "Map Name", "ypserv.map", FT_STRING
, BASE_NONE
,
612 NULL
, 0, NULL
, HFILL
}},
614 "Peer Name", "ypserv.peer", FT_STRING
, BASE_NONE
,
615 NULL
, 0, NULL
, HFILL
}},
617 "More", "ypserv.more", FT_BOOLEAN
, BASE_NONE
,
618 TFS(&tfs_yes_no
), 0x0, NULL
, HFILL
}},
619 { &hf_ypserv_ordernum
, {
620 "Order Number", "ypserv.ordernum", FT_UINT32
, BASE_DEC
,
621 NULL
, 0, "Order Number for XFR", HFILL
}},
622 { &hf_ypserv_transid
, {
623 "Host Transport ID", "ypserv.transid", FT_IPv4
, BASE_NONE
,
624 NULL
, 0, "Host Transport ID to use for XFR Callback", HFILL
}},
626 "Program Number", "ypserv.prog", FT_UINT32
, BASE_DEC
,
627 NULL
, 0, "Program Number to use for XFR Callback", HFILL
}},
629 "Port", "ypserv.port", FT_UINT32
, BASE_DEC
,
630 NULL
, 0, "Port to use for XFR Callback", HFILL
}},
632 "Key", "ypserv.key", FT_STRING
, BASE_NONE
,
633 NULL
, 0, NULL
, HFILL
}},
634 { &hf_ypserv_value
, {
635 "Value", "ypserv.value", FT_STRING
, BASE_NONE
,
636 NULL
, 0, NULL
, HFILL
}},
637 { &hf_ypserv_status
, {
638 "Status", "ypserv.status", FT_INT32
, BASE_DEC
,
639 VALS(ypstat
) , 0, NULL
, HFILL
}},
640 { &hf_ypserv_map_parms
, {
641 "YP Map Parameters", "ypserv.map_parms", FT_NONE
, BASE_NONE
,
642 NULL
, 0, NULL
, HFILL
}},
643 { &hf_ypserv_xfrstat
, {
644 "Xfrstat", "ypserv.xfrstat", FT_INT32
, BASE_DEC
,
645 VALS(xfrstat
), 0, NULL
, HFILL
}},
647 static gint
*ett
[] = {
649 &ett_ypserv_map_parms
,
652 proto_ypserv
= proto_register_protocol("Yellow Pages Service",
654 proto_register_field_array(proto_ypserv
, hf
, array_length(hf
));
655 proto_register_subtree_array(ett
, array_length(ett
));
659 proto_reg_handoff_ypserv(void)
661 /* Register the protocol as RPC */
662 rpc_init_prog(proto_ypserv
, YPSERV_PROGRAM
, ett_ypserv
);
663 /* Register the procedure tables */
664 rpc_init_proc_table(YPSERV_PROGRAM
, 1, ypserv1_proc
,
665 hf_ypserv_procedure_v1
);
666 rpc_init_proc_table(YPSERV_PROGRAM
, 2, ypserv2_proc
,
667 hf_ypserv_procedure_v2
);