Coverage Report

Created: 2026-08-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-portmap.c
Line
Count
Source
1
/* packet-portmap.c
2
 * Routines for portmap dissection
3
 *
4
 * Wireshark - Network traffic analyzer
5
 * By Gerald Combs <gerald@wireshark.org>
6
 * Copyright 1998 Gerald Combs
7
 *
8
 * Copied from packet-smb.c
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
#include "config.h"
14
15
#include <epan/packet.h>
16
#include <epan/conversation.h>
17
#include <epan/uuid_types.h>
18
#include <epan/iana-info.h>
19
#include "packet-rpc.h"
20
#include "packet-portmap.h"
21
#include "packet-ip.h"
22
23
/*
24
 * See:
25
 *
26
 *  RFC 1833, "Binding Protocols for ONC RPC Version 2".
27
 */
28
void proto_register_portmap(void);
29
void proto_reg_handoff_portmap(void);
30
31
static int proto_portmap;
32
static int hf_portmap_procedure_v1;
33
static int hf_portmap_procedure_v2;
34
static int hf_portmap_procedure_v3;
35
static int hf_portmap_procedure_v4;
36
static int hf_portmap_proto;
37
static int hf_portmap_prog;
38
static int hf_portmap_proc;
39
static int hf_portmap_version;
40
static int hf_portmap_port;
41
static int hf_portmap_answer;
42
static int hf_portmap_args;
43
static int hf_portmap_result;
44
static int hf_portmap_rpcb;
45
static int hf_portmap_rpcb_prog;
46
static int hf_portmap_rpcb_version;
47
static int hf_portmap_rpcb_netid;
48
static int hf_portmap_rpcb_addr;
49
static int hf_portmap_rpcb_owner;
50
static int hf_portmap_uaddr;
51
52
53
static int ett_portmap;
54
static int ett_portmap_rpcb;
55
static int ett_portmap_entry;
56
57
static dissector_handle_t rpc_handle;
58
59
/* Dissect a getport call */
60
static int
61
dissect_getport_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
62
0
{
63
0
  uint32_t proto, version;
64
0
  uint32_t prog;
65
0
  const char *prog_name;
66
0
  const char *proto_name;
67
0
  unsigned offset = 0;
68
69
  /* make sure we remember protocol type until the reply packet */
70
0
  if(!pinfo->fd->visited){
71
0
    rpc_call_info_value *rpc_call=(rpc_call_info_value *)data;
72
0
    if(rpc_call){
73
0
      proto = tvb_get_ntohl(tvb, offset+8);
74
0
      if(proto==IP_PROTO_UDP){  /* only do this for UDP */
75
0
        rpc_call->private_data=(void *)PT_UDP;
76
0
      }
77
0
    }
78
0
  }
79
80
  /* program */
81
0
  prog = tvb_get_ntohl(tvb, offset+0);
82
0
  prog_name = uuid_type_get_uuid_name("rpc", GUINT_TO_POINTER(prog), pinfo->pool);
83
0
  proto_tree_add_uint_format_value(tree, hf_portmap_prog, tvb,
84
0
    offset, 4, prog, "%s (%u)",
85
0
    prog_name, prog);
86
0
  col_append_fstr(pinfo->cinfo, COL_INFO,  " %s(%u)", prog_name, prog);
87
88
0
  proto_item_append_text(tree, " GETPORT Call %s(%u)", prog_name, prog);
89
90
  /* version */
91
0
  version = tvb_get_ntohl(tvb, offset+4);
92
0
  proto_tree_add_item(tree, hf_portmap_version, tvb,
93
0
    offset+4, 4, ENC_BIG_ENDIAN);
94
0
  col_append_fstr(pinfo->cinfo, COL_INFO,  " V:%d", version);
95
96
97
0
  proto_item_append_text(tree, " Version:%d", version);
98
99
100
  /* protocol */
101
0
  proto = tvb_get_ntohl(tvb, offset+8);
102
0
  proto_name = ipprotostr(proto);
103
0
  proto_tree_add_uint_format(tree, hf_portmap_proto, tvb,
104
0
    offset+8, 4, proto, "Proto: %s (%u)", proto_name, proto);
105
0
  col_append_fstr(pinfo->cinfo, COL_INFO,  " %s", proto_name);
106
107
0
  proto_item_append_text(tree, " %s", proto_name);
108
109
  /* port */
110
0
  proto_tree_add_item(tree, hf_portmap_port, tvb,
111
0
    offset+12, 4, ENC_BIG_ENDIAN);
112
113
0
  return offset+16;
114
0
}
115
116
static int
117
dissect_getport_reply(tvbuff_t *tvb, packet_info *pinfo _U_,
118
  proto_tree *tree, void* data)
119
0
{
120
0
  uint32_t portx;
121
0
  unsigned offset = 0;
122
123
  /* we might have learnt a <ipaddr><protocol><port> mapping for ONC-RPC*/
124
0
  if(!pinfo->fd->visited){
125
0
    rpc_call_info_value *rpc_call=(rpc_call_info_value *)data;
126
    /* only do this for UDP, TCP does not need anything like this */
127
0
    if(rpc_call && (GPOINTER_TO_UINT(rpc_call->private_data)==PT_UDP) ){
128
0
      uint32_t port;
129
0
      port=tvb_get_ntohl(tvb, offset);
130
0
      if(port){
131
0
        conversation_t *conv;
132
0
        conv=find_conversation(pinfo->num, &pinfo->src, &pinfo->dst, CONVERSATION_UDP, port, 0, NO_ADDR_B|NO_PORT_B);
133
0
        if(!conv){
134
0
          conv=conversation_new(pinfo->num, &pinfo->src, &pinfo->dst, CONVERSATION_UDP, port, 0, NO_ADDR2|NO_PORT2);
135
0
        }
136
0
        conversation_set_dissector(conv, rpc_handle);
137
0
      }
138
0
    }
139
0
  }
140
141
0
  portx = tvb_get_ntohl(tvb, offset);
142
0
  offset = dissect_rpc_uint32(tvb, tree, hf_portmap_port,
143
0
      offset);
144
0
  proto_item_append_text(tree, " GETPORT Reply Port:%d", portx);
145
0
  if(portx){
146
0
    col_append_fstr(pinfo->cinfo, COL_INFO,  " Port:%d", portx);
147
0
  } else {
148
0
    col_append_str(pinfo->cinfo, COL_INFO,  " PROGRAM_NOT_AVAILABLE");
149
0
    proto_item_append_text(tree, " PROGRAM_NOT_AVAILABLE");
150
0
  }
151
152
0
  return offset;
153
0
}
154
155
/* Dissect a 'set' call */
156
static int
157
dissect_set_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
158
0
{
159
0
  uint32_t proto;
160
0
  uint32_t prog;
161
0
  unsigned offset = 0;
162
163
0
  if ( tree )
164
0
  {
165
0
    prog = tvb_get_ntohl(tvb, offset+0);
166
0
    proto_tree_add_uint_format_value(tree, hf_portmap_prog, tvb,
167
0
      offset, 4, prog, "%s (%d)",
168
0
      uuid_type_get_uuid_name("rpc", GUINT_TO_POINTER(prog), pinfo->pool), prog);
169
0
    proto_tree_add_item(tree, hf_portmap_version, tvb,
170
0
      offset+4, 4, ENC_BIG_ENDIAN);
171
172
0
    proto = tvb_get_ntohl(tvb, offset+8);
173
0
    proto_tree_add_uint_format(tree, hf_portmap_proto,tvb,
174
0
      offset+8, 4, proto, "Proto: %s (%d)", ipprotostr(proto), proto);
175
176
0
    proto_tree_add_item(tree, hf_portmap_port, tvb,
177
0
      offset+12, 4, ENC_BIG_ENDIAN);
178
0
  }
179
180
0
  return offset+16;
181
0
}
182
183
/* Dissect a 'unset' call */
184
static int
185
dissect_unset_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
186
0
{
187
0
  uint32_t proto;
188
0
  uint32_t prog;
189
0
  unsigned offset = 0;
190
191
0
  if ( tree )
192
0
  {
193
0
    prog = tvb_get_ntohl(tvb, offset+0);
194
0
    proto_tree_add_uint_format_value(tree, hf_portmap_prog, tvb,
195
0
      offset, 4, prog, "%s (%d)",
196
0
      uuid_type_get_uuid_name("rpc", GUINT_TO_POINTER(prog), pinfo->pool), prog);
197
0
    proto_tree_add_item(tree, hf_portmap_version, tvb,
198
0
      offset+4, 4, ENC_BIG_ENDIAN);
199
200
0
    proto = tvb_get_ntohl(tvb, offset+8);
201
0
    proto_tree_add_uint(tree, hf_portmap_proto, tvb,
202
0
      offset+8, 4, proto);
203
204
0
    proto_tree_add_item(tree, hf_portmap_port, tvb,
205
0
      offset+12, 4, ENC_BIG_ENDIAN);
206
0
  }
207
208
0
  return offset+16;
209
0
}
210
211
static int
212
dissect_set_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
213
0
{
214
0
  return dissect_rpc_bool(tvb, tree, hf_portmap_answer, 0);
215
0
}
216
217
static int
218
dissect_dump_entry(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
219
0
{
220
0
  int prog, version, proto, port;
221
0
  proto_tree *subtree;
222
223
0
  prog = tvb_get_ntohl(tvb, offset+0);
224
0
  version = tvb_get_ntohl(tvb, offset+4);
225
0
  proto = tvb_get_ntohl(tvb, offset+8);
226
0
  port = tvb_get_ntohl(tvb, offset+12);
227
0
  if ( tree )
228
0
  {
229
0
    const char* prog_name = uuid_type_get_uuid_name("rpc", GUINT_TO_POINTER(prog), pinfo->pool);
230
0
    subtree = proto_tree_add_subtree_format(tree, tvb, offset, 16,
231
0
      ett_portmap_entry, NULL, "Map Entry: %s (%u) V%d",
232
0
      prog_name, prog, version);
233
234
0
    proto_tree_add_uint_format_value(subtree, hf_portmap_prog, tvb,
235
0
      offset+0, 4, prog,
236
0
      "%s (%u)", prog_name, prog);
237
0
    proto_tree_add_uint(subtree, hf_portmap_version, tvb,
238
0
      offset+4, 4, version);
239
0
    proto_tree_add_uint_format_value(subtree, hf_portmap_proto, tvb,
240
0
      offset+8, 4, proto,
241
0
      "%s (0x%02x)", ipprotostr(proto), proto);
242
0
    proto_tree_add_uint(subtree, hf_portmap_port, tvb,
243
0
      offset+12, 4, port);
244
0
  }
245
0
  offset += 16;
246
0
  return offset;
247
0
}
248
249
static int
250
dissect_dump_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
251
0
{
252
0
  return dissect_rpc_list(tvb, pinfo, tree, 0, dissect_dump_entry, NULL);
253
0
}
254
255
/* Dissect a callit call */
256
static int
257
dissect_callit_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
258
0
{
259
0
  uint32_t prog, vers, proc;
260
0
  unsigned offset = 0;
261
262
0
  prog = tvb_get_ntohl(tvb, offset+0);
263
0
  if ( tree )
264
0
  {
265
0
    proto_tree_add_uint_format_value(tree, hf_portmap_prog, tvb,
266
0
      offset, 4, prog, "%s (%u)",
267
0
      uuid_type_get_uuid_name("rpc", GUINT_TO_POINTER(prog), pinfo->pool), prog);
268
0
  }
269
270
0
  vers = tvb_get_ntohl(tvb, offset+4);
271
0
  if ( tree )
272
0
  {
273
0
    proto_tree_add_uint(tree, hf_portmap_version, tvb,
274
0
      offset+4, 4, vers);
275
0
  }
276
277
0
  proc = tvb_get_ntohl(tvb, offset+8);
278
0
  if ( tree )
279
0
  {
280
0
    proto_tree_add_uint_format_value(tree, hf_portmap_proc, tvb,
281
0
      offset+8, 4, proc, "%s (%u)",
282
0
      rpc_proc_name(pinfo->pool, prog, vers, proc), proc);
283
0
  }
284
285
0
  offset += 12;
286
287
  /* Dissect the arguments for this procedure.
288
     Make the columns non-writable, so the dissector won't change
289
     them out from under us. */
290
0
  col_set_writable(pinfo->cinfo, -1, false);
291
0
  offset = dissect_rpc_indir_call(tvb, pinfo, tree, offset,
292
0
    hf_portmap_args, prog, vers, proc);
293
294
0
  return offset;
295
0
}
296
297
/* Dissect a callit reply */
298
static int
299
dissect_callit_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
300
0
{
301
0
  unsigned offset = 0;
302
303
0
  proto_tree_add_item(tree, hf_portmap_port, tvb,
304
0
      offset, 4, ENC_BIG_ENDIAN);
305
0
  offset += 4;
306
307
  /* Dissect the result of this procedure.
308
     Make the columns non-writable, so the dissector won't change
309
     them out from under us. */
310
0
  col_set_writable(pinfo->cinfo, -1, false);
311
0
  offset = dissect_rpc_indir_reply(tvb, pinfo, tree, offset,
312
0
    hf_portmap_result, hf_portmap_prog, hf_portmap_version,
313
0
    hf_portmap_proc);
314
315
0
  return offset;
316
0
}
317
318
/* proc number, "proc name", dissect_request, dissect_reply */
319
static const vsff portmap1_proc[] = {
320
  { PORTMAPPROC_NULL, "NULL",   dissect_rpc_void, dissect_rpc_void },
321
  { PORTMAPPROC_SET,  "SET",    dissect_rpc_unknown,  dissect_rpc_unknown },
322
  { PORTMAPPROC_UNSET,  "UNSET",  dissect_rpc_unknown,  dissect_rpc_unknown },
323
  { PORTMAPPROC_GETPORT,  "GETPORT",  dissect_rpc_unknown,  dissect_rpc_unknown },
324
  { PORTMAPPROC_DUMP, "DUMP",   dissect_rpc_unknown,  dissect_rpc_unknown },
325
  { PORTMAPPROC_CALLIT, "CALLIT", dissect_rpc_unknown,  dissect_rpc_unknown },
326
  { 0,      NULL,   NULL, NULL }
327
};
328
static const value_string portmap_proc_vals[] = {
329
  { PORTMAPPROC_NULL, "NULL" },
330
  { PORTMAPPROC_SET,  "SET" },
331
  { PORTMAPPROC_UNSET,  "UNSET" },
332
  { PORTMAPPROC_GETPORT,  "GETPORT" },
333
  { PORTMAPPROC_DUMP, "DUMP" },
334
  { PORTMAPPROC_CALLIT, "CALLIT" },
335
  { 0,      NULL }
336
};
337
/* end of Portmap version 1 */
338
339
static const vsff portmap2_proc[] = {
340
  { PORTMAPPROC_NULL, "NULL",
341
    dissect_rpc_void, dissect_rpc_void },
342
  { PORTMAPPROC_SET, "SET",
343
    dissect_set_call, dissect_set_reply },
344
  { PORTMAPPROC_UNSET, "UNSET",
345
    dissect_unset_call, dissect_set_reply },
346
  { PORTMAPPROC_GETPORT,  "GETPORT",
347
    dissect_getport_call, dissect_getport_reply },
348
  { PORTMAPPROC_DUMP, "DUMP",
349
    dissect_rpc_void, dissect_dump_reply },
350
  { PORTMAPPROC_CALLIT, "CALLIT",
351
    dissect_callit_call, dissect_callit_reply },
352
  { 0, NULL, NULL, NULL }
353
};
354
/* end of Portmap version 2 */
355
356
357
/* RFC 1833, Page 3 */
358
static int
359
dissect_rpcb(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, void* data _U_)
360
0
{
361
0
  proto_item* rpcb_item;
362
0
  proto_tree* rpcb_tree;
363
0
  int old_offset = offset;
364
0
  uint32_t prog;
365
366
0
  rpcb_item = proto_tree_add_item(tree, hf_portmap_rpcb, tvb,
367
0
      offset, -1, ENC_NA);
368
0
  rpcb_tree = proto_item_add_subtree(rpcb_item, ett_portmap_rpcb);
369
370
0
  prog = tvb_get_ntohl(tvb, offset);
371
0
  proto_tree_add_uint_format_value(rpcb_tree, hf_portmap_rpcb_prog, tvb,
372
0
      offset, 4, prog,
373
0
      "%s (%u)", uuid_type_get_uuid_name("rpc", GUINT_TO_POINTER(prog), pinfo->pool), prog);
374
0
  offset += 4;
375
376
0
  offset = dissect_rpc_uint32(tvb, rpcb_tree,
377
0
      hf_portmap_rpcb_version, offset);
378
0
  offset = dissect_rpc_string(tvb, pinfo, rpcb_tree,
379
0
      hf_portmap_rpcb_netid, offset, NULL);
380
0
  offset = dissect_rpc_string(tvb, pinfo, rpcb_tree,
381
0
      hf_portmap_rpcb_addr, offset, NULL);
382
0
  offset = dissect_rpc_string(tvb, pinfo, rpcb_tree,
383
0
      hf_portmap_rpcb_owner, offset, NULL);
384
385
  /* now we know, that rpcb is shorter */
386
0
  if (rpcb_item) {
387
0
    proto_item_set_len(rpcb_item, offset - old_offset);
388
0
  }
389
390
0
  return offset;
391
0
}
392
393
394
395
/* RFC 1833, Page 7 */
396
static int
397
dissect_rpcb3_getaddr_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
398
0
{
399
0
  return dissect_rpcb(tvb, 0, pinfo, tree, data);
400
0
}
401
402
403
/* RFC 1833, Page 7 */
404
static int
405
dissect_rpcb3_getaddr_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
406
0
{
407
0
  return dissect_rpc_string(tvb, pinfo, tree, hf_portmap_uaddr, 0, NULL);
408
0
}
409
410
411
/* RFC 1833, Page 7 */
412
static int
413
dissect_rpcb3_dump_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
414
0
{
415
0
  return dissect_rpc_list(tvb, pinfo, tree, 0, dissect_rpcb, NULL);
416
0
}
417
418
/* RFC 1833, page 4 */
419
static int
420
dissect_rpcb_rmtcallres(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
421
0
{
422
0
  unsigned offset = 0;
423
424
  /* Dissect the remote universal address. */
425
0
  offset = dissect_rpc_string(tvb, pinfo, tree,
426
0
      hf_portmap_rpcb_addr, offset, NULL);
427
428
  /* Dissect the result of this procedure.
429
     Make the columns non-writable, so the dissector won't change
430
     them out from under us. */
431
0
  col_set_writable(pinfo->cinfo, -1, false);
432
0
  offset = dissect_rpc_indir_reply(tvb, pinfo, tree, offset,
433
0
    hf_portmap_result, hf_portmap_prog, hf_portmap_version,
434
0
    hf_portmap_proc);
435
436
0
  return offset;
437
0
}
438
439
440
/* Portmapper version 3, RFC 1833, Page 7 */
441
static const vsff portmap3_proc[] = {
442
  { RPCBPROC_NULL,  "NULL",
443
    dissect_rpc_void, dissect_rpc_void },
444
  { RPCBPROC_SET,   "SET",
445
    dissect_rpcb3_getaddr_call, dissect_set_reply },
446
  { RPCBPROC_UNSET, "UNSET",
447
    dissect_rpcb3_getaddr_call, dissect_set_reply },
448
  { RPCBPROC_GETADDR, "GETADDR",
449
    dissect_rpcb3_getaddr_call, dissect_rpcb3_getaddr_reply},
450
  { RPCBPROC_DUMP,  "DUMP",
451
    dissect_rpc_void, dissect_rpcb3_dump_reply },
452
  { RPCBPROC_CALLIT,  "CALLIT",
453
    dissect_callit_call, dissect_rpcb_rmtcallres },
454
  { RPCBPROC_GETTIME, "GETTIME",
455
    dissect_rpc_unknown, dissect_rpc_unknown },
456
  { RPCBPROC_UADDR2TADDR, "UADDR2TADDR",
457
    dissect_rpc_unknown, dissect_rpc_unknown },
458
  { RPCBPROC_TADDR2UADDR, "TADDR2UADDR",
459
    dissect_rpc_unknown, dissect_rpc_unknown },
460
  { 0, NULL, NULL, NULL }
461
};
462
static const value_string portmap3_proc_vals[] = {
463
  { RPCBPROC_NULL,  "NULL" },
464
  { RPCBPROC_SET,   "SET" },
465
  { RPCBPROC_UNSET, "UNSET" },
466
  { RPCBPROC_GETADDR, "GETADDR" },
467
  { RPCBPROC_DUMP,  "DUMP" },
468
  { RPCBPROC_CALLIT,  "CALLIT" },
469
  { RPCBPROC_GETTIME, "GETTIME" },
470
  { RPCBPROC_UADDR2TADDR, "UADDR2TADDR" },
471
  { RPCBPROC_TADDR2UADDR, "TADDR2UADDR" },
472
  { 0, NULL }
473
};
474
/* end of Portmap version 3 */
475
476
477
/* Portmapper version 4, RFC 1833, Page 8 */
478
static const vsff portmap4_proc[] = {
479
  { RPCBPROC_NULL,  "NULL",
480
    dissect_rpc_void, dissect_rpc_void },
481
  { RPCBPROC_SET,   "SET",
482
    dissect_rpcb3_getaddr_call, dissect_set_reply },
483
  { RPCBPROC_UNSET, "UNSET",
484
    dissect_rpcb3_getaddr_call, dissect_set_reply },
485
  { RPCBPROC_GETADDR, "GETADDR",
486
    dissect_rpcb3_getaddr_call, dissect_rpcb3_getaddr_reply},
487
  { RPCBPROC_DUMP,  "DUMP",
488
    dissect_rpc_void, dissect_rpcb3_dump_reply },
489
  { RPCBPROC_BCAST, "BCAST",
490
    dissect_callit_call, dissect_rpcb_rmtcallres },
491
  { RPCBPROC_GETTIME, "GETTIME",
492
    dissect_rpc_unknown, dissect_rpc_unknown },
493
  { RPCBPROC_UADDR2TADDR, "UADDR2TADDR",
494
    dissect_rpc_unknown, dissect_rpc_unknown },
495
  { RPCBPROC_TADDR2UADDR, "TADDR2UADDR",
496
    dissect_rpc_unknown, dissect_rpc_unknown },
497
  { RPCBPROC_GETVERSADDR, "GETVERSADDR",
498
    dissect_rpc_unknown, dissect_rpc_unknown },
499
  { RPCBPROC_INDIRECT,  "INDIRECT",
500
    dissect_callit_call, dissect_rpcb_rmtcallres },
501
  { RPCBPROC_GETADDRLIST, "GETADDRLIST",
502
    dissect_rpc_unknown, dissect_rpc_unknown },
503
  { RPCBPROC_GETSTAT, "GETSTAT",
504
    dissect_rpc_unknown, dissect_rpc_unknown },
505
  { 0, NULL, NULL, NULL }
506
};
507
static const value_string portmap4_proc_vals[] = {
508
  { RPCBPROC_NULL,  "NULL" },
509
  { RPCBPROC_SET,   "SET" },
510
  { RPCBPROC_UNSET, "UNSET" },
511
  { RPCBPROC_GETADDR, "GETADDR" },
512
  { RPCBPROC_DUMP,  "DUMP" },
513
  { RPCBPROC_BCAST, "BCAST" },
514
  { RPCBPROC_GETTIME, "GETTIME" },
515
  { RPCBPROC_UADDR2TADDR, "UADDR2TADDR" },
516
  { RPCBPROC_TADDR2UADDR, "TADDR2UADDR" },
517
  { RPCBPROC_GETVERSADDR, "GETVERSADDR" },
518
  { RPCBPROC_INDIRECT,  "INDIRECT" },
519
  { RPCBPROC_GETADDRLIST, "GETADDRLIST" },
520
  { RPCBPROC_GETSTAT, "GETSTAT" },
521
  { 0, NULL }
522
};
523
/* end of Portmap version 4 */
524
525
static const rpc_prog_vers_info portmap_vers_info[] = {
526
  { 1, portmap1_proc, &hf_portmap_procedure_v1 },
527
  { 2, portmap2_proc, &hf_portmap_procedure_v2 },
528
  { 3, portmap3_proc, &hf_portmap_procedure_v3 },
529
  { 4, portmap4_proc, &hf_portmap_procedure_v4 },
530
};
531
532
void
533
proto_register_portmap(void)
534
16
{
535
16
  static hf_register_info hf[] = {
536
16
    { &hf_portmap_procedure_v1, {
537
16
      "V1 Procedure", "portmap.procedure_v1", FT_UINT32, BASE_DEC,
538
16
      VALS(portmap_proc_vals), 0, NULL, HFILL }},
539
16
    { &hf_portmap_procedure_v2, {
540
16
      "V2 Procedure", "portmap.procedure_v2", FT_UINT32, BASE_DEC,
541
16
      VALS(portmap_proc_vals), 0, NULL, HFILL }},
542
16
    { &hf_portmap_procedure_v3, {
543
16
      "V3 Procedure", "portmap.procedure_v3", FT_UINT32, BASE_DEC,
544
16
      VALS(portmap3_proc_vals), 0, NULL, HFILL }},
545
16
    { &hf_portmap_procedure_v4, {
546
16
      "V4 Procedure", "portmap.procedure_v4", FT_UINT32, BASE_DEC,
547
16
      VALS(portmap4_proc_vals), 0, NULL, HFILL }},
548
16
    { &hf_portmap_prog, {
549
16
      "Program", "portmap.prog", FT_UINT32, BASE_DEC,
550
16
      NULL, 0, NULL, HFILL }},
551
16
    { &hf_portmap_port, {
552
16
      "Port", "portmap.port", FT_UINT32, BASE_DEC,
553
16
      NULL, 0, NULL, HFILL }},
554
16
    { &hf_portmap_proc, {
555
16
      "Procedure", "portmap.proc", FT_UINT32, BASE_DEC,
556
16
      NULL, 0, NULL, HFILL }},
557
16
    { &hf_portmap_proto, {
558
16
      "Protocol", "portmap.proto", FT_UINT32, BASE_DEC,
559
16
      NULL, 0, NULL, HFILL }},
560
16
    { &hf_portmap_version, {
561
16
      "Version", "portmap.version", FT_UINT32, BASE_DEC,
562
16
      NULL, 0, NULL, HFILL }},
563
16
    { &hf_portmap_answer, {
564
16
      "Answer", "portmap.answer", FT_BOOLEAN, BASE_NONE,
565
16
      NULL, 0x0, NULL, HFILL }},
566
16
    { &hf_portmap_args, {
567
16
      "Arguments", "portmap.args", FT_BYTES, BASE_NONE,
568
16
      NULL, 0, NULL, HFILL }},
569
16
    { &hf_portmap_result, {
570
16
      "Result", "portmap.result", FT_BYTES, BASE_NONE,
571
16
      NULL, 0, NULL, HFILL }},
572
16
    { &hf_portmap_rpcb, {
573
16
      "RPCB", "portmap.rpcb", FT_NONE, BASE_NONE,
574
16
      NULL, 0, NULL, HFILL }},
575
16
    { &hf_portmap_rpcb_prog, {
576
16
      "Program", "portmap.rpcb.prog", FT_UINT32, BASE_DEC,
577
16
      NULL, 0, NULL, HFILL }},
578
16
    { &hf_portmap_rpcb_version, {
579
16
      "Version", "portmap.rpcb.version", FT_UINT32, BASE_DEC,
580
16
      NULL, 0, NULL, HFILL }},
581
16
    { &hf_portmap_rpcb_netid, {
582
16
      "Network Id", "portmap.rpcb.netid", FT_STRING, BASE_NONE,
583
16
      NULL, 0, NULL, HFILL }},
584
16
    { &hf_portmap_rpcb_addr, {  /* address in rpcb structure in request */
585
16
      "Universal Address", "portmap.rpcb.addr", FT_STRING, BASE_NONE,
586
16
      NULL, 0, NULL, HFILL }},
587
16
    { &hf_portmap_rpcb_owner, {
588
16
      "Owner of this Service", "portmap.rpcb.owner", FT_STRING, BASE_NONE,
589
16
      NULL, 0, NULL, HFILL }},
590
16
    { &hf_portmap_uaddr, {  /* address in RPCBPROC_GETADDR reply */
591
16
      "Universal Address", "portmap.uaddr", FT_STRING, BASE_NONE,
592
16
      NULL, 0, NULL, HFILL }},
593
16
  };
594
16
  static int *ett[] = {
595
16
    &ett_portmap,
596
16
    &ett_portmap_rpcb,
597
16
    &ett_portmap_entry
598
16
  };
599
600
16
  proto_portmap = proto_register_protocol("Portmap", "Portmap", "portmap");
601
16
  proto_register_field_array(proto_portmap, hf, array_length(hf));
602
16
  proto_register_subtree_array(ett, array_length(ett));
603
16
}
604
605
void
606
proto_reg_handoff_portmap(void)
607
16
{
608
  /* Register the protocol as RPC */
609
16
  rpc_init_prog(proto_portmap, PORTMAP_PROGRAM, ett_portmap,
610
16
      G_N_ELEMENTS(portmap_vers_info), portmap_vers_info);
611
612
16
  rpc_handle = find_dissector("rpc");
613
16
}
614
615
/*
616
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
617
 *
618
 * Local variables:
619
 * c-basic-offset: 8
620
 * tab-width: 8
621
 * indent-tabs-mode: t
622
 * End:
623
 *
624
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
625
 * :indentSize=8:tabSize=8:noTabs=false:
626
 */