The frame header in HP-UX 11 trace files is 4 octets longer (than HP-UX 9
[obnox/wireshark/wip.git] / wiretap / nettl.c
1 /* nettl.c
2  *
3  * $Id: nettl.c,v 1.8 2000/03/01 10:25:14 oabad 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 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <time.h>
30 #include "wtap.h"
31 #include "file_wrappers.h"
32 #include "buffer.h"
33 #include "nettl.h"
34
35 static char nettl_magic_hpux9[12] = {
36     0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xD0, 0x00
37 };
38 static char nettl_magic_hpux10[12] = {
39     0x54, 0x52, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
40 };
41
42 static gboolean is_hpux_11;
43
44 /* HP nettl record header for the SX25L2 subsystem - The FCS is not included in the file. */
45 struct nettlrec_sx25l2_hdr {
46     guint8      xxa[8];
47     guint8      from_dce;
48     guint8      xxb[55];
49     guint8      length[2];
50     guint8      length2[2];    /* don't know which one is captured length / real length */
51     guint8      xxc[4];
52     guint8      sec[4];
53     guint8      usec[4];
54     guint8      xxd[4];
55 };
56
57 /* HP nettl record header for the NS_LS_IP subsystem */
58 struct nettlrec_ns_ls_ip_hdr {
59     guint8      xxa[28];
60     guint8      length[4];
61     guint8      length2[4];    /* don't know which one is captured length / real length */
62     guint8      sec[4];
63     guint8      usec[4];
64     guint8      xxb[16];
65 };
66
67 /* header is followed by data and once again the total length (2 bytes) ! */
68
69 static int nettl_read(wtap *wth, int *err);
70
71 int nettl_open(wtap *wth, int *err)
72 {
73     char magic[12], os_vers[2];
74     int bytes_read;
75
76     /* Read in the string that should be at the start of a HP file */
77     file_seek(wth->fh, 0, SEEK_SET);
78     errno = WTAP_ERR_CANT_READ;
79     bytes_read = file_read(magic, 1, 12, wth->fh);
80     if (bytes_read != 12) {
81         *err = file_error(wth->fh);
82         if (*err != 0)
83             return -1;
84         return 0;
85     }
86
87     if (memcmp(magic, nettl_magic_hpux9, 12) &&
88         memcmp(magic, nettl_magic_hpux10, 12)) {
89         return 0;
90     }
91
92     file_seek(wth->fh, 0x63, SEEK_SET);
93     wth->data_offset = 0x63;
94     bytes_read = file_read(os_vers, 1, 2, wth->fh);
95     if (bytes_read != 2) {
96         *err = file_error(wth->fh);
97         if (*err != 0)
98             return -1;
99         return 0;
100     }
101     if (os_vers[0] == '1' && os_vers[1] == '1')
102         is_hpux_11 = TRUE;
103     else
104         is_hpux_11 = FALSE;
105
106     file_seek(wth->fh, 0x80, SEEK_SET);
107     wth->data_offset = 0x80;
108
109     /* This is an nettl file */
110     wth->file_type = WTAP_FILE_NETTL;
111     wth->capture.nettl = g_malloc(sizeof(nettl_t));
112     wth->subtype_read = nettl_read;
113     wth->snapshot_length = 16384;       /* not available in header, only in frame */
114
115     wth->capture.nettl->start = 0;
116
117     return 1;
118 }
119
120 /* Read the next packet */
121 static int nettl_read(wtap *wth, int *err)
122 {
123     int bytes_read;
124     struct nettlrec_sx25l2_hdr lapb_hdr;
125     struct nettlrec_ns_ls_ip_hdr ip_hdr;
126     guint16 length;
127     int data_offset;
128     guint8 encap[4];
129     guint8 dummy[4];
130
131     /* Read record header. */
132     errno = WTAP_ERR_CANT_READ;
133     bytes_read = file_read(encap, 1, 4, wth->fh);
134     if (bytes_read != 4) {
135         *err = file_error(wth->fh);
136         if (*err != 0)
137             return -1;
138         if (bytes_read != 0) {
139             *err = WTAP_ERR_SHORT_READ;
140             return -1;
141         }
142         return 0;
143     }
144     wth->data_offset += 4;
145     switch (encap[3]) {
146     case NETTL_SUBSYS_NS_LS_IP :
147         wth->phdr.pkt_encap = WTAP_ENCAP_RAW_IP;
148         bytes_read = file_read(&ip_hdr, 1, sizeof ip_hdr, wth->fh);
149         if (bytes_read != sizeof ip_hdr) {
150             *err = file_error(wth->fh);
151             if (*err != 0)
152                 return -1;
153             if (bytes_read != 0) {
154                 *err = WTAP_ERR_SHORT_READ;
155                 return -1;
156             }
157             return 0;
158         }
159         wth->data_offset += sizeof ip_hdr;
160
161         /* The packet header in HP-UX 11 nettl traces is 4 octets longer than
162          * HP-UX 9 and 10 */
163         if (is_hpux_11) {
164             bytes_read = file_read(dummy, 1, 4, wth->fh);
165             if (bytes_read != 4) {
166                 *err = file_error(wth->fh);
167                 if (*err != 0)
168                     return -1;
169                 if (bytes_read != 0) {
170                     *err = WTAP_ERR_SHORT_READ;
171                     return -1;
172                 }
173                 return 0;
174             }
175             wth->data_offset += 4;
176         }
177
178         length = pntohl(&ip_hdr.length);
179         if (length <= 0) return 0;
180         wth->phdr.len = length;
181         wth->phdr.caplen = length;
182
183         wth->phdr.ts.tv_sec = pntohl(&ip_hdr.sec);
184         wth->phdr.ts.tv_usec = pntohl(&ip_hdr.usec);
185         if (wth->capture.nettl->start == 0)
186             wth->capture.nettl->start = wth->phdr.ts.tv_sec;
187
188         /*
189          * Read the packet data.
190          */
191         buffer_assure_space(wth->frame_buffer, length);
192         data_offset = wth->data_offset;
193         errno = WTAP_ERR_CANT_READ;
194         bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), 1,
195                 length, wth->fh);
196
197         if (bytes_read != length) {
198             *err = file_error(wth->fh);
199             if (*err == 0)
200                 *err = WTAP_ERR_SHORT_READ;
201             return -1;
202         }
203         wth->data_offset += length;
204         break;
205     case NETTL_SUBSYS_SX25L2 :
206         wth->phdr.pkt_encap = WTAP_ENCAP_LAPB;
207         bytes_read = file_read(&lapb_hdr, 1, sizeof lapb_hdr, wth->fh);
208         if (bytes_read != sizeof lapb_hdr) {
209             *err = file_error(wth->fh);
210             if (*err != 0)
211                 return -1;
212             if (bytes_read != 0) {
213                 *err = WTAP_ERR_SHORT_READ;
214                 return -1;
215             }
216             return 0;
217         }
218         wth->data_offset += sizeof lapb_hdr;
219
220         if (is_hpux_11) {
221             bytes_read = file_read(dummy, 1, 4, wth->fh);
222             if (bytes_read != 4) {
223                 *err = file_error(wth->fh);
224                 if (*err != 0)
225                     return -1;
226                 if (bytes_read != 0) {
227                     *err = WTAP_ERR_SHORT_READ;
228                     return -1;
229                 }
230                 return 0;
231             }
232             wth->data_offset += 4;
233         }
234
235         length = pntohs(&lapb_hdr.length);
236         if (length <= 0) return 0;
237         wth->phdr.len = length;
238         wth->phdr.caplen = length;
239
240         wth->phdr.ts.tv_sec = pntohl(&lapb_hdr.sec);
241         wth->phdr.ts.tv_usec = pntohl(&lapb_hdr.usec);
242         if (wth->capture.nettl->start == 0)
243             wth->capture.nettl->start = wth->phdr.ts.tv_sec;
244         wth->phdr.pseudo_header.x25.flags = (lapb_hdr.from_dce & 0x20 ? 0x80 : 0x00);
245
246         /*
247          * Read the packet data.
248          */
249         buffer_assure_space(wth->frame_buffer, length);
250         data_offset = wth->data_offset;
251         errno = WTAP_ERR_CANT_READ;
252         bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), 1,
253                 length, wth->fh);
254
255         if (bytes_read != length) {
256             *err = file_error(wth->fh);
257             if (*err == 0)
258                 *err = WTAP_ERR_SHORT_READ;
259             return -1;
260         }
261         wth->data_offset += length;
262         break;
263     default:
264         g_message("nettl: network type %u unknown or unsupported",
265                     encap[3]);
266         *err = WTAP_ERR_UNSUPPORTED_ENCAP;
267         return -1;
268     }
269     return data_offset;
270 }