44f8e9ddcd1029dfaf8c7580194cb04bd448bd3c
[obnox/wireshark/wip.git] / packet-ddtp.c
1 /* packet-ddtp.c
2  * Routines for DDTP (Dynamic DNS Tools Protocol) packet disassembly
3  * see http://ddt.sourceforge.net/
4  * Olivier Abad <abad@daba.dhis.net>
5  *
6  * $Id: packet-ddtp.c,v 1.2 2000/04/13 21:16:22 oabad Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@zing.org>
10  * Copyright 2000
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
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #ifdef HAVE_SYS_TYPES_H
34 #include <sys/types.h>
35 #endif
36
37 /*#include <string.h>
38 #include <ctype.h>
39 #include <time.h>*/
40
41 #include <glib.h>
42 #ifdef HAVE_NETINET_IN_H
43 # include <netinet/in.h>
44 #endif
45 #include "packet.h"
46 #include "dfilter.h"
47 #include "packet-ddtp.h"
48
49 static int proto_ddtp = -1;
50 static int hf_ddtp_version = -1;
51 static int hf_ddtp_encrypt = -1;
52 static int hf_ddtp_hostid = -1;
53 static int hf_ddtp_msgtype = -1;
54 static int hf_ddtp_opcode = -1;
55 static int hf_ddtp_ipaddr = -1;
56 static int hf_ddtp_status = -1;
57
58 static int ett_ddtp = -1;
59
60 #define UDP_PORT_DDTP1  58800
61 #define UDP_PORT_DDTP2  58801
62
63 static const value_string vals_ddtp_version[] = {
64     { DDTP_VERSION_ERROR, "Protocol Error" },
65     { DDTP_VERSION_4,     "4" },
66     { DDTP_VERSION_5,     "5" },
67     { 0, NULL}
68 };
69
70 static const value_string vals_ddtp_encrypt[] = {
71     { DDTP_ENCRYPT_ERROR,     "Encryption Error" },
72     { DDTP_ENCRYPT_PLAINTEXT, "Plain text" },
73     { DDTP_ENCRYPT_BLOWFISH,  "Blowfish" },
74     { 0, NULL}
75 };
76
77 static const value_string vals_ddtp_msgtype[] = {
78     { DDTP_MESSAGE_ERROR, "Message Error" },
79     { DDTP_UPDATE_QUERY,  "Update Query" },
80     { DDTP_UPDATE_REPLY,  "Update Reply" },
81     { DDTP_ALIVE_QUERY,   "Alive Query" },
82     { DDTP_ALIVE_REPLY,   "Alive Reply" },
83     { 0, NULL}
84 };
85
86 static const value_string vals_ddtp_opcode[] = {
87     { DDTP_MARK_ONLINE,  "Mark online" },
88     { DDTP_MARK_OFFLINE, "Mark offline" },
89     { 0, NULL}
90 };
91
92 static const value_string vals_ddtp_status[] = {
93     { DDTP_UPDATE_SUCCEEDED, "Update succeeded" },
94     { DDTP_UPDATE_FAILED,    "Update failed" },
95     { DDTP_INVALID_PASSWORD, "Invalid password" },
96     { DDTP_INVALID_ACCOUNT,  "Invalid account" },
97     { DDTP_INVALID_OPCODE,   "Invalid opcode" },
98     { 0, NULL}
99 };
100
101 static void
102 dissect_ddtp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
103 {
104
105     proto_tree      *ddtp_tree;
106     proto_item      *ti;
107
108     if (check_col(fd, COL_PROTOCOL)) {
109         /* Indicate what kind of message this is. */
110         col_add_str (fd, COL_PROTOCOL, "DDTP");
111     }
112     if (tree) {
113         ti = proto_tree_add_item(tree, proto_ddtp, offset,
114                 END_OF_FRAME - offset, NULL);
115         ddtp_tree = proto_item_add_subtree(ti, ett_ddtp);
116
117         if (!BYTES_ARE_IN_FRAME(offset, 4)) {
118             proto_tree_add_text(ddtp_tree, offset, END_OF_FRAME-offset, "Frame too short");
119             return;
120         }
121         proto_tree_add_item(ddtp_tree, hf_ddtp_version, offset, 4, pntohl(pd+offset));
122         offset += 4;
123         if (!BYTES_ARE_IN_FRAME(offset, 4)) {
124             proto_tree_add_text(ddtp_tree, offset, END_OF_FRAME-offset, "Frame too short");
125             return;
126         }
127         proto_tree_add_item(ddtp_tree, hf_ddtp_encrypt, offset, 4, pntohl(pd+offset));
128         if (!BYTES_ARE_IN_FRAME(offset+4, 4)) {
129             proto_tree_add_text(ddtp_tree, offset+4, END_OF_FRAME-offset-4, "Frame too short");
130             return;
131         }
132         proto_tree_add_item(ddtp_tree, hf_ddtp_hostid, offset+4, 4, pntohl(pd+offset+4));
133         if (pntohl(pd+offset) == DDTP_ENCRYPT_PLAINTEXT) {
134             offset += 8;
135             if (!BYTES_ARE_IN_FRAME(offset, 4)) {
136                 proto_tree_add_text(ddtp_tree, offset, END_OF_FRAME-offset, "Frame too short");
137                 return;
138             }
139             proto_tree_add_item(ddtp_tree, hf_ddtp_msgtype, offset, 4, pntohl(pd+offset));
140             switch (pntohl(pd+offset)) {
141             case DDTP_MESSAGE_ERROR :
142                 offset += 4;
143                 if (check_col(fd, COL_INFO)) col_add_str (fd, COL_INFO, "Message Error");
144                 break;
145             case DDTP_UPDATE_QUERY :
146                 offset += 4;
147                 if (check_col(fd, COL_INFO)) col_add_str (fd, COL_INFO, "Update Query");
148                 if (!BYTES_ARE_IN_FRAME(offset, 4)) {
149                     proto_tree_add_text(ddtp_tree, offset, END_OF_FRAME-offset, "Frame too short");
150                     return;
151                 }
152                 proto_tree_add_item(ddtp_tree, hf_ddtp_opcode, offset, 4, pntohl(pd+offset));
153                 offset += 4;
154                 if (!BYTES_ARE_IN_FRAME(offset, 4)) {
155                     proto_tree_add_text(ddtp_tree, offset, END_OF_FRAME-offset, "Frame too short");
156                     return;
157                 }
158                 proto_tree_add_item(ddtp_tree, hf_ddtp_ipaddr, offset, 4, pntohl(pd+offset));
159                 break;
160             case DDTP_UPDATE_REPLY :
161                 offset += 4;
162                 if (check_col(fd, COL_INFO)) col_add_str (fd, COL_INFO, "Update Reply");
163                 if (!BYTES_ARE_IN_FRAME(offset, 4)) {
164                     proto_tree_add_text(ddtp_tree, offset, END_OF_FRAME-offset, "Frame too short");
165                     return;
166                 }
167                 proto_tree_add_item(ddtp_tree, hf_ddtp_status, offset, 4, pntohl(pd+offset));
168                 break;
169             case DDTP_ALIVE_QUERY :
170                 offset += 4;
171                 if (check_col(fd, COL_INFO)) col_add_str (fd, COL_INFO, "Alive Query");
172                 if (!BYTES_ARE_IN_FRAME(offset, 4)) {
173                     proto_tree_add_text(ddtp_tree, offset, END_OF_FRAME-offset, "Frame too short");
174                     return;
175                 }
176                 proto_tree_add_text(ddtp_tree, offset, 4, "Dummy : %u", pntohl(pd+offset));
177                 break;
178             case DDTP_ALIVE_REPLY :
179                 offset += 4;
180                 if (check_col(fd, COL_INFO)) col_add_str (fd, COL_INFO, "Alive Reply");
181                 if (!BYTES_ARE_IN_FRAME(offset, 4)) {
182                     proto_tree_add_text(ddtp_tree, offset, END_OF_FRAME-offset, "Frame too short");
183                     return;
184                 }
185                 proto_tree_add_text(ddtp_tree, offset, 4, "Dummy : %u", pntohl(pd+offset));
186                 break;
187             default :
188                 if (check_col(fd, COL_INFO)) col_add_str (fd, COL_INFO, "Unknwon type");
189                 if (!BYTES_ARE_IN_FRAME(offset, 4)) {
190                     proto_tree_add_text(ddtp_tree, offset, END_OF_FRAME-offset, "Frame too short");
191                     return;
192                 }
193                 proto_tree_add_text(ddtp_tree, offset, 4, "Unknown type : %u", pntohl(pd+offset));
194             }
195         }
196    }
197 }
198
199 void
200 proto_register_ddtp(void)
201 {
202     static hf_register_info hf_ddtp[] = {
203         { &hf_ddtp_version,
204             { "Version", "ddtp.version", FT_UINT32, BASE_DEC, VALS(vals_ddtp_version), 0x0,
205                 "Version" } },
206         { &hf_ddtp_encrypt,
207             { "Encryption", "ddtp.encrypt", FT_UINT32, BASE_DEC, VALS(vals_ddtp_encrypt), 0x0,
208                 "Encryption type" } },
209         { &hf_ddtp_hostid,
210             { "Hostid", "ddtp.hostid", FT_UINT32, BASE_DEC, NULL, 0x0,
211                 "Host ID" } },
212         { &hf_ddtp_msgtype,
213             { "Message type", "ddtp.msgtype", FT_UINT32, BASE_DEC, VALS(vals_ddtp_msgtype), 0x0,
214                 "Message Type" } },
215         { &hf_ddtp_opcode,
216             { "Opcode", "ddtp.opcode", FT_UINT32, BASE_DEC, VALS(vals_ddtp_opcode), 0x0,
217                 "Update query opcode" } },
218         { &hf_ddtp_ipaddr,
219             { "IP addres", "ddtp.ipaddr", FT_IPv4, BASE_NONE, NULL, 0x0,
220                 "IP address" } },
221         { &hf_ddtp_status,
222             { "Status", "ddtp.status", FT_UINT32, BASE_DEC, VALS(vals_ddtp_status), 0x0,
223                 "Update reply status" } }
224     };
225
226     static gint *ett[] = { &ett_ddtp };
227
228     proto_ddtp = proto_register_protocol("Dynamic DNS Tools Protocol", "ddtp");
229     proto_register_field_array(proto_ddtp, hf_ddtp, array_length(hf_ddtp));
230     proto_register_subtree_array(ett, array_length(ett));
231 }
232
233 void
234 proto_reg_handoff_ddtp(void)
235 {
236     dissector_add("udp.port", UDP_PORT_DDTP1, dissect_ddtp);
237     dissector_add("udp.port", UDP_PORT_DDTP2, dissect_ddtp);
238 }