We are obliged to define HAVE_UNISTD_H in "config.h"; to avoid the
[obnox/wireshark/wip.git] / wiretap / nettl.c
1 /* nettl.c
2  *
3  * $Id: nettl.c,v 1.3 2000/01/13 07:09:18 guy Exp $
4  *
5  * Wiretap Library
6  * Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
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[5] = {
36     0x54, 0x52, 0x00, 0x64, 0x00
37 };
38
39 /* HP nettl record header - The FCS is not included in the file. */
40 struct nettlrec_hdr {
41     char        xxa[12];
42     char        from_dce;
43     char        xxb[55];
44     guint16     length;
45     guint16     length2;    /* don't know which one is captured length / real length */
46     char        xxc[4];
47     char        sec[4];
48     char        usec[4];
49     char        xxd[4];
50 };
51
52 /* header is followed by data and once again the total length (2 bytes) ! */
53
54 static int nettl_read(wtap *wth, int *err);
55
56 int nettl_open(wtap *wth, int *err)
57 {
58     char magic[5];
59     int bytes_read;
60
61     /* Read in the string that should be at the start of a HP file */
62     file_seek(wth->fh, 0, SEEK_SET);
63     errno = WTAP_ERR_CANT_READ;
64     bytes_read = file_read(magic, 1, 5, wth->fh);
65     if (bytes_read != 5) {
66         *err = file_error(wth->fh);
67         if (*err != 0)
68             return -1;
69         return 0;
70     }
71
72     if (memcmp(magic, nettl_magic, 5)) {
73         return 0;
74     }
75
76     file_seek(wth->fh, 0x80, SEEK_SET);
77     wth->data_offset = 0x80;
78
79     /* This is an nettl file */
80     wth->file_type = WTAP_FILE_NETTL;
81     wth->capture.nettl = g_malloc(sizeof(nettl_t));
82     wth->subtype_read = nettl_read;
83     wth->snapshot_length = 16384;       /* not available in header, only in frame */
84
85     wth->capture.nettl->start = 0;
86
87     wth->file_encap = WTAP_ENCAP_LAPB;
88
89     return 1;
90 }
91
92 /* Read the next packet */
93 static int nettl_read(wtap *wth, int *err)
94 {
95     int bytes_read;
96     struct nettlrec_hdr hdr;
97     guint16 length;
98     int data_offset;
99
100     /* Read record header. */
101     errno = WTAP_ERR_CANT_READ;
102     bytes_read = file_read(&hdr, 1, sizeof hdr, wth->fh);
103     if (bytes_read != sizeof hdr) {
104         *err = file_error(wth->fh);
105         if (*err != 0)
106             return -1;
107         if (bytes_read != 0) {
108             *err = WTAP_ERR_SHORT_READ;
109             return -1;
110         }
111         return 0;
112     }
113     wth->data_offset += sizeof hdr;
114     length = pntohs(&hdr.length);
115     if (length <= 0) return 0;
116
117     wth->phdr.len = length;
118     wth->phdr.caplen = length;
119
120     wth->phdr.ts.tv_sec = pntohl(&hdr.sec);
121     wth->phdr.ts.tv_usec = pntohl(&hdr.usec);
122     if (wth->capture.nettl->start == 0)
123         wth->capture.nettl->start = wth->phdr.ts.tv_sec;
124     wth->phdr.pseudo_header.x25.flags = (hdr.from_dce & 0x20 ? 0x80 : 0x00);
125
126     /*
127      * Read the packet data.
128      */
129     buffer_assure_space(wth->frame_buffer, length);
130     data_offset = wth->data_offset;
131     errno = WTAP_ERR_CANT_READ;
132     bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), 1,
133             length, wth->fh);
134
135     if (bytes_read != length) {
136         *err = file_error(wth->fh);
137         if (*err == 0)
138             *err = WTAP_ERR_SHORT_READ;
139         return -1;
140     }
141     wth->data_offset += length;
142
143     wth->phdr.pkt_encap = wth->file_encap;
144
145     return data_offset;
146 }