Make the "Preferences" dialog box use the new utilities to make the Esc
[obnox/wireshark/wip.git] / packet-tacacs.c
1 /* packet-tacacs.c
2  * Routines for cisco tacacs/tacplus/AAA packet dissection
3  *
4  * $Id: packet-tacacs.c,v 1.3 2000/04/08 07:07:39 guy Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@zing.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * Copied from packet-tftp.c
11  * 
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  * 
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  * 
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <stdio.h>
32
33 #ifdef HAVE_SYS_TYPES_H
34 # include <sys/types.h>
35 #endif
36
37 #ifdef HAVE_NETINET_IN_H
38 # include <netinet/in.h>
39 #endif
40
41 #include <string.h>
42 #include <glib.h>
43 #include "packet.h"
44
45 static int proto_tacacs = -1;
46 static int hf_tacacs_request = -1;
47 static int hf_tacacs_response = -1;
48 static int hf_tacacs_version = -1;
49
50 static gint ett_tacacs = -1;
51
52 #define UDP_PORT_TACACS 49
53 #define TCP_PORT_TACACS 49
54
55 static void
56 dissect_tacacs(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
57 {
58         proto_tree      *tacacs_tree, *ti;
59
60         if (check_col(fd, COL_PROTOCOL))
61                 col_add_str(fd, COL_PROTOCOL, "TACACS");
62
63         if (check_col(fd, COL_INFO))
64         {
65                 col_add_fstr(fd, COL_INFO, "%s", 
66                         (pi.match_port == pi.destport) ? "Request" : "Response");         
67         }
68
69         if (tree) 
70         {
71                 ti = proto_tree_add_item(tree, proto_tacacs, offset, END_OF_FRAME, NULL);
72                 tacacs_tree = proto_item_add_subtree(ti, ett_tacacs);
73
74                 proto_tree_add_item(tacacs_tree, hf_tacacs_version, 0, 0, "XTacacs");
75
76                 if (pi.match_port == pi.destport)
77                 {
78                         proto_tree_add_item_hidden(tacacs_tree, hf_tacacs_request,
79                                                    offset, END_OF_FRAME, TRUE);
80                         proto_tree_add_text(tacacs_tree, offset, 
81                                 END_OF_FRAME, "Request: <opaque data>" );
82                 }
83                 else
84                 {
85                         proto_tree_add_item_hidden(tacacs_tree, hf_tacacs_response,
86                                                    offset, END_OF_FRAME, TRUE);
87                         proto_tree_add_text(tacacs_tree, offset, 
88                                 END_OF_FRAME, "Response: <opaque data>");
89                 }
90         }
91 }
92
93 static void
94 dissect_tacplus(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
95 {
96         proto_tree      *tacacs_tree, *ti;
97
98         if (check_col(fd, COL_PROTOCOL))
99         col_add_str(fd, COL_PROTOCOL, "TACACS");
100
101         if (check_col(fd, COL_INFO))
102         {
103                 col_add_fstr(fd, COL_INFO, "%s", 
104                         (pi.match_port == pi.destport) ? "Request" : "Response");         
105         }
106
107         if (tree) 
108         {
109                 ti = proto_tree_add_item(tree, proto_tacacs, offset, END_OF_FRAME, NULL);
110                 tacacs_tree = proto_item_add_subtree(ti, ett_tacacs);
111
112                 proto_tree_add_item(tacacs_tree, hf_tacacs_version, 0, 0, "Tacacs+");
113
114                 if (pi.match_port == pi.destport)
115                 {
116                         proto_tree_add_item_hidden(tacacs_tree, hf_tacacs_request,
117                                                    offset, END_OF_FRAME, TRUE);
118                         proto_tree_add_text(tacacs_tree, offset, 
119                                 END_OF_FRAME, "Request: <opaque data>" );
120                 }
121                 else
122                 {
123                         proto_tree_add_item_hidden(tacacs_tree, hf_tacacs_response,
124                                                    offset, END_OF_FRAME, TRUE);
125                         proto_tree_add_text(tacacs_tree, offset, 
126                                 END_OF_FRAME, "Response: <opaque data>");
127                 }
128         }
129 }
130
131 void
132 proto_register_tacacs(void)
133 {
134         static hf_register_info hf[] = {
135           { &hf_tacacs_version,
136             { "Tacacs Version",           "tacacs.version",
137               FT_STRING, BASE_NONE, NULL, 0x0,
138               "xtacacs or tacplus" }},
139           { &hf_tacacs_response,
140             { "Response",           "tacacs.response",
141               FT_BOOLEAN, BASE_NONE, NULL, 0x0,
142               "TRUE if TACACS response" }},
143           { &hf_tacacs_request,
144             { "Request",            "tacacs.request",
145               FT_BOOLEAN, BASE_NONE, NULL, 0x0,
146               "TRUE if TACACS request" }}
147         };
148
149         static gint *ett[] = {
150                 &ett_tacacs,
151         };
152         proto_tacacs = proto_register_protocol("TACACS", "tacacs");
153         proto_register_field_array(proto_tacacs, hf, array_length(hf));
154         proto_register_subtree_array(ett, array_length(ett));
155 }
156
157 void
158 proto_reg_handoff_tacacs(void)
159 {
160         dissector_add("udp.port", UDP_PORT_TACACS, dissect_tacacs);
161         dissector_add("tcp.port", TCP_PORT_TACACS, dissect_tacplus);
162 }