6 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
8 * Enhancements by Mark C. Brown <mbrown@hp.com>
9 * Copyright (C) 2003, 2005 Hewlett-Packard Development Company, L.P.
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #include "file_wrappers.h"
38 static guchar nettl_magic_hpux9[12] = {
39 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xD0, 0x00
41 static guchar nettl_magic_hpux10[12] = {
42 0x54, 0x52, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
45 /* HP nettl file header */
46 struct nettl_file_hdr {
58 /* HP nettl record header for the SX25L2 subsystem - The FCS is not included in the file. */
59 struct nettlrec_sx25l2_hdr {
71 /* HP nettl record header for the NS_LS_IP subsystem */
72 /* This also works for BASE100 and GSC100BT */
73 /* see /usr/include/sys/netdiag1.h for hints */
74 struct nettlrec_ns_ls_ip_hdr {
88 /* Full record header for writing out a nettl file */
89 struct nettlrec_dump_hdr {
92 struct nettlrec_ns_ls_ip_hdr hdr;
96 /* header is followed by data and once again the total length (2 bytes) ! */
100 The following shows what the header looks like for NS_LS_DRIVER
101 The capture was taken on HPUX11 and for a 100baseT interface.
103 000080 00 44 00 0b 00 00 00 02 00 00 00 00 20 00 00 00
104 000090 00 00 00 00 00 00 04 06 00 00 00 00 00 00 00 00
105 0000a0 00 00 00 74 00 00 00 74 3c e3 76 19 00 06 34 63
106 0000b0 ff ff ff ff 00 00 00 00 00 00 00 00 ff ff ff ff
107 0000c0 00 00 00 00 00 00 01 02 00 5c 00 5c ff ff ff ff
108 0000d0 3c e3 76 19 00 06 34 5a 00 0b 00 14 <here starts the MAC heder>
110 Each entry starts with 0x0044000b
112 The values 0x005c at position 0x0000c8 and 0x0000ca matches the number of bytes in
113 the packet up to the next entry, which starts with 0x00440b again. These probably
114 indicate the real and captured length of the packet (order unknown)
116 The values 0x00000074 at positions 0x0000a0 and 0x0000a4 seems to indicate
117 the same number as positions 0x0000c8 and 0x0000ca but added with 24.
118 Perhaps we have here two layers of headers.
119 The first layer is fixed and consists of all the bytes from 0x000084 up to and
120 including 0x0000c3 which is a generic header for all packets captured from any
121 device. This header might be of fixed size 64 bytes and there might be something in
122 it which indicates the type of the next header which is link type specific.
123 Following this header there is another header for the 100baseT interface which
124 in this case is 24 bytes long spanning positions 0x0000c4 to 0x0000db.
126 When someone reports that the loading of the captures breaks, we can compare
127 this header above with what he/she got to learn how to distinguish between different
128 types of link specific headers.
132 The first header seems to be
133 a normal nettlrec_ns_ls_ip_hdr
135 The header for 100baseT seems to be
144 struct nettlrec_ns_ls_drv_eth_hdr {
155 static gboolean nettl_read(wtap *wth, int *err, gchar **err_info,
157 static gboolean nettl_seek_read(wtap *wth, long seek_off,
158 union wtap_pseudo_header *pseudo_header, guchar *pd,
159 int length, int *err, gchar **err_info);
160 static int nettl_read_rec_header(wtap *wth, FILE_T fh,
161 struct wtap_pkthdr *phdr, union wtap_pseudo_header *pseudo_header,
162 int *err, gchar **err_info, gboolean *fddihack);
163 static gboolean nettl_read_rec_data(FILE_T fh, guchar *pd, int length,
164 int *err, gboolean fddihack);
165 static void nettl_close(wtap *wth);
166 static gboolean nettl_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
167 const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err);
169 int nettl_open(wtap *wth, int *err, gchar **err_info _U_)
171 char magic[12], os_vers[2];
176 /* Read in the string that should be at the start of a HP file */
177 errno = WTAP_ERR_CANT_READ;
178 bytes_read = file_read(magic, 1, 12, wth->fh);
179 if (bytes_read != 12) {
180 *err = file_error(wth->fh);
186 if (memcmp(magic, nettl_magic_hpux9, 12) &&
187 memcmp(magic, nettl_magic_hpux10, 12)) {
191 if (file_seek(wth->fh, 0x63, SEEK_SET, err) == -1)
193 wth->data_offset = 0x63;
194 bytes_read = file_read(os_vers, 1, 2, wth->fh);
195 if (bytes_read != 2) {
196 *err = file_error(wth->fh);
202 if (file_seek(wth->fh, 0x80, SEEK_SET, err) == -1)
204 wth->data_offset = 0x80;
206 /* This is an nettl file */
207 wth->file_type = WTAP_FILE_NETTL;
208 wth->capture.nettl = g_malloc(sizeof(nettl_t));
209 if (os_vers[0] == '1' && os_vers[1] == '1')
210 wth->capture.nettl->is_hpux_11 = TRUE;
212 wth->capture.nettl->is_hpux_11 = FALSE;
213 wth->subtype_read = nettl_read;
214 wth->subtype_seek_read = nettl_seek_read;
215 wth->subtype_close = nettl_close;
216 wth->snapshot_length = 0; /* not available in header, only in frame */
218 /* read the first header to take a guess at the file encap */
219 bytes_read = file_read(dummy, 1, 4, wth->fh);
220 if (bytes_read != 4) {
223 if (bytes_read != 0) {
224 *err = WTAP_ERR_SHORT_READ;
230 subsys = g_ntohs(dummy[1]);
232 case NETTL_SUBSYS_HPPB_FDDI :
233 case NETTL_SUBSYS_EISA_FDDI :
234 case NETTL_SUBSYS_PCI_FDDI :
235 case NETTL_SUBSYS_HSC_FDDI :
236 wth->file_encap = WTAP_ENCAP_NETTL_FDDI;
238 case NETTL_SUBSYS_TOKEN :
239 case NETTL_SUBSYS_PCI_TR :
240 wth->file_encap = WTAP_ENCAP_NETTL_TOKEN_RING;
242 case NETTL_SUBSYS_NS_LS_IP :
243 case NETTL_SUBSYS_NS_LS_LOOPBACK :
244 case NETTL_SUBSYS_NS_LS_TCP :
245 case NETTL_SUBSYS_NS_LS_UDP :
246 case NETTL_SUBSYS_NS_LS_IPV6 :
247 wth->file_encap = WTAP_ENCAP_NETTL_RAW_IP;
250 /* If this assumption is bad, the read will catch it */
251 wth->file_encap = WTAP_ENCAP_NETTL_ETHERNET;
254 if (file_seek(wth->fh, 0x80, SEEK_SET, err) == -1)
256 wth->data_offset = 0x80;
261 /* Read the next packet */
262 static gboolean nettl_read(wtap *wth, int *err, gchar **err_info,
266 gboolean fddihack=FALSE;
268 /* Read record header. */
269 *data_offset = wth->data_offset;
270 ret = nettl_read_rec_header(wth, wth->fh, &wth->phdr, &wth->pseudo_header,
271 err, err_info, &fddihack);
273 /* Read error or EOF */
276 wth->data_offset += ret;
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 = wth->phdr.pkt_encap;
289 if (wth->file_encap != wth->phdr.pkt_encap)
290 wth->file_encap = WTAP_ENCAP_PER_PACKET;
294 * Read the packet data.
296 buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);
297 if (!nettl_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer),
298 wth->phdr.caplen, err, fddihack))
299 return FALSE; /* Read error */
300 wth->data_offset += wth->phdr.caplen;
305 nettl_seek_read(wtap *wth, long seek_off,
306 union wtap_pseudo_header *pseudo_header, guchar *pd,
307 int length, int *err, gchar **err_info)
310 struct wtap_pkthdr phdr;
311 gboolean fddihack=FALSE;
313 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
316 /* Read record header. */
317 ret = nettl_read_rec_header(wth, wth->random_fh, &phdr, pseudo_header,
318 err, err_info, &fddihack);
320 /* Read error or EOF */
322 /* EOF means "short read" in random-access mode */
323 *err = WTAP_ERR_SHORT_READ;
329 * Read the packet data.
331 return nettl_read_rec_data(wth->random_fh, pd, length, err, fddihack);
335 nettl_read_rec_header(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
336 union wtap_pseudo_header *pseudo_header, int *err,
337 gchar **err_info, gboolean *fddihack)
340 struct nettlrec_ns_ls_ip_hdr ip_hdr;
341 struct nettlrec_ns_ls_drv_eth_hdr drv_eth_hdr;
349 errno = WTAP_ERR_CANT_READ;
350 bytes_read = file_read(dummy, 1, 4, fh);
351 if (bytes_read != 4) {
352 *err = file_error(fh);
353 if (*err != 0) return -1;
354 if (bytes_read != 0) {
355 *err = WTAP_ERR_SHORT_READ;
362 subsys = g_ntohs(dummy[1]);
364 case NETTL_SUBSYS_LAN100 :
365 case NETTL_SUBSYS_EISA100BT :
366 case NETTL_SUBSYS_BASE100 :
367 case NETTL_SUBSYS_GSC100BT :
368 case NETTL_SUBSYS_PCI100BT :
369 case NETTL_SUBSYS_SPP100BT :
370 case NETTL_SUBSYS_100VG :
371 case NETTL_SUBSYS_GELAN :
372 case NETTL_SUBSYS_BTLAN :
373 case NETTL_SUBSYS_INTL100 :
374 case NETTL_SUBSYS_IGELAN :
375 case NETTL_SUBSYS_IETHER :
376 case NETTL_SUBSYS_IXGBE :
377 case NETTL_SUBSYS_HPPB_FDDI :
378 case NETTL_SUBSYS_EISA_FDDI :
379 case NETTL_SUBSYS_PCI_FDDI :
380 case NETTL_SUBSYS_HSC_FDDI :
381 case NETTL_SUBSYS_TOKEN :
382 case NETTL_SUBSYS_PCI_TR :
383 case NETTL_SUBSYS_NS_LS_IP :
384 case NETTL_SUBSYS_NS_LS_LOOPBACK :
385 case NETTL_SUBSYS_NS_LS_TCP :
386 case NETTL_SUBSYS_NS_LS_UDP :
387 case NETTL_SUBSYS_HP_APAPORT :
388 case NETTL_SUBSYS_HP_APALACP :
389 case NETTL_SUBSYS_NS_LS_IPV6 :
390 case NETTL_SUBSYS_NS_LS_ICMPV6 :
391 case NETTL_SUBSYS_NS_LS_ICMP :
392 if( (subsys == NETTL_SUBSYS_NS_LS_IP)
393 || (subsys == NETTL_SUBSYS_NS_LS_LOOPBACK)
394 || (subsys == NETTL_SUBSYS_NS_LS_UDP)
395 || (subsys == NETTL_SUBSYS_NS_LS_TCP)
396 || (subsys == NETTL_SUBSYS_NS_LS_IPV6)) {
397 phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_IP;
398 } else if (subsys == NETTL_SUBSYS_NS_LS_ICMP) {
399 phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_ICMP;
400 } else if (subsys == NETTL_SUBSYS_NS_LS_ICMPV6) {
401 phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_ICMPV6;
402 } else if( (subsys == NETTL_SUBSYS_HPPB_FDDI)
403 || (subsys == NETTL_SUBSYS_EISA_FDDI)
404 || (subsys == NETTL_SUBSYS_PCI_FDDI)
405 || (subsys == NETTL_SUBSYS_HSC_FDDI) ) {
406 phdr->pkt_encap = WTAP_ENCAP_NETTL_FDDI;
407 } else if( (subsys == NETTL_SUBSYS_PCI_TR)
408 || (subsys == NETTL_SUBSYS_TOKEN) ) {
409 phdr->pkt_encap = WTAP_ENCAP_NETTL_TOKEN_RING;
411 phdr->pkt_encap = WTAP_ENCAP_NETTL_ETHERNET;
414 bytes_read = file_read(&ip_hdr, 1, sizeof ip_hdr, fh);
415 if (bytes_read != sizeof ip_hdr) {
416 *err = file_error(fh);
417 if (*err != 0) return -1;
418 if (bytes_read != 0) {
419 *err = WTAP_ERR_SHORT_READ;
424 offset += sizeof ip_hdr;
426 /* The packet header in HP-UX 11 nettl traces is 4 octets longer than
428 if (wth->capture.nettl->is_hpux_11) {
429 if (file_seek(fh, 4, SEEK_CUR, err) == -1) return -1;
433 /* HPPB FDDI has different inbound vs outbound trace records */
434 if (subsys == NETTL_SUBSYS_HPPB_FDDI) {
435 if (pntohl(&ip_hdr.kind) == NETTL_HDR_PDUIN) {
436 /* inbound is very strange...
437 there are an extra 3 bytes after the DSAP and SSAP
441 length = pntohl(&ip_hdr.length);
442 if (length <= 0) return 0;
444 phdr->caplen = pntohl(&ip_hdr.caplen);
446 /* outbound appears to have variable padding */
447 bytes_read = file_read(dummyc, 1, 9, fh);
448 if (bytes_read != 9) {
449 *err = file_error(fh);
450 if (*err != 0) return -1;
451 if (bytes_read != 0) {
452 *err = WTAP_ERR_SHORT_READ;
457 /* padding is usually either a total 11 or 16 bytes??? */
458 padlen = (int)dummyc[8];
459 if (file_seek(fh, padlen, SEEK_CUR, err) == -1) return -1;
462 length = pntohl(&ip_hdr.length);
463 if (length <= 0) return 0;
464 phdr->len = length - padlen;
465 length = pntohl(&ip_hdr.caplen);
466 phdr->caplen = length - padlen;
468 } else if ( (subsys == NETTL_SUBSYS_PCI_FDDI)
469 || (subsys == NETTL_SUBSYS_EISA_FDDI)
470 || (subsys == NETTL_SUBSYS_HSC_FDDI) ) {
471 /* other flavor FDDI cards have an extra 3 bytes of padding */
472 if (file_seek(fh, 3, SEEK_CUR, err) == -1) return -1;
474 length = pntohl(&ip_hdr.length);
475 if (length <= 0) return 0;
476 phdr->len = length - 3;
477 length = pntohl(&ip_hdr.caplen);
478 phdr->caplen = length - 3;
479 } else if (subsys == NETTL_SUBSYS_NS_LS_LOOPBACK) {
480 /* LOOPBACK has an extra 26 bytes of padding */
481 if (file_seek(fh, 26, SEEK_CUR, err) == -1) return -1;
483 length = pntohl(&ip_hdr.length);
484 if (length <= 0) return 0;
485 phdr->len = length - 26;
486 length = pntohl(&ip_hdr.caplen);
487 phdr->caplen = length - 26;
489 length = pntohl(&ip_hdr.length);
490 if (length <= 0) return 0;
492 phdr->caplen = pntohl(&ip_hdr.caplen);
495 phdr->ts.tv_sec = pntohl(&ip_hdr.sec);
496 phdr->ts.tv_usec = pntohl(&ip_hdr.usec);
499 case NETTL_SUBSYS_NS_LS_DRIVER :
500 bytes_read = file_read(&ip_hdr, 1, sizeof ip_hdr, fh);
501 if (bytes_read != sizeof ip_hdr) {
502 *err = file_error(fh);
503 if (*err != 0) return -1;
504 if (bytes_read != 0) {
505 *err = WTAP_ERR_SHORT_READ;
510 offset += sizeof ip_hdr;
512 /* The packet header in HP-UX 11 nettl traces is 4 octets longer than
514 if (wth->capture.nettl->is_hpux_11) {
515 if (file_seek(fh, 4, SEEK_CUR, err) == -1) return -1;
519 /* XXX we dont know how to identify this as ethernet frames, so
520 we assumes everything is. We will crash and burn for anything else */
521 /* for encapsulated 100baseT we do this */
522 phdr->pkt_encap = WTAP_ENCAP_NETTL_ETHERNET;
523 bytes_read = file_read(&drv_eth_hdr, 1, sizeof drv_eth_hdr, fh);
524 if (bytes_read != sizeof drv_eth_hdr) {
525 *err = file_error(fh);
526 if (*err != 0) return -1;
527 if (bytes_read != 0) {
528 *err = WTAP_ERR_SHORT_READ;
533 offset += sizeof drv_eth_hdr;
535 length = pntohs(&drv_eth_hdr.length);
536 if (length <= 0) return 0;
538 phdr->caplen = pntohs(&drv_eth_hdr.caplen);
540 phdr->ts.tv_sec = pntohl(&ip_hdr.sec);
541 phdr->ts.tv_usec = pntohl(&ip_hdr.usec);
544 case NETTL_SUBSYS_SX25L2:
545 case NETTL_SUBSYS_SX25L3:
546 bytes_read = file_read(&ip_hdr, 1, sizeof ip_hdr, fh);
547 if (bytes_read != sizeof ip_hdr) {
548 *err = file_error(fh);
549 if (*err != 0) return -1;
550 if (bytes_read != 0) {
551 *err = WTAP_ERR_SHORT_READ;
556 offset += sizeof ip_hdr;
557 length = pntohl(&ip_hdr.length);
558 if (length <= 0) return 0;
559 phdr->len = length - 24;
560 phdr->caplen = pntohl(&ip_hdr.caplen) - 24;
561 phdr->ts.tv_sec = pntohl(&ip_hdr.sec);
562 phdr->ts.tv_usec = pntohl(&ip_hdr.usec);
563 if (wth->capture.nettl->is_hpux_11)
567 if (file_seek(fh, padlen, SEEK_CUR, err) == -1) return -1;
569 phdr->pkt_encap = WTAP_ENCAP_NETTL_X25;
573 wth->file_encap = WTAP_ENCAP_PER_PACKET;
574 phdr->pkt_encap = WTAP_ENCAP_NETTL_UNKNOWN;
575 bytes_read = file_read(&ip_hdr, 1, sizeof ip_hdr, fh);
576 if (bytes_read != sizeof ip_hdr) {
577 *err = file_error(fh);
578 if (*err != 0) return -1;
579 if (bytes_read != 0) {
580 *err = WTAP_ERR_SHORT_READ;
585 offset += sizeof ip_hdr;
586 length = pntohl(&ip_hdr.length);
587 if (length <= 0) return 0;
589 phdr->caplen = pntohl(&ip_hdr.caplen);
590 phdr->ts.tv_sec = pntohl(&ip_hdr.sec);
591 phdr->ts.tv_usec = pntohl(&ip_hdr.usec);
592 if (wth->capture.nettl->is_hpux_11) {
593 if (file_seek(fh, 4, SEEK_CUR, err) == -1) return -1;
598 pseudo_header->nettl.subsys = subsys;
599 pseudo_header->nettl.devid = pntohl(&ip_hdr.devid);
600 pseudo_header->nettl.kind = pntohl(&ip_hdr.kind);
601 pseudo_header->nettl.pid = pntohl(&ip_hdr.pid);
602 pseudo_header->nettl.uid = pntohs(&ip_hdr.uid);
608 nettl_read_rec_data(FILE_T fh, guchar *pd, int length, int *err, gboolean fddihack)
614 if (fddihack == TRUE) {
615 /* read in FC, dest, src, DSAP and SSAP */
616 if (file_read(pd, 1, 15, fh) == 15) {
617 if (pd[13] == 0xAA) {
618 /* it's SNAP, have to eat 3 bytes??? */
619 if (file_read(dummy, 1, 3, fh) == 3) {
621 bytes_read = file_read(p, 1, length-18, fh);
629 bytes_read = file_read(p, 1, length-15, fh);
635 bytes_read = file_read(pd, 1, length, fh);
637 if (bytes_read != length) {
638 *err = file_error(fh);
640 *err = WTAP_ERR_SHORT_READ;
646 static void nettl_close(wtap *wth)
648 g_free(wth->capture.nettl);
652 /* Returns 0 if we could write the specified encapsulation type,
653 an error indication otherwise. nettl files are WTAP_ENCAP_UNKNOWN
654 when they are first opened, so we allow that for tethereal read/write.
657 int nettl_dump_can_write_encap(int encap)
661 case WTAP_ENCAP_ETHERNET:
662 case WTAP_ENCAP_FDDI_BITSWAPPED:
663 case WTAP_ENCAP_TOKEN_RING:
664 case WTAP_ENCAP_NETTL_ETHERNET:
665 case WTAP_ENCAP_NETTL_FDDI:
666 case WTAP_ENCAP_NETTL_TOKEN_RING:
667 case WTAP_ENCAP_NETTL_RAW_IP:
668 case WTAP_ENCAP_NETTL_RAW_ICMP:
669 case WTAP_ENCAP_NETTL_RAW_ICMPV6:
671 case WTAP_ENCAP_NETTL_X25:
673 case WTAP_ENCAP_PER_PACKET:
674 case WTAP_ENCAP_UNKNOWN:
675 case WTAP_ENCAP_NETTL_UNKNOWN:
678 return WTAP_ERR_UNSUPPORTED_ENCAP;
683 /* Returns TRUE on success, FALSE on failure;
684 sets "*err" to an error code on failure */
685 gboolean nettl_dump_open(wtap_dumper *wdh, gboolean cant_seek _U_, int *err)
687 struct nettl_file_hdr file_hdr;
690 /* This is a nettl file */
691 wdh->subtype_write = nettl_dump;
692 wdh->subtype_close = NULL;
694 /* Write the file header. */
695 memset(&file_hdr,0,sizeof(file_hdr));
696 memcpy(file_hdr.magic,nettl_magic_hpux10,sizeof(file_hdr.magic));
697 strcpy(file_hdr.file_name,"/tmp/ethereal.TRC000");
698 strcpy(file_hdr.tz,"UTC");
699 strcpy(file_hdr.host_name,"ethereal");
700 strcpy(file_hdr.os_vers,"B.11.11");
702 strcpy(file_hdr.model,"9000/800");
703 file_hdr.unknown=g_htons(0x406);
704 nwritten = fwrite(&file_hdr, 1, sizeof file_hdr, wdh->fh);
705 if (nwritten != sizeof(file_hdr)) {
706 if (nwritten == 0 && ferror(wdh->fh))
709 *err = WTAP_ERR_SHORT_WRITE;
712 wdh->bytes_dumped += sizeof(file_hdr);
717 /* Write a record for a packet to a dump file.
718 Returns TRUE on success, FALSE on failure. */
719 static gboolean nettl_dump(wtap_dumper *wdh,
720 const struct wtap_pkthdr *phdr,
721 const union wtap_pseudo_header *pseudo_header _U_,
722 const guchar *pd, int *err)
724 struct nettlrec_dump_hdr rec_hdr;
728 memset(&rec_hdr,0,sizeof(rec_hdr));
729 rec_hdr.hdr_len = g_htons(sizeof(rec_hdr));
730 rec_hdr.hdr.kind = g_htonl(NETTL_HDR_PDUIN);
731 rec_hdr.hdr.sec = g_htonl(phdr->ts.tv_sec);
732 rec_hdr.hdr.usec = g_htonl(phdr->ts.tv_usec);
733 rec_hdr.hdr.caplen = g_htonl(phdr->caplen);
734 rec_hdr.hdr.length = g_htonl(phdr->len);
735 rec_hdr.hdr.devid = -1;
736 rec_hdr.hdr.pid = -1;
737 rec_hdr.hdr.uid = -1;
739 switch (phdr->pkt_encap) {
741 case WTAP_ENCAP_NETTL_FDDI:
742 /* account for pad bytes */
743 rec_hdr.hdr.caplen = g_htonl(phdr->caplen + 3);
744 rec_hdr.hdr.length = g_htonl(phdr->len + 3);
745 /* fall through and fill the rest of the fields */
746 case WTAP_ENCAP_NETTL_ETHERNET:
747 case WTAP_ENCAP_NETTL_TOKEN_RING:
748 case WTAP_ENCAP_NETTL_RAW_IP:
749 case WTAP_ENCAP_NETTL_RAW_ICMP:
750 case WTAP_ENCAP_NETTL_RAW_ICMPV6:
751 case WTAP_ENCAP_NETTL_UNKNOWN:
752 rec_hdr.subsys = g_htons(pseudo_header->nettl.subsys);
753 rec_hdr.hdr.devid = g_htonl(pseudo_header->nettl.devid);
754 rec_hdr.hdr.kind = g_htonl(pseudo_header->nettl.kind);
755 rec_hdr.hdr.pid = g_htonl(pseudo_header->nettl.pid);
756 rec_hdr.hdr.uid = g_htons(pseudo_header->nettl.uid);
759 case WTAP_ENCAP_RAW_IP:
760 rec_hdr.subsys = g_htons(NETTL_SUBSYS_NS_LS_IP);
763 case WTAP_ENCAP_ETHERNET:
764 rec_hdr.subsys = g_htons(NETTL_SUBSYS_BTLAN);
767 case WTAP_ENCAP_FDDI_BITSWAPPED:
768 rec_hdr.subsys = g_htons(NETTL_SUBSYS_PCI_FDDI);
769 /* account for pad bytes */
770 rec_hdr.hdr.caplen = g_htonl(phdr->caplen + 3);
771 rec_hdr.hdr.length = g_htonl(phdr->len + 3);
774 case WTAP_ENCAP_TOKEN_RING:
775 rec_hdr.subsys = g_htons(NETTL_SUBSYS_PCI_TR);
778 case WTAP_ENCAP_NETTL_X25:
779 rec_hdr.hdr.caplen = g_htonl(phdr->caplen + 24);
780 rec_hdr.hdr.length = g_htonl(phdr->len + 24);
781 rec_hdr.subsys = g_htons(pseudo_header->nettl.subsys);
782 rec_hdr.hdr.devid = g_htonl(pseudo_header->nettl.devid);
783 rec_hdr.hdr.kind = g_htonl(pseudo_header->nettl.kind);
784 rec_hdr.hdr.pid = g_htonl(pseudo_header->nettl.pid);
785 rec_hdr.hdr.uid = g_htons(pseudo_header->nettl.uid);
789 /* found one we don't support */
790 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
794 nwritten = fwrite(&rec_hdr, 1, sizeof(rec_hdr), wdh->fh);
795 if (nwritten != sizeof(rec_hdr)) {
796 if (nwritten == 0 && ferror(wdh->fh))
799 *err = WTAP_ERR_SHORT_WRITE;
802 wdh->bytes_dumped += sizeof(rec_hdr);
804 if ((phdr->pkt_encap == WTAP_ENCAP_FDDI_BITSWAPPED) ||
805 (phdr->pkt_encap == WTAP_ENCAP_NETTL_FDDI)) {
806 /* add those weird 3 bytes of padding */
807 nwritten = fwrite(&padding, 1, 3, wdh->fh);
809 if (nwritten == 0 && ferror(wdh->fh))
812 *err = WTAP_ERR_SHORT_WRITE;
815 wdh->bytes_dumped += 3;
818 } else if (phdr->pkt_encap == WTAP_ENCAP_NETTL_X25) {
819 nwritten = fwrite(&padding, 1, 24, wdh->fh);
820 if (nwritten != 24) {
821 if (nwritten == 0 && ferror(wdh->fh))
824 *err = WTAP_ERR_SHORT_WRITE;
827 wdh->bytes_dumped += 24;
831 /* write actual PDU data */
833 nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
834 if (nwritten != phdr->caplen) {
835 if (nwritten == 0 && ferror(wdh->fh))
838 *err = WTAP_ERR_SHORT_WRITE;
841 wdh->bytes_dumped += phdr->caplen;