Convert the seconds value to the right byte order before using it at
[obnox/wireshark/wip.git] / wiretap / radcom.c
1 /* radcom.c
2  *
3  * Wiretap Library
4  * Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
5  * 
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  * 
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  */
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <time.h>
28 #include "wtap.h"
29 #include "buffer.h"
30 #include "radcom.h"
31
32 struct frame_date {
33         guint16 year;
34         guint8  month;
35         guint8  day;
36         guint32 sec;            /* seconds since midnight */
37         guint32 usec;
38 };
39
40 static char radcom_magic[8] = {
41         0x42, 0xD2, 0x00, 0x34, 0x12, 0x66, 0x22, 0x88
42 };
43
44 static int radcom_read(wtap *wth, int *err);
45
46 int radcom_open(wtap *wth, int *err)
47 {
48         int bytes_read;
49         char magic[8];
50         struct frame_date start_date;
51         guint32 sec;
52         struct tm tm;
53         char byte;
54         char encap_magic[7] = {0x54, 0x43, 0x50, 0x00, 0x42, 0x43, 0x09};
55         char search_encap[7];
56
57         /* Read in the string that should be at the start of a RADCOM file */
58         fseek(wth->fh, 0, SEEK_SET);
59         errno = WTAP_ERR_CANT_READ;
60         bytes_read = fread(magic, 1, 8, wth->fh);
61         if (bytes_read != 8) {
62                 if (ferror(wth->fh)) {
63                         *err = errno;
64                         return -1;
65                 }
66                 return 0;
67         }
68
69         if (memcmp(magic, radcom_magic, 8)) {
70                 return 0;
71         }
72
73         fseek(wth->fh, 0x8B, SEEK_SET);
74         wth->data_offset = 0x8B;
75         errno = WTAP_ERR_CANT_READ;
76         bytes_read = fread(&byte, 1, 1, wth->fh);
77         if (bytes_read != 1) {
78                 if (ferror(wth->fh)) {
79                         *err = errno;
80                         return -1;
81                 }
82                 return 0;
83         }
84         wth->data_offset += 1;
85         while (byte) {
86                 errno = WTAP_ERR_CANT_READ;
87                 bytes_read = fread(&byte, 1, 1, wth->fh);
88                 if (bytes_read != 1) {
89                         if (ferror(wth->fh)) {
90                                 *err = errno;
91                                 return -1;
92                         }
93                         return 0;
94                 }
95                 wth->data_offset += 1;
96         }
97         fseek(wth->fh, 1, SEEK_CUR);
98         wth->data_offset += 1;
99
100         /* Get capture start time */
101         errno = WTAP_ERR_CANT_READ;
102         bytes_read = fread(&start_date, 1, sizeof(struct frame_date), wth->fh);
103         if (bytes_read != sizeof(struct frame_date)) {
104                 if (ferror(wth->fh)) {
105                         *err = errno;
106                         return -1;
107                 }
108                 return 0;
109         }
110         wth->data_offset += sizeof(struct frame_date);
111
112         /* This is a radcom file */
113         wth->file_type = WTAP_FILE_RADCOM;
114         wth->capture.radcom = g_malloc(sizeof(radcom_t));
115         wth->subtype_read = radcom_read;
116         wth->snapshot_length = 16384;   /* not available in header, only in frame */
117
118         tm.tm_year = pletohs(&start_date.year)-1900;
119         tm.tm_mon = start_date.month-1;
120         tm.tm_mday = start_date.day;
121         sec = pletohl(&start_date.sec);
122         tm.tm_hour = sec/3600;
123         tm.tm_min = (sec%3600)/60;
124         tm.tm_sec = sec%60;
125         tm.tm_isdst = -1;
126         wth->capture.radcom->start = mktime(&tm);
127
128         fseek(wth->fh, sizeof(struct frame_date), SEEK_CUR);
129         wth->data_offset += sizeof(struct frame_date);
130
131         errno = WTAP_ERR_CANT_READ;
132         bytes_read = fread(search_encap, 1, 7, wth->fh);
133         if (bytes_read != 7) {
134                 goto read_error;
135         }
136         wth->data_offset += 7;
137         while (memcmp(encap_magic, search_encap, 7)) {
138                 fseek(wth->fh, -6, SEEK_CUR);
139                 wth->data_offset -= 6;
140                 errno = WTAP_ERR_CANT_READ;
141                 bytes_read = fread(search_encap, 1, 7, wth->fh);
142                 if (bytes_read != 7) {
143                         goto read_error;
144                 }
145                 wth->data_offset += 7;
146         }
147         fseek(wth->fh, 12, SEEK_CUR);
148         wth->data_offset += 12;
149         errno = WTAP_ERR_CANT_READ;
150         bytes_read = fread(search_encap, 1, 4, wth->fh);
151         if (bytes_read != 4) {
152                 goto read_error;
153         }
154         wth->data_offset += 4;
155         if (!memcmp(search_encap, "LAPB", 4))
156                 wth->file_encap = WTAP_ENCAP_LAPB;
157         else if (!memcmp(search_encap, "Ethe", 4))
158                 wth->file_encap = WTAP_ENCAP_ETHERNET;
159         else {
160                 g_message("pcap: network type \"%.4s\" unknown", search_encap);
161                 *err = WTAP_ERR_UNSUPPORTED;
162                 return -1;
163         }
164
165         /*bytes_read = fread(&next_date, 1, sizeof(struct frame_date), wth->fh);
166         errno = WTAP_ERR_CANT_READ;
167         if (bytes_read != sizeof(struct frame_date)) {
168                 goto read_error;
169         }
170
171         while (memcmp(&start_date, &next_date, 4)) {
172                 fseek(wth->fh, 1-sizeof(struct frame_date), SEEK_CUR);
173                 errno = WTAP_ERR_CANT_READ;
174                 bytes_read = fread(&next_date, 1, sizeof(struct frame_date),
175                                    wth->fh);
176                 if (bytes_read != sizeof(struct frame_date)) {
177                         goto read_error;
178                 }
179         }*/
180
181         if (wth->file_encap == WTAP_ENCAP_ETHERNET) {
182                 fseek(wth->fh, 294, SEEK_CUR);
183                 wth->data_offset += 294;
184         } else if (wth->file_encap == WTAP_ENCAP_LAPB) {
185                 fseek(wth->fh, 297, SEEK_CUR);
186                 wth->data_offset += 297;
187         }
188
189         return 1;
190
191 read_error:
192         if (ferror(wth->fh)) {
193                 *err = errno;
194                 free(wth->capture.radcom);
195                 return -1;
196         }
197         free(wth->capture.radcom);
198         return 0;
199 }
200
201 /* Read the next packet */
202 static int radcom_read(wtap *wth, int *err)
203 {
204         int     bytes_read;
205         guint16 length;
206         struct frame_date date;
207         guint32 sec;
208         int     data_offset;
209         struct tm tm;
210         char dce;
211
212         fseek(wth->fh, 4, SEEK_CUR);
213         wth->data_offset += 4;
214
215         /*
216          * Read the frame size
217          */
218         errno = WTAP_ERR_CANT_READ;
219         bytes_read = fread(&length, 1, 2, wth->fh);
220         if (bytes_read != 2) {
221                 if (ferror(wth->fh)) {
222                         *err = errno;
223                         return -1;
224                 }
225                 if (bytes_read != 0) {
226                         *err = WTAP_ERR_SHORT_READ;
227                         return -1;
228                 }
229                 return 0;
230         }
231         wth->data_offset += 2;
232         length = pletohs(&length);
233
234         if (wth->file_encap == WTAP_ENCAP_LAPB)
235                 length -= 2; /* FCS */
236
237         wth->phdr.len = length;
238         wth->phdr.caplen = length;
239
240         fseek(wth->fh, 5, SEEK_CUR);
241         wth->data_offset += 5;
242         errno = WTAP_ERR_CANT_READ;
243         bytes_read = fread(&date, 1, sizeof(struct frame_date), wth->fh);
244         if (bytes_read != sizeof(struct frame_date)) {
245                 if (ferror(wth->fh))
246                         *err = errno;
247                 else
248                         *err = WTAP_ERR_SHORT_READ;
249                 return -1;
250         }
251         wth->data_offset += sizeof(struct frame_date);
252
253         tm.tm_year = pletohs(&date.year)-1900;
254         tm.tm_mon = date.month-1;
255         tm.tm_mday = date.day;
256         sec = pletohl(&date.sec);
257         tm.tm_hour = sec/3600;
258         tm.tm_min = (sec%3600)/60;
259         tm.tm_sec = sec%60;
260         tm.tm_isdst = -1;
261         wth->phdr.ts.tv_sec = mktime(&tm);
262         wth->phdr.ts.tv_usec = pletohl(&date.usec);
263
264         fseek(wth->fh, 6, SEEK_CUR);
265         wth->data_offset += 6;
266         errno = WTAP_ERR_CANT_READ;
267         bytes_read = fread(&dce, 1, 1, wth->fh);
268         if (bytes_read != 1) {
269                 if (ferror(wth->fh))
270                         *err = errno;
271                 else
272                         *err = WTAP_ERR_SHORT_READ;
273                 return -1;
274         }
275         wth->data_offset += 1;
276         wth->phdr.pseudo_header.x25.flags = (dce & 0x1) ? 0x00 : 0x80;
277
278         fseek(wth->fh, 9, SEEK_CUR);
279         wth->data_offset += 9;
280
281         /*
282          * Read the packet data.
283          */
284         buffer_assure_space(wth->frame_buffer, length);
285         data_offset = wth->data_offset;
286         errno = WTAP_ERR_CANT_READ;
287         bytes_read = fread(buffer_start_ptr(wth->frame_buffer), 1,
288                         length, wth->fh);
289
290         if (bytes_read != length) {
291                 if (ferror(wth->fh))
292                         *err = errno;
293                 else
294                         *err = WTAP_ERR_SHORT_READ;
295                 return -1;
296         }
297         wth->data_offset += length;
298
299         wth->phdr.pkt_encap = wth->file_encap;
300
301         if (wth->file_encap == WTAP_ENCAP_LAPB) {
302                 fseek(wth->fh, 2, SEEK_CUR); /* FCS */
303                 wth->data_offset += 2;
304         }
305
306         return data_offset;
307 }