e6ffb4321de5050719c02fb432a06f2e74c053e7
[obnox/wireshark/wip.git] / packet-portmap.c
1 /* packet-portmap.c
2  * Routines for portmap dissection
3  *
4  * $Id: packet-portmap.c,v 1.4 1999/11/11 20:18:46 nneul Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@unicom.net>
8  * Copyright 1998 Gerald Combs
9  *
10  * Copied from packet-smb.c
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31
32 #ifdef HAVE_SYS_TYPES_H
33 #include <sys/types.h>
34 #endif
35
36
37 #include "packet-rpc.h"
38 #include "packet-portmap.h"
39
40 static int proto_portmap = -1;
41 static int hf_portmap_proto = -1;
42 static int hf_portmap_prog = -1;
43 static int hf_portmap_proc = -1;
44 static int hf_portmap_version = -1;
45 static int hf_portmap_port = -1;
46
47 /* Dissect a getport call */
48 int dissect_getport_call(const u_char *pd, int offset, frame_data *fd,
49         proto_tree *tree)
50 {
51         guint32 proto;
52         if ( !BYTES_ARE_IN_FRAME(offset, 12)) return offset;
53
54         if ( tree )
55         {
56                 proto_tree_add_item(tree, hf_portmap_prog,
57                         offset, 4, pntohl(&pd[offset+0]));
58                 proto_tree_add_item(tree, hf_portmap_version,
59                         offset+4, 4, pntohl(&pd[offset+4]));
60
61                 proto = pntohl(&pd[offset+8]);
62                 proto_tree_add_item_format(tree, hf_portmap_proto,
63                         offset+8, 4, proto, "Proto: %s (%d)", ipprotostr(proto), proto);
64         }
65         
66         return offset+12;
67 }
68
69 int dissect_getport_reply(const u_char *pd, int offset, frame_data *fd,
70         proto_tree *tree)
71 {
72         if ( tree )
73         {
74                 if ( !BYTES_ARE_IN_FRAME(offset, 4)) return offset;
75
76                 proto_tree_add_item(tree, hf_portmap_port,
77                         offset, 4, pntohl(&pd[offset+0]));
78         }
79     return offset;
80 }
81
82 /* Dissect a 'set' call */
83 int dissect_set_call(const u_char *pd, int offset, frame_data *fd,
84         proto_tree *tree)
85 {
86         guint32 proto;
87         if ( !BYTES_ARE_IN_FRAME(offset, 16)) return offset;
88
89         if ( tree )
90         {
91                 proto_tree_add_item(tree, hf_portmap_prog,
92                         offset, 4, pntohl(&pd[offset+0]));
93                 proto_tree_add_item(tree, hf_portmap_version,
94                         offset+4, 4, pntohl(&pd[offset+4]));
95
96                 proto = pntohl(&pd[offset+8]);
97                 proto_tree_add_item_format(tree, hf_portmap_proto,
98                         offset+8, 4, proto, "Proto: %s (%d)", ipprotostr(proto), proto);
99
100                 proto_tree_add_item(tree, hf_portmap_port,
101                         offset+12, 4, pntohl(&pd[offset+12]));
102         }
103         
104         return offset+16;
105 }
106
107 /* Dissect a 'unset' call */
108 int dissect_unset_call(const u_char *pd, int offset, frame_data *fd,
109         proto_tree *tree)
110 {
111         guint32 proto;
112         if ( !BYTES_ARE_IN_FRAME(offset, 16)) return offset;
113
114         if ( tree )
115         {
116                 proto_tree_add_item(tree, hf_portmap_prog,
117                         offset, 4, pntohl(&pd[offset+0]));
118                 proto_tree_add_item(tree, hf_portmap_version,
119                         offset+4, 4, pntohl(&pd[offset+4]));
120
121                 proto = pntohl(&pd[offset+8]);
122                 proto_tree_add_item(tree, hf_portmap_proto,
123                         offset+8, 4, proto);
124
125                 proto_tree_add_item(tree, hf_portmap_port,
126                         offset+12, 4, pntohl(&pd[offset+12]));
127         }
128         
129         return offset+16;
130 }
131
132
133 /* proc number, "proc name", dissect_request, dissect_reply */
134 /* NULL as function pointer means: take the generic one. */
135 const vsff portmap1_proc[] = {
136         { PORTMAPPROC_NULL,     "NULL",         NULL,                           NULL },
137         { PORTMAPPROC_SET,      "SET",          NULL,                           NULL },
138         { PORTMAPPROC_UNSET,    "UNSET",                NULL,                           NULL },
139         { PORTMAPPROC_GETPORT,  "GETPORT",              NULL,                           NULL },
140         { PORTMAPPROC_DUMP,     "DUMP",         NULL,                           NULL },
141         { PORTMAPPROC_CALLIT,   "CALLIT",               NULL,                           NULL },
142         { 0,    NULL,           NULL,                           NULL }
143 };
144 /* end of Portmap version 1 */
145
146 const vsff portmap2_proc[] = {
147         { PORTMAPPROC_NULL, "NULL",
148                 NULL, NULL },
149         { PORTMAPPROC_SET, "SET",
150                 dissect_set_call, NULL },
151         { PORTMAPPROC_UNSET, "UNSET",
152                 dissect_unset_call, NULL },
153         { PORTMAPPROC_GETPORT,  "GETPORT",
154                 dissect_getport_call, dissect_getport_reply },
155         { PORTMAPPROC_DUMP, "DUMP",
156                 NULL, NULL },
157         { PORTMAPPROC_CALLIT, "CALLIT",
158                 NULL, NULL },
159     { 0, NULL, NULL, NULL }
160 };
161 /* end of Portmap version 2 */
162
163
164 void
165 proto_register_portmap(void)
166 {
167         static hf_register_info hf[] = {
168                 { &hf_portmap_prog, {
169                         "Program", "portmap.prog", FT_UINT32, BASE_DEC,
170                         NULL, 0, "Program" }},
171                 { &hf_portmap_port, {
172                         "Port", "portmap.port", FT_UINT32, BASE_DEC,
173                         NULL, 0, "Port" }},
174                 { &hf_portmap_proc, {
175                         "Procedure", "portmap.proc", FT_UINT32, BASE_DEC,
176                         NULL, 0, "Procedure" }},
177                 { &hf_portmap_proto, {
178                         "Protocol", "portmap.proto", FT_UINT32, BASE_DEC,
179                         NULL, 0, "Protocol" }},
180                 { &hf_portmap_version, {
181                         "Version", "portmap.version", FT_UINT32, BASE_DEC,
182                         NULL, 0, "Version" }},
183         };
184
185         proto_portmap = proto_register_protocol("Portmap", "portmap");
186         proto_register_field_array(proto_portmap, hf, array_length(hf));
187
188         /* Register the protocol as RPC */
189         rpc_init_prog(proto_portmap, PORTMAP_PROGRAM, ETT_PORTMAP);
190         /* Register the procedure tables */
191         rpc_init_proc_table(PORTMAP_PROGRAM, 1, portmap1_proc);
192         rpc_init_proc_table(PORTMAP_PROGRAM, 2, portmap2_proc);
193 }
194