Fix a comment.
[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         struct tm tm;
52         char byte;
53         char encap_magic[7] = {0x54, 0x43, 0x50, 0x00, 0x42, 0x43, 0x09};
54         char search_encap[7];
55
56         /* Read in the string that should be at the start of a RADCOM file */
57         fseek(wth->fh, 0, SEEK_SET);
58         errno = WTAP_ERR_CANT_READ;
59         bytes_read = fread(magic, 1, 8, wth->fh);
60         if (bytes_read != 8) {
61                 if (ferror(wth->fh)) {
62                         *err = errno;
63                         return -1;
64                 }
65                 return 0;
66         }
67
68         if (memcmp(magic, radcom_magic, 8)) {
69                 return 0;
70         }
71
72         fseek(wth->fh, 0x8B, SEEK_SET);
73         errno = WTAP_ERR_CANT_READ;
74         bytes_read = fread(&byte, 1, 1, wth->fh);
75         if (bytes_read != 1) {
76                 if (ferror(wth->fh)) {
77                         *err = errno;
78                         return -1;
79                 }
80                 return 0;
81         }
82         while (byte) {
83                 errno = WTAP_ERR_CANT_READ;
84                 bytes_read = fread(&byte, 1, 1, wth->fh);
85                 if (bytes_read != 1) {
86                         if (ferror(wth->fh)) {
87                                 *err = errno;
88                                 return -1;
89                         }
90                         return 0;
91                 }
92         }
93         fseek(wth->fh, 1, SEEK_CUR);
94
95         /* Get capture start time */
96         errno = WTAP_ERR_CANT_READ;
97         bytes_read = fread(&start_date, 1, sizeof(struct frame_date), wth->fh);
98         if (bytes_read != sizeof(struct frame_date)) {
99                 if (ferror(wth->fh)) {
100                         *err = errno;
101                         return -1;
102                 }
103                 return 0;
104         }
105
106         /* This is a radcom file */
107         wth->file_type = WTAP_FILE_RADCOM;
108         wth->capture.radcom = g_malloc(sizeof(radcom_t));
109         wth->subtype_read = radcom_read;
110         wth->snapshot_length = 16384;   /* not available in header, only in frame */
111
112         tm.tm_year = start_date.year-1900;
113         tm.tm_mon = start_date.month-1;
114         tm.tm_mday = start_date.day;
115         tm.tm_hour = start_date.sec/3600;
116         tm.tm_min = (start_date.sec%3600)/60;
117         tm.tm_sec = start_date.sec%60;
118         tm.tm_isdst = -1;
119         wth->capture.radcom->start = mktime(&tm);
120
121         fseek(wth->fh, sizeof(struct frame_date), SEEK_CUR);
122
123         errno = WTAP_ERR_CANT_READ;
124         bytes_read = fread(search_encap, 1, 7, wth->fh);
125         if (bytes_read != 7) {
126                 goto read_error;
127         }
128         while (memcmp(encap_magic, search_encap, 7)) {
129                 fseek(wth->fh, -6, SEEK_CUR);
130                 errno = WTAP_ERR_CANT_READ;
131                 bytes_read = fread(search_encap, 1, 7, wth->fh);
132                 if (bytes_read != 7) {
133                         goto read_error;
134                 }
135         }
136         fseek(wth->fh, 12, SEEK_CUR);
137         errno = WTAP_ERR_CANT_READ;
138         bytes_read = fread(search_encap, 1, 4, wth->fh);
139         if (bytes_read != 4) {
140                 goto read_error;
141         }
142         if (!memcmp(search_encap, "LAPB", 4))
143                 wth->file_encap = WTAP_ENCAP_LAPB;
144         else if (!memcmp(search_encap, "Ethe", 4))
145                 wth->file_encap = WTAP_ENCAP_ETHERNET;
146         else {
147                 g_message("pcap: network type \"%.4s\" unknown", search_encap);
148                 *err = WTAP_ERR_UNSUPPORTED;
149                 return -1;
150         }
151
152         /*bytes_read = fread(&next_date, 1, sizeof(struct frame_date), wth->fh);
153         errno = WTAP_ERR_CANT_READ;
154         if (bytes_read != sizeof(struct frame_date)) {
155                 goto read_error;
156         }
157
158         while (memcmp(&start_date, &next_date, 4)) {
159                 fseek(wth->fh, 1-sizeof(struct frame_date), SEEK_CUR);
160                 errno = WTAP_ERR_CANT_READ;
161                 bytes_read = fread(&next_date, 1, sizeof(struct frame_date),
162                                    wth->fh);
163                 if (bytes_read != sizeof(struct frame_date)) {
164                         goto read_error;
165                 }
166         }*/
167
168         if (wth->file_encap == WTAP_ENCAP_ETHERNET)
169                 fseek(wth->fh, 294, SEEK_CUR);
170         else if (wth->file_encap == WTAP_ENCAP_LAPB)
171                 fseek(wth->fh, 297, SEEK_CUR);
172
173         return 1;
174
175 read_error:
176         if (ferror(wth->fh)) {
177                 *err = errno;
178                 free(wth->capture.radcom);
179                 return -1;
180         }
181         free(wth->capture.radcom);
182         return 0;
183 }
184
185 /* Read the next packet */
186 static int radcom_read(wtap *wth, int *err)
187 {
188         int     bytes_read;
189         guint16 length;
190         struct frame_date date;
191         int     data_offset;
192         struct tm tm;
193         char dce;
194
195         fseek(wth->fh, 4, SEEK_CUR);
196
197         /*
198          * Read the frame size
199          */
200         errno = WTAP_ERR_CANT_READ;
201         bytes_read = fread(&length, 1, 2, wth->fh);
202         if (bytes_read != 2) {
203                 if (ferror(wth->fh)) {
204                         *err = errno;
205                         return -1;
206                 }
207                 if (bytes_read != 0) {
208                         *err = WTAP_ERR_SHORT_READ;
209                         return -1;
210                 }
211                 return 0;
212         }
213
214         if (wth->file_encap == WTAP_ENCAP_LAPB)
215                 length -= 2; /* FCS */
216
217         wth->phdr.len = length;
218         wth->phdr.caplen = length;
219
220         fseek(wth->fh, 5, SEEK_CUR);
221         errno = WTAP_ERR_CANT_READ;
222         bytes_read = fread(&date, 1, sizeof(struct frame_date), wth->fh);
223         if (bytes_read != sizeof(struct frame_date)) {
224                 if (ferror(wth->fh))
225                         *err = errno;
226                 else
227                         *err = WTAP_ERR_SHORT_READ;
228                 return -1;
229         }
230
231         tm.tm_year = date.year-1900;
232         tm.tm_mon = date.month-1;
233         tm.tm_mday = date.day;
234         tm.tm_hour = date.sec/3600;
235         tm.tm_min = (date.sec%3600)/60;
236         tm.tm_sec = date.sec%60;
237         tm.tm_isdst = -1;
238         wth->phdr.ts.tv_sec = mktime(&tm);
239         wth->phdr.ts.tv_usec = date.usec;
240
241         fseek(wth->fh, 6, SEEK_CUR);
242         errno = WTAP_ERR_CANT_READ;
243         bytes_read = fread(&dce, 1, 1, wth->fh);
244         if (bytes_read != 1) {
245                 if (ferror(wth->fh))
246                         *err = errno;
247                 else
248                         *err = WTAP_ERR_SHORT_READ;
249                 return -1;
250         }
251         wth->phdr.pseudo_header.x25.flags = (dce & 0x1) ? 0x00 : 0x80;
252
253         fseek(wth->fh, 9, SEEK_CUR);
254
255         /*
256          * Read the packet data.
257          */
258         buffer_assure_space(wth->frame_buffer, length);
259         data_offset = ftell(wth->fh);
260         errno = WTAP_ERR_CANT_READ;
261         bytes_read = fread(buffer_start_ptr(wth->frame_buffer), 1,
262                         length, wth->fh);
263
264         if (bytes_read != length) {
265                 if (ferror(wth->fh))
266                         *err = errno;
267                 else
268                         *err = WTAP_ERR_SHORT_READ;
269                 return -1;
270         }
271
272         wth->phdr.pkt_encap = wth->file_encap;
273
274         if (wth->file_encap == WTAP_ENCAP_LAPB)
275                 fseek(wth->fh, 2, SEEK_CUR); /* FCS */
276
277         return data_offset;
278 }