3 * $Id: nettl.c,v 1.32 2003/05/05 01:01:36 guy Exp $
6 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
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.
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.
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.
31 #include "file_wrappers.h"
35 static guchar nettl_magic_hpux9[12] = {
36 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xD0, 0x00
38 static guchar nettl_magic_hpux10[12] = {
39 0x54, 0x52, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
42 /* HP nettl record header for the SX25L2 subsystem - The FCS is not included in the file. */
43 struct nettlrec_sx25l2_hdr {
55 /* HP nettl record header for the NS_LS_IP subsystem */
56 /* This also works for BASE100 and GSC100BT */
57 struct nettlrec_ns_ls_ip_hdr {
67 /* header is followed by data and once again the total length (2 bytes) ! */
71 The following shows what the header looks like for NS_LS_DRIVER
72 The capture was taken on HPUX11 and for a 100baseT interface.
74 000080 00 44 00 0b 00 00 00 02 00 00 00 00 20 00 00 00
75 000090 00 00 00 00 00 00 04 06 00 00 00 00 00 00 00 00
76 0000a0 00 00 00 74 00 00 00 74 3c e3 76 19 00 06 34 63
77 0000b0 ff ff ff ff 00 00 00 00 00 00 00 00 ff ff ff ff
78 0000c0 00 00 00 00 00 00 01 02 00 5c 00 5c ff ff ff ff
79 0000d0 3c e3 76 19 00 06 34 5a 00 0b 00 14 <here starts the MAC heder>
81 Each entry starts with 0x0044000b
83 The values 0x005c at position 0x0000c8 and 0x0000ca matches the number of bytes in
84 the packet up to the next entry, which starts with 0x00440b again. These probably
85 indicate the real and captured length of the packet (order unknown)
87 The values 0x00000074 at positions 0x0000a0 and 0x0000a4 seems to indicate
88 the same number as positions 0x0000c8 and 0x0000ca but added with 24.
89 Perhaps we have here two layers of headers.
90 The first layer is fixed and consists of all the bytes from 0x000084 up to and
91 including 0x0000c3 which is a generic header for all packets captured from any
92 device. This header might be of fixed size 64 bytes and there might be something in
93 it which indicates the type of the next header which is link type specific.
94 Following this header there is another header for the 100baseT interface which
95 in this case is 24 bytes long spanning positions 0x0000c4 to 0x0000db.
97 When someone reports that the loading of the captures breaks, we can compare
98 this header above with what he/she got to learn how to distinguish between different
99 types of link specific headers.
103 The first header seems to be
104 a normal nettlrec_ns_ls_ip_hdr
106 The header for 100baseT seems to be
115 struct nettlrec_ns_ls_drv_eth_hdr {
126 static gboolean nettl_read(wtap *wth, int *err, long *data_offset);
127 static gboolean nettl_seek_read(wtap *wth, long seek_off,
128 union wtap_pseudo_header *pseudo_header, guchar *pd,
129 int length, int *err);
130 static int nettl_read_rec_header(wtap *wth, FILE_T fh,
131 struct wtap_pkthdr *phdr, union wtap_pseudo_header *pseudo_header,
133 static gboolean nettl_read_rec_data(FILE_T fh, guchar *pd, int length,
135 static void nettl_close(wtap *wth);
137 int nettl_open(wtap *wth, int *err)
139 char magic[12], os_vers[2];
142 /* Read in the string that should be at the start of a HP file */
143 errno = WTAP_ERR_CANT_READ;
144 bytes_read = file_read(magic, 1, 12, wth->fh);
145 if (bytes_read != 12) {
146 *err = file_error(wth->fh);
152 if (memcmp(magic, nettl_magic_hpux9, 12) &&
153 memcmp(magic, nettl_magic_hpux10, 12)) {
157 if (file_seek(wth->fh, 0x63, SEEK_SET, err) == -1)
159 wth->data_offset = 0x63;
160 bytes_read = file_read(os_vers, 1, 2, wth->fh);
161 if (bytes_read != 2) {
162 *err = file_error(wth->fh);
168 if (file_seek(wth->fh, 0x80, SEEK_SET, err) == -1)
170 wth->data_offset = 0x80;
172 /* This is an nettl file */
173 wth->file_type = WTAP_FILE_NETTL;
174 wth->capture.nettl = g_malloc(sizeof(nettl_t));
175 if (os_vers[0] == '1' && os_vers[1] == '1')
176 wth->capture.nettl->is_hpux_11 = TRUE;
178 wth->capture.nettl->is_hpux_11 = FALSE;
179 wth->subtype_read = nettl_read;
180 wth->subtype_seek_read = nettl_seek_read;
181 wth->subtype_close = nettl_close;
182 wth->snapshot_length = 0; /* not available in header, only in frame */
187 /* Read the next packet */
188 static gboolean nettl_read(wtap *wth, int *err, long *data_offset)
192 /* Read record header. */
193 *data_offset = wth->data_offset;
194 ret = nettl_read_rec_header(wth, wth->fh, &wth->phdr, &wth->pseudo_header,
197 /* Read error or EOF */
200 wth->data_offset += ret;
203 * Read the packet data.
205 buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);
206 if (!nettl_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer),
207 wth->phdr.caplen, err))
208 return FALSE; /* Read error */
209 wth->data_offset += wth->phdr.caplen;
214 nettl_seek_read(wtap *wth, long seek_off,
215 union wtap_pseudo_header *pseudo_header, guchar *pd,
216 int length, int *err)
219 struct wtap_pkthdr phdr;
221 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
224 /* Read record header. */
225 ret = nettl_read_rec_header(wth, wth->random_fh, &phdr, pseudo_header,
228 /* Read error or EOF */
230 /* EOF means "short read" in random-access mode */
231 *err = WTAP_ERR_SHORT_READ;
237 * Read the packet data.
239 return nettl_read_rec_data(wth->random_fh, pd, length, err);
243 nettl_read_rec_header(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
244 union wtap_pseudo_header *pseudo_header, int *err)
247 struct nettlrec_sx25l2_hdr lapb_hdr;
248 struct nettlrec_ns_ls_ip_hdr ip_hdr;
249 struct nettlrec_ns_ls_drv_eth_hdr drv_eth_hdr;
255 errno = WTAP_ERR_CANT_READ;
256 bytes_read = file_read(encap, 1, 4, fh);
257 if (bytes_read != 4) {
258 *err = file_error(fh);
261 if (bytes_read != 0) {
262 *err = WTAP_ERR_SHORT_READ;
270 case NETTL_SUBSYS_LAN100 :
271 case NETTL_SUBSYS_BASE100 :
272 case NETTL_SUBSYS_GSC100BT :
273 case NETTL_SUBSYS_PCI100BT :
274 case NETTL_SUBSYS_SPP100BT :
275 case NETTL_SUBSYS_GELAN :
276 case NETTL_SUBSYS_BTLAN :
277 case NETTL_SUBSYS_INTL100 :
278 case NETTL_SUBSYS_IGELAN :
279 case NETTL_SUBSYS_NS_LS_IP :
280 case NETTL_SUBSYS_NS_LS_LOOPBACK :
281 case NETTL_SUBSYS_NS_LS_TCP :
282 case NETTL_SUBSYS_NS_LS_UDP :
283 case NETTL_SUBSYS_NS_LS_ICMP :
284 if( (encap[3] == NETTL_SUBSYS_NS_LS_IP)
285 || (encap[3] == NETTL_SUBSYS_NS_LS_LOOPBACK)
286 || (encap[3] == NETTL_SUBSYS_NS_LS_UDP)
287 || (encap[3] == NETTL_SUBSYS_NS_LS_TCP) ){
288 phdr->pkt_encap = WTAP_ENCAP_RAW_IP;
289 } else if (encap[3] == NETTL_SUBSYS_NS_LS_ICMP) {
290 phdr->pkt_encap = WTAP_ENCAP_UNKNOWN;
292 wth->file_encap = WTAP_ENCAP_ETHERNET;
293 phdr->pkt_encap = WTAP_ENCAP_ETHERNET;
296 bytes_read = file_read(&ip_hdr, 1, sizeof ip_hdr, fh);
297 if (bytes_read != sizeof ip_hdr) {
298 *err = file_error(fh);
301 if (bytes_read != 0) {
302 *err = WTAP_ERR_SHORT_READ;
307 offset += sizeof ip_hdr;
309 /* The packet header in HP-UX 11 nettl traces is 4 octets longer than
311 if (wth->capture.nettl->is_hpux_11) {
312 bytes_read = file_read(dummy, 1, 4, fh);
313 if (bytes_read != 4) {
314 *err = file_error(fh);
317 if (bytes_read != 0) {
318 *err = WTAP_ERR_SHORT_READ;
326 length = pntohl(&ip_hdr.length);
327 if (length <= 0) return 0;
329 length = pntohl(&ip_hdr.caplen);
330 phdr->caplen = length;
333 phdr->ts.tv_sec = pntohl(&ip_hdr.sec);
334 phdr->ts.tv_usec = pntohl(&ip_hdr.usec);
336 case NETTL_SUBSYS_NS_LS_DRIVER :
337 bytes_read = file_read(&ip_hdr, 1, sizeof ip_hdr, fh);
338 if (bytes_read != sizeof ip_hdr) {
339 *err = file_error(fh);
342 if (bytes_read != 0) {
343 *err = WTAP_ERR_SHORT_READ;
348 offset += sizeof ip_hdr;
350 /* The packet header in HP-UX 11 nettl traces is 4 octets longer than
352 if (wth->capture.nettl->is_hpux_11) {
353 bytes_read = file_read(dummy, 1, 4, fh);
354 if (bytes_read != 4) {
355 *err = file_error(fh);
358 if (bytes_read != 0) {
359 *err = WTAP_ERR_SHORT_READ;
367 /* XXX we dont know how to identify this as ethernet frames, so
368 we assumes everything is. We will crash and burn for anything else */
369 /* for encapsulated 100baseT we do this */
370 phdr->pkt_encap = WTAP_ENCAP_ETHERNET;
371 bytes_read = file_read(&drv_eth_hdr, 1, sizeof drv_eth_hdr, fh);
372 if (bytes_read != sizeof drv_eth_hdr) {
373 *err = file_error(fh);
376 if (bytes_read != 0) {
377 *err = WTAP_ERR_SHORT_READ;
382 offset += sizeof drv_eth_hdr;
384 length = pntohs(&drv_eth_hdr.length);
385 if (length <= 0) return 0;
387 length = pntohs(&drv_eth_hdr.caplen);
388 phdr->caplen = length;
390 phdr->ts.tv_sec = pntohl(&ip_hdr.sec);
391 phdr->ts.tv_usec = pntohl(&ip_hdr.usec);
393 case NETTL_SUBSYS_SX25L2 :
394 phdr->pkt_encap = WTAP_ENCAP_LAPB;
395 bytes_read = file_read(&lapb_hdr, 1, sizeof lapb_hdr, fh);
396 if (bytes_read != sizeof lapb_hdr) {
397 *err = file_error(fh);
400 if (bytes_read != 0) {
401 *err = WTAP_ERR_SHORT_READ;
406 offset += sizeof lapb_hdr;
408 if (wth->capture.nettl->is_hpux_11) {
409 bytes_read = file_read(dummy, 1, 4, fh);
410 if (bytes_read != 4) {
411 *err = file_error(fh);
414 if (bytes_read != 0) {
415 *err = WTAP_ERR_SHORT_READ;
423 length = pntohs(&lapb_hdr.length);
424 if (length <= 0) return 0;
426 phdr->caplen = length;
428 phdr->ts.tv_sec = pntohl(&lapb_hdr.sec);
429 phdr->ts.tv_usec = pntohl(&lapb_hdr.usec);
430 pseudo_header->x25.flags =
431 (lapb_hdr.from_dce & 0x20 ? FROM_DCE : 0x00);
434 g_message("nettl: network type %u unknown or unsupported",
436 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
443 nettl_read_rec_data(FILE_T fh, guchar *pd, int length, int *err)
447 bytes_read = file_read(pd, 1, length, fh);
449 if (bytes_read != length) {
450 *err = file_error(fh);
452 *err = WTAP_ERR_SHORT_READ;
458 static void nettl_close(wtap *wth)
460 g_free(wth->capture.nettl);