Fix files that had Gilbert's old e-mail address or that didn't have my
[obnox/wireshark/wip.git] / wiretap / wtap.c
1 /* wtap.c
2  *
3  * $Id: wtap.c,v 1.37 2000/01/22 06:22:44 guy Exp $
4  *
5  * Wiretap Library
6  * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
7  * 
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  * 
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  */
23 #include <string.h>
24 #include <errno.h>
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 #include "wtap.h"
30 #include "file_wrappers.h"
31 #include "buffer.h"
32 #include "ascend.h"
33 #include "toshiba.h"
34
35 FILE* wtap_file(wtap *wth)
36 {
37         return wth->fh;
38 }
39
40 int wtap_fd(wtap *wth)
41 {
42         return wth->fd;
43 }
44
45 int wtap_file_type(wtap *wth)
46 {
47         return wth->file_type;
48 }
49
50 int wtap_snapshot_length(wtap *wth)
51 {
52         return wth->snapshot_length;
53 }
54
55 int wtap_file_encap(wtap *wth)
56 {
57         return wth->file_encap;
58 }
59
60 /* Table of the encapsulation types we know about. */
61 const static struct encap_type_info {
62         const char *name;
63         const char *short_name;
64 } encap_table[WTAP_NUM_ENCAP_TYPES] = {
65         /* WTAP_ENCAP_UNKNOWN */
66         { "Unknown", NULL },
67
68         /* WTAP_ENCAP_ETHERNET */
69         { "Ethernet", "ether" },
70
71         /* WTAP_ENCAP_TR */
72         { "Token Ring", "tr" },
73
74         /* WTAP_ENCAP_SLIP */
75         { "SLIP", "slip" },
76
77         /* WTAP_ENCAP_PPP */
78         { "PPP", "ppp" },
79
80         /* WTAP_ENCAP_FDDI */
81         { "FDDI", "fddi" },
82
83         /* WTAP_ENCAP_FDDI_BITSWAPPED */
84         { "FDDI with bit-swapped MAC addresses", "fddi-swapped" },
85
86         /* WTAP_ENCAP_RAW_IP */
87         { "Raw IP", "rawip" },
88
89         /* WTAP_ENCAP_ARCNET */
90         { "ARCNET", "arcnet" },
91
92         /* WTAP_ENCAP_ATM_RFC1483 */
93         { "RFC 1483 ATM", "atm-rfc1483" },
94
95         /* WTAP_ENCAP_LINUX_ATM_CLIP */
96         { "Linux ATM CLIP", "linux-atm-clip" },
97
98         /* WTAP_ENCAP_LAPB */
99         { "LAPB", "lapb" },
100
101         /* WTAP_ENCAP_ATM_SNIFFER */
102         { "ATM Sniffer", "atm-sniffer" },
103
104         /* WTAP_ENCAP_NULL */
105         { "NULL", "null" },
106
107         /* WTAP_ENCAP_ASCEND */
108         { "Lucent/Ascend access equipment", "ascend" },
109
110         /* WTAP_ENCAP_LAPD */
111         { "LAPD", "lapd" },
112
113         /* WTAP_ENCAP_V120 */
114         { "V.120", "v120" },
115 };
116
117 /* Name that should be somewhat descriptive. */
118 const char *wtap_encap_string(int encap)
119 {
120         if (encap < 0 || encap >= WTAP_NUM_ENCAP_TYPES)
121                 return NULL;
122         else
123                 return encap_table[encap].name;
124 }
125
126 /* Name to use in, say, a command-line flag specifying the type. */
127 const char *wtap_encap_short_string(int encap)
128 {
129         if (encap < 0 || encap >= WTAP_NUM_ENCAP_TYPES)
130                 return NULL;
131         else
132                 return encap_table[encap].short_name;
133 }
134
135 /* Translate a short name to a capture file type. */
136 int wtap_short_string_to_encap(const char *short_name)
137 {
138         int encap;
139
140         for (encap = 0; encap < WTAP_NUM_ENCAP_TYPES; encap++) {
141                 if (encap_table[encap].short_name != NULL &&
142                     strcmp(short_name, encap_table[encap].short_name) == 0)
143                         return encap;
144         }
145         return -1;      /* no such encapsulation type */
146 }
147
148 static const char *wtap_errlist[] = {
149         "The file isn't a plain file",
150         "The file isn't a capture file in a known format",
151         "File contains record data we don't support",
152         NULL,
153         "Files can't be saved in that format",
154         "Files from that network type can't be saved in that format",
155         "That format doesn't support per-packet encapsulations",
156         NULL,
157         NULL,
158         "Less data was read than was expected",
159         "File contains a record that's not valid",
160         "Less data was written than was requested"
161 };
162 #define WTAP_ERRLIST_SIZE       (sizeof wtap_errlist / sizeof wtap_errlist[0])
163
164 const char *wtap_strerror(int err)
165 {
166         static char errbuf[6+11+1];     /* "Error %d" */
167         int wtap_errlist_index;
168
169         if (err < 0) {
170 #ifdef HAVE_LIBZ
171                 if (err >= WTAP_ERR_ZLIB_MIN && err <= WTAP_ERR_ZLIB_MAX) {
172                         /* Assume it's a zlib error. */
173                         sprintf(errbuf, "Uncompression error: %s",
174                             zError(err - WTAP_ERR_ZLIB));
175                         return errbuf;
176                 }
177 #endif
178                 wtap_errlist_index = -1 - err;
179                 if (wtap_errlist_index >= WTAP_ERRLIST_SIZE) {
180                         sprintf(errbuf, "Error %d", err);
181                         return errbuf;
182                 }
183                 if (wtap_errlist[wtap_errlist_index] == NULL)
184                         return "Unknown reason";
185                 return wtap_errlist[wtap_errlist_index];
186         } else
187                 return strerror(err);
188 }
189
190 void wtap_close(wtap *wth)
191 {
192         /* free up memory. If any capture structure ever allocates
193          * its own memory, it would be better to make a *close() function
194          * for each filetype, like pcap_close(0, lanalyzer_close(), etc.
195          * But for now this will work. */
196         switch(wth->file_type) {
197                 case WTAP_FILE_PCAP:
198                 case WTAP_FILE_PCAP_MODIFIED:
199                         g_free(wth->capture.pcap);
200                         break;
201
202                 case WTAP_FILE_LANALYZER:
203                         g_free(wth->capture.lanalyzer);
204                         break;
205
206                 case WTAP_FILE_NGSNIFFER:
207                         g_free(wth->capture.ngsniffer);
208                         break;
209
210                 case WTAP_FILE_RADCOM:
211                         g_free(wth->capture.radcom);
212                         break;
213
214                 case WTAP_FILE_NETMON_1_x:
215                 case WTAP_FILE_NETMON_2_x:
216                         g_free(wth->capture.netmon);
217                         break;
218
219                 case WTAP_FILE_NETXRAY_1_0:
220                 case WTAP_FILE_NETXRAY_1_1:
221                 case WTAP_FILE_NETXRAY_2_001:
222                         g_free(wth->capture.netxray);
223                         break;
224
225                 case WTAP_FILE_ASCEND:
226                         g_free(wth->capture.ascend);
227                         break;
228
229                 case WTAP_FILE_NETTL:
230                         g_free(wth->capture.nettl);
231                         break;
232
233                 /* default:
234                          nothing */
235         }
236
237         file_close(wth->fh);
238
239         if (wth->frame_buffer) {
240                 buffer_free(wth->frame_buffer);
241                 g_free(wth->frame_buffer);
242         }
243
244         g_free(wth);
245 }
246
247 int wtap_loop(wtap *wth, int count, wtap_handler callback, u_char* user,
248         int *err)
249 {
250         int data_offset, loop = 0;
251
252         while ((data_offset = wth->subtype_read(wth, err)) > 0) {
253                 callback(user, &wth->phdr, data_offset,
254                     buffer_start_ptr(wth->frame_buffer));
255                 if (count > 0 && ++loop >= count)
256                         break;
257         }
258         if (data_offset < 0)
259                 return FALSE;   /* failure */
260         else
261                 return TRUE;    /* success */
262 }
263
264 int wtap_seek_read(int file_type, FILE *fh, int seek_off, guint8 *pd, int len)
265 {
266         switch (file_type) {
267
268         case WTAP_FILE_ASCEND:
269                 return ascend_seek_read(fh, seek_off, pd, len);
270
271         case WTAP_FILE_TOSHIBA:
272                 return toshiba_seek_read(fh, seek_off, pd, len);
273
274         default:
275                 return wtap_def_seek_read(fh, seek_off, pd, len);
276         }
277 }