4 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
6 * Enhancements by Mark C. Brown <mbrown@hp.com>
7 * Copyright (C) 2003, 2005 Hewlett-Packard Development Company, L.P.
9 * SPDX-License-Identifier: GPL-2.0-or-later
18 #include "file_wrappers.h"
20 /* HP nettl file header */
22 /* Magic number size */
26 static const uint8_t nettl_magic_hpux9
[MAGIC_SIZE
] = {
27 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xD0, 0x00
29 /* HP-UX 10.x and 11.x */
30 static const uint8_t nettl_magic_hpux10
[MAGIC_SIZE
] = {
31 0x54, 0x52, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
34 #define FILE_HDR_SIZE 128
35 #define NETTL_FILENAME_SIZE 56
37 struct nettl_file_hdr
{
38 uint8_t magic
[MAGIC_SIZE
];
39 char file_name
[NETTL_FILENAME_SIZE
];
46 uint16_t unknown
; /* just padding to 128 bytes? */
49 /* HP nettl record header */
50 /* see /usr/include/sys/netdiag1.h for hints */
65 /* Other stuff might be here, but isn't always here */
69 * This is what we treat as the minimum size of a record header.
70 * It is *not* necessarily the same as sizeof(struct nettlrec_hdr),
71 * because it doesn't include any padding added to the structure.
73 #define NETTL_REC_HDR_LEN 64
75 /* HP nettl record header for the SX25L2 subsystem - The FCS is not included
77 struct nettlrec_sx25l2_hdr
{
90 The following shows what the header and subheader looks like for NS_LS_DRIVER
91 The capture was taken on HPUX11 and for a 100baseT interface.
93 000080 00 44 00 0b 00 00 00 02 00 00 00 00 20 00 00 00
94 000090 00 00 00 00 00 00 04 06 00 00 00 00 00 00 00 00
95 0000a0 00 00 00 74 00 00 00 74 3c e3 76 19 00 06 34 63
96 0000b0 ff ff ff ff 00 00 00 00 00 00 00 00 ff ff ff ff
97 0000c0 00 00 00 00 00 00 01 02 00 5c 00 5c ff ff ff ff
98 0000d0 3c e3 76 19 00 06 34 5a 00 0b 00 14 <here starts the MAC header>
100 Each entry starts with 0x0044000b
102 The values 0x005c at position 0x0000c8 and 0x0000ca matches the number of
103 bytes in the packet up to the next entry, which starts with 0x00440b again.
104 These are the captured and real and captured length of the packet.
106 The values 0x00000074 at positions 0x0000a0 and 0x0000a4 seems to indicate
107 the same number as positions 0x0000c8 and 0x0000ca but added with 24.
108 Perhaps we have here two layers of headers.
109 The first layer is fixed and consists of all the bytes from 0x000084 up to and
110 including 0x0000c3 which is a generic header for all packets captured from any
111 device. This header might be of fixed size 64 bytes (although the first two
112 bytes appear to be the length of that header, in big-endian format) and there
113 might be something in it which indicates the type of the next header which is
114 link type specific. Following this header there is another header for the
115 100baseT interface which in this case is 24 bytes long spanning positions
116 0x0000c4 to 0x0000db.
118 In another capture, claimed to be taken on an HP-UX 8 box, but with a
119 file header suggesting it was taken on HP-UX 10.20, the header for
120 NS_LS_DRIVER looks like:
122 000080 00 40 00 0b ff ff ff ff 00 00 00 00 00 00 00 00
123 000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
124 0000a0 00 00 00 51 00 00 00 51 42 02 5e bf 00 0e ab 7c
125 0000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
126 0000c0 00 02 01 00 00 3b 00 3b ff ff ff ff 42 02 5e bf
127 0000d0 00 0e 8e 44 00 0b <here starts the MAC header>
129 When someone reports that the loading of the captures breaks, we can
130 compare this header above with what he/she got to learn how to
131 distinguish between different types of link specific headers.
134 For now, the subheader for 100baseT seems to be
142 struct nettlrec_ns_ls_drv_eth_hdr
{
153 * This is the size of an NS_LS_DRV_ETH header; it is *not* necessarily
154 * the same as sizeof(struct nettlrec_ns_ls_drv_eth_hdr), because it
155 * doesn't include any padding added to the structure.
157 #define NS_LS_DRV_ETH_HDR_LEN 22
159 /* header is followed by data and once again the total length (2 bytes) ! */
165 static bool nettl_read(wtap
*wth
, wtap_rec
*rec
, Buffer
*buf
,
166 int *err
, char **err_info
, int64_t *data_offset
);
167 static bool nettl_seek_read(wtap
*wth
, int64_t seek_off
,
168 wtap_rec
*rec
, Buffer
*buf
,
169 int *err
, char **err_info
);
170 static bool nettl_read_rec(wtap
*wth
, FILE_T fh
, wtap_rec
*rec
,
171 Buffer
*buf
, int *err
, char **err_info
);
172 static bool nettl_dump(wtap_dumper
*wdh
, const wtap_rec
*rec
,
173 const uint8_t *pd
, int *err
, char **err_info
);
175 static int nettl_file_type_subtype
= -1;
177 void register_nettl(void);
179 wtap_open_return_val
nettl_open(wtap
*wth
, int *err
, char **err_info
)
181 struct nettl_file_hdr file_hdr
;
186 memset(&file_hdr
, 0, sizeof(file_hdr
));
188 /* Read in the string that should be at the start of a HP file */
189 if (!wtap_read_bytes(wth
->fh
, file_hdr
.magic
, MAGIC_SIZE
, err
, err_info
)) {
190 if (*err
!= WTAP_ERR_SHORT_READ
)
191 return WTAP_OPEN_ERROR
;
192 return WTAP_OPEN_NOT_MINE
;
195 if (memcmp(file_hdr
.magic
, nettl_magic_hpux9
, MAGIC_SIZE
) &&
196 memcmp(file_hdr
.magic
, nettl_magic_hpux10
, MAGIC_SIZE
)) {
197 return WTAP_OPEN_NOT_MINE
;
200 /* Read the rest of the file header */
201 if (!wtap_read_bytes(wth
->fh
, file_hdr
.file_name
, FILE_HDR_SIZE
- MAGIC_SIZE
,
203 return WTAP_OPEN_ERROR
;
205 /* This is an nettl file */
206 wth
->file_type_subtype
= nettl_file_type_subtype
;
207 nettl
= g_new(nettl_t
,1);
208 wth
->priv
= (void *)nettl
;
209 if (file_hdr
.os_vers
[2] == '1' && file_hdr
.os_vers
[3] == '1')
210 nettl
->is_hpux_11
= true;
212 nettl
->is_hpux_11
= false;
213 wth
->subtype_read
= nettl_read
;
214 wth
->subtype_seek_read
= nettl_seek_read
;
215 wth
->snapshot_length
= 0; /* not available */
217 /* read the first header to take a guess at the file encap */
218 if (!wtap_read_bytes_or_eof(wth
->fh
, dummy
, 4, err
, err_info
)) {
220 /* EOF, so no records */
221 return WTAP_OPEN_NOT_MINE
;
223 return WTAP_OPEN_ERROR
;
226 subsys
= g_ntohs(dummy
[1]);
228 case NETTL_SUBSYS_HPPB_FDDI
:
229 case NETTL_SUBSYS_EISA_FDDI
:
230 case NETTL_SUBSYS_PCI_FDDI
:
231 case NETTL_SUBSYS_HSC_FDDI
:
232 wth
->file_encap
= WTAP_ENCAP_NETTL_FDDI
;
234 case NETTL_SUBSYS_TOKEN
:
235 case NETTL_SUBSYS_PCI_TR
:
236 wth
->file_encap
= WTAP_ENCAP_NETTL_TOKEN_RING
;
238 case NETTL_SUBSYS_NS_LS_IP
:
239 case NETTL_SUBSYS_NS_LS_LOOPBACK
:
240 case NETTL_SUBSYS_NS_LS_TCP
:
241 case NETTL_SUBSYS_NS_LS_UDP
:
242 case NETTL_SUBSYS_NS_LS_IPV6
:
243 wth
->file_encap
= WTAP_ENCAP_NETTL_RAW_IP
;
245 case NETTL_SUBSYS_NS_LS_ICMP
:
246 wth
->file_encap
= WTAP_ENCAP_NETTL_RAW_ICMP
;
248 case NETTL_SUBSYS_NS_LS_ICMPV6
:
249 wth
->file_encap
= WTAP_ENCAP_NETTL_RAW_ICMPV6
;
251 case NETTL_SUBSYS_NS_LS_TELNET
:
252 wth
->file_encap
= WTAP_ENCAP_NETTL_RAW_TELNET
;
255 /* If this assumption is bad, the read will catch it */
256 wth
->file_encap
= WTAP_ENCAP_NETTL_ETHERNET
;
259 if (file_seek(wth
->fh
, FILE_HDR_SIZE
, SEEK_SET
, err
) == -1) {
260 return WTAP_OPEN_ERROR
;
262 wth
->file_tsprec
= WTAP_TSPREC_USEC
;
264 return WTAP_OPEN_MINE
;
267 /* Read the next packet */
268 static bool nettl_read(wtap
*wth
, wtap_rec
*rec
, Buffer
*buf
,
269 int *err
, char **err_info
, int64_t *data_offset
)
272 *data_offset
= file_tell(wth
->fh
);
273 if (!nettl_read_rec(wth
, wth
->fh
, rec
, buf
, err
, err_info
)) {
274 /* Read error or EOF */
279 * If the per-file encapsulation isn't known, set it to this
280 * packet's encapsulation.
282 * If it *is* known, and it isn't this packet's encapsulation,
283 * set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
284 * have a single encapsulation for all packets in the file.
286 if (wth
->file_encap
== WTAP_ENCAP_UNKNOWN
)
287 wth
->file_encap
= rec
->rec_header
.packet_header
.pkt_encap
;
289 if (wth
->file_encap
!= rec
->rec_header
.packet_header
.pkt_encap
)
290 wth
->file_encap
= WTAP_ENCAP_PER_PACKET
;
297 nettl_seek_read(wtap
*wth
, int64_t seek_off
, wtap_rec
*rec
,
298 Buffer
*buf
, int *err
, char **err_info
)
300 if (file_seek(wth
->random_fh
, seek_off
, SEEK_SET
, err
) == -1)
304 if (!nettl_read_rec(wth
, wth
->random_fh
, rec
, buf
, err
, err_info
)) {
305 /* Read error or EOF */
307 /* EOF means "short read" in random-access mode */
308 *err
= WTAP_ERR_SHORT_READ
;
316 nettl_read_rec(wtap
*wth
, FILE_T fh
, wtap_rec
*rec
, Buffer
*buf
,
317 int *err
, char **err_info
)
319 union wtap_pseudo_header
*pseudo_header
= &rec
->rec_header
.packet_header
.pseudo_header
;
320 nettl_t
*nettl
= (nettl_t
*)wth
->priv
;
321 bool fddihack
= false;
322 struct nettlrec_hdr rec_hdr
;
324 struct nettlrec_ns_ls_drv_eth_hdr drv_eth_hdr
;
325 uint32_t length
, caplen
;
333 if (!wtap_read_bytes_or_eof(fh
, &rec_hdr
.hdr_len
, sizeof rec_hdr
.hdr_len
,
336 hdr_len
= g_ntohs(rec_hdr
.hdr_len
);
337 if (hdr_len
< NETTL_REC_HDR_LEN
) {
338 *err
= WTAP_ERR_BAD_FILE
;
339 *err_info
= ws_strdup_printf("nettl: record header length %u too short",
343 if (!wtap_read_bytes(fh
, &rec_hdr
.subsys
, NETTL_REC_HDR_LEN
- 2,
346 subsys
= g_ntohs(rec_hdr
.subsys
);
347 hdr_len
-= NETTL_REC_HDR_LEN
;
348 /* Skip the rest of the header. */
349 if (!wtap_read_bytes(fh
, NULL
, hdr_len
, err
, err_info
))
352 if ( (pntoh32(&rec_hdr
.kind
) & NETTL_HDR_PDU_MASK
) == 0 ) {
353 /* not actually a data packet (PDU) trace record */
354 rec
->rec_header
.packet_header
.pkt_encap
= WTAP_ENCAP_NETTL_RAW_IP
;
355 length
= pntoh32(&rec_hdr
.length
);
356 caplen
= pntoh32(&rec_hdr
.caplen
);
358 } else switch (subsys
) {
359 case NETTL_SUBSYS_LAN100
:
360 case NETTL_SUBSYS_EISA100BT
:
361 case NETTL_SUBSYS_BASE100
:
362 case NETTL_SUBSYS_GSC100BT
:
363 case NETTL_SUBSYS_PCI100BT
:
364 case NETTL_SUBSYS_SPP100BT
:
365 case NETTL_SUBSYS_100VG
:
366 case NETTL_SUBSYS_GELAN
:
367 case NETTL_SUBSYS_BTLAN
:
368 case NETTL_SUBSYS_INTL100
:
369 case NETTL_SUBSYS_IGELAN
:
370 case NETTL_SUBSYS_IETHER
:
371 case NETTL_SUBSYS_IXGBE
:
372 case NETTL_SUBSYS_HSSN
:
373 case NETTL_SUBSYS_IGSSN
:
374 case NETTL_SUBSYS_ICXGBE
:
375 case NETTL_SUBSYS_IEXGBE
:
376 case NETTL_SUBSYS_IOCXGBE
:
377 case NETTL_SUBSYS_IQXGBE
:
378 case NETTL_SUBSYS_HPPB_FDDI
:
379 case NETTL_SUBSYS_EISA_FDDI
:
380 case NETTL_SUBSYS_PCI_FDDI
:
381 case NETTL_SUBSYS_HSC_FDDI
:
382 case NETTL_SUBSYS_TOKEN
:
383 case NETTL_SUBSYS_PCI_TR
:
384 case NETTL_SUBSYS_NS_LS_IP
:
385 case NETTL_SUBSYS_NS_LS_LOOPBACK
:
386 case NETTL_SUBSYS_NS_LS_TCP
:
387 case NETTL_SUBSYS_NS_LS_UDP
:
388 case NETTL_SUBSYS_HP_APAPORT
:
389 case NETTL_SUBSYS_HP_APALACP
:
390 case NETTL_SUBSYS_NS_LS_IPV6
:
391 case NETTL_SUBSYS_NS_LS_ICMPV6
:
392 case NETTL_SUBSYS_NS_LS_ICMP
:
393 case NETTL_SUBSYS_NS_LS_TELNET
:
394 case NETTL_SUBSYS_NS_LS_SCTP
:
395 if( (subsys
== NETTL_SUBSYS_NS_LS_IP
)
396 || (subsys
== NETTL_SUBSYS_NS_LS_LOOPBACK
)
397 || (subsys
== NETTL_SUBSYS_NS_LS_UDP
)
398 || (subsys
== NETTL_SUBSYS_NS_LS_TCP
)
399 || (subsys
== NETTL_SUBSYS_NS_LS_SCTP
)
400 || (subsys
== NETTL_SUBSYS_NS_LS_IPV6
)) {
401 rec
->rec_header
.packet_header
.pkt_encap
= WTAP_ENCAP_NETTL_RAW_IP
;
402 } else if (subsys
== NETTL_SUBSYS_NS_LS_ICMP
) {
403 rec
->rec_header
.packet_header
.pkt_encap
= WTAP_ENCAP_NETTL_RAW_ICMP
;
404 } else if (subsys
== NETTL_SUBSYS_NS_LS_ICMPV6
) {
405 rec
->rec_header
.packet_header
.pkt_encap
= WTAP_ENCAP_NETTL_RAW_ICMPV6
;
406 } else if (subsys
== NETTL_SUBSYS_NS_LS_TELNET
) {
407 rec
->rec_header
.packet_header
.pkt_encap
= WTAP_ENCAP_NETTL_RAW_TELNET
;
408 } else if( (subsys
== NETTL_SUBSYS_HPPB_FDDI
)
409 || (subsys
== NETTL_SUBSYS_EISA_FDDI
)
410 || (subsys
== NETTL_SUBSYS_PCI_FDDI
)
411 || (subsys
== NETTL_SUBSYS_HSC_FDDI
) ) {
412 rec
->rec_header
.packet_header
.pkt_encap
= WTAP_ENCAP_NETTL_FDDI
;
413 } else if( (subsys
== NETTL_SUBSYS_PCI_TR
)
414 || (subsys
== NETTL_SUBSYS_TOKEN
) ) {
415 rec
->rec_header
.packet_header
.pkt_encap
= WTAP_ENCAP_NETTL_TOKEN_RING
;
417 rec
->rec_header
.packet_header
.pkt_encap
= WTAP_ENCAP_NETTL_ETHERNET
;
420 length
= pntoh32(&rec_hdr
.length
);
421 caplen
= pntoh32(&rec_hdr
.caplen
);
423 /* HPPB FDDI has different inbound vs outbound trace records */
424 if (subsys
== NETTL_SUBSYS_HPPB_FDDI
) {
425 if (pntoh32(&rec_hdr
.kind
) == NETTL_HDR_PDUIN
) {
426 /* inbound is very strange...
427 there are an extra 3 bytes after the DSAP and SSAP
433 /* outbound appears to have variable padding */
434 if (!wtap_read_bytes(fh
, dummyc
, 9, err
, err_info
))
436 /* padding is usually either a total 11 or 16 bytes??? */
437 padlen
= (int)dummyc
[8];
438 if (!wtap_read_bytes(fh
, NULL
, padlen
, err
, err_info
))
442 } else if ( (subsys
== NETTL_SUBSYS_PCI_FDDI
)
443 || (subsys
== NETTL_SUBSYS_EISA_FDDI
)
444 || (subsys
== NETTL_SUBSYS_HSC_FDDI
) ) {
445 /* other flavor FDDI cards have an extra 3 bytes of padding */
446 if (!wtap_read_bytes(fh
, NULL
, 3, err
, err_info
))
449 } else if (subsys
== NETTL_SUBSYS_NS_LS_LOOPBACK
) {
450 /* LOOPBACK has an extra 26 bytes of padding */
451 if (!wtap_read_bytes(fh
, NULL
, 26, err
, err_info
))
454 } else if (subsys
== NETTL_SUBSYS_NS_LS_SCTP
) {
456 * SCTP 8 byte header that we will ignore...
457 * 32 bit integer defines format
460 * 3 = Binary (PDUs should be Binary format)
461 * 32 bit integer defines type
465 if (!wtap_read_bytes(fh
, NULL
, 8, err
, err_info
))
473 case NETTL_SUBSYS_NS_LS_DRIVER
:
474 /* XXX we don't know how to identify this as ethernet frames, so
475 we assume everything is. We will crash and burn for anything else */
476 /* for encapsulated 100baseT we do this */
477 rec
->rec_header
.packet_header
.pkt_encap
= WTAP_ENCAP_NETTL_ETHERNET
;
478 if (!wtap_read_bytes(fh
, &drv_eth_hdr
, NS_LS_DRV_ETH_HDR_LEN
,
482 length
= pntoh16(&drv_eth_hdr
.length
);
483 caplen
= pntoh16(&drv_eth_hdr
.caplen
);
485 * XXX - is there a length field that would give the length
486 * of this header, so that we don't have to check for
487 * nettl files from HP-UX 11?
489 * And what are the extra two bytes?
491 if (nettl
->is_hpux_11
) {
492 if (!wtap_read_bytes(fh
, NULL
, 2, err
, err_info
))
498 case NETTL_SUBSYS_SX25L2
:
499 case NETTL_SUBSYS_SX25L3
:
501 * XXX - is the 24-byte padding actually a header with
502 * packet lengths, time stamps, etc., just as is the case
503 * for NETTL_SUBSYS_NS_LS_DRIVER? It might be
512 * or something such as that - if it has 4 bytes before that
513 * (making it 24 bytes), it'd be like struct
514 * nettlrec_ns_ls_drv_eth_hdr but with 2 more bytes at the end.
516 * And is "from_dce" at xxa[0] in the nettlrec_hdr structure?
518 rec
->rec_header
.packet_header
.pkt_encap
= WTAP_ENCAP_NETTL_X25
;
519 length
= pntoh32(&rec_hdr
.length
);
520 caplen
= pntoh32(&rec_hdr
.caplen
);
521 padlen
= 24; /* sizeof (struct nettlrec_sx25l2_hdr) - NETTL_REC_HDR_LEN + 4 */
522 if (!wtap_read_bytes(fh
, NULL
, padlen
, err
, err_info
))
527 /* We're going to assume it's ethernet if we don't recognize the
528 subsystem -- We'll probably spew junks and core if it isn't... */
529 wth
->file_encap
= WTAP_ENCAP_PER_PACKET
;
530 rec
->rec_header
.packet_header
.pkt_encap
= WTAP_ENCAP_NETTL_ETHERNET
;
531 length
= pntoh32(&rec_hdr
.length
);
532 caplen
= pntoh32(&rec_hdr
.caplen
);
537 if (length
< padlen
) {
538 *err
= WTAP_ERR_BAD_FILE
;
539 *err_info
= ws_strdup_printf("nettl: packet length %u in record header too short, less than %u",
543 rec
->rec_type
= REC_TYPE_PACKET
;
544 rec
->block
= wtap_block_create(WTAP_BLOCK_PACKET
);
545 rec
->presence_flags
= WTAP_HAS_TS
|WTAP_HAS_CAP_LEN
;
546 rec
->rec_header
.packet_header
.len
= length
- padlen
;
547 if (caplen
< padlen
) {
548 *err
= WTAP_ERR_BAD_FILE
;
549 *err_info
= ws_strdup_printf("nettl: captured length %u in record header too short, less than %u",
553 datalen
= caplen
- padlen
;
554 rec
->rec_header
.packet_header
.caplen
= datalen
;
555 rec
->ts
.secs
= pntoh32(&rec_hdr
.sec
);
556 rec
->ts
.nsecs
= pntoh32(&rec_hdr
.usec
) * 1000;
558 pseudo_header
->nettl
.subsys
= subsys
;
559 pseudo_header
->nettl
.devid
= pntoh32(&rec_hdr
.devid
);
560 pseudo_header
->nettl
.kind
= pntoh32(&rec_hdr
.kind
);
561 pseudo_header
->nettl
.pid
= pntoh32(&rec_hdr
.pid
);
562 pseudo_header
->nettl
.uid
= pntoh32(&rec_hdr
.uid
);
564 if (rec
->rec_header
.packet_header
.caplen
> WTAP_MAX_PACKET_SIZE_STANDARD
) {
566 * Probably a corrupt capture file; don't blow up trying
567 * to allocate space for an immensely-large packet.
569 *err
= WTAP_ERR_BAD_FILE
;
570 *err_info
= ws_strdup_printf("nettl: File has %u-byte packet, bigger than maximum of %u",
571 rec
->rec_header
.packet_header
.caplen
, WTAP_MAX_PACKET_SIZE_STANDARD
);
576 * Read the packet data.
578 ws_buffer_assure_space(buf
, datalen
);
579 pd
= ws_buffer_start_ptr(buf
);
581 /* read in FC, dest, src, DSAP and SSAP */
583 if (bytes_to_read
> datalen
)
584 bytes_to_read
= datalen
;
585 if (!wtap_read_bytes(fh
, pd
, bytes_to_read
, err
, err_info
))
587 datalen
-= bytes_to_read
;
589 /* There's nothing past the FC, dest, src, DSAP and SSAP */
592 if (pd
[13] == 0xAA) {
593 /* it's SNAP, have to eat 3 bytes??? */
595 if (bytes_to_read
> datalen
)
596 bytes_to_read
= datalen
;
597 if (!wtap_read_bytes(fh
, NULL
, bytes_to_read
, err
, err_info
))
599 datalen
-= bytes_to_read
;
601 /* There's nothing past the FC, dest, src, DSAP, SSAP, and 3 bytes to eat */
605 if (!wtap_read_bytes(fh
, pd
+ 15, datalen
, err
, err_info
))
608 if (!wtap_read_bytes(fh
, pd
, datalen
, err
, err_info
))
615 /* Returns 0 if we could write the specified encapsulation type,
616 an error indication otherwise. nettl files are WTAP_ENCAP_UNKNOWN
617 when they are first opened, so we allow that for tshark read/write.
620 static int nettl_dump_can_write_encap(int encap
)
624 case WTAP_ENCAP_ETHERNET
:
625 case WTAP_ENCAP_FDDI_BITSWAPPED
:
626 case WTAP_ENCAP_TOKEN_RING
:
627 case WTAP_ENCAP_NETTL_ETHERNET
:
628 case WTAP_ENCAP_NETTL_FDDI
:
629 case WTAP_ENCAP_NETTL_TOKEN_RING
:
630 case WTAP_ENCAP_NETTL_RAW_IP
:
631 case WTAP_ENCAP_NETTL_RAW_ICMP
:
632 case WTAP_ENCAP_NETTL_RAW_ICMPV6
:
633 case WTAP_ENCAP_NETTL_RAW_TELNET
:
635 case WTAP_ENCAP_NETTL_X25:
637 case WTAP_ENCAP_PER_PACKET
:
638 case WTAP_ENCAP_UNKNOWN
:
639 case WTAP_ENCAP_NETTL_UNKNOWN
:
642 return WTAP_ERR_UNWRITABLE_ENCAP
;
647 /* Returns true on success, false on failure;
648 sets "*err" to an error code on failure */
649 static bool nettl_dump_open(wtap_dumper
*wdh
, int *err
, char **err_info _U_
)
651 struct nettl_file_hdr file_hdr
;
653 /* This is a nettl file */
654 wdh
->subtype_write
= nettl_dump
;
656 /* Write the file header. */
657 memset(&file_hdr
,0,sizeof(file_hdr
));
658 memcpy(file_hdr
.magic
,nettl_magic_hpux10
,sizeof(file_hdr
.magic
));
659 (void) g_strlcpy(file_hdr
.file_name
,"/tmp/wireshark.TRC000",NETTL_FILENAME_SIZE
);
660 (void) g_strlcpy(file_hdr
.tz
,"UTC",20);
661 (void) g_strlcpy(file_hdr
.host_name
,"",9);
662 (void) g_strlcpy(file_hdr
.os_vers
,"B.11.11",9);
664 (void) g_strlcpy(file_hdr
.model
,"9000/800",11);
665 file_hdr
.unknown
=g_htons(0x406);
666 if (!wtap_dump_file_write(wdh
, &file_hdr
, sizeof file_hdr
, err
))
672 /* Write a record for a packet to a dump file.
673 Returns true on success, false on failure. */
674 static bool nettl_dump(wtap_dumper
*wdh
,
676 const uint8_t *pd
, int *err
, char **err_info _U_
)
678 const union wtap_pseudo_header
*pseudo_header
= &rec
->rec_header
.packet_header
.pseudo_header
;
679 struct nettlrec_hdr rec_hdr
;
682 /* We can only write packet records. */
683 if (rec
->rec_type
!= REC_TYPE_PACKET
) {
684 *err
= WTAP_ERR_UNWRITABLE_REC_TYPE
;
688 /* Don't write anything we're not willing to read. */
689 if (rec
->rec_header
.packet_header
.caplen
> WTAP_MAX_PACKET_SIZE_STANDARD
) {
690 *err
= WTAP_ERR_PACKET_TOO_LARGE
;
694 memset(&rec_hdr
,0,sizeof(rec_hdr
));
695 /* HP-UX 11.X header should be 68 bytes */
696 rec_hdr
.hdr_len
= g_htons(sizeof(rec_hdr
) + 4);
697 rec_hdr
.kind
= g_htonl(NETTL_HDR_PDUIN
);
699 * Probably interpreted as signed in other programs that read it.
700 * Maybe HPE will decide to make it unsigned, which could probably
701 * be made to work once the last 32-bit UN*X is gone and time_t
702 * is universally 64-bit.
704 if (rec
->ts
.secs
< 0 || rec
->ts
.secs
> INT32_MAX
) {
705 *err
= WTAP_ERR_TIME_STAMP_NOT_SUPPORTED
;
708 rec_hdr
.sec
= g_htonl((uint32_t)rec
->ts
.secs
);
709 rec_hdr
.usec
= g_htonl(rec
->ts
.nsecs
/1000);
710 rec_hdr
.caplen
= g_htonl(rec
->rec_header
.packet_header
.caplen
);
711 rec_hdr
.length
= g_htonl(rec
->rec_header
.packet_header
.len
);
716 switch (rec
->rec_header
.packet_header
.pkt_encap
) {
718 case WTAP_ENCAP_NETTL_FDDI
:
719 /* account for pad bytes */
720 rec_hdr
.caplen
= g_htonl(rec
->rec_header
.packet_header
.caplen
+ 3);
721 rec_hdr
.length
= g_htonl(rec
->rec_header
.packet_header
.len
+ 3);
722 /* fall through and fill the rest of the fields */
724 case WTAP_ENCAP_NETTL_ETHERNET
:
725 case WTAP_ENCAP_NETTL_TOKEN_RING
:
726 case WTAP_ENCAP_NETTL_RAW_IP
:
727 case WTAP_ENCAP_NETTL_RAW_ICMP
:
728 case WTAP_ENCAP_NETTL_RAW_ICMPV6
:
729 case WTAP_ENCAP_NETTL_RAW_TELNET
:
730 case WTAP_ENCAP_NETTL_UNKNOWN
:
731 rec_hdr
.subsys
= g_htons(pseudo_header
->nettl
.subsys
);
732 rec_hdr
.devid
= g_htonl(pseudo_header
->nettl
.devid
);
733 rec_hdr
.kind
= g_htonl(pseudo_header
->nettl
.kind
);
734 rec_hdr
.pid
= g_htonl(pseudo_header
->nettl
.pid
);
735 rec_hdr
.uid
= g_htons(pseudo_header
->nettl
.uid
);
738 case WTAP_ENCAP_RAW_IP
:
739 rec_hdr
.subsys
= g_htons(NETTL_SUBSYS_NS_LS_IP
);
742 case WTAP_ENCAP_ETHERNET
:
743 rec_hdr
.subsys
= g_htons(NETTL_SUBSYS_BTLAN
);
746 case WTAP_ENCAP_FDDI_BITSWAPPED
:
747 rec_hdr
.subsys
= g_htons(NETTL_SUBSYS_PCI_FDDI
);
748 /* account for pad bytes */
749 rec_hdr
.caplen
= g_htonl(rec
->rec_header
.packet_header
.caplen
+ 3);
750 rec_hdr
.length
= g_htonl(rec
->rec_header
.packet_header
.len
+ 3);
753 case WTAP_ENCAP_TOKEN_RING
:
754 rec_hdr
.subsys
= g_htons(NETTL_SUBSYS_PCI_TR
);
757 case WTAP_ENCAP_NETTL_X25
:
758 rec_hdr
.caplen
= g_htonl(rec
->rec_header
.packet_header
.caplen
+ 24);
759 rec_hdr
.length
= g_htonl(rec
->rec_header
.packet_header
.len
+ 24);
760 rec_hdr
.subsys
= g_htons(pseudo_header
->nettl
.subsys
);
761 rec_hdr
.devid
= g_htonl(pseudo_header
->nettl
.devid
);
762 rec_hdr
.kind
= g_htonl(pseudo_header
->nettl
.kind
);
763 rec_hdr
.pid
= g_htonl(pseudo_header
->nettl
.pid
);
764 rec_hdr
.uid
= g_htons(pseudo_header
->nettl
.uid
);
768 /* found one we don't support */
769 *err
= WTAP_ERR_UNWRITABLE_ENCAP
;
773 if (!wtap_dump_file_write(wdh
, &rec_hdr
, sizeof(rec_hdr
), err
))
776 /* Write out 4 extra bytes of unknown stuff for HP-UX11
779 memset(dummyc
, 0, sizeof dummyc
);
780 if (!wtap_dump_file_write(wdh
, dummyc
, 4, err
))
783 if ((rec
->rec_header
.packet_header
.pkt_encap
== WTAP_ENCAP_FDDI_BITSWAPPED
) ||
784 (rec
->rec_header
.packet_header
.pkt_encap
== WTAP_ENCAP_NETTL_FDDI
)) {
785 /* add those weird 3 bytes of padding */
786 if (!wtap_dump_file_write(wdh
, dummyc
, 3, err
))
790 } else if (rec->rec_header.packet_header.pkt_encap == WTAP_ENCAP_NETTL_X25) {
791 if (!wtap_dump_file_write(wdh, dummyc, 24, err))
796 /* write actual PDU data */
798 if (!wtap_dump_file_write(wdh
, pd
, rec
->rec_header
.packet_header
.caplen
, err
))
804 static const struct supported_block_type nettl_blocks_supported
[] = {
806 * We support packet blocks, with no comments or other options.
808 { WTAP_BLOCK_PACKET
, MULTIPLE_BLOCKS_SUPPORTED
, NO_OPTIONS_SUPPORTED
}
811 static const struct file_type_subtype_info nettl_info
= {
812 "HP-UX nettl trace", "nettl", "trc0", "trc1",
813 false, BLOCKS_SUPPORTED(nettl_blocks_supported
),
814 nettl_dump_can_write_encap
, nettl_dump_open
, NULL
817 void register_nettl(void)
819 nettl_file_type_subtype
= wtap_register_file_type_subtype(&nettl_info
);
822 * Register name for backwards compatibility with the
823 * wtap_filetypes table in Lua.
825 wtap_register_backwards_compatibility_lua_name("NETTL",
826 nettl_file_type_subtype
);
830 * Editor modelines - https://www.wireshark.org/tools/modelines.html
835 * indent-tabs-mode: nil
838 * vi: set shiftwidth=4 tabstop=8 expandtab:
839 * :indentSize=4:tabSize=8:noTabs=true: