3 * Basic Encoding Rules (BER) file reading
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "file_wrappers.h"
26 #include <wsutil/buffer.h>
30 #define BER_CLASS_UNI 0
31 #define BER_CLASS_APP 1
32 #define BER_CLASS_CON 2
34 #define BER_UNI_TAG_SEQ 16 /* SEQUENCE, SEQUENCE OF */
35 #define BER_UNI_TAG_SET 17 /* SET, SET OF */
37 static gboolean ber_read_file(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
38 Buffer *buf, int *err, gchar **err_info)
43 if ((file_size = wtap_file_size(wth, err)) == -1)
46 if (file_size > G_MAXINT) {
48 * Probably a corrupt capture file; don't blow up trying
49 * to allocate space for an immensely-large packet.
51 *err = WTAP_ERR_BAD_FILE;
52 *err_info = g_strdup_printf("ber: File has %" G_GINT64_MODIFIER "d-byte packet, bigger than maximum of %u",
56 packet_size = (int)file_size;
58 phdr->rec_type = REC_TYPE_PACKET;
59 phdr->presence_flags = 0; /* yes, we have no bananas^Wtime stamp */
61 phdr->caplen = packet_size;
62 phdr->len = packet_size;
67 ws_buffer_assure_space(buf, packet_size);
68 return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info);
71 static gboolean ber_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
77 offset = file_tell(wth->fh);
79 /* there is only ever one packet */
83 *data_offset = offset;
85 return ber_read_file(wth, wth->fh, &wth->phdr, wth->frame_buffer, err, err_info);
88 static gboolean ber_seek_read(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr,
89 Buffer *buf, int *err, gchar **err_info)
91 /* there is only one packet */
97 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
100 return ber_read_file(wth, wth->random_fh, phdr, buf, err, err_info);
103 wtap_open_return_val ber_open(wtap *wth, int *err, gchar **err_info)
105 #define BER_BYTES_TO_CHECK 8
106 guint8 bytes[BER_BYTES_TO_CHECK];
116 if (!wtap_read_bytes(wth->fh, &bytes, BER_BYTES_TO_CHECK, err, err_info)) {
117 if (*err != WTAP_ERR_SHORT_READ)
118 return WTAP_OPEN_ERROR;
119 return WTAP_OPEN_NOT_MINE;
122 ber_id = bytes[offset++];
124 ber_class = (ber_id>>6) & 0x03;
125 ber_pc = (ber_id>>5) & 0x01;
126 ber_tag = ber_id & 0x1F;
128 /* it must be constructed and either a SET or a SEQUENCE */
129 /* or a CONTEXT/APPLICATION less than 32 (arbitrary) */
131 (((ber_class == BER_CLASS_UNI) && ((ber_tag == BER_UNI_TAG_SET) || (ber_tag == BER_UNI_TAG_SEQ))) ||
132 (((ber_class == BER_CLASS_CON) || (ber_class == BER_CLASS_APP)) && (ber_tag < 32)))))
133 return WTAP_OPEN_NOT_MINE;
135 /* now check the length */
136 oct = bytes[offset++];
139 /* not indefinite length encoded */
142 /* length fits into a single byte */
145 nlb = oct & 0x7F; /* number of length bytes */
147 if((nlb > 0) && (nlb <= (BER_BYTES_TO_CHECK - 2))) {
148 /* not indefinite length and we have read enough bytes to compute the length */
151 oct = bytes[offset++];
152 len = (len<<8) + oct;
157 len += (2 + nlb); /* add back Tag and Length bytes */
158 file_size = wtap_file_size(wth, err);
160 if(len != file_size) {
161 return WTAP_OPEN_NOT_MINE; /* not ASN.1 */
164 /* Indefinite length encoded - assume it is BER */
167 /* seek back to the start of the file */
168 if (file_seek(wth->fh, 0, SEEK_SET, err) == -1)
169 return WTAP_OPEN_ERROR;
171 wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_BER;
172 wth->file_encap = WTAP_ENCAP_BER;
173 wth->snapshot_length = 0;
175 wth->subtype_read = ber_read;
176 wth->subtype_seek_read = ber_seek_read;
177 wth->file_tsprec = WTAP_TSPREC_SEC;
179 return WTAP_OPEN_MINE;
183 * Editor modelines - http://www.wireshark.org/tools/modelines.html
188 * indent-tabs-mode: nil
191 * vi: set shiftwidth=2 tabstop=8 expandtab:
192 * :indentSize=2:tabSize=8:noTabs=true: