5 * Copyright (c) 2000 by Mike Hall <mlh@io.com>
6 * Copyright (c) 2000 by Cisco Systems
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "file_wrappers.h"
34 * This module reads the output from the Cisco Secure Intrusion Detection
35 * System iplogging facility. The term iplogging is misleading since this
36 * logger will only output TCP. There is no link layer information.
37 * Packet format is 4 byte timestamp (seconds since epoch), and a 4 byte size
38 * of data following for that packet.
40 * For a time there was an error in iplogging and the ip length, flags, and id
41 * were byteswapped. We will check for this and handle it before handing to
49 static gboolean
csids_read(wtap
*wth
, int *err
, gchar
**err_info
,
51 static gboolean
csids_seek_read(wtap
*wth
, gint64 seek_off
,
52 struct wtap_pkthdr
*phdr
, Buffer
*buf
, int len
,
53 int *err
, gchar
**err_info
);
54 static gboolean
csids_read_packet(FILE_T fh
, csids_t
*csids
,
55 struct wtap_pkthdr
*phdr
, Buffer
*buf
, int *err
, gchar
**err_info
);
58 guint32 seconds
; /* seconds since epoch */
59 guint16 zeropad
; /* 2 byte zero'ed pads */
60 guint16 caplen
; /* the capture length */
63 /* XXX - return -1 on I/O error and actually do something with 'err'. */
64 int csids_open(wtap
*wth
, int *err
, gchar
**err_info
)
66 /* There is no file header. There is only a header for each packet
67 * so we read a packet header and compare the caplen with iplen. They
68 * should always be equal except with the weird byteswap version.
70 * THIS IS BROKEN-- anytime the caplen is 0x0101 or 0x0202 up to 0x0505
71 * this will byteswap it. I need to fix this. XXX --mlh
74 int tmp
,iplen
,bytesRead
;
76 gboolean byteswap
= FALSE
;
77 struct csids_header hdr
;
80 /* check the file to make sure it is a csids file. */
81 bytesRead
= file_read( &hdr
, sizeof( struct csids_header
), wth
->fh
);
82 if( bytesRead
!= sizeof( struct csids_header
) ) {
83 *err
= file_error( wth
->fh
, err_info
);
84 if( *err
!= 0 && *err
!= WTAP_ERR_SHORT_READ
) {
89 if( hdr
.zeropad
!= 0 || hdr
.caplen
== 0 ) {
92 hdr
.seconds
= pntohl( &hdr
.seconds
);
93 hdr
.caplen
= pntohs( &hdr
.caplen
);
94 bytesRead
= file_read( &tmp
, 2, wth
->fh
);
95 if( bytesRead
!= 2 ) {
96 *err
= file_error( wth
->fh
, err_info
);
97 if( *err
!= 0 && *err
!= WTAP_ERR_SHORT_READ
) {
102 bytesRead
= file_read( &iplen
, 2, wth
->fh
);
103 if( bytesRead
!= 2 ) {
104 *err
= file_error( wth
->fh
, err_info
);
105 if( *err
!= 0 && *err
!= WTAP_ERR_SHORT_READ
) {
110 iplen
= pntohs(&iplen
);
115 /* if iplen and hdr.caplen are equal, default to no byteswap. */
116 if( iplen
> hdr
.caplen
) {
117 /* maybe this is just a byteswapped version. the iplen ipflags */
118 /* and ipid are swapped. We cannot use the normal swaps because */
119 /* we don't know the host */
120 iplen
= BSWAP16(iplen
);
121 if( iplen
<= hdr
.caplen
) {
122 /* we know this format */
125 /* don't know this one */
132 /* no file header. So reset the fh to 0 so we can read the first packet */
133 if (file_seek(wth
->fh
, 0, SEEK_SET
, err
) == -1)
136 csids
= (csids_t
*)g_malloc(sizeof(csids_t
));
137 wth
->priv
= (void *)csids
;
138 csids
->byteswapped
= byteswap
;
139 wth
->file_encap
= WTAP_ENCAP_RAW_IP
;
140 wth
->file_type_subtype
= WTAP_FILE_TYPE_SUBTYPE_CSIDS
;
141 wth
->snapshot_length
= 0; /* not known */
142 wth
->subtype_read
= csids_read
;
143 wth
->subtype_seek_read
= csids_seek_read
;
144 wth
->tsprecision
= WTAP_FILE_TSPREC_SEC
;
149 /* Find the next packet and parse it; called from wtap_read(). */
150 static gboolean
csids_read(wtap
*wth
, int *err
, gchar
**err_info
,
153 csids_t
*csids
= (csids_t
*)wth
->priv
;
155 *data_offset
= file_tell(wth
->fh
);
157 return csids_read_packet( wth
->fh
, csids
, &wth
->phdr
, wth
->frame_buffer
,
161 /* Used to read packets in random-access fashion */
163 csids_seek_read(wtap
*wth
,
165 struct wtap_pkthdr
*phdr
,
171 csids_t
*csids
= (csids_t
*)wth
->priv
;
173 if( file_seek( wth
->random_fh
, seek_off
, SEEK_SET
, err
) == -1 )
176 if( !csids_read_packet( wth
->random_fh
, csids
, phdr
, buf
, err
, err_info
) ) {
178 *err
= WTAP_ERR_SHORT_READ
;
185 csids_read_packet(FILE_T fh
, csids_t
*csids
, struct wtap_pkthdr
*phdr
,
186 Buffer
*buf
, int *err
, gchar
**err_info
)
188 struct csids_header hdr
;
192 bytesRead
= file_read( &hdr
, sizeof( struct csids_header
), fh
);
193 if( bytesRead
!= sizeof( struct csids_header
) ) {
194 *err
= file_error( fh
, err_info
);
195 if (*err
== 0 && bytesRead
!= 0)
196 *err
= WTAP_ERR_SHORT_READ
;
199 hdr
.seconds
= pntohl(&hdr
.seconds
);
200 hdr
.caplen
= pntohs(&hdr
.caplen
);
202 phdr
->presence_flags
= WTAP_HAS_TS
;
203 phdr
->len
= hdr
.caplen
;
204 phdr
->caplen
= hdr
.caplen
;
205 phdr
->ts
.secs
= hdr
.seconds
;
208 if( !wtap_read_packet_bytes( fh
, buf
, phdr
->caplen
, err
, err_info
) )
211 pd
= buffer_start_ptr( buf
);
212 if( csids
->byteswapped
) {
213 if( phdr
->caplen
>= 2 ) {
214 PBSWAP16(pd
); /* the ip len */
215 if( phdr
->caplen
>= 4 ) {
216 PBSWAP16(pd
+2); /* ip id */
217 if( phdr
->caplen
>= 6 )
218 PBSWAP16(pd
+4); /* ip flags and fragoff */