1 /* packet-tivoconnect.c
2 * Routines for TiVoConnect Discovery Protocol dissection
3 * Copyright 2006, Kees Cook <kees@outflux.net>
4 * IANA UDP/TCP port: 2190 (tivoconnect)
5 * Protocol Spec: http://tivo.com/developer/i/TiVoConnectDiscovery.pdf
7 * IANA's full name is "TiVoConnect Beacon", where as TiVo's own
8 * documentation calls this protocol "TiVoConnect Discovery Protocol".
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * SPDX-License-Identifier: GPL-2.0-or-later
19 * - split services into a subtree
20 * - split platform into a subtree
26 #include <epan/packet.h>
28 void proto_reg_handoff_tivoconnect(void);
29 void proto_register_tivoconnect(void);
31 static dissector_handle_t tivoconnect_tcp_handle
;
32 static dissector_handle_t tivoconnect_udp_handle
;
34 #define TIVOCONNECT_PORT 2190
36 static int proto_tivoconnect
;
37 static int hf_tivoconnect_flavor
;
38 static int hf_tivoconnect_method
;
39 static int hf_tivoconnect_platform
;
40 static int hf_tivoconnect_machine
;
41 static int hf_tivoconnect_identity
;
42 static int hf_tivoconnect_services
;
43 static int hf_tivoconnect_version
;
45 static int ett_tivoconnect
;
48 dissect_tivoconnect(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, bool is_tcp
)
50 /* parsing variables */
54 const char * proto_name
;
55 char * packet_identity
= NULL
;
56 char * packet_machine
= NULL
;
58 /* validate that we have a tivoconnect packet */
59 if ( tvb_strncaseeql(tvb
, 0, "tivoconnect", 11) != 0) {
63 length
= tvb_captured_length(tvb
);
64 string
= (char*)tvb_get_string_enc(pinfo
->pool
, tvb
, 0, length
, ENC_ASCII
);
66 /* Make entries in Protocol column and Info column on summary display */
67 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "TiVoConnect");
69 /* make a distinction between UDP and TCP packets */
70 proto_name
= is_tcp
? "Discovery Connection" : "Discovery Beacon";
72 col_set_str(pinfo
->cinfo
, COL_INFO
, proto_name
);
75 /* Set up structures needed to add the protocol subtree and manage it */
77 proto_tree
*tivoconnect_tree
;
79 /* parsing variables */
83 /* create display subtree for the protocol */
84 ti
= proto_tree_add_item(tree
, proto_tivoconnect
, tvb
, 0, -1, ENC_NA
);
86 tivoconnect_tree
= proto_item_add_subtree(ti
, ett_tivoconnect
);
88 /* process the packet */
89 for ( field
= strtok(string
, "\n");
91 offset
+= length
, field
= strtok(NULL
, "\n") ) {
95 length
= (int)strlen(field
) + 1;
97 if ( !(value
= strchr(field
, '=')) ) {
98 /* bad packet: missing the field separator */
102 fieldlen
= (int)strlen(field
) + 1;
104 if ( g_ascii_strcasecmp(field
, "tivoconnect") == 0 ) {
105 proto_tree_add_item(tivoconnect_tree
,
106 hf_tivoconnect_flavor
, tvb
, offset
+fieldlen
,
107 length
-fieldlen
-1, ENC_ASCII
);
109 else if ( g_ascii_strcasecmp(field
, "method") == 0 ) {
110 proto_tree_add_item(tivoconnect_tree
,
111 hf_tivoconnect_method
, tvb
, offset
+fieldlen
,
112 length
-fieldlen
-1, ENC_ASCII
);
114 else if ( g_ascii_strcasecmp(field
, "platform") == 0 ) {
115 proto_tree_add_item(tivoconnect_tree
,
116 hf_tivoconnect_platform
, tvb
, offset
+fieldlen
,
117 length
-fieldlen
-1, ENC_ASCII
);
119 else if ( g_ascii_strcasecmp(field
, "machine") == 0 ) {
120 proto_tree_add_item(tivoconnect_tree
,
121 hf_tivoconnect_machine
, tvb
, offset
+fieldlen
,
122 length
-fieldlen
-1, ENC_ASCII
);
123 packet_machine
= value
;
125 else if ( g_ascii_strcasecmp(field
, "identity") == 0 ) {
126 proto_tree_add_item(tivoconnect_tree
,
127 hf_tivoconnect_identity
, tvb
, offset
+fieldlen
,
128 length
-fieldlen
-1, ENC_ASCII
);
129 packet_identity
= value
;
131 else if ( g_ascii_strcasecmp(field
, "services") == 0 ) {
132 proto_tree_add_item(tivoconnect_tree
,
133 hf_tivoconnect_services
, tvb
, offset
+fieldlen
,
134 length
-fieldlen
-1, ENC_ASCII
);
136 else if ( g_ascii_strcasecmp(field
, "swversion") == 0 ) {
137 proto_tree_add_item(tivoconnect_tree
,
138 hf_tivoconnect_version
, tvb
, offset
+fieldlen
,
139 length
-fieldlen
-1, ENC_ASCII
);
146 /* Adjust "Info" column and top of tree into more useful info */
147 if (packet_machine
) {
148 proto_item_append_text(ti
, ", %s", packet_machine
);
149 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s %s",
150 proto_name
, packet_machine
);
152 if (packet_identity
) {
153 proto_item_append_text(ti
,
154 packet_machine
? " (%s)" : ", ID:%s",
156 if (packet_machine
) {
157 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s %s (%s)",
158 proto_name
, packet_machine
, packet_identity
);
161 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s ID:%s",
162 proto_name
, packet_identity
);
168 return tvb_reported_length(tvb
);
172 dissect_tivoconnect_tcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
174 return dissect_tivoconnect(tvb
, pinfo
, tree
, true);
178 dissect_tivoconnect_udp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
180 return dissect_tivoconnect(tvb
, pinfo
, tree
, false);
184 proto_register_tivoconnect(void)
186 static hf_register_info hf
[] = {
187 { &hf_tivoconnect_flavor
,
188 { "Flavor", "tivoconnect.flavor",
189 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
190 "Protocol Flavor supported by the originator", HFILL
}},
191 { &hf_tivoconnect_method
,
192 { "Method", "tivoconnect.method",
193 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
194 "Packet was delivered via UDP(broadcast) or TCP(connected)", HFILL
}},
195 { &hf_tivoconnect_platform
,
196 { "Platform", "tivoconnect.platform",
197 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
198 "System platform, either tcd(TiVo) or pc(Computer)", HFILL
}},
199 { &hf_tivoconnect_machine
,
200 { "Machine", "tivoconnect.machine",
201 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
202 "Human-readable system name", HFILL
}},
203 { &hf_tivoconnect_identity
,
204 { "Identity", "tivoconnect.identity",
205 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
206 "Unique serial number for the system", HFILL
}},
207 { &hf_tivoconnect_services
,
208 { "Services", "tivoconnect.services",
209 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
210 "List of available services on the system", HFILL
}},
211 { &hf_tivoconnect_version
,
212 { "Version", "tivoconnect.version",
213 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
214 "System software version", HFILL
}},
217 static int *ett
[] = {
221 proto_tivoconnect
= proto_register_protocol("TiVoConnect Discovery Protocol",
222 "TiVoConnect", "tivoconnect");
224 proto_register_field_array(proto_tivoconnect
, hf
, array_length(hf
));
225 proto_register_subtree_array(ett
, array_length(ett
));
227 tivoconnect_tcp_handle
= register_dissector("tivo.tcp", dissect_tivoconnect_tcp
, proto_tivoconnect
);
228 tivoconnect_udp_handle
= register_dissector("tivo.udp", dissect_tivoconnect_udp
, proto_tivoconnect
);
233 proto_reg_handoff_tivoconnect(void)
235 dissector_add_uint_with_preference("udp.port", TIVOCONNECT_PORT
, tivoconnect_udp_handle
);
236 dissector_add_uint_with_preference("tcp.port", TIVOCONNECT_PORT
, tivoconnect_tcp_handle
);
240 * Editor modelines - https://www.wireshark.org/tools/modelines.html
245 * indent-tabs-mode: nil
248 * vi: set shiftwidth=4 tabstop=8 expandtab:
249 * :indentSize=4:tabSize=8:noTabs=true: