Make dissect_icmp_extension_structure into a dissector function.
[metze/wireshark/wip.git] / epan / dissectors / packet-rsip.c
1 /* packet-rsip.c
2  * Routines for Realm Specific IP (RSIP) Protocol dissection
3  * Brian Ginsbach <ginsbach@cray.com>
4  *
5  * Copyright (c) 2006, 2010 Cray Inc. All Rights Reserved.
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * SPDX-License-Identifier: GPL-2.0-or-later
12  */
13
14 #include "config.h"
15
16 #include <epan/packet.h>
17 #include <epan/to_str.h>
18
19 void proto_register_rsip(void);
20
21 /* Forward declaration we need below */
22 void proto_reg_handoff_rsip(void);
23
24 /* Initialize the protocol and registered fields */
25 static int proto_rsip = -1;
26 static int hf_rsip_version = -1;
27 static int hf_rsip_message_type = -1;
28 static int hf_rsip_message_length = -1;
29 static int hf_rsip_parameter_type = -1;
30 static int hf_rsip_parameter_length = -1;
31 static int hf_rsip_parameter_value = -1;
32 static int hf_rsip_parameter_address_type = -1;
33 static int hf_rsip_parameter_address_ipv4 = -1;
34 static int hf_rsip_parameter_address_ipv4_netmask = -1;
35 static int hf_rsip_parameter_address_ipv6 = -1;
36 static int hf_rsip_parameter_address_fqdn = -1;
37 static int hf_rsip_parameter_ports_number = -1;
38 static int hf_rsip_parameter_ports_port_number = -1;
39 static int hf_rsip_parameter_lease_time = -1;
40 static int hf_rsip_parameter_client_id = -1;
41 static int hf_rsip_parameter_bind_id = -1;
42 static int hf_rsip_parameter_tunnel_type = -1;
43 static int hf_rsip_parameter_method = -1;
44 static int hf_rsip_parameter_error = -1;
45 static int hf_rsip_parameter_flow_policy_local = -1;
46 static int hf_rsip_parameter_flow_policy_remote = -1;
47 static int hf_rsip_parameter_indicator = -1;
48 static int hf_rsip_parameter_message_counter = -1;
49 static int hf_rsip_parameter_vendor_specific_vendor_id = -1;
50 static int hf_rsip_parameter_vendor_specific_subtype = -1;
51 static int hf_rsip_parameter_vendor_specific_value = -1;
52 static int hf_rsip_parameter_spi_number = -1;
53 static int hf_rsip_parameter_spi = -1;
54
55 /* Initialize the subtree pointers */
56 static gint ett_rsip = -1;
57 static gint ett_rsip_param = -1;
58 static gint ett_rsip_param_val = -1;
59
60 #define UDP_PORT_RSIP   4555
61 #define TCP_PORT_RSIP   4555
62
63 /* Message Types in RFC 3103 Appendix B / RFC 3104 Appendix C style */
64 static const value_string msg_type_appendix_vals[] = {
65         {  1,   "ERROR_RESPONSE" },
66         {  2,   "REGISTER_REQUEST" },
67         {  3,   "REGISTER_RESPONSE" },
68         {  4,   "DE-REGISTER_REQUEST" },
69         {  5,   "DE-REGISTER_RESPONSE" },
70         {  6,   "ASSIGN_REQUEST_RSA-IP" },
71         {  7,   "ASSIGN_RESPONSE_RSA-IP" },
72         {  8,   "ASSIGN_REQUEST_RSAP-IP" },
73         {  9,   "ASSIGN_RESPONSE_RSAP-IP" },
74         { 10,   "EXTEND_REQUEST" },
75         { 11,   "EXTEND_RESPONSE" },
76         { 12,   "FREE_REQUEST" },
77         { 13,   "FREE_RESPONSE" },
78         { 14,   "QUERY_REQUEST" },
79         { 15,   "QUERY_RESPONSE" },
80         { 16,   "LISTEN_REQUEST" },
81         { 17,   "LISTEN_RESPONSE" },
82         { 22,   "ASSIGN_REQUEST_RSIPSEC" },
83         { 23,   "ASSIGN_RESPONSE_RSIPEC" },
84         { 0,    NULL }
85 };
86
87 static const value_string msg_type_vals[] = {
88         {  1,   "Error Response" },
89         {  2,   "Register Request" },
90         {  3,   "Register Response" },
91         {  4,   "Deregister Request" },
92         {  5,   "Deregister Response" },
93         {  6,   "Assign Request RSA-IP" },
94         {  7,   "Assign Response RSA-IP" },
95         {  8,   "Assign Request RSAP-IP" },
96         {  9,   "Assign Response RSAP-IP" },
97         { 10,   "Extend Request" },
98         { 11,   "Extend Response" },
99         { 12,   "Free Request" },
100         { 13,   "Free Response" },
101         { 14,   "Query Request" },
102         { 15,   "Query Response" },
103         { 16,   "Listen Request" },
104         { 17,   "Listen Response" },
105         { 22,   "Assign Request RSIPsec" },
106         { 23,   "Assign Response RSIPsec" },
107         { 0,    NULL }
108 };
109
110 static const value_string param_type_vals[] = {
111         {  1,   "Address" },
112         {  2,   "Port" },
113         {  3,   "Lease Time" },
114         {  4,   "Client ID" },
115         {  5,   "Bind ID" },
116         {  6,   "Tunnel Type" },
117         {  7,   "RSIP Method" },
118         {  8,   "Error" },
119         {  9,   "Flow Policy" },
120         { 10,   "Indicator" },
121         { 11,   "Message Counter" },
122         { 12,   "Vendor Specific" },
123         { 22,   "SPI" },
124         { 0,    NULL }
125 };
126
127 static const value_string addr_type_vals[] = {
128         { 0,    "Reserved" },
129         { 1,    "IPv4" },
130         { 2,    "IPv4 Netmask" },
131         { 3,    "IPv6" },
132         { 4,    "Fully Qualified Domain Name" },
133         { 0,    NULL }
134 };
135
136 static const value_string tunnel_type_vals[] = {
137         { 1,    "IP-IP Tunnel" },
138         { 2,    "GRE Tunnel" },
139         { 3,    "L2TP" },
140         { 0,    NULL }
141 };
142
143 static const value_string method_vals[] = {
144         { 1,    "RSA-IP" },
145         { 2,    "RSAP-IP" },
146         { 0,    NULL }
147 };
148
149 #if 0
150 /* Error Numbers in RFC 3103 Appendix A / RFC 3104 Appendix B style */
151 static const value_string error_number_appendix_vals[] = {
152         { 101,  "UNKNOWN_ERROR" },
153         { 102,  "USE_TCP" },
154         { 103,  "FLOW_POLICY_VIOLATION" },
155         { 104,  "INTERNAL_SERVER_ERROR" },
156         { 105,  "MESSAGE_COUNTER_REQUIRED" },
157         { 106,  "UNSUPPORTED_RSIP_VERSION" },
158         { 201,  "MISSING_PARAM" },
159         { 202,  "DUPLICATE_PARAM" },
160         { 203,  "EXTRA_PARAM" },
161         { 204,  "ILLEGAL_PARAM" },
162         { 205,  "BAD_PARAM" },
163         { 206,  "ILLEGAL_MESSAGE" },
164         { 207,  "BAD_MESSAGE" },
165         { 208,  "UNSUPPORTED_MESSAGE" },
166         { 301,  "REGISTER_FIRST" },
167         { 302,  "ALREADY_REGISTERED" },
168         { 303,  "ALREADY_UNREGISTERED" },
169         { 304,  "REGISTRATION_DENIED" },
170         { 305,  "BAD_CLIENT_ID" },
171         { 306,  "BAD_BIND_ID" },
172         { 307,  "BAD_TUNNEL_TYPE" },
173         { 308,  "LOCAL_ADDR_UNAVAILABLE" },
174         { 309,  "LOCAL_ADDRPORT_UNAVAILABLE" },
175         { 310,  "LOCAL_ADDR_INUSE" },
176         { 311,  "LOCAL_ADDRPORT_INUSE" },
177         { 312,  "LOCAL_ADDR_UNALlOWED" },
178         { 313,  "LOCAL_ADDRPORT_UNALLOWED" },
179         { 314,  "REMOTE_ADDR_UNALLOWED" },
180         { 315,  "REMOTE_ADDRPORT_UNALLOWED" },
181         { 400,  "IPSEC_UNALLOWED" },
182         { 401,  "IPSEC_SPI_UNAVAILABLE" },
183         { 402,  "IPSEC_SPI_INUSE" },
184         { 0,    NULL }
185 };
186 #endif
187
188 static const value_string error_number_vals[] = {
189         { 101,  "Unknown Error" },
190         { 102,  "Use TCP" },
191         { 103,  "Flow Policy Violation" },
192         { 104,  "Internal Server Error" },
193         { 105,  "Message Counter Required" },
194         { 106,  "Unsupported RSIP Version" },
195         { 201,  "Missing Parameter" },
196         { 202,  "Duplicate Parameter" },
197         { 203,  "Extra Parameter" },
198         { 204,  "Illegal Parameter" },
199         { 205,  "Bad Parameter" },
200         { 206,  "Illegal Message" },
201         { 207,  "Bad Message" },
202         { 208,  "Unsupported Message" },
203         { 301,  "Register First" },
204         { 302,  "Already Registered" },
205         { 303,  "Already Unregistered" },
206         { 304,  "Registration Denied" },
207         { 305,  "Bad Client ID" },
208         { 306,  "Bad Bind ID" },
209         { 307,  "Bad Tunnel Type" },
210         { 308,  "Local Address Unavailable" },
211         { 309,  "Local Address Port Unavailable" },
212         { 310,  "Local Address Inuse" },
213         { 311,  "Local Address Port Inuse" },
214         { 312,  "Local Address Unallowed" },
215         { 313,  "Local Address Port Unallowed" },
216         { 314,  "Remote Address Unallowed" },
217         { 315,  "Remote Address Port Unallowed" },
218         { 400,  "IPsec Unallowed" },
219         { 401,  "IPsec SPI Unavailable" },
220         { 402,  "IPsec SPI Inuse" },
221         { 0,    NULL }
222 };
223
224 static const value_string lcl_flow_policy_vals[] = {
225         { 1,    "Macro Flows" },
226         { 2,    "Micro Flows " },
227         { 0,    NULL }
228 };
229
230 static const value_string rmt_flow_policy_vals[] = {
231         { 1,    "Macro Flows" },
232         { 2,    "Micro Flows" },
233         { 3,    "No Policy" },
234         { 0,    NULL }
235 };
236
237 /* Code to actually dissect the packets */
238 static int
239 rsip_parameter(tvbuff_t *tvb, proto_tree *rsip_tree, int off, int eoff)
240 {
241         int             consumed, i, paramleft;
242         guint8          addrtype, flowpolicy, method, number, paramtype, tuntype;
243         guint16         error, ind, paramlen, portnum;
244         guint32         bid, cid, leasetm, msgc;
245         proto_tree      *p_tree, *v_tree;
246         proto_item      *pti, *vti;
247
248         /* XXX */
249         if (off >= eoff)
250                 return 0;
251
252         paramtype = tvb_get_guint8(tvb, off);
253         paramlen = tvb_get_ntohs(tvb, off + 1);
254
255         p_tree = proto_tree_add_subtree(rsip_tree, tvb, off, 3 + paramlen,
256             ett_rsip_param, &pti,
257             val_to_str(paramtype, param_type_vals, "Unknown (%d)"));
258
259         proto_tree_add_item(p_tree, hf_rsip_parameter_type, tvb,
260             off, 1, ENC_BIG_ENDIAN);
261         proto_tree_add_item(p_tree, hf_rsip_parameter_length, tvb,
262             off + 1, 2, ENC_BIG_ENDIAN);
263         consumed = 3;
264
265         if (paramlen == 0)
266             return consumed;
267
268         vti = proto_tree_add_item(p_tree, hf_rsip_parameter_value,
269             tvb, off + 3, paramlen, ENC_NA);
270         v_tree = proto_item_add_subtree(vti, ett_rsip_param_val);
271
272         switch (paramtype) {
273         case 1:         /* Address */
274                 proto_tree_add_item(v_tree, hf_rsip_parameter_address_type,
275                     tvb, off + 3, 1, ENC_BIG_ENDIAN);
276
277                 addrtype = tvb_get_guint8(tvb, off + 3);
278
279                 switch (addrtype) {
280                 case 0:         /* Reserved */
281                         break;
282                 case 1:         /* IPv4 */
283                         if (paramlen - 1 > 0) {
284                                 proto_tree_add_item(v_tree,
285                                     hf_rsip_parameter_address_ipv4, tvb,
286                                     off + 4, paramlen - 1, ENC_BIG_ENDIAN);
287                                 proto_item_append_text(pti, ": %s",
288                                     tvb_ip_to_str(tvb, off + 4));
289                         } else
290                                 proto_item_append_text(pti,
291                                     ": Any IPv4 Address");
292                         break;
293                 case 2:         /* IPv4 netmask */
294                         if (paramlen - 1 > 0) {
295                                 proto_tree_add_item(v_tree,
296                                     hf_rsip_parameter_address_ipv4_netmask,
297                                     tvb, off + 4, paramlen - 1, ENC_BIG_ENDIAN);
298                                 proto_item_append_text(pti, "(netmask): %s",
299                                     tvb_ip_to_str(tvb, off + 4));
300                         } else
301                                 proto_item_append_text(pti,
302                                     ": Any IPv4 Netmask");
303                         break;
304                 case 3:         /* IPv6 */
305                         if (paramlen - 1 > 0) {
306                                 proto_tree_add_item(v_tree,
307                                     hf_rsip_parameter_address_ipv6, tvb,
308                                     off + 4, paramlen - 1, ENC_NA);
309                                 proto_item_append_text(pti, ": %s",
310                                     tvb_ip6_to_str(tvb, off + 4));
311                         } else
312                                 proto_item_append_text(pti,
313                                     ": Any IPv6 Address");
314                         break;
315                 case 4:         /* FQDN */
316                         if (paramlen - 1 > 0) {
317                                 proto_tree_add_item(v_tree,
318                                     hf_rsip_parameter_address_fqdn, tvb,
319                                     off + 4, paramlen - 1, ENC_ASCII|ENC_NA);
320                                 proto_item_append_text(pti, ": %s",
321                                     tvb_format_text(tvb, off + 4, paramlen - 1));
322                         } else
323                                 proto_item_append_text(pti,
324                                     ": Any Fully Qualified Domain Name");
325                         break;
326                 default:
327                         proto_item_append_text(pti, ": Unknown Address Type");
328                         break;
329                 }
330                 break;
331         case 2:         /* Ports */
332                 proto_tree_add_item(v_tree, hf_rsip_parameter_ports_number,
333                     tvb, off + 3, 1, ENC_BIG_ENDIAN);
334                 number = tvb_get_guint8(tvb, off + 3);
335                 if (paramlen == 1) {
336                         switch (number) {
337                         case 0:
338                                 proto_item_append_text(pti, ": Unspecified");
339                                 break;
340                         case 1:
341                                 proto_item_append_text(pti, ": Any port");
342                                 break;
343                         default:
344                                 proto_item_append_text(pti, ": Any %d ports",
345                                     number);
346                                 break;
347                         }
348                 } else {
349                         portnum = tvb_get_ntohs(tvb, off + 4);
350                         if (number == 1) {
351                                 proto_tree_add_item(v_tree,
352                                     hf_rsip_parameter_ports_port_number,
353                                     tvb, off + 4, 2, ENC_BIG_ENDIAN);
354                         } else {
355                                 paramleft = paramlen - 1;
356                                 if (paramleft == 2) {
357                                         proto_tree_add_uint_format_value(v_tree,
358                                             hf_rsip_parameter_ports_port_number,
359                                             tvb, off + 4, 2, portnum, "%d - %d",
360                                             portnum, portnum + number);
361                                         proto_item_append_text(pti,
362                                             ": %d - %d", portnum,
363                                             portnum + number);
364                                 } else {
365                                         for (i = off + 4;
366                                             paramleft > 0;
367                                             i += 2, paramleft -= 2)
368                                                 proto_tree_add_item(v_tree,
369                                                     hf_rsip_parameter_ports_port_number,
370                                                     tvb, i, 2, ENC_BIG_ENDIAN);
371                                         proto_item_append_text(pti,
372                                             ": List of %d Ports", number);
373                                 }
374                         }
375                 }
376                 break;
377         case 3:         /* Lease Time */
378                 /* XXX if paramlen != 4 we've got a protocol violation */
379                 proto_tree_add_item(v_tree, hf_rsip_parameter_lease_time,
380                     tvb, off + 3, paramlen, ENC_BIG_ENDIAN);
381                 leasetm = tvb_get_ntohl(tvb, off + 3);
382                 proto_item_append_text(pti, ": %d seconds", leasetm);
383                 break;
384         case 4:         /* Client ID */
385                 /* XXX if paramlen != 4 we've got a protocol violation */
386                 proto_tree_add_item(v_tree, hf_rsip_parameter_client_id,
387                     tvb, off + 3, paramlen, ENC_BIG_ENDIAN);
388                 cid = tvb_get_ntohl(tvb, off + 3);
389                 proto_item_append_text(pti, ": %d", cid);
390                 break;
391         case 5:         /* Bind ID */
392                 /* XXX if paramlen != 4 we've got a protocol violation */
393                 proto_tree_add_item(v_tree, hf_rsip_parameter_bind_id,
394                     tvb, off + 3, paramlen, ENC_BIG_ENDIAN);
395                 bid = tvb_get_ntohl(tvb, off + 3);
396                 proto_item_append_text(pti, ": %d", bid);
397                 break;
398         case 6:         /* Tunnel Type */
399                 /* XXX if paramlen != 1 we've got a protocol violation */
400                 proto_tree_add_item(v_tree, hf_rsip_parameter_tunnel_type,
401                     tvb, off + 3, paramlen, ENC_BIG_ENDIAN);
402                 tuntype = tvb_get_guint8(tvb, off + 3);
403                 proto_item_append_text(pti, ": %s",
404                     val_to_str(tuntype, tunnel_type_vals,
405                         "Unknown Tunnel Type (%d)"));
406                 break;
407         case 7:         /* RSIP Method */
408                 /* XXX if paramlen != 1 we've got a protocol violation */
409                 proto_tree_add_item(v_tree, hf_rsip_parameter_method,
410                     tvb, off + 3, paramlen, ENC_BIG_ENDIAN);
411                 method = tvb_get_guint8(tvb, off + 3);
412                 proto_item_append_text(pti, ": %s",
413                     val_to_str(method, method_vals,
414                     "Unknown RSIP Method (%d)"));
415                 break;
416         case 8:         /* Error */
417                 /* XXX if paramlen != 2 we've got a protocol violation */
418                 proto_tree_add_item(v_tree, hf_rsip_parameter_error,
419                     tvb, off + 3, paramlen, ENC_BIG_ENDIAN);
420                 error = tvb_get_ntohs(tvb, off + 3);
421                 proto_item_append_text(pti, ": %s",
422                     val_to_str(error, error_number_vals, "Undefined Error (%d)"));
423                 break;
424         case 9:         /* Flow Policy */
425                 /* XXX if paramlen != 2 we've got a protocol violation */
426                 proto_tree_add_item(v_tree,
427                     hf_rsip_parameter_flow_policy_local, tvb, off + 3, 1, ENC_BIG_ENDIAN);
428                 flowpolicy = tvb_get_guint8(tvb, off + 3);
429                 proto_item_append_text(pti, ": %s",
430                     val_to_str(flowpolicy, lcl_flow_policy_vals,
431                     "Undefined Local Flow Policy (%d)"));
432                 proto_tree_add_item(v_tree,
433                     hf_rsip_parameter_flow_policy_remote, tvb, off + 4, 1,
434                     ENC_BIG_ENDIAN);
435                 flowpolicy = tvb_get_guint8(tvb, off + 4);
436                 proto_item_append_text(pti, "/%s",
437                     val_to_str(flowpolicy, rmt_flow_policy_vals,
438                     "Undefined Remote Flow Policy (%d)"));
439                 break;
440         case 10:        /* Indicator */
441                 /* XXX if paramlen != 2 we've got a protocol violation */
442                 proto_tree_add_item(v_tree, hf_rsip_parameter_indicator, tvb,
443                     off + 3, 2, ENC_BIG_ENDIAN);
444                 ind = tvb_get_ntohs(tvb, off + 3);
445                 proto_item_append_text(pti, ": %d", ind);
446                 break;
447         case 11:        /* Message Counter */
448                 /* XXX if paramlen != 4 we've got a protocol violation */
449                 proto_tree_add_item(v_tree, hf_rsip_parameter_message_counter,
450                     tvb, off + 3, 4, ENC_BIG_ENDIAN);
451                 msgc = tvb_get_ntohl(tvb, off + 3);
452                 proto_item_append_text(pti, ": %d", msgc);
453                 break;
454         case 12:        /* Vendor Specific */
455                 proto_tree_add_item(v_tree,
456                     hf_rsip_parameter_vendor_specific_vendor_id, tvb, off + 3,
457                     2, ENC_BIG_ENDIAN);
458                 proto_tree_add_item(v_tree,
459                     hf_rsip_parameter_vendor_specific_subtype, tvb, off + 5,
460                     2, ENC_BIG_ENDIAN);
461                 proto_tree_add_item(v_tree,
462                     hf_rsip_parameter_vendor_specific_value, tvb, off + 9,
463                     paramlen - 4, ENC_NA);
464                 break;
465         case 22:        /* SPI */
466                 proto_tree_add_item(v_tree, hf_rsip_parameter_spi_number, tvb,
467                     off + 3, 2, ENC_BIG_ENDIAN);
468                 /* XXX need loop? */
469                 proto_tree_add_item(v_tree, hf_rsip_parameter_spi, tvb,
470                     off + 5, 4, ENC_BIG_ENDIAN);
471                 break;
472         default:
473                 break;
474         }
475
476         consumed += paramlen;
477
478         return consumed;
479 }
480
481 static int
482 rsip_message_error_response(tvbuff_t *tvb, proto_tree *rsip_tree,
483                             int offset, int eoffset)
484 {
485         int             consumed, offset_delta;
486         /*
487            <Error>
488            [Message Counter]    UDP required
489            [Client ID]
490            [Bind ID]
491          */
492
493         consumed = 0;
494         do {
495                 offset_delta =
496                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
497                 offset += offset_delta;
498                 consumed += offset_delta;
499         } while ((offset_delta > 0) && (offset < eoffset));
500
501         return consumed;
502 }
503
504 static int
505 rsip_message_register_request(tvbuff_t *tvb, proto_tree *rsip_tree,
506                               int offset, int eoffset)
507 {
508         int             consumed, offset_delta;
509         /*
510            [Message Counter]    UDP required
511          */
512
513         consumed = 0;
514         do {
515                 offset_delta =
516                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
517                 offset += offset_delta;
518                 consumed += offset_delta;
519         } while ((offset_delta > 0) && (offset < eoffset));
520
521         return consumed;
522 }
523
524 static int
525 rsip_message_register_response(tvbuff_t *tvb, proto_tree *rsip_tree,
526                                int offset, int eoffset)
527 {
528         int             consumed, offset_delta;
529         /*
530            <Client ID>
531            <Lease Time>
532            <Flow Policy>
533            [Message Counter]    UDP required
534            [RSIP Method]...
535            [Tunnel Type]...
536          */
537
538         consumed = 0;
539         do {
540                 offset_delta =
541                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
542                 offset += offset_delta;
543                 consumed += offset_delta;
544         } while ((offset_delta > 0) && (offset < eoffset));
545
546         return consumed;
547 }
548
549 static int
550 rsip_message_deregister_request(tvbuff_t *tvb, proto_tree *rsip_tree,
551                                 int offset, int eoffset)
552 {
553         int             consumed, offset_delta;
554         /*
555            <Client ID>
556            [Message Counter]    UDP required
557          */
558
559         consumed = 0;
560         do {
561                 offset_delta =
562                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
563                 offset += offset_delta;
564                 consumed += offset_delta;
565         } while ((offset_delta > 0) && (offset < eoffset));
566
567         return consumed;
568 }
569
570 static int
571 rsip_message_deregister_response(tvbuff_t *tvb, proto_tree *rsip_tree,
572                                  int offset, int eoffset)
573 {
574         return rsip_message_deregister_request(tvb, rsip_tree, offset, eoffset);
575 }
576
577 static int
578 rsip_message_assign_request_rsaip(tvbuff_t *tvb, proto_tree *rsip_tree,
579                                   int offset, int eoffset)
580 {
581         int             consumed, offset_delta;
582         /*
583            <Client ID>
584            <Address (local)>
585            <Address (remote)>
586            <Ports (remote)>
587            [Message Counter]    UDP required
588            [Lease Time]
589            [Tunnel Type]
590          */
591
592         consumed = 0;
593         do {
594                 offset_delta =
595                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
596                 offset += offset_delta;
597                 consumed += offset_delta;
598         } while ((offset_delta > 0) && (offset < eoffset));
599
600         return consumed;
601 }
602
603 static int
604 rsip_message_assign_response_rsaip(tvbuff_t *tvb, proto_tree *rsip_tree,
605                                    int offset, int eoffset)
606 {
607         int             consumed, offset_delta;
608         /*
609            <Client ID>
610            <Bind ID>
611            <Address (local)>
612            <Address (remote)>
613            <Ports (remote)>
614            <Lease Time>
615            <Tunnel Type>
616            [Message Counter]    UDP required
617            [Address (tunnel endpoint)]
618          */
619
620         consumed = 0;
621         do {
622                 offset_delta =
623                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
624                 offset += offset_delta;
625                 consumed += offset_delta;
626         } while ((offset_delta > 0) && (offset < eoffset));
627
628         return consumed;
629 }
630
631 static int
632 rsip_message_assign_request_rsapip(tvbuff_t *tvb, proto_tree *rsip_tree,
633                                    int offset, int eoffset)
634 {
635         int             consumed, offset_delta;
636         /*
637            <Client ID>
638            <Address (local)>
639            <Ports (local)>
640            <Address (remote)>
641            <Ports (remote)>
642            [Message Counter]    UDP required
643            [Lease Time]
644            [Tunnel Type]
645          */
646
647         consumed = 0;
648         do {
649                 offset_delta =
650                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
651                 offset += offset_delta;
652                 consumed += offset_delta;
653         } while ((offset_delta > 0) && (offset < eoffset));
654
655         return consumed;
656 }
657
658 static int
659 rsip_message_assign_response_rsapip(tvbuff_t *tvb, proto_tree *rsip_tree,
660                                     int offset, int eoffset)
661 {
662         int             consumed, offset_delta;
663         /*
664            <Client ID>
665            <Bind ID>
666            <Address (local)>
667            <Ports (local)>
668            <Address (remote)>
669            <Ports (remote)>
670            <Lease Time>
671            <Tunnel Type>
672            [Address (tunnel endpoint)]
673            [Message Counter]    UDP required
674          */
675
676         consumed = 0;
677         do {
678                 offset_delta =
679                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
680                 offset += offset_delta;
681                 consumed += offset_delta;
682         } while ((offset_delta > 0) && (offset < eoffset));
683
684         return consumed;
685 }
686
687 static int
688 rsip_message_extend_request(tvbuff_t *tvb, proto_tree *rsip_tree,
689                             int offset, int eoffset)
690 {
691         int             consumed, offset_delta;
692         /*
693            <Client ID>
694            <Bind ID>
695            [Lease Time]
696            [Message Counter]    UDP required
697         */
698
699         consumed = 0;
700         do {
701                 offset_delta =
702                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
703                 offset += offset_delta;
704                 consumed += offset_delta;
705         } while ((offset_delta > 0) && (offset < eoffset));
706
707         return consumed;
708 }
709
710 static int
711 rsip_message_extend_response(tvbuff_t *tvb, proto_tree *rsip_tree,
712                              int offset, int eoffset)
713 {
714         int             consumed, offset_delta;
715         /*
716            <Client ID>
717            <Bind ID>
718            <Lease Time>
719            [Message Counter]    UDP required
720         */
721
722         consumed = 0;
723         do {
724                 offset_delta =
725                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
726                 offset += offset_delta;
727                 consumed += offset_delta;
728         } while ((offset_delta > 0) && (offset < eoffset));
729
730         return consumed;
731 }
732
733 static int
734 rsip_message_free_request(tvbuff_t *tvb, proto_tree *rsip_tree,
735                           int offset, int eoffset)
736 {
737         int             consumed, offset_delta;
738         /*
739            <Client ID>
740            <Bind ID>
741            [Message Counter]    UDP required
742         */
743
744         consumed = 0;
745         do {
746                 offset_delta =
747                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
748                 offset += offset_delta;
749                 consumed += offset_delta;
750         } while ((offset_delta > 0) && (offset < eoffset));
751
752         return consumed;
753 }
754
755 static int
756 rsip_message_free_response(tvbuff_t *tvb, proto_tree *rsip_tree,
757                            int offset, int eoffset)
758 {
759         int             consumed, offset_delta;
760         /*
761            <Client ID>
762            <Bind ID>
763            [Message Counter]    UDP required
764         */
765
766         consumed = 0;
767         do {
768                 offset_delta =
769                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
770                 offset += offset_delta;
771                 consumed += offset_delta;
772         } while ((offset_delta > 0) && (offset < eoffset));
773
774         return consumed;
775 }
776
777 static int
778 rsip_message_query_request(tvbuff_t *tvb, proto_tree *rsip_tree,
779                            int offset, int eoffset)
780 {
781         int             consumed, offset_delta;
782         /*
783            <Client ID>
784            [Message Counter]    UDP required
785            [Address Tuple]...
786            [Network Tuple]...
787
788            <Address Tuple> ::= <Indicator (address)>
789                                <Address>
790
791            <Network Tuple> ::= <Indicator (network)>
792                                <Address (network)>
793                                <Address (netmask)>
794         */
795
796         consumed = 0;
797         do {
798                 offset_delta =
799                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
800                 offset += offset_delta;
801                 consumed += offset_delta;
802         } while ((offset_delta > 0) && (offset < eoffset));
803
804         return consumed;
805 }
806
807 static int
808 rsip_message_query_response(tvbuff_t *tvb, proto_tree *rsip_tree,
809                             int offset, int eoffset)
810 {
811         int             consumed, offset_delta;
812         /*
813            <Client ID>
814            [Message Counter]    UDP required
815            [Local Address Tuple]...
816            [Local Network Tuple]...
817            [Remote Address Tuple]...
818            [Remote Network Tuple]...
819
820            <Local Address Tuple> ::= <Indicator (local address)>
821                                      <Address>
822
823            <Local Network Tuple> ::= <Indicator (local network)>
824                                      <Address (network)>
825                                      <Address (netmask)>
826
827            <Remote Address Tuple> ::= <Indicator (remote address)>
828                                       <Address>
829
830            <Remote Network Tuple> ::= <Indicator (remote network)>
831                                       <Address (network)>
832                                       <Address (netmask)>
833         */
834
835         consumed = 0;
836         do {
837                 offset_delta =
838                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
839                 offset += offset_delta;
840                 consumed += offset_delta;
841         } while ((offset_delta > 0) && (offset < eoffset));
842
843         return consumed;
844 }
845
846 static int
847 rsip_message_listen_request(tvbuff_t *tvb, proto_tree *rsip_tree,
848                             int offset, int eoffset)
849 {
850         int             consumed, offset_delta;
851         /*
852            <Client ID>
853            <Address (local)>
854            <Ports (local)>
855            <Address (remote)>
856            <Ports (remote)>
857            [Message Counter]    UDP required
858            [Lease Time]
859            [Tunnel Type]...
860          */
861
862         consumed = 0;
863         do {
864                 offset_delta =
865                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
866                 offset += offset_delta;
867                 consumed += offset_delta;
868         } while ((offset_delta > 0) && (offset < eoffset));
869
870         return consumed;
871 }
872
873 static int
874 rsip_message_listen_response(tvbuff_t *tvb, proto_tree *rsip_tree,
875                              int offset, int eoffset)
876 {
877         int             consumed, offset_delta;
878         /*
879            <Client ID>
880            <Bind ID>
881            <Address (local)>
882            <Ports (local)>
883            <Address (remote)>
884            <Ports (remote)>
885            <Tunnel Type>
886            <Lease Time>
887            [Address (tunnel endpoint)]
888            [Message Counter]    UDP required
889          */
890
891         consumed = 0;
892         do {
893                 offset_delta =
894                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
895                 offset += offset_delta;
896                 consumed += offset_delta;
897         } while ((offset_delta > 0) && (offset < eoffset));
898
899         return consumed;
900 }
901
902 static int
903 rsip_message_assign_request_rsipsec(tvbuff_t *tvb, proto_tree *rsip_tree,
904                                     int offset, int eoffset)
905 {
906         int             consumed, offset_delta;
907         /*
908            <Client ID>
909            <Address (local)>
910            <Ports (local)>
911            <Address (remote)>
912            <Ports (remote)>
913            [Message Counter]    UDP required
914            [Lease Time]
915            [Tunnel Type]...
916          */
917
918         consumed = 0;
919         do {
920                 offset_delta =
921                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
922                 offset += offset_delta;
923                 consumed += offset_delta;
924         } while ((offset_delta > 0) && (offset < eoffset));
925
926         return consumed;
927 }
928
929 static int
930 rsip_message_assign_response_rsipsec(tvbuff_t *tvb, proto_tree *rsip_tree,
931                                      int offset, int eoffset)
932 {
933         int             consumed, offset_delta;
934         /*
935            <Client ID>
936            <Bind ID>
937            <Address (local)>
938            <Ports (local)>
939            <Address (remote)>
940            <Ports (remote)>
941            <Tunnel Type>
942            <Lease Time>
943            [Address (tunnel endpoint)]
944            [Message Counter]    UDP required
945          */
946
947         consumed = 0;
948         do {
949                 offset_delta =
950                     rsip_parameter(tvb, rsip_tree, offset, eoffset);
951                 offset += offset_delta;
952                 consumed += offset_delta;
953         } while ((offset_delta > 0) && (offset < eoffset));
954
955         return consumed;
956 }
957
958 static int
959 dissect_rsip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
960 {
961         proto_item      *ti;
962         proto_tree      *rsip_tree;
963         guint8          msgtype;
964         /*gboolean      msgcnt_required;*/
965         int             eoff;
966
967         msgtype = tvb_get_guint8(tvb, 1);
968
969         /*msgcnt_required = (pinfo->ipproto == IP_PROTO_UDP)? TRUE : FALSE;*/
970
971         col_set_str(pinfo->cinfo, COL_PROTOCOL, "RSIP");
972
973         col_add_str(pinfo->cinfo, COL_INFO,
974             val_to_str(msgtype, msg_type_vals,
975                 "Unknown Message Type (0x%0x)"));
976
977         if (tree) {
978                 ti = proto_tree_add_item(tree, proto_rsip, tvb, 0, -1, ENC_NA);
979
980                 rsip_tree = proto_item_add_subtree(ti, ett_rsip);
981
982                 proto_tree_add_item(rsip_tree,
983                     hf_rsip_version, tvb, 0, 1, ENC_BIG_ENDIAN);
984                 proto_tree_add_item(rsip_tree,
985                     hf_rsip_message_type, tvb, 1, 1, ENC_BIG_ENDIAN);
986                 proto_tree_add_item(rsip_tree,
987                     hf_rsip_message_length, tvb, 2, 2, ENC_BIG_ENDIAN);
988
989                 eoff = tvb_reported_length(tvb);
990
991                 switch (msgtype) {
992                 case 1:         /* Error Response */
993                         rsip_message_error_response(tvb, rsip_tree, 4, eoff);
994                         break;
995                 case 2:         /* Register Request */
996                         rsip_message_register_request(tvb, rsip_tree, 4, eoff);
997                         break;
998                 case 3:         /* Register Response */
999                         rsip_message_register_response(tvb, rsip_tree, 4, eoff);
1000                         break;
1001                 case 4:         /* De-register Request */
1002                         rsip_message_deregister_request(tvb, rsip_tree, 4, eoff);
1003                         break;
1004                 case 5:         /* De-register Response */
1005                         rsip_message_deregister_response(tvb, rsip_tree, 4, eoff);
1006                         break;
1007                 case 6:         /* Assign Request RSA-IP */
1008                         rsip_message_assign_request_rsaip(tvb, rsip_tree, 4, eoff);
1009                         break;
1010                 case 7:         /* Assign Response RSA-IP */
1011                         rsip_message_assign_response_rsaip(tvb, rsip_tree, 4, eoff);
1012                         break;
1013                 case 8:         /* Assign Request RSAP-IP */
1014                         rsip_message_assign_request_rsapip(tvb, rsip_tree, 4, eoff);
1015                         break;
1016                 case 9:         /* Assign Response RSAP-IP */
1017                         rsip_message_assign_response_rsapip(tvb, rsip_tree, 4, eoff);
1018                         break;
1019                 case 10:        /* Extend Request */
1020                         rsip_message_extend_request(tvb, rsip_tree, 4, eoff);
1021                         break;
1022                 case 11:        /* Extend Response */
1023                         rsip_message_extend_response(tvb, rsip_tree, 4, eoff);
1024                         break;
1025                 case 12:        /* Free Request */
1026                         rsip_message_free_request(tvb, rsip_tree, 4, eoff);
1027                         break;
1028                 case 13:        /* Free Response */
1029                         rsip_message_free_response(tvb, rsip_tree, 4, eoff);
1030                         break;
1031                 case 14:        /* Query Request */
1032                         rsip_message_query_request(tvb, rsip_tree, 4, eoff);
1033                         break;
1034                 case 15:        /* Query Response */
1035                         rsip_message_query_response(tvb, rsip_tree, 4, eoff);
1036                         break;
1037                 case 16:        /* Listen Request */
1038                         rsip_message_listen_request(tvb, rsip_tree, 4, eoff);
1039                         break;
1040                 case 17:        /* Listen Response */
1041                         rsip_message_listen_response(tvb, rsip_tree, 4, eoff);
1042                         break;
1043                 case 22:        /* Assign Request RSIPsec */
1044                         rsip_message_assign_request_rsipsec(tvb, rsip_tree, 4, eoff);
1045                         break;
1046                 case 23:        /* Assign Response RSIPsec */
1047                         rsip_message_assign_response_rsipsec(tvb, rsip_tree, 4, eoff);
1048                         break;
1049                 }
1050         }
1051         return tvb_captured_length(tvb);
1052 }
1053
1054
1055 /* Register the protocol with Wireshark */
1056 void
1057 proto_register_rsip(void)
1058 {
1059
1060         static hf_register_info hf[] = {
1061                 { &hf_rsip_version,
1062                         { "Protocol version",   "rsip.version",
1063                           FT_UINT8, BASE_DEC, NULL, 0x0,
1064                           NULL, HFILL }
1065                 },
1066                 { &hf_rsip_message_type,
1067                         { "Message type",       "rsip.message_type",
1068                           FT_UINT8, BASE_DEC, VALS(msg_type_appendix_vals), 0x0,
1069                           NULL, HFILL }
1070                 },
1071                 { &hf_rsip_message_length,
1072                         { "Message length",     "rsip.message_length",
1073                           FT_UINT16, BASE_DEC, NULL, 0x0,
1074                           NULL, HFILL }
1075                 },
1076
1077                 { &hf_rsip_parameter_type,
1078                         { "Type",               "rsip.parameter.type",
1079                           FT_UINT8, BASE_DEC, VALS(param_type_vals), 0x0,
1080                           NULL, HFILL }
1081                 },
1082                 { &hf_rsip_parameter_length,
1083                         { "Length",             "rsip.parameter.length",
1084                           FT_UINT8, BASE_DEC, NULL, 0x0,
1085                           NULL, HFILL }
1086                 },
1087                 { &hf_rsip_parameter_value,
1088                         { "Value",              "rsip.parameter.value",
1089                           FT_BYTES, BASE_NONE, NULL, 0x0,
1090                           NULL, HFILL }},
1091
1092                 { &hf_rsip_parameter_address_type,
1093                         { "Address type",       "rsip.parameter.address_type",
1094                           FT_UINT8, BASE_DEC, VALS(addr_type_vals), 0x0,
1095                           NULL, HFILL }
1096                 },
1097                 { &hf_rsip_parameter_address_ipv4,
1098                         { "IPv4 Address",       "rsip.parameter.address",
1099                           FT_IPv4, BASE_NONE, NULL, 0x0,
1100                           NULL, HFILL }
1101                 },
1102                 { &hf_rsip_parameter_address_ipv4_netmask,
1103                         { "IPv4 Netmask",       "rsip.parameter.netmask",
1104                           FT_IPv4, BASE_NETMASK, NULL, 0x0,
1105                           NULL, HFILL }
1106                 },
1107                 { &hf_rsip_parameter_address_ipv6,
1108                         { "IPv6 Address",       "rsip.parameter.address.ipv6",
1109                           FT_IPv6, BASE_NONE, NULL, 0x0,
1110                           NULL, HFILL }
1111                 },
1112                 { &hf_rsip_parameter_address_fqdn,
1113                         { "Fully Qualified Domain Name", "rsip.parameter.fqdn",
1114                           FT_STRING, BASE_NONE, NULL, 0x0,
1115                           NULL, HFILL }
1116                 },
1117
1118                 { &hf_rsip_parameter_ports_number,
1119                         { "Number",             "rsip.parameter.ports.number",
1120                           FT_UINT8, BASE_DEC, NULL, 0x0,
1121                           NULL, HFILL }
1122                 },
1123                 { &hf_rsip_parameter_ports_port_number,
1124                         { "Port",       "rsip.parameter.ports.port_number",
1125                           FT_UINT16, BASE_DEC, NULL, 0x0,
1126                           NULL, HFILL }
1127                 },
1128
1129                 { &hf_rsip_parameter_lease_time,
1130                         { "Lease time",         "rsip.parameter.lease_time",
1131                           FT_UINT32, BASE_DEC, NULL, 0x0,
1132                           NULL, HFILL }
1133                 },
1134
1135                 { &hf_rsip_parameter_client_id,
1136                         { "Client ID",          "rsip.parameter.client_id",
1137                           FT_UINT32, BASE_DEC, NULL, 0x0,
1138                           NULL, HFILL }
1139                 },
1140
1141                 { &hf_rsip_parameter_bind_id,
1142                         { "Bind ID",            "rsip.parameter.bind_id",
1143                           FT_UINT32, BASE_DEC, NULL, 0x0,
1144                           NULL, HFILL }
1145                 },
1146
1147                 { &hf_rsip_parameter_tunnel_type,
1148                         { "Tunnel type",                "rsip.parameter.tunnel_type",
1149                           FT_UINT8, BASE_DEC, VALS(tunnel_type_vals), 0x0,
1150                           NULL, HFILL }
1151                 },
1152
1153                 { &hf_rsip_parameter_method,
1154                         { "Method",             "rsip.method_param.method",
1155                           FT_UINT8, BASE_DEC, VALS(method_vals), 0x0,
1156                           NULL, HFILL }
1157                 },
1158
1159                 { &hf_rsip_parameter_error,
1160                         { "Error",              "rsip.parameter.error",
1161                           FT_UINT16, BASE_DEC, VALS(error_number_vals), 0x0,
1162                           NULL, HFILL }
1163                 },
1164
1165                 { &hf_rsip_parameter_flow_policy_local,
1166                         { "Local Flow Policy",  "rsip.parameter.local_flow_policy",
1167                           FT_UINT8, BASE_DEC, VALS(lcl_flow_policy_vals), 0x0,
1168                           NULL, HFILL }
1169                 },
1170                 { &hf_rsip_parameter_flow_policy_remote,
1171                         { "Remote Flow Policy", "rsip.parameter.remote_flow_policy",
1172                           FT_UINT8, BASE_DEC, VALS(rmt_flow_policy_vals), 0x0,
1173                           NULL, HFILL }
1174                 },
1175
1176                 { &hf_rsip_parameter_indicator,
1177                         { "Value",      "rsip.parameter.indicator",
1178                           FT_UINT16, BASE_HEX, NULL, 0x0,
1179                           NULL, HFILL }
1180                 },
1181
1182                 { &hf_rsip_parameter_message_counter,
1183                         { "Counter",    "rsip.parameter.message_counter",
1184                           FT_UINT32, BASE_DEC, NULL, 0x0,
1185                           NULL, HFILL }
1186                 },
1187
1188                 { &hf_rsip_parameter_vendor_specific_vendor_id,
1189                         { "Vendor ID",  "rsip.parameter.vendor_specific.vendor_id",
1190                           FT_UINT16, BASE_DEC, NULL, 0x0,
1191                           NULL, HFILL }
1192                 },
1193                 { &hf_rsip_parameter_vendor_specific_subtype,
1194                         { "Subtype",    "rsip.parameter.vendor_specific.subtype",
1195                           FT_UINT16, BASE_DEC, NULL, 0x0,
1196                           NULL, HFILL }
1197                 },
1198                 { &hf_rsip_parameter_vendor_specific_value,
1199                         { "Value",      "rsip.parameter.vendor_specific.value",
1200                           FT_NONE, BASE_NONE, NULL, 0x0,
1201                           NULL, HFILL }
1202                 },
1203
1204                 { &hf_rsip_parameter_spi_number,
1205                         { "Number",     "rsip.parameter.spi_number",
1206                           FT_UINT16, BASE_DEC, NULL, 0x0,
1207                           NULL, HFILL }
1208                 },
1209                 { &hf_rsip_parameter_spi,
1210                         { "SPI",        "rsip.parameter.spi",
1211                           FT_UINT32, BASE_HEX, NULL, 0x0,
1212                           NULL, HFILL }
1213                 }
1214         };
1215
1216         static gint *ett[] = {
1217                 &ett_rsip,
1218                 &ett_rsip_param,
1219                 &ett_rsip_param_val
1220         };
1221
1222         proto_rsip = proto_register_protocol("Realm Specific IP Protocol",
1223             "RSIP", "rsip");
1224
1225         proto_register_field_array(proto_rsip, hf, array_length(hf));
1226         proto_register_subtree_array(ett, array_length(ett));
1227
1228 }
1229
1230 void
1231 proto_reg_handoff_rsip(void)
1232 {
1233         dissector_handle_t rsip_handle;
1234
1235         rsip_handle = create_dissector_handle(dissect_rsip, proto_rsip);
1236         dissector_add_uint_with_preference("udp.port", UDP_PORT_RSIP, rsip_handle);
1237         dissector_add_uint_with_preference("tcp.port", TCP_PORT_RSIP, rsip_handle);
1238 }
1239
1240 /*
1241  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
1242  *
1243  * Local variables:
1244  * c-basic-offset: 8
1245  * tab-width: 8
1246  * indent-tabs-mode: t
1247  * End:
1248  *
1249  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1250  * :indentSize=8:tabSize=8:noTabs=false:
1251  */