diff options
-rw-r--r-- | capture.c | 3 | ||||
-rw-r--r-- | packet-airopeek.c | 6 | ||||
-rw-r--r-- | packet-ieee80211.c | 64 | ||||
-rw-r--r-- | wiretap/netxray.c | 208 | ||||
-rw-r--r-- | wiretap/wtap-int.h | 16 | ||||
-rw-r--r-- | wiretap/wtap.c | 5 | ||||
-rw-r--r-- | wiretap/wtap.h | 31 |
7 files changed, 259 insertions, 74 deletions
@@ -1,7 +1,7 @@ /* capture.c * Routines for packet capture windows * - * $Id: capture.c,v 1.171 2002/02/24 09:25:34 guy Exp $ + * $Id: capture.c,v 1.172 2002/04/08 09:09:47 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -1235,6 +1235,7 @@ pipe_dispatch(int fd, loop_data *ld, struct pcap_hdr *hdr) capture_clip(pd, whdr.caplen, &ld->counts); break; case WTAP_ENCAP_IEEE_802_11: + case WTAP_ENCAP_IEEE_802_11_WITH_RADIO: capture_ieee80211(pd, 0, whdr.caplen, &ld->counts); break; case WTAP_ENCAP_CHDLC: diff --git a/packet-airopeek.c b/packet-airopeek.c index d688fb8931..9e19f05444 100644 --- a/packet-airopeek.c +++ b/packet-airopeek.c @@ -1,7 +1,7 @@ /* packet-airopeek.c * Routines for AiroPeek capture file dissection * - * $Id: packet-airopeek.c,v 1.3 2002/02/22 07:15:28 guy Exp $ + * $Id: packet-airopeek.c,v 1.4 2002/04/08 09:09:47 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -78,8 +78,8 @@ dissect_airopeek(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) tvb, 1, 1, FALSE); signal_strength = tvb_get_guint8(tvb, 2); - proto_tree_add_uint_format(airopeek_tree, hf_airopeek_data_rate, - tvb, 2, 1, data_rate, + proto_tree_add_uint_format(airopeek_tree, hf_airopeek_signal_strength, + tvb, 2, 1, signal_strength, "Signal Strength: %u%%", signal_strength); } diff --git a/packet-ieee80211.c b/packet-ieee80211.c index 61c22be571..ac448d113c 100644 --- a/packet-ieee80211.c +++ b/packet-ieee80211.c @@ -3,7 +3,7 @@ * Copyright 2000, Axis Communications AB * Inquiries/bugreports should be sent to Johan.Jorgensen@axis.com * - * $Id: packet-ieee80211.c,v 1.52 2002/03/09 22:41:50 guy Exp $ + * $Id: packet-ieee80211.c,v 1.53 2002/04/08 09:09:47 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -226,6 +226,14 @@ static const value_string frame_type_subtype_vals[] = { }; static int proto_wlan = -1; + +/* ************************************************************************* */ +/* Header field info values for radio information */ +/* ************************************************************************* */ +static int hf_data_rate = -1; +static int hf_channel = -1; +static int hf_signal_strength = -1; + /* ************************************************************************* */ /* Header field info values for FC-field */ /* ************************************************************************* */ @@ -1058,7 +1066,8 @@ set_dst_addr_cols(packet_info *pinfo, const guint8 *addr, char *type) /* ************************************************************************* */ static void dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo, - proto_tree * tree, gboolean fixed_length_header) + proto_tree * tree, gboolean fixed_length_header, + gboolean has_radio_information) { guint16 fcf, flags, frame_type_subtype; const guint8 *src = NULL, *dst = NULL; @@ -1090,13 +1099,31 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo, val_to_str(frame_type_subtype, frame_type_subtype_vals, "Unrecognized (Reserved frame)")); - /* Add the FC to the current tree */ + /* Add the radio information, if present, and the FC to the current tree */ if (tree) { ti = proto_tree_add_protocol_format (tree, proto_wlan, tvb, 0, hdr_len, "IEEE 802.11"); hdr_tree = proto_item_add_subtree (ti, ett_80211); + if (has_radio_information) { + proto_tree_add_uint_format(hdr_tree, hf_data_rate, + tvb, 0, 0, + pinfo->pseudo_header->ieee_802_11.data_rate, + "Data Rate: %g mb/s", + .5*pinfo->pseudo_header->ieee_802_11.data_rate); + + proto_tree_add_uint(hdr_tree, hf_channel, + tvb, 0, 0, + pinfo->pseudo_header->ieee_802_11.channel); + + proto_tree_add_uint_format(hdr_tree, hf_signal_strength, + tvb, 0, 0, + pinfo->pseudo_header->ieee_802_11.signal_level, + "Signal Strength: %u%%", + pinfo->pseudo_header->ieee_802_11.signal_level); + } + proto_tree_add_uint (hdr_tree, hf_fc_frame_type_subtype, tvb, 0, 1, frame_type_subtype); @@ -1546,7 +1573,17 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo, static void dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) { - dissect_ieee80211_common (tvb, pinfo, tree, FALSE); + dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE); +} + +/* + * Dissect 802.11 with a variable-length link-layer header and a pseudo- + * header containing radio information. + */ +static void +dissect_ieee80211_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) +{ + dissect_ieee80211_common (tvb, pinfo, tree, FALSE, TRUE); } /* @@ -1556,7 +1593,7 @@ dissect_ieee80211 (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) static void dissect_ieee80211_fixed (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) { - dissect_ieee80211_common (tvb, pinfo, tree, TRUE); + dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE); } void @@ -1717,6 +1754,18 @@ proto_register_wlan (void) }; static hf_register_info hf[] = { + {&hf_data_rate, + {"Data Rate", "wlan.data_rate", FT_UINT8, BASE_DEC, NULL, 0, + "Data rate (.5 Mb/s units)", HFILL }}, + + {&hf_channel, + {"Channel", "wlan.channel", FT_UINT8, BASE_DEC, NULL, 0, + "Radio channel", HFILL }}, + + {&hf_signal_strength, + {"Signal Strength", "wlan.signal_strength", FT_UINT8, BASE_DEC, NULL, 0, + "Signal strength (percentage)", HFILL }}, + {&hf_fc_field, {"Frame Control Field", "wlan.fc", FT_UINT16, BASE_HEX, NULL, 0, "MAC Frame control", HFILL }}, @@ -1962,6 +2011,7 @@ void proto_reg_handoff_wlan(void) { dissector_handle_t ieee80211_handle; + dissector_handle_t ieee80211_radio_handle; /* * Get handles for the LLC and IPX dissectors. @@ -1972,4 +2022,8 @@ proto_reg_handoff_wlan(void) ieee80211_handle = find_dissector("wlan"); dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11, ieee80211_handle); + ieee80211_radio_handle = create_dissector_handle(dissect_ieee80211_radio, + proto_wlan); + dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO, + ieee80211_radio_handle); } diff --git a/wiretap/netxray.c b/wiretap/netxray.c index ea7894dca5..d4a8726fb1 100644 --- a/wiretap/netxray.c +++ b/wiretap/netxray.c @@ -1,6 +1,6 @@ /* netxray.c * - * $Id: netxray.c,v 1.51 2002/04/08 02:11:24 guy Exp $ + * $Id: netxray.c,v 1.52 2002/04/08 09:09:49 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu> @@ -89,7 +89,7 @@ struct netxrayrec_1_x_hdr { guint32 timehi; /* upper 32 bits of time stamp */ guint16 orig_len; /* packet length */ guint16 incl_len; /* capture length */ - guint32 xxx[4]; /* unknown */ + guint8 xxx[16]; /* unknown */ }; /* NetXRay 2.x data record format - followed by frame data. */ @@ -98,12 +98,31 @@ struct netxrayrec_2_x_hdr { guint32 timehi; /* upper 32 bits of time stamp */ guint16 orig_len; /* packet length */ guint16 incl_len; /* capture length */ - guint32 xxx[7]; /* unknown */ - /* For 802.11 captures, the "unkown" data appears to include - signal level, channel, and data rate information */ + guint8 xxx[28]; /* unknown */ + /* For 802.11 captures, "xxx" data appears to include: + the channel, in xxx[12]; + the data rate, in .5 Mb/s units, in xxx[13]; + the signal level, as a percentage, in xxx[14]; + 0xff, in xxx[15]. */ +}; + +/* + * Union of the two headers. + */ +union netxrayrec_hdr { + struct netxrayrec_1_x_hdr hdr_1_x; + struct netxrayrec_2_x_hdr hdr_2_x; }; static gboolean netxray_read(wtap *wth, int *err, long *data_offset); +static gboolean netxray_seek_read(wtap *wth, long seek_off, + union wtap_pseudo_header *pseudo_header, u_char *pd, int length, int *err); +static int netxray_read_rec_header(wtap *wth, FILE_T fh, + union netxrayrec_hdr *hdr, int *err); +static void netxray_set_pseudo_header(wtap *wth, + union wtap_pseudo_header *pseudo_header, union netxrayrec_hdr *hdr); +static gboolean netxray_read_rec_data(FILE_T fh, guint8 *data_ptr, + guint32 packet_size, int *err); static void netxray_close(wtap *wth); static gboolean netxray_dump_1_1(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, const union wtap_pseudo_header *pseudo_header, const u_char *pd, int *err); @@ -122,13 +141,14 @@ int netxray_open(wtap *wth, int *err) WTAP_ENCAP_ETHERNET, WTAP_ENCAP_TOKEN_RING, WTAP_ENCAP_FDDI_BITSWAPPED, - WTAP_ENCAP_ETHERNET, /* WAN(PPP), but shaped like ethernet */ + WTAP_ENCAP_ETHERNET, /* WAN(PPP), but shaped like Ethernet */ WTAP_ENCAP_UNKNOWN, /* LocalTalk */ WTAP_ENCAP_UNKNOWN, /* "DIX" - should not occur */ WTAP_ENCAP_UNKNOWN, /* ARCNET raw */ WTAP_ENCAP_UNKNOWN, /* ARCNET 878.2 */ WTAP_ENCAP_ATM_RFC1483, /* ATM */ - WTAP_ENCAP_IEEE_802_11, /* Wireless WAN */ + WTAP_ENCAP_IEEE_802_11_WITH_RADIO, + /* Wireless WAN with radio information */ WTAP_ENCAP_UNKNOWN /* IrDA */ }; #define NUM_NETXRAY_ENCAPS (sizeof netxray_encap / sizeof netxray_encap[0]) @@ -205,7 +225,7 @@ int netxray_open(wtap *wth, int *err) wth->file_type = file_type; wth->capture.netxray = g_malloc(sizeof(netxray_t)); wth->subtype_read = netxray_read; - wth->subtype_seek_read = wtap_def_seek_read; + wth->subtype_seek_read = netxray_seek_read; wth->subtype_close = netxray_close; wth->file_encap = netxray_encap[hdr.network]; wth->snapshot_length = 0; /* not available in header */ @@ -227,7 +247,7 @@ int netxray_open(wtap *wth, int *err) * that look like FCS values. */ wth->capture.netxray->padding = 0; - if (netxray_encap[hdr.network] == WTAP_ENCAP_IEEE_802_11) { + if (netxray_encap[hdr.network] == WTAP_ENCAP_IEEE_802_11_WITH_RADIO) { wth->capture.netxray->padding = 4; } /*wth->frame_number = 0;*/ @@ -236,7 +256,7 @@ int netxray_open(wtap *wth, int *err) /* Remember the offset after the last packet in the capture (which * isn't necessarily the last packet in the file), as it appears * there's sometimes crud after it. */ - wth->capture.netxray->wrapped = 0; + wth->capture.netxray->wrapped = FALSE; wth->capture.netxray->end_offset = pletohl(&hdr.end_offset); /* Seek to the beginning of the data records. */ @@ -254,12 +274,8 @@ int netxray_open(wtap *wth, int *err) static gboolean netxray_read(wtap *wth, int *err, long *data_offset) { guint32 packet_size; - int bytes_read; - union { - struct netxrayrec_1_x_hdr hdr_1_x; - struct netxrayrec_2_x_hdr hdr_2_x; - } hdr; - int hdr_size = 0; + union netxrayrec_hdr hdr; + int hdr_size; double t; reread: @@ -270,31 +286,22 @@ reread: return FALSE; } /* Read record header. */ - switch (wth->capture.netxray->version_major) { - - case 1: - hdr_size = sizeof (struct netxrayrec_1_x_hdr); - break; - - case 2: - hdr_size = sizeof (struct netxrayrec_2_x_hdr); - break; - } - errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(&hdr, 1, hdr_size, wth->fh); - if (bytes_read != hdr_size) { - *err = file_error(wth->fh); - if (*err != 0) - return FALSE; - if (bytes_read != 0) { - *err = WTAP_ERR_SHORT_READ; + hdr_size = netxray_read_rec_header(wth, wth->fh, &hdr, err); + if (hdr_size == 0) { + /* + * Error or EOF. + */ + if (*err != 0) { + /* + * Error of some sort; give up. + */ return FALSE; } /* We're at EOF. Wrap? */ if (!wth->capture.netxray->wrapped) { /* Yes. Remember that we did. */ - wth->capture.netxray->wrapped = 1; + wth->capture.netxray->wrapped = TRUE; if (file_seek(wth->fh, CAPTUREFILE_HEADER_SIZE, SEEK_SET) == -1) { *err = file_error(wth->fh); @@ -307,23 +314,29 @@ reread: /* We've already wrapped - don't wrap again. */ return FALSE; } + + /* + * Return the offset of the record header, so we can reread it + * if we go back to this frame. + */ + *data_offset = wth->data_offset; wth->data_offset += hdr_size; + /* + * Read the packet data. + */ packet_size = pletohs(&hdr.hdr_1_x.incl_len); buffer_assure_space(wth->frame_buffer, packet_size); - *data_offset = wth->data_offset; - errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), 1, - packet_size, wth->fh); - - if ((guint32)bytes_read != packet_size) { - *err = file_error(wth->fh); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; + if (!netxray_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer), + packet_size, err)) return FALSE; - } wth->data_offset += packet_size; + /* + * Set the pseudo-header. + */ + netxray_set_pseudo_header(wth, &wth->pseudo_header, &hdr); + t = (double)pletohl(&hdr.hdr_1_x.timelo) + (double)pletohl(&hdr.hdr_1_x.timehi)*4294967296.0; t /= wth->capture.netxray->timeunit; @@ -342,6 +355,111 @@ reread: return TRUE; } +static gboolean +netxray_seek_read(wtap *wth, long seek_off, + union wtap_pseudo_header *pseudo_header, u_char *pd, int length, int *err) +{ + union netxrayrec_hdr hdr; + + if (file_seek(wth->random_fh, seek_off, SEEK_SET) == -1) { + *err = file_error(wth->random_fh); + return FALSE; + } + + if (!netxray_read_rec_header(wth, wth->random_fh, &hdr, err)) { + if (*err == 0) { + /* + * EOF - we report that as a short read, as + * we've read this once and know that it + * should be there. + */ + *err = WTAP_ERR_SHORT_READ; + } + return FALSE; + } + + /* + * Set the pseudo-header. + */ + netxray_set_pseudo_header(wth, pseudo_header, &hdr); + + /* + * Read the packet data. + */ + return netxray_read_rec_data(wth->random_fh, pd, length, err); +} + +static int +netxray_read_rec_header(wtap *wth, FILE_T fh, union netxrayrec_hdr *hdr, + int *err) +{ + int bytes_read; + int hdr_size = 0; + + /* Read record header. */ + switch (wth->capture.netxray->version_major) { + + case 1: + hdr_size = sizeof (struct netxrayrec_1_x_hdr); + break; + + case 2: + hdr_size = sizeof (struct netxrayrec_2_x_hdr); + break; + } + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(hdr, 1, hdr_size, fh); + if (bytes_read != hdr_size) { + *err = file_error(wth->fh); + if (*err != 0) + return 0; + if (bytes_read != 0) { + *err = WTAP_ERR_SHORT_READ; + return 0; + } + + /* + * We're at EOF. "*err" is 0; we return FALSE - that + * combination tells our caller we're at EOF. + */ + return 0; + } + return hdr_size; +} + +static void +netxray_set_pseudo_header(wtap *wth, union wtap_pseudo_header *pseudo_header, + union netxrayrec_hdr *hdr) +{ + /* + * If this is 802.11, set the pseudo-header. + */ + if (wth->capture.netxray->version_major == 2 && + wth->file_encap == WTAP_ENCAP_IEEE_802_11_WITH_RADIO) { + pseudo_header->ieee_802_11.channel = hdr->hdr_2_x.xxx[12]; + pseudo_header->ieee_802_11.data_rate = hdr->hdr_2_x.xxx[13]; + pseudo_header->ieee_802_11.signal_level = hdr->hdr_2_x.xxx[14]; + } +} + +static gboolean +netxray_read_rec_data(FILE_T fh, guint8 *data_ptr, guint32 packet_size, + int *err) +{ + int bytes_read; + + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(data_ptr, 1, packet_size, fh); + + if (bytes_read <= 0 || (guint32)bytes_read != packet_size) { + *err = file_error(fh); + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return FALSE; + } + return TRUE; +} + static void netxray_close(wtap *wth) { diff --git a/wiretap/wtap-int.h b/wiretap/wtap-int.h index 470bf6d9c9..d36f1ed37d 100644 --- a/wiretap/wtap-int.h +++ b/wiretap/wtap-int.h @@ -1,6 +1,6 @@ /* wtap-int.h * - * $Id: wtap-int.h,v 1.23 2002/04/07 21:29:01 guy Exp $ + * $Id: wtap-int.h,v 1.24 2002/04/08 09:09:49 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu> @@ -97,13 +97,13 @@ typedef struct { } netmon_t; typedef struct { - time_t start_time; - double timeunit; - double start_timestamp; - int wrapped; - int end_offset; - int version_major; - guint padding; /* end-of-packet padding */ + time_t start_time; + double timeunit; + double start_timestamp; + gboolean wrapped; + int end_offset; + int version_major; + guint padding; /* end-of-packet padding */ } netxray_t; typedef struct { diff --git a/wiretap/wtap.c b/wiretap/wtap.c index dd6a6ff558..f6d82b3518 100644 --- a/wiretap/wtap.c +++ b/wiretap/wtap.c @@ -1,6 +1,6 @@ /* wtap.c * - * $Id: wtap.c,v 1.63 2002/03/05 08:39:30 guy Exp $ + * $Id: wtap.c,v 1.64 2002/04/08 09:09:49 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu> @@ -116,6 +116,9 @@ static const struct encap_type_info { /* WTAP_ENCAP_IEEE_802_11 */ { "IEEE 802.11 Wireless LAN", "ieee-802-11" }, + /* WTAP_ENCAP_IEEE_802_11_WITH_RADIO */ + { "IEEE 802.11 Wireless LAN with radio information", "ieee-802-11-radio" }, + /* WTAP_ENCAP_SLL */ { "Linux cooked-mode capture", "linux-sll" }, diff --git a/wiretap/wtap.h b/wiretap/wtap.h index c3a29319c5..830afcd3bf 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -1,6 +1,6 @@ /* wtap.h * - * $Id: wtap.h,v 1.107 2002/03/05 08:39:30 guy Exp $ + * $Id: wtap.h,v 1.108 2002/04/08 09:09:49 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu> @@ -98,18 +98,19 @@ #define WTAP_ENCAP_V120 16 #define WTAP_ENCAP_PPP_WITH_PHDR 17 #define WTAP_ENCAP_IEEE_802_11 18 -#define WTAP_ENCAP_SLL 19 -#define WTAP_ENCAP_FRELAY 20 -#define WTAP_ENCAP_CHDLC 21 -#define WTAP_ENCAP_CISCO_IOS 22 -#define WTAP_ENCAP_LOCALTALK 23 -#define WTAP_ENCAP_PRISM_HEADER 24 -#define WTAP_ENCAP_PFLOG 25 -#define WTAP_ENCAP_AIROPEEK 26 -#define WTAP_ENCAP_HHDLC 27 +#define WTAP_ENCAP_IEEE_802_11_WITH_RADIO 19 +#define WTAP_ENCAP_SLL 20 +#define WTAP_ENCAP_FRELAY 21 +#define WTAP_ENCAP_CHDLC 22 +#define WTAP_ENCAP_CISCO_IOS 23 +#define WTAP_ENCAP_LOCALTALK 24 +#define WTAP_ENCAP_PRISM_HEADER 25 +#define WTAP_ENCAP_PFLOG 26 +#define WTAP_ENCAP_AIROPEEK 27 +#define WTAP_ENCAP_HHDLC 28 /* last WTAP_ENCAP_ value + 1 */ -#define WTAP_NUM_ENCAP_TYPES 28 +#define WTAP_NUM_ENCAP_TYPES 29 /* File types that can be read by wiretap. We support writing some many of these file types, too, so we @@ -221,10 +222,17 @@ struct ascend_phdr { guint32 task; /* Task number */ }; +/* Packet "pseudo-header" for point-to-point links with direction flags. */ struct p2p_phdr { gboolean sent; /* TRUE=sent, FALSE=received */ }; +/* Packet "pseudo-header" information for 802.11 with radio information. */ +struct ieee_802_11_phdr { + guint8 channel; /* Channel number */ + guint8 data_rate; /* in .5 Mb/s units */ + guint8 signal_level; /* percentage */ +}; /* * Bits in AppTrafType. @@ -283,6 +291,7 @@ union wtap_pseudo_header { struct ngsniffer_atm_phdr ngsniffer_atm; struct ascend_phdr ascend; struct p2p_phdr p2p; + struct ieee_802_11_phdr ieee_802_11; }; struct wtap_pkthdr { |