5 * Copyright 2002, Tazmen Technologies Inc
7 * Tazmen Sniffer Protocol for encapsulating the packets across a network
8 * from a remote packet sniffer. TZSP can encapsulate any other protocol.
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include <epan/packet.h>
38 * http://web.archive.org/web/20050404125022/http://www.networkchemistry.com/support/appnotes/an001_tzsp.html
40 * for a description of the protocol.
43 #define UDP_PORT_TZSP 0x9090
45 static int proto_tzsp
= -1;
46 static int hf_tzsp_version
= -1;
47 static int hf_tzsp_type
= -1;
48 static int hf_tzsp_encap
= -1;
50 static dissector_handle_t tzsp_handle
;
55 #define TZSP_RX_PACKET 0 /* Packet received from the sensor */
56 #define TZSP_TX_PACKET 1 /* Packet for the sensor to transmit */
57 #define TZSP_CONFIG 3 /* Configuration information for the sensor */
58 #define TZSP_NULL 4 /* Null frame, used as a keepalive */
59 #define TZSP_PORT 5 /* Port opener - opens a NAT tunnel */
61 static const value_string tzsp_type
[] = {
62 {TZSP_RX_PACKET
, "Received packet"},
63 {TZSP_TX_PACKET
, "Packet for transmit"},
64 {TZSP_CONFIG
, "Configuration"},
65 {TZSP_NULL
, "Keepalive"},
66 {TZSP_PORT
, "Port opener"},
70 static gint ett_tzsp
= -1;
71 static gint ett_tag
= -1;
73 static dissector_handle_t data_handle
;
74 static dissector_table_t encap_dissector_table
;
76 /* ************************************************************************* */
77 /* WLAN radio header felds */
78 /* ************************************************************************* */
80 static int hf_option_tag
= -1;
81 static int hf_option_length
= -1;
82 /* static int hf_status_field = -1; */
83 static int hf_status_msg_type
= -1;
84 static int hf_status_pcf
= -1;
85 /* static int hf_status_mac_port = -1; */
86 static int hf_status_undecrypted
= -1;
87 static int hf_status_fcs_error
= -1;
89 static int hf_time
= -1;
90 static int hf_silence
= -1;
91 static int hf_signal
= -1;
92 static int hf_rate
= -1;
93 static int hf_channel
= -1;
94 static int hf_unknown
= -1;
95 static int hf_original_length
= -1;
96 static int hf_sensormac
= -1;
98 /* ************************************************************************* */
99 /* Encapsulation type values */
100 /* Note that these are not all the same as DLT_ values */
101 /* ************************************************************************* */
103 #define TZSP_ENCAP_ETHERNET 1
104 #define TZSP_ENCAP_TOKEN_RING 2
105 #define TZSP_ENCAP_SLIP 3
106 #define TZSP_ENCAP_PPP 4
107 #define TZSP_ENCAP_FDDI 5
108 #define TZSP_ENCAP_RAW 7 /* "Raw UO", presumably meaning "Raw IP" */
109 #define TZSP_ENCAP_IEEE_802_11 18
110 #define TZSP_ENCAP_IEEE_802_11_PRISM 119
111 #define TZSP_ENCAP_IEEE_802_11_AVS 127
113 /* ************************************************************************* */
114 /* Generic header options */
115 /* ************************************************************************* */
117 #define TZSP_HDR_PAD 0 /* Pad. */
118 #define TZSP_HDR_END 1 /* End of the list. */
119 #define TZSP_WLAN_STA 30 /* Station statistics */
120 #define TZSP_WLAN_PKT 31 /* Packet statistics */
121 #define TZSP_PACKET_ID 40 /* Unique ID of the packet */
122 #define TZSP_HDR_ORIGINAL_LENGTH 41 /* Length of the packet before slicing. 2 bytes. */
123 #define TZSP_HDR_SENSOR 60 /* Sensor MAC address packet was received on, 6 byte ethernet address.*/
125 /* ************************************************************************* */
126 /* Options for 802.11 radios */
127 /* ************************************************************************* */
129 #define WLAN_RADIO_HDR_SIGNAL 10 /* Signal strength in dBm, signed byte. */
130 #define WLAN_RADIO_HDR_NOISE 11 /* Noise level in dBm, signed byte. */
131 #define WLAN_RADIO_HDR_RATE 12 /* Data rate, unsigned byte. */
132 #define WLAN_RADIO_HDR_TIMESTAMP 13 /* Timestamp in us, unsigned 32-bits network byte order. */
133 #define WLAN_RADIO_HDR_MSG_TYPE 14 /* Packet type, unsigned byte. */
134 #define WLAN_RADIO_HDR_CF 15 /* Whether packet arrived during CF period, unsigned byte. */
135 #define WLAN_RADIO_HDR_UN_DECR 16 /* Whether packet could not be decrypted by MAC, unsigned byte. */
136 #define WLAN_RADIO_HDR_FCS_ERR 17 /* Whether packet contains an FCS error, unsigned byte. */
137 #define WLAN_RADIO_HDR_CHANNEL 18 /* Channel number packet was received on, unsigned byte.*/
139 static const value_string option_tag_vals
[] = {
140 {TZSP_HDR_PAD
, "Pad"},
141 {TZSP_HDR_END
, "End"},
142 {TZSP_HDR_ORIGINAL_LENGTH
, "Original Length"},
143 {WLAN_RADIO_HDR_SIGNAL
, "Signal"},
144 {WLAN_RADIO_HDR_NOISE
, "Silence"},
145 {WLAN_RADIO_HDR_RATE
, "Rate"},
146 {WLAN_RADIO_HDR_TIMESTAMP
, "Time"},
147 {WLAN_RADIO_HDR_MSG_TYPE
, "Message Type"},
148 {WLAN_RADIO_HDR_CF
, "Point Coordination Function"},
149 {WLAN_RADIO_HDR_UN_DECR
, "Undecrypted"},
150 {WLAN_RADIO_HDR_FCS_ERR
, "Frame check sequence"},
151 {WLAN_RADIO_HDR_CHANNEL
, "Channel"},
152 {TZSP_HDR_SENSOR
, "Sensor MAC"},
157 /* ************************************************************************* */
158 /* Add option information to the display */
159 /* ************************************************************************* */
162 add_option_info(tvbuff_t
*tvb
, int pos
, proto_tree
*tree
, proto_item
*ti
)
164 guint8 tag
, length
, fcs_err
= 0, encr
= 0, seen_fcs_err
= 0;
165 proto_tree
*tag_tree
;
166 proto_item
*tag_item
;
169 * Read all option tags in an endless loop. If the packet is malformed this
170 * loop might be a problem.
173 tag
= tvb_get_guint8(tvb
, pos
);
174 if ((tag
!= TZSP_HDR_PAD
) && (tag
!= TZSP_HDR_END
)) {
175 length
= tvb_get_guint8(tvb
, pos
+1);
176 tag_item
= proto_tree_add_text(tree
, tvb
, pos
, 2+length
, "%s", val_to_str_const(tag
, option_tag_vals
, "Unknown"));
178 tag_item
= proto_tree_add_text(tree
, tvb
, pos
, 1, "%s", val_to_str_const(tag
, option_tag_vals
, "Unknown"));
182 tag_tree
= proto_item_add_subtree(tag_item
, ett_tag
);
184 proto_tree_add_item(tag_tree
, hf_option_tag
, tvb
, pos
, 1, ENC_NA
);
186 if ((tag
!= TZSP_HDR_PAD
) && (tag
!= TZSP_HDR_END
)) {
187 proto_tree_add_item(tag_tree
, hf_option_length
, tvb
, pos
, 1, ENC_NA
);
196 /* Fill in header with information from other tags. */
198 proto_item_append_text(ti
,"%s", fcs_err
?"FCS Error":(encr
?"Encrypted":"Good"));
202 case TZSP_HDR_ORIGINAL_LENGTH
:
203 proto_tree_add_item(tag_tree
, hf_original_length
, tvb
, pos
, 2, ENC_BIG_ENDIAN
);
206 case WLAN_RADIO_HDR_SIGNAL
:
207 proto_tree_add_item(tag_tree
, hf_signal
, tvb
, pos
, 1, ENC_NA
);
210 case WLAN_RADIO_HDR_NOISE
:
211 proto_tree_add_item(tag_tree
, hf_silence
, tvb
, pos
, 1, ENC_NA
);
214 case WLAN_RADIO_HDR_RATE
:
215 proto_tree_add_item(tag_tree
, hf_rate
, tvb
, pos
, 1, ENC_NA
);
218 case WLAN_RADIO_HDR_TIMESTAMP
:
219 proto_tree_add_item(tag_tree
, hf_time
, tvb
, pos
, 4, ENC_BIG_ENDIAN
);
222 case WLAN_RADIO_HDR_MSG_TYPE
:
223 proto_tree_add_item(tag_tree
, hf_status_msg_type
, tvb
, pos
, 1, ENC_NA
);
226 case WLAN_RADIO_HDR_CF
:
227 proto_tree_add_item(tag_tree
, hf_status_pcf
, tvb
, pos
, 1, ENC_NA
);
230 case WLAN_RADIO_HDR_UN_DECR
:
231 proto_tree_add_item(tag_tree
, hf_status_undecrypted
, tvb
, pos
, 1, ENC_NA
);
232 encr
= tvb_get_guint8(tvb
, pos
);
235 case WLAN_RADIO_HDR_FCS_ERR
:
237 proto_tree_add_item(tag_tree
, hf_status_fcs_error
, tvb
, pos
, 1, ENC_NA
);
238 fcs_err
= tvb_get_guint8(tvb
, pos
);
241 case WLAN_RADIO_HDR_CHANNEL
:
242 proto_tree_add_item(tag_tree
, hf_channel
, tvb
, pos
, 1, ENC_NA
);
245 case TZSP_HDR_SENSOR
:
246 proto_tree_add_item(tag_tree
, hf_sensormac
, tvb
, pos
, 6, ENC_NA
);
250 proto_tree_add_item(tag_tree
, hf_unknown
, tvb
, pos
, length
, ENC_NA
);
258 /* ************************************************************************* */
259 /* Map TZSP encapsulation types to Wiretap encapsulation types */
260 /* ************************************************************************* */
266 static const struct encap_map map_table
[] = {
267 { TZSP_ENCAP_ETHERNET
, WTAP_ENCAP_ETHERNET
},
268 { TZSP_ENCAP_IEEE_802_11_PRISM
, WTAP_ENCAP_IEEE_802_11_PRISM
},
269 { TZSP_ENCAP_IEEE_802_11_AVS
, WTAP_ENCAP_IEEE_802_11_AVS
},
270 { TZSP_ENCAP_IEEE_802_11
, WTAP_ENCAP_IEEE_802_11
},
275 tzsp_encap_to_wtap_encap(guint16 encap
)
279 for (i
= 0; map_table
[i
].wtap_encap
!= -1; i
++) {
280 if (map_table
[i
].tzsp_encap
== encap
)
281 return map_table
[i
].wtap_encap
;
286 /* ************************************************************************* */
287 /* Dissect a TZSP packet */
288 /* ************************************************************************* */
291 dissect_tzsp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
293 proto_tree
*tzsp_tree
= NULL
;
294 proto_item
*ti
= NULL
;
297 guint16 encapsulation
= 0;
299 dissector_handle_t encap_dissector
;
300 const char *encap_name
;
304 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "TZSP");
305 col_clear(pinfo
->cinfo
, COL_INFO
);
307 type
= tvb_get_guint8(tvb
, 1);
309 /* Find the dissector. */
310 encapsulation
= tvb_get_ntohs(tvb
, 2);
311 if (encapsulation
!= 0) {
312 wtap_encap
= tzsp_encap_to_wtap_encap(encapsulation
);
313 if ((wtap_encap
!= -1) &&
314 (encap_dissector
= dissector_get_uint_handle(encap_dissector_table
, wtap_encap
))) {
315 encap_name
= dissector_handle_get_short_name(encap_dissector
);
318 encap_name
= "Unknown";
324 encap_name
= "Nothing";
325 info
= val_to_str(type
, tzsp_type
, "Unknown (%u)");
328 col_add_str(pinfo
->cinfo
, COL_INFO
, info
);
331 /* Adding TZSP item and subtree */
332 ti
= proto_tree_add_protocol_format(tree
, proto_tzsp
, tvb
, 0,
333 -1, "TZSP: %s: ", info
);
334 tzsp_tree
= proto_item_add_subtree(ti
, ett_tzsp
);
336 proto_tree_add_item (tzsp_tree
, hf_tzsp_version
, tvb
, 0, 1,
338 proto_tree_add_uint (tzsp_tree
, hf_tzsp_type
, tvb
, 1, 1,
340 proto_tree_add_uint_format (tzsp_tree
, hf_tzsp_encap
, tvb
, 2, 2,
341 encapsulation
, "Encapsulates: %s (%d)",
342 encap_name
, encapsulation
);
346 * XXX - what about TZSP_CONFIG frames?
350 * http://web.archive.org/web/20021221195733/http://www.networkchemistry.com/support/appnotes/SENSOR-MIB
352 * seems to indicate that you can configure the probe using SNMP;
353 * does TZSP_CONFIG also support that? An old version of Kismet
354 * included code to control a Network Chemistry WSP100 sensor:
356 * https://www.kismetwireless.net/code-old/svn/tags/kismet-2004-02-R1/wsp100source.cc
358 * and it used SNMP to configure the probe.
360 if ((type
!= TZSP_NULL
) && (type
!= TZSP_PORT
)) {
361 pos
= add_option_info(tvb
, 4, tzsp_tree
, ti
);
364 proto_item_set_end(ti
, tvb
, pos
);
365 next_tvb
= tvb_new_subset_remaining(tvb
, pos
);
366 if ((encapsulation
!= 0)
367 && ((wtap_encap
== -1)
368 || !dissector_try_uint(encap_dissector_table
, wtap_encap
,
369 next_tvb
, pinfo
, tree
))) {
371 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "UNKNOWN");
372 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "TZSP_ENCAP = %u",
374 call_dissector(data_handle
, next_tvb
, pinfo
, tree
);
379 /* ************************************************************************* */
380 /* Register the TZSP dissector */
381 /* ************************************************************************* */
384 proto_register_tzsp(void)
386 static const value_string msg_type
[] = {
388 {1, "RFC1042 encoded"},
389 {2, "Bridge-tunnel encoded"},
390 {4, "802.11 management frame"},
394 static const true_false_string pcf_flag
= {
395 "CF: Frame received during CF period",
399 static const true_false_string undecr_flag
= {
400 "Encrypted frame could not be decrypted",
404 static const true_false_string fcs_err_flag
= {
405 "FCS error, frame is corrupted",
409 static const value_string channels
[] = {
411 { 1, "1 (2.412 GHz)"},
412 { 2, "2 (2.417 GHz)"},
413 { 3, "3 (2.422 GHz)"},
414 { 4, "4 (2.427 GHz)"},
415 { 5, "5 (2.432 GHz)"},
416 { 6, "6 (2.437 GHz)"},
417 { 7, "7 (2.442 GHz)"},
418 { 8, "8 (2.447 GHz)"},
419 { 9, "9 (2.452 GHz)"},
420 { 10, "10 (2.457 GHz)"},
421 { 11, "11 (2.462 GHz)"},
422 { 12, "12 (2.467 GHz)"},
423 { 13, "13 (2.472 GHz)"},
424 { 14, "14 (2.484 GHz)"},
426 { 36, "36 (5.180 GHz)"},
427 { 40, "40 (5.200 GHz)"},
428 { 44, "44 (5.220 GHz)"},
429 { 48, "48 (5.240 GHz)"},
430 { 52, "52 (5.260 GHz)"},
431 { 56, "56 (5.280 GHz)"},
432 { 60, "60 (5.300 GHz)"},
433 { 64, "64 (5.320 GHz)"},
434 {149, "149 (5.745 GHz)"},
435 {153, "153 (5.765 GHz)"},
436 {157, "157 (5.785 GHz)"},
437 {161, "161 (5.805 GHz)"},
441 static const value_string rates
[] = {
442 /* Old PRISM rates */
445 {0x37, "5.5 Mbit/s"},
463 static hf_register_info hf
[] = {
464 { &hf_tzsp_version
, {
465 "Version", "tzsp.version", FT_UINT8
, BASE_DEC
,
466 NULL
, 0, NULL
, HFILL
}},
468 "Type", "tzsp.type", FT_UINT8
, BASE_DEC
,
469 VALS(tzsp_type
), 0, NULL
, HFILL
}},
471 "Encapsulation", "tzsp.encap", FT_UINT16
, BASE_DEC
,
472 NULL
, 0, NULL
, HFILL
}},
475 "Option Tag", "tzsp.option_tag", FT_UINT8
, BASE_DEC
,
476 VALS(option_tag_vals
), 0, NULL
, HFILL
}},
477 { &hf_option_length
, {
478 "Option Length", "tzsp.option_length", FT_UINT8
, BASE_DEC
,
479 NULL
, 0, NULL
, HFILL
}},
481 { &hf_status_field
, {
482 "Status", "tzsp.wlan.status", FT_UINT16
, BASE_HEX
,
483 NULL
, 0, NULL
, HFILL
}},
485 { &hf_status_msg_type
, {
486 "Type", "tzsp.wlan.status.msg_type", FT_UINT8
, BASE_HEX
,
487 VALS(msg_type
), 0, "Message type", HFILL
}},
489 { &hf_status_mac_port
, {
490 "Port", "tzsp.wlan.status.mac_port", FT_UINT8
, BASE_DEC
,
491 NULL
, 0, "MAC port", HFILL
}},
494 "PCF", "tzsp.wlan.status.pcf", FT_BOOLEAN
, BASE_NONE
,
495 TFS (&pcf_flag
), 0x0, "Point Coordination Function", HFILL
}},
496 { &hf_status_undecrypted
, {
497 "Undecrypted", "tzsp.wlan.status.undecrypted", FT_BOOLEAN
, BASE_NONE
,
498 TFS (&undecr_flag
), 0x0, NULL
, HFILL
}},
499 { &hf_status_fcs_error
, {
500 "FCS", "tzsp.wlan.status.fcs_err", FT_BOOLEAN
, BASE_NONE
,
501 TFS (&fcs_err_flag
), 0x0, "Frame check sequence", HFILL
}},
503 "Time", "tzsp.wlan.time", FT_UINT32
, BASE_HEX
,
504 NULL
, 0, NULL
, HFILL
}},
506 "Silence", "tzsp.wlan.silence", FT_INT8
, BASE_DEC
,
507 NULL
, 0, NULL
, HFILL
}},
508 { &hf_original_length
, {
509 "Original Length", "tzsp.original_length", FT_INT16
, BASE_DEC
,
510 NULL
, 0, "OrigLength", HFILL
}},
512 "Signal", "tzsp.wlan.signal", FT_INT8
, BASE_DEC
,
513 NULL
, 0, NULL
, HFILL
}},
515 "Rate", "tzsp.wlan.rate", FT_UINT8
, BASE_DEC
,
516 VALS(rates
), 0, NULL
, HFILL
}},
518 "Channel", "tzsp.wlan.channel", FT_UINT8
, BASE_DEC
,
519 VALS(channels
), 0, NULL
, HFILL
}},
521 "Unknown tag", "tzsp.unknown", FT_BYTES
, BASE_NONE
,
522 NULL
, 0, "Unknown", HFILL
}},
524 "Sensor Address", "tzsp.sensormac", FT_ETHER
, BASE_NONE
,
525 NULL
, 0, "Sensor MAC", HFILL
}}
528 static gint
*ett
[] = {
533 proto_tzsp
= proto_register_protocol("Tazmen Sniffer Protocol", "TZSP",
535 proto_register_field_array(proto_tzsp
, hf
, array_length(hf
));
536 proto_register_subtree_array(ett
, array_length(ett
));
538 tzsp_handle
= register_dissector("tzsp", dissect_tzsp
, proto_tzsp
);
542 proto_reg_handoff_tzsp(void)
544 dissector_add_uint("udp.port", UDP_PORT_TZSP
, tzsp_handle
);
546 /* Get the data dissector for handling unknown encapsulation types. */
547 data_handle
= find_dissector("data");
549 /* Register this protocol as an ecapsulation type. */
550 dissector_add_uint("wtap_encap", WTAP_ENCAP_TZSP
, tzsp_handle
);
552 encap_dissector_table
= find_dissector_table("wtap_encap");
556 * Editor modelines - http://www.wireshark.org/tools/modelines.html
561 * indent-tabs-mode: nil
564 * vi: set shiftwidth=4 tabstop=8 expandtab:
565 * :indentSize=4:tabSize=8:noTabs=true: