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