Fix up the "ethereal-dev" address to refer to "ethereal.com" rather than
[obnox/wireshark/wip.git] / packet-ripng.c
1 /* packet-ripng.c
2  * Routines for RIPng disassembly
3  * (c) Copyright Jun-ichiro itojun Hagino <itojun@itojun.org>
4  * derived from packet-rip.c
5  *
6  * $Id: packet-ripng.c,v 1.17 2001/01/09 06:31:40 guy Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@zing.org>
10  * Copyright 1998 Gerald Combs
11  * 
12  * 
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  * 
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  * 
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27  
28 #include "config.h"
29
30 #ifdef HAVE_SYS_TYPES_H
31 #include <sys/types.h>
32 #endif
33
34 #ifdef HAVE_NETINET_IN_H
35 #include <netinet/in.h>
36 #endif
37
38 #include <string.h>
39 #include <glib.h>
40 #include "packet.h"
41 #include "packet-ipv6.h"
42 #include "packet-ripng.h"
43
44 #ifndef offsetof
45 #define offsetof(type, member)  ((size_t)(&((type *)0)->member))
46 #endif
47
48 static int proto_ripng = -1;
49 static int hf_ripng_cmd = -1;
50 static int hf_ripng_version = -1;
51
52 static gint ett_ripng = -1;
53 static gint ett_ripng_addr = -1;
54
55 #define UDP_PORT_RIPNG  521
56
57 static void 
58 dissect_ripng(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
59     struct rip6 rip6;
60     struct netinfo6 ni6;
61     proto_tree *ripng_tree = NULL;
62     proto_tree *subtree = NULL;
63     proto_item *ti; 
64     static const value_string cmdvals[] = {
65         { RIP6_REQUEST, "Request" },
66         { RIP6_RESPONSE, "Response" },
67         { 0, NULL },
68     };
69     const char *cmd;
70
71     OLD_CHECK_DISPLAY_AS_DATA(proto_ripng, pd, offset, fd, tree);
72
73     /* avoid alignment problem */
74     memcpy(&rip6, &pd[offset], sizeof(rip6));
75   
76     cmd = val_to_str(rip6.rip6_cmd, cmdvals, "Unknown");
77
78     if (check_col(fd, COL_PROTOCOL))
79         col_add_fstr(fd, COL_PROTOCOL, "RIPng version %u", rip6.rip6_vers);
80     if (check_col(fd, COL_INFO))
81         col_add_fstr(fd, COL_INFO, "%s", cmd); 
82
83     if (tree) {
84         ti = proto_tree_add_item(tree, proto_ripng, NullTVB, offset, END_OF_FRAME, FALSE);
85         ripng_tree = proto_item_add_subtree(ti, ett_ripng);
86
87         proto_tree_add_uint_format(ripng_tree, hf_ripng_cmd, NullTVB, offset, 1,
88             rip6.rip6_cmd,
89             "Command: %s (%u)", cmd, rip6.rip6_cmd); 
90         proto_tree_add_uint(ripng_tree, hf_ripng_version, NullTVB, offset + 1, 1,
91             rip6.rip6_vers);
92
93         offset += 4;
94         while ((pi.captured_len - offset) >= sizeof(struct netinfo6)){
95                     if (! BYTES_ARE_IN_FRAME(offset, sizeof(ni6))) {
96                        proto_tree_add_text(ripng_tree, NullTVB, offset, sizeof(ni6), "No IP Address information");
97                        break;
98                     }
99
100                     memcpy(&ni6, &pd[offset], sizeof(ni6));
101                     if (ni6.rip6_tag) {
102                         ti = proto_tree_add_text(ripng_tree, NullTVB, offset,
103                                         sizeof(ni6), "IP Address: %s/%u, Metric: %u, tag: 0x%04x",
104                                         ip6_to_str(&ni6.rip6_dest),
105                                         ni6.rip6_plen,
106                                         ni6.rip6_metric,
107                                         ntohs(ni6.rip6_tag));
108                     } else {
109                         ti = proto_tree_add_text(ripng_tree, NullTVB, offset,
110                                         sizeof(ni6), "IP Address: %s/%u, Metric: %u",
111                                         ip6_to_str(&ni6.rip6_dest),
112                                         ni6.rip6_plen,
113                                         ni6.rip6_metric);
114                     }
115                     subtree = proto_item_add_subtree(ti, ett_ripng_addr);
116                     proto_tree_add_text(subtree, NullTVB,
117                                 offset + offsetof(struct netinfo6, rip6_dest),
118                                 sizeof(ni6.rip6_dest), "IP Address: %s",
119                                 ip6_to_str(&ni6.rip6_dest));
120                     proto_tree_add_text(subtree, NullTVB,
121                                 offset + offsetof(struct netinfo6, rip6_tag),
122                                 sizeof(ni6.rip6_tag), "Tag: 0x%04x",
123                                 ntohs(ni6.rip6_tag));
124                     proto_tree_add_text(subtree, NullTVB,
125                                 offset + offsetof(struct netinfo6, rip6_plen),
126                                 sizeof(ni6.rip6_plen), "Prefix length: %u",
127                                 ni6.rip6_plen);
128                     proto_tree_add_text(subtree, NullTVB,
129                                 offset + offsetof(struct netinfo6, rip6_metric),
130                                 sizeof(ni6.rip6_metric), "Metric: %u",
131                                 ni6.rip6_metric);
132
133                     offset += sizeof(ni6);
134         }
135     }
136 }
137
138 void
139 proto_register_ripng(void)
140 {
141     static hf_register_info hf[] = {
142       { &hf_ripng_cmd,
143         { "Command",            "ripng.cmd",
144                                 FT_UINT8, BASE_DEC, NULL, 0x0, "" }},
145       { &hf_ripng_version,
146         { "Version",            "ripng.version",
147                                 FT_UINT8, BASE_DEC, NULL, 0x0, "" }},
148     };
149     static gint *ett[] = {
150       &ett_ripng,
151       &ett_ripng_addr,
152     };
153
154     proto_ripng = proto_register_protocol("RIPng", "RIPng", "ripng");
155     proto_register_field_array(proto_ripng, hf, array_length(hf));
156     proto_register_subtree_array(ett, array_length(ett));
157 }
158
159 void
160 proto_reg_handoff_ripng(void)
161 {
162     old_dissector_add("udp.port", UDP_PORT_RIPNG, dissect_ripng, proto_ripng);
163 }