4 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
6 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "file_wrappers.h"
18 * Private per-wtap_t data needed to read a file.
21 GHashTable
*interface_ids
; /* map name/description/link-layer type to interface ID */
22 unsigned num_interface_ids
; /* Number of interface IDs assigned */
25 #define IPTRACE_IFT_HF 0x3d /* Support for PERCS IP-HFI*/
26 #define IPTRACE_IFT_IB 0xc7 /* IP over Infiniband. Number by IANA */
28 static void iptrace_close(wtap
*wth
);
30 static bool iptrace_read_1_0(wtap
*wth
, wtap_rec
*rec
,
31 Buffer
*buf
, int *err
, char **err_info
, int64_t *data_offset
);
32 static bool iptrace_seek_read_1_0(wtap
*wth
, int64_t seek_off
,
33 wtap_rec
*rec
, Buffer
*buf
, int *err
, char **err_info
);
35 static bool iptrace_read_2_0(wtap
*wth
, wtap_rec
*rec
,
36 Buffer
*buf
, int *err
, char **err_info
, int64_t *data_offset
);
37 static bool iptrace_seek_read_2_0(wtap
*wth
, int64_t seek_off
,
38 wtap_rec
*rec
, Buffer
*buf
, int *err
, char **err_info
);
40 static bool iptrace_read_rec_data(FILE_T fh
, Buffer
*buf
,
41 wtap_rec
*rec
, int *err
, char **err_info
);
42 static void fill_in_pseudo_header(int encap
,
43 union wtap_pseudo_header
*pseudo_header
, const char *pkt_text
);
44 static int wtap_encap_ift(unsigned int ift
);
47 * Size of the version string in the file header.
49 #define VERSION_STRING_SIZE 11
52 * Hash table to map interface name and description, and link-layer
53 * type, to interface ID.
58 char prefix
[PREFIX_SIZE
+1];
63 static int iptrace_1_0_file_type_subtype
= -1;
64 static int iptrace_2_0_file_type_subtype
= -1;
66 void register_iptrace(void);
68 static gboolean
destroy_if_info(void *key
, void *value _U_
,
71 if_info
*info
= (if_info
*)key
;
78 static unsigned if_info_hash(gconstpointer info_arg
)
80 if_info
*info
= (if_info
*)info_arg
;
82 return g_str_hash(info
->prefix
) + info
->unit
+ info
->if_type
;
85 static gboolean
if_info_equal(gconstpointer info1_arg
, gconstpointer info2_arg
)
87 if_info
*info1
= (if_info
*)info1_arg
;
88 if_info
*info2
= (if_info
*)info2_arg
;
90 return strcmp(info1
->prefix
, info2
->prefix
) == 0 &&
91 info1
->unit
== info2
->unit
&&
92 info1
->if_type
== info2
->if_type
;
95 wtap_open_return_val
iptrace_open(wtap
*wth
, int *err
, char **err_info
)
97 char version_string
[VERSION_STRING_SIZE
+1];
100 if (!wtap_read_bytes(wth
->fh
, version_string
, VERSION_STRING_SIZE
,
102 if (*err
!= WTAP_ERR_SHORT_READ
)
103 return WTAP_OPEN_ERROR
;
104 return WTAP_OPEN_NOT_MINE
;
106 version_string
[VERSION_STRING_SIZE
] = '\0';
108 if (strcmp(version_string
, "iptrace 1.0") == 0) {
109 wth
->file_type_subtype
= iptrace_1_0_file_type_subtype
;
110 wth
->subtype_read
= iptrace_read_1_0
;
111 wth
->subtype_seek_read
= iptrace_seek_read_1_0
;
112 wth
->file_tsprec
= WTAP_TSPREC_SEC
;
114 else if (strcmp(version_string
, "iptrace 2.0") == 0) {
115 wth
->file_type_subtype
= iptrace_2_0_file_type_subtype
;
116 wth
->subtype_read
= iptrace_read_2_0
;
117 wth
->subtype_seek_read
= iptrace_seek_read_2_0
;
118 wth
->file_tsprec
= WTAP_TSPREC_NSEC
;
121 return WTAP_OPEN_NOT_MINE
;
124 /* This is an iptrace file */
125 wth
->subtype_close
= iptrace_close
;
126 iptrace
= g_new(iptrace_t
, 1);
127 iptrace
->interface_ids
= g_hash_table_new(if_info_hash
, if_info_equal
);
128 iptrace
->num_interface_ids
= 0;
129 wth
->priv
= (void *)iptrace
;
131 return WTAP_OPEN_MINE
;
134 static void iptrace_close(wtap
*wth
)
136 iptrace_t
*iptrace
= (iptrace_t
*)wth
->priv
;
138 g_hash_table_foreach_remove(iptrace
->interface_ids
, destroy_if_info
, NULL
);
139 g_hash_table_destroy(iptrace
->interface_ids
);
142 static void add_new_if_info(iptrace_t
*iptrace
, if_info
*info
, void * *result
)
144 if_info
*new_info
= g_new(if_info
, 1);
146 *result
= GUINT_TO_POINTER(iptrace
->num_interface_ids
);
147 g_hash_table_insert(iptrace
->interface_ids
, (void *)new_info
, *result
);
148 iptrace
->num_interface_ids
++;
151 /***********************************************************
153 ***********************************************************/
156 * iptrace 1.0, discovered through inspection
158 * Packet record contains:
160 * an initial header, with a length field and a time stamp, in
161 * seconds since the Epoch;
163 * data, with the specified length.
167 * a bunch of information about the packet;
169 * padding, at least for FDDI;
171 * the raw packet data.
175 * Offsets of fields in the initial header.
177 #define IPTRACE_1_0_REC_LENGTH_OFFSET 0 /* 0-3: size of record data */
178 #define IPTRACE_1_0_TV_SEC_OFFSET 4 /* 4-7: time stamp, seconds since the Epoch */
180 #define IPTRACE_1_0_PHDR_SIZE 8 /* initial header */
183 * Offsets of fields in the packet information.
185 /* Bytes 0-2 unknown */
186 #define IPTRACE_1_0_UNIT_OFFSET 3 /* 3: interface unit number */
187 #define IPTRACE_1_0_PREFIX_OFFSET 4 /* 4-7: null-terminated name prefix */
188 #define IPTRACE_1_0_PKT_TEXT_OFFSET 8 /* 8-19: text in 2.0; what is it in 1.0? */
189 #define IPTRACE_1_0_IF_TYPE_OFFSET 20 /* 20: SNMP ifType value */
190 #define IPTRACE_1_0_TX_FLAGS_OFFSET 21 /* 21: 0=receive, 1=transmit */
192 #define IPTRACE_1_0_PINFO_SIZE 22 /* packet information */
195 iptrace_read_rec_1_0(wtap
*wth
, FILE_T fh
, wtap_rec
*rec
, Buffer
*buf
,
196 int *err
, char **err_info
)
198 iptrace_t
*iptrace
= (iptrace_t
*)wth
->priv
;
199 uint8_t header
[IPTRACE_1_0_PHDR_SIZE
];
200 uint32_t record_length
;
201 uint8_t pkt_info
[IPTRACE_1_0_PINFO_SIZE
];
203 uint32_t packet_size
;
206 if (!wtap_read_bytes_or_eof(fh
, header
, IPTRACE_1_0_PHDR_SIZE
, err
,
208 /* Read error or EOF */
212 /* Get the record length */
213 record_length
= pntoh32(&header
[IPTRACE_1_0_REC_LENGTH_OFFSET
]);
214 if (record_length
< IPTRACE_1_0_PINFO_SIZE
) {
216 * Uh-oh, the record isn't big enough to even have a
217 * packet information header.
219 *err
= WTAP_ERR_BAD_FILE
;
220 *err_info
= ws_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet information header",
226 * Get the packet information.
228 if (!wtap_read_bytes(fh
, pkt_info
, IPTRACE_1_0_PINFO_SIZE
, err
,
230 /* Read error or EOF */
235 * The if_type field of the frame header appears to be an SNMP
236 * ifType value giving the type of the interface. Check out the
237 * <net/if_types.h> header file.
239 info
.if_type
= pkt_info
[IPTRACE_1_0_IF_TYPE_OFFSET
];
240 rec
->rec_header
.packet_header
.pkt_encap
= wtap_encap_ift(info
.if_type
);
241 if (rec
->rec_header
.packet_header
.pkt_encap
== WTAP_ENCAP_UNKNOWN
) {
242 *err
= WTAP_ERR_UNSUPPORTED
;
243 *err_info
= ws_strdup_printf("iptrace: interface type IFT=0x%02x unknown or unsupported",
248 /* Get the packet data size */
249 packet_size
= record_length
- IPTRACE_1_0_PINFO_SIZE
;
252 * AIX appears to put 3 bytes of padding in front of FDDI
253 * frames; strip that crap off.
255 if (rec
->rec_header
.packet_header
.pkt_encap
== WTAP_ENCAP_FDDI_BITSWAPPED
) {
257 * The packet size is really a record size and includes
260 if (packet_size
< 3) {
262 * Uh-oh, the record isn't big enough to even have
265 *err
= WTAP_ERR_BAD_FILE
;
266 *err_info
= ws_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
275 if (!wtap_read_bytes(fh
, NULL
, 3, err
, err_info
))
278 if (packet_size
> WTAP_MAX_PACKET_SIZE_STANDARD
) {
280 * Probably a corrupt capture file; don't blow up trying
281 * to allocate space for an immensely-large packet.
283 *err
= WTAP_ERR_BAD_FILE
;
284 *err_info
= ws_strdup_printf("iptrace: File has %u-byte packet, bigger than maximum of %u",
285 packet_size
, WTAP_MAX_PACKET_SIZE_STANDARD
);
289 rec
->rec_type
= REC_TYPE_PACKET
;
290 rec
->block
= wtap_block_create(WTAP_BLOCK_PACKET
);
291 rec
->presence_flags
= WTAP_HAS_TS
| WTAP_HAS_INTERFACE_ID
;
292 rec
->rec_header
.packet_header
.len
= packet_size
;
293 rec
->rec_header
.packet_header
.caplen
= packet_size
;
294 rec
->ts
.secs
= pntoh32(&header
[IPTRACE_1_0_TV_SEC_OFFSET
]);
296 wtap_block_add_uint32_option(rec
->block
, OPT_PKT_FLAGS
,
297 pkt_info
[IPTRACE_1_0_TX_FLAGS_OFFSET
] ?
298 (PACK_FLAGS_DIRECTION_OUTBOUND
<< PACK_FLAGS_DIRECTION_SHIFT
) :
299 (PACK_FLAGS_DIRECTION_INBOUND
<< PACK_FLAGS_DIRECTION_SHIFT
));
301 /* Fill in the pseudo-header. */
302 fill_in_pseudo_header(rec
->rec_header
.packet_header
.pkt_encap
,
303 &rec
->rec_header
.packet_header
.pseudo_header
,
304 (const char *)&pkt_info
[IPTRACE_1_0_PKT_TEXT_OFFSET
]);
306 /* Get the packet data */
307 if (!iptrace_read_rec_data(fh
, buf
, rec
, err
, err_info
))
311 * No errors - get the interface ID.
313 * We do *not* trust the name to be null-terminated.
315 memcpy(info
.prefix
, &pkt_info
[IPTRACE_1_0_PREFIX_OFFSET
],
317 info
.prefix
[PREFIX_SIZE
] = '\0';
318 info
.unit
= pkt_info
[IPTRACE_1_0_UNIT_OFFSET
];
321 * Try to find the entry with that name, description, and
324 if (!g_hash_table_lookup_extended(iptrace
->interface_ids
,
325 (gconstpointer
)&info
, NULL
, &result
)) {
326 wtap_block_t int_data
;
327 wtapng_if_descr_mandatory_t
*int_data_mand
;
330 * Not found; make a new entry.
332 add_new_if_info(iptrace
, &info
, &result
);
335 * Now make a new IDB and add it.
337 int_data
= wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO
);
338 int_data_mand
= (wtapng_if_descr_mandatory_t
*)wtap_block_get_mandatory_data(int_data
);
340 int_data_mand
->wtap_encap
= rec
->rec_header
.packet_header
.pkt_encap
;
341 int_data_mand
->tsprecision
= WTAP_TSPREC_SEC
;
342 int_data_mand
->time_units_per_second
= 1; /* No fractional time stamp */
343 int_data_mand
->snap_len
= WTAP_MAX_PACKET_SIZE_STANDARD
; /* XXX - not known */
345 wtap_block_add_uint8_option(int_data
, OPT_IDB_TSRESOL
, 0); /* 1-second resolution */
346 /* Interface statistics */
347 int_data_mand
->num_stat_entries
= 0;
348 int_data_mand
->interface_statistics
= NULL
;
350 wtap_block_set_string_option_value_format(int_data
,
351 OPT_IDB_NAME
, "%s%u", info
.prefix
, info
.unit
);
352 wtap_add_idb(wth
, int_data
);
354 rec
->rec_header
.packet_header
.interface_id
= GPOINTER_TO_UINT(result
);
358 /* Read the next packet */
359 static bool iptrace_read_1_0(wtap
*wth
, wtap_rec
*rec
,
360 Buffer
*buf
, int *err
, char **err_info
, int64_t *data_offset
)
362 *data_offset
= file_tell(wth
->fh
);
364 /* Read the packet */
365 if (!iptrace_read_rec_1_0(wth
, wth
->fh
, rec
, buf
, err
, err_info
)) {
366 /* Read error or EOF */
370 /* If the per-file encapsulation isn't known, set it to this
371 packet's encapsulation.
373 If it *is* known, and it isn't this packet's encapsulation,
374 set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
375 have a single encapsulation for all packets in the file. */
376 if (wth
->file_encap
== WTAP_ENCAP_UNKNOWN
)
377 wth
->file_encap
= rec
->rec_header
.packet_header
.pkt_encap
;
379 if (wth
->file_encap
!= rec
->rec_header
.packet_header
.pkt_encap
)
380 wth
->file_encap
= WTAP_ENCAP_PER_PACKET
;
386 static bool iptrace_seek_read_1_0(wtap
*wth
, int64_t seek_off
,
387 wtap_rec
*rec
, Buffer
*buf
, int *err
, char **err_info
)
389 if (file_seek(wth
->random_fh
, seek_off
, SEEK_SET
, err
) == -1)
392 /* Read the packet */
393 if (!iptrace_read_rec_1_0(wth
, wth
->random_fh
, rec
, buf
, err
,
396 *err
= WTAP_ERR_SHORT_READ
;
402 /***********************************************************
404 ***********************************************************/
407 * iptrace 2.0, discovered through inspection
409 * Packet record contains:
411 * an initial header, with a length field and a time stamp, in
412 * seconds since the Epoch;
414 * data, with the specified length.
418 * a bunch of information about the packet;
420 * padding, at least for FDDI;
422 * the raw packet data.
426 * Offsets of fields in the initial header.
428 #define IPTRACE_2_0_REC_LENGTH_OFFSET 0 /* 0-3: size of record data */
429 #define IPTRACE_2_0_TV_SEC0_OFFSET 4 /* 4-7: time stamp, seconds since the Epoch */
431 #define IPTRACE_2_0_PHDR_SIZE 8 /* initial header */
434 * Offsets of fields in the packet information.
436 /* Bytes 0-2 unknown */
437 #define IPTRACE_2_0_UNIT_OFFSET 3 /* 3: interface unit number */
438 #define IPTRACE_2_0_PREFIX_OFFSET 4 /* 4-7: null-terminated name prefix */
439 #define IPTRACE_2_0_PKT_TEXT_OFFSET 8 /* 8-19: text stuff */
440 #define IPTRACE_2_0_IF_TYPE_OFFSET 20 /* 20: SNMP ifType value */
441 #define IPTRACE_2_0_TX_FLAGS_OFFSET 21 /* 21: 0=receive, 1=transmit */
442 /* Bytes 22-23 unknown */
443 #define IPTRACE_2_0_TV_SEC_OFFSET 24 /* 24-27: time stamp, seconds since the Epoch */
444 #define IPTRACE_2_0_TV_NSEC_OFFSET 28 /* 28-31: nanoseconds since that second */
446 #define IPTRACE_2_0_PINFO_SIZE 32 /* packet information */
449 iptrace_read_rec_2_0(wtap
*wth
, FILE_T fh
, wtap_rec
*rec
, Buffer
*buf
,
450 int *err
, char **err_info
)
452 iptrace_t
*iptrace
= (iptrace_t
*)wth
->priv
;
453 uint8_t header
[IPTRACE_2_0_PHDR_SIZE
];
454 uint32_t record_length
;
455 uint8_t pkt_info
[IPTRACE_2_0_PINFO_SIZE
];
457 uint32_t packet_size
;
460 if (!wtap_read_bytes_or_eof(fh
, header
, IPTRACE_2_0_PHDR_SIZE
, err
,
462 /* Read error or EOF */
466 /* Get the record length */
467 record_length
= pntoh32(&header
[IPTRACE_2_0_REC_LENGTH_OFFSET
]);
468 if (record_length
< IPTRACE_2_0_PINFO_SIZE
) {
470 * Uh-oh, the record isn't big enough to even have a
471 * packet information header.
473 *err
= WTAP_ERR_BAD_FILE
;
474 *err_info
= ws_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet information header",
480 * Get the packet information.
482 if (!wtap_read_bytes(fh
, pkt_info
, IPTRACE_2_0_PINFO_SIZE
, err
,
484 /* Read error or EOF */
489 * The if_type field of the frame header appears to be an SNMP
490 * ifType value giving the type of the interface. Check out the
491 * <net/if_types.h> header file.
493 info
.if_type
= pkt_info
[IPTRACE_2_0_IF_TYPE_OFFSET
];
494 rec
->rec_header
.packet_header
.pkt_encap
= wtap_encap_ift(info
.if_type
);
497 * We used to error out if the interface type in iptrace was
498 * unknown/unhandled, but an iptrace may contain packets
499 * from a variety of interfaces, some known, and others
502 * It is better to display the data even for unknown interface
503 * types, isntead of erroring out. In the future, it would be
504 * nice to be able to flag which frames are shown as data
505 * because their interface type is unknown, and also present
506 * the interface type number to the user so that it can be
507 * reported easily back to the Wireshark developer.
509 * XXX - what types are there that are used in files but
510 * that we don't handle?
512 if (rec
->rec_header
.packet_header
.pkt_encap
== WTAP_ENCAP_UNKNOWN
) {
513 *err
= WTAP_ERR_UNSUPPORTED
;
514 *err_info
= ws_strdup_printf("iptrace: interface type IFT=0x%02x unknown or unsupported",
520 /* Get the packet data size */
521 packet_size
= record_length
- IPTRACE_2_0_PINFO_SIZE
;
524 * AIX appears to put 3 bytes of padding in front of FDDI
525 * frames; strip that crap off.
527 if (rec
->rec_header
.packet_header
.pkt_encap
== WTAP_ENCAP_FDDI_BITSWAPPED
) {
529 * The packet size is really a record size and includes
532 if (packet_size
< 3) {
534 * Uh-oh, the record isn't big enough to even have
537 *err
= WTAP_ERR_BAD_FILE
;
538 *err_info
= ws_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
547 if (!wtap_read_bytes(fh
, NULL
, 3, err
, err_info
))
550 if (packet_size
> WTAP_MAX_PACKET_SIZE_STANDARD
) {
552 * Probably a corrupt capture file; don't blow up trying
553 * to allocate space for an immensely-large packet.
555 *err
= WTAP_ERR_BAD_FILE
;
556 *err_info
= ws_strdup_printf("iptrace: File has %u-byte packet, bigger than maximum of %u",
557 packet_size
, WTAP_MAX_PACKET_SIZE_STANDARD
);
561 rec
->rec_type
= REC_TYPE_PACKET
;
562 rec
->block
= wtap_block_create(WTAP_BLOCK_PACKET
);
563 rec
->presence_flags
= WTAP_HAS_TS
| WTAP_HAS_INTERFACE_ID
;
564 rec
->rec_header
.packet_header
.len
= packet_size
;
565 rec
->rec_header
.packet_header
.caplen
= packet_size
;
566 rec
->ts
.secs
= pntoh32(&pkt_info
[IPTRACE_2_0_TV_SEC_OFFSET
]);
567 rec
->ts
.nsecs
= pntoh32(&pkt_info
[IPTRACE_2_0_TV_NSEC_OFFSET
]);
568 wtap_block_add_uint32_option(rec
->block
, OPT_PKT_FLAGS
,
569 pkt_info
[IPTRACE_2_0_TX_FLAGS_OFFSET
] ?
570 (PACK_FLAGS_DIRECTION_OUTBOUND
<< PACK_FLAGS_DIRECTION_SHIFT
) :
571 (PACK_FLAGS_DIRECTION_INBOUND
<< PACK_FLAGS_DIRECTION_SHIFT
));
573 /* Fill in the pseudo-header. */
574 fill_in_pseudo_header(rec
->rec_header
.packet_header
.pkt_encap
,
575 &rec
->rec_header
.packet_header
.pseudo_header
,
576 (const char *)&pkt_info
[IPTRACE_1_0_PKT_TEXT_OFFSET
]);
578 /* Get the packet data */
579 if (!iptrace_read_rec_data(fh
, buf
, rec
, err
, err_info
))
583 * No errors - get the interface ID.
585 * We do *not* trust the name to be null-terminated.
587 memcpy(info
.prefix
, &pkt_info
[IPTRACE_2_0_PREFIX_OFFSET
],
589 info
.prefix
[PREFIX_SIZE
] = '\0';
590 info
.unit
= pkt_info
[IPTRACE_2_0_UNIT_OFFSET
];
593 * Try to find the entry with that name, description, and
596 if (!g_hash_table_lookup_extended(iptrace
->interface_ids
,
597 (gconstpointer
)&info
, NULL
, &result
)) {
598 wtap_block_t int_data
;
599 wtapng_if_descr_mandatory_t
*int_data_mand
;
602 * Not found; make a new entry.
604 add_new_if_info(iptrace
, &info
, &result
);
607 * Now make a new IDB and add it.
609 int_data
= wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO
);
610 int_data_mand
= (wtapng_if_descr_mandatory_t
*)wtap_block_get_mandatory_data(int_data
);
612 int_data_mand
->wtap_encap
= rec
->rec_header
.packet_header
.pkt_encap
;
613 int_data_mand
->tsprecision
= WTAP_TSPREC_NSEC
;
614 int_data_mand
->time_units_per_second
= 1000000000; /* Nanosecond resolution */
615 int_data_mand
->snap_len
= WTAP_MAX_PACKET_SIZE_STANDARD
; /* XXX - not known */
617 wtap_block_add_uint8_option(int_data
, OPT_IDB_TSRESOL
, 0x09); /* nanosecond resolution */
618 /* Interface statistics */
619 int_data_mand
->num_stat_entries
= 0;
620 int_data_mand
->interface_statistics
= NULL
;
622 wtap_block_set_string_option_value_format(int_data
,
623 OPT_IDB_NAME
, "%s%u", info
.prefix
, info
.unit
);
624 wtap_add_idb(wth
, int_data
);
626 rec
->rec_header
.packet_header
.interface_id
= GPOINTER_TO_UINT(result
);
630 /* Read the next packet */
631 static bool iptrace_read_2_0(wtap
*wth
, wtap_rec
*rec
,
632 Buffer
*buf
, int *err
, char **err_info
, int64_t *data_offset
)
634 *data_offset
= file_tell(wth
->fh
);
636 /* Read the packet */
637 if (!iptrace_read_rec_2_0(wth
, wth
->fh
, rec
, buf
, err
, err_info
)) {
638 /* Read error or EOF */
642 /* If the per-file encapsulation isn't known, set it to this
643 packet's encapsulation.
645 If it *is* known, and it isn't this packet's encapsulation,
646 set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
647 have a single encapsulation for all packets in the file. */
648 if (wth
->file_encap
== WTAP_ENCAP_UNKNOWN
)
649 wth
->file_encap
= rec
->rec_header
.packet_header
.pkt_encap
;
651 if (wth
->file_encap
!= rec
->rec_header
.packet_header
.pkt_encap
)
652 wth
->file_encap
= WTAP_ENCAP_PER_PACKET
;
658 static bool iptrace_seek_read_2_0(wtap
*wth
, int64_t seek_off
,
659 wtap_rec
*rec
, Buffer
*buf
, int *err
, char **err_info
)
661 if (file_seek(wth
->random_fh
, seek_off
, SEEK_SET
, err
) == -1)
664 /* Read the packet */
665 if (!iptrace_read_rec_2_0(wth
, wth
->random_fh
, rec
, buf
, err
,
668 *err
= WTAP_ERR_SHORT_READ
;
675 iptrace_read_rec_data(FILE_T fh
, Buffer
*buf
, wtap_rec
*rec
,
676 int *err
, char **err_info
)
678 if (!wtap_read_packet_bytes(fh
, buf
, rec
->rec_header
.packet_header
.caplen
, err
, err_info
))
681 if (rec
->rec_header
.packet_header
.pkt_encap
== WTAP_ENCAP_ATM_PDUS
) {
683 * Attempt to guess from the packet data, the VPI,
684 * and the VCI information about the type of traffic.
686 atm_guess_traffic_type(rec
, ws_buffer_start_ptr(buf
));
693 * Fill in the pseudo-header information we can.
695 * For ATM traffic, "iptrace", alas, doesn't tell us what type of traffic
696 * is in the packet - it was presumably run on a machine that was one of
697 * the endpoints of the connection, so in theory it could presumably have
698 * told us, but, for whatever reason, it failed to do so - perhaps the
699 * low-level mechanism that feeds the presumably-AAL5 frames to us doesn't
700 * have access to that information (e.g., because it's in the ATM driver,
701 * and the ATM driver merely knows that stuff on VPI/VCI X.Y should be
702 * handed up to some particular client, it doesn't know what that client is).
704 * We let our caller try to figure out what kind of traffic it is, either
705 * by guessing based on the VPI/VCI, guessing based on the header of the
706 * packet, seeing earlier traffic that set up the circuit and specified
707 * in some fashion what sort of traffic it is, or being told by the user.
710 fill_in_pseudo_header(int encap
, union wtap_pseudo_header
*pseudo_header
,
711 const char *pkt_text
)
720 case WTAP_ENCAP_ATM_PDUS
:
721 /* Rip apart the "x.y" text into Vpi/Vci numbers */
722 memcpy(if_text
, &pkt_text
[4], 8);
724 decimal
= strchr(if_text
, '.');
727 Vpi
= (int)strtoul(if_text
, NULL
, 10);
729 Vci
= (int)strtoul(decimal
, NULL
, 10);
733 * OK, which value means "DTE->DCE" and which value means
736 pseudo_header
->atm
.channel
= pkt_text
[13];
738 pseudo_header
->atm
.vpi
= Vpi
;
739 pseudo_header
->atm
.vci
= Vci
;
741 /* We don't have this information */
742 pseudo_header
->atm
.flags
= 0;
743 pseudo_header
->atm
.cells
= 0;
744 pseudo_header
->atm
.aal5t_u2u
= 0;
745 pseudo_header
->atm
.aal5t_len
= 0;
746 pseudo_header
->atm
.aal5t_chksum
= 0;
749 case WTAP_ENCAP_ETHERNET
:
750 /* We assume there's no FCS in this frame. */
751 pseudo_header
->eth
.fcs_len
= 0;
756 /* Given an RFC1573 (SNMP ifType) interface type,
757 * return the appropriate Wiretap Encapsulation Type.
760 wtap_encap_ift(unsigned int ift
)
763 static const int ift_encap
[] = {
764 /* 0x0 */ WTAP_ENCAP_UNKNOWN
, /* nothing */
765 /* 0x1 */ WTAP_ENCAP_UNKNOWN
, /* IFT_OTHER */
766 /* 0x2 */ WTAP_ENCAP_UNKNOWN
, /* IFT_1822 */
767 /* 0x3 */ WTAP_ENCAP_UNKNOWN
, /* IFT_HDH1822 */
768 /* 0x4 */ WTAP_ENCAP_RAW_IP
, /* IFT_X25DDN */
769 /* 0x5 */ WTAP_ENCAP_UNKNOWN
, /* IFT_X25 */
770 /* 0x6 */ WTAP_ENCAP_ETHERNET
, /* IFT_ETHER */
771 /* 0x7 */ WTAP_ENCAP_ETHERNET
, /* IFT_ISO88023 */
772 /* 0x8 */ WTAP_ENCAP_UNKNOWN
, /* IFT_ISO88024 */
773 /* 0x9 */ WTAP_ENCAP_TOKEN_RING
, /* IFT_ISO88025 */
774 /* 0xa */ WTAP_ENCAP_UNKNOWN
, /* IFT_ISO88026 */
775 /* 0xb */ WTAP_ENCAP_UNKNOWN
, /* IFT_STARLAN */
776 /* 0xc */ WTAP_ENCAP_RAW_IP
, /* IFT_P10, IBM SP switch */
777 /* 0xd */ WTAP_ENCAP_UNKNOWN
, /* IFT_P80 */
778 /* 0xe */ WTAP_ENCAP_UNKNOWN
, /* IFT_HY */
779 /* 0xf */ WTAP_ENCAP_FDDI_BITSWAPPED
, /* IFT_FDDI */
780 /* 0x10 */ WTAP_ENCAP_LAPB
, /* IFT_LAPB */ /* no data to back this up */
781 /* 0x11 */ WTAP_ENCAP_UNKNOWN
, /* IFT_SDLC */
782 /* 0x12 */ WTAP_ENCAP_UNKNOWN
, /* IFT_T1 */
783 /* 0x13 */ WTAP_ENCAP_UNKNOWN
, /* IFT_CEPT */
784 /* 0x14 */ WTAP_ENCAP_UNKNOWN
, /* IFT_ISDNBASIC */
785 /* 0x15 */ WTAP_ENCAP_UNKNOWN
, /* IFT_ISDNPRIMARY */
786 /* 0x16 */ WTAP_ENCAP_UNKNOWN
, /* IFT_PTPSERIAL */
787 /* 0x17 */ WTAP_ENCAP_UNKNOWN
, /* IFT_PPP */
788 /* 0x18 */ WTAP_ENCAP_RAW_IP
, /* IFT_LOOP */
789 /* 0x19 */ WTAP_ENCAP_UNKNOWN
, /* IFT_EON */
790 /* 0x1a */ WTAP_ENCAP_UNKNOWN
, /* IFT_XETHER */
791 /* 0x1b */ WTAP_ENCAP_UNKNOWN
, /* IFT_NSIP */
792 /* 0x1c */ WTAP_ENCAP_UNKNOWN
, /* IFT_SLIP */
793 /* 0x1d */ WTAP_ENCAP_UNKNOWN
, /* IFT_ULTRA */
794 /* 0x1e */ WTAP_ENCAP_UNKNOWN
, /* IFT_DS3 */
795 /* 0x1f */ WTAP_ENCAP_UNKNOWN
, /* IFT_SIP */
796 /* 0x20 */ WTAP_ENCAP_UNKNOWN
, /* IFT_FRELAY */
797 /* 0x21 */ WTAP_ENCAP_UNKNOWN
, /* IFT_RS232 */
798 /* 0x22 */ WTAP_ENCAP_UNKNOWN
, /* IFT_PARA */
799 /* 0x23 */ WTAP_ENCAP_UNKNOWN
, /* IFT_ARCNET */
800 /* 0x24 */ WTAP_ENCAP_UNKNOWN
, /* IFT_ARCNETPLUS */
801 /* 0x25 */ WTAP_ENCAP_ATM_PDUS
, /* IFT_ATM */
803 #define NUM_IFT_ENCAPS (sizeof ift_encap / sizeof ift_encap[0])
805 if (ift
< NUM_IFT_ENCAPS
) {
806 return ift_encap
[ift
];
812 return WTAP_ENCAP_INFINIBAND
;
815 /* Host Fabric Interface */
817 /* The HFI interface on AIX provides raw IP
818 in the packet trace. It's unclear if the HFI
819 can be configured for any other protocol, and if
820 any field in the iptrace header indicates what
821 that protocol is. For now, we are hard-coding
822 this as RAW_IP, but if we find another iptrace file
823 using HFI that provides another protocol, we will
824 have to figure out which field in the iptrace file
826 return WTAP_ENCAP_RAW_IP
;
830 return WTAP_ENCAP_UNKNOWN
;
835 /* Options for interface blocks. */
836 static const struct supported_option_type interface_block_options_supported
[] = {
837 /* No comments, just an interface name. */
838 { OPT_IDB_NAME
, ONE_OPTION_SUPPORTED
}
841 static const struct supported_block_type iptrace_1_0_blocks_supported
[] = {
843 * iptrace supports multiple interfaces, with descriptions, and
844 * supports associating packets with interfaces. Interface
845 * description blocks are used for that.
847 { WTAP_BLOCK_IF_ID_AND_INFO
, MULTIPLE_BLOCKS_SUPPORTED
, OPTION_TYPES_SUPPORTED(interface_block_options_supported
) },
850 * iptrace is a capture format, so it obviously supports packets.
851 * It supports no packet options, however.
853 { WTAP_BLOCK_PACKET
, MULTIPLE_BLOCKS_SUPPORTED
, NO_OPTIONS_SUPPORTED
}
856 static const struct file_type_subtype_info iptrace_1_0_info
= {
857 "AIX iptrace 1.0", "iptrace_1", NULL
, NULL
,
858 false, BLOCKS_SUPPORTED(iptrace_1_0_blocks_supported
),
862 static const struct supported_block_type iptrace_2_0_blocks_supported
[] = {
864 * iptrace supports multiple interfaces, with descriptions, and
865 * supports associating packets with interfaces. Interface
866 * description blocks are used for that.
868 { WTAP_BLOCK_IF_ID_AND_INFO
, MULTIPLE_BLOCKS_SUPPORTED
, OPTION_TYPES_SUPPORTED(interface_block_options_supported
) },
871 * iptrace is a capture format, so it obviously supports packets.
872 * It supports no packet options, however.
874 { WTAP_BLOCK_PACKET
, MULTIPLE_BLOCKS_SUPPORTED
, NO_OPTIONS_SUPPORTED
}
877 static const struct file_type_subtype_info iptrace_2_0_info
= {
878 "AIX iptrace 2.0", "iptrace_2", NULL
, NULL
,
879 false, BLOCKS_SUPPORTED(iptrace_2_0_blocks_supported
),
883 void register_iptrace(void)
885 iptrace_1_0_file_type_subtype
= wtap_register_file_type_subtype(&iptrace_1_0_info
);
886 iptrace_2_0_file_type_subtype
= wtap_register_file_type_subtype(&iptrace_2_0_info
);
889 * Register names for backwards compatibility with the
890 * wtap_filetypes table in Lua.
892 wtap_register_backwards_compatibility_lua_name("IPTRACE_1_0",
893 iptrace_1_0_file_type_subtype
);
894 wtap_register_backwards_compatibility_lua_name("IPTRACE_2_0",
895 iptrace_2_0_file_type_subtype
);
899 * Editor modelines - https://www.wireshark.org/tools/modelines.html
904 * indent-tabs-mode: t
907 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
908 * :indentSize=8:tabSize=8:noTabs=false: