4 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
6 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include "file_wrappers.h"
19 * Private per-wtap_t data needed to read a file.
22 GHashTable
*interface_ids
; /* map name/description/link-layer type to interface ID */
23 unsigned num_interface_ids
; /* Number of interface IDs assigned */
26 #define IPTRACE_IFT_HF 0x3d /* Support for PERCS IP-HFI*/
27 #define IPTRACE_IFT_IB 0xc7 /* IP over Infiniband. Number by IANA */
29 static void iptrace_close(wtap
*wth
);
31 static bool iptrace_read_1_0(wtap
*wth
, wtap_rec
*rec
,
32 Buffer
*buf
, int *err
, char **err_info
, int64_t *data_offset
);
33 static bool iptrace_seek_read_1_0(wtap
*wth
, int64_t seek_off
,
34 wtap_rec
*rec
, Buffer
*buf
, int *err
, char **err_info
);
36 static bool iptrace_read_2_0(wtap
*wth
, wtap_rec
*rec
,
37 Buffer
*buf
, int *err
, char **err_info
, int64_t *data_offset
);
38 static bool iptrace_seek_read_2_0(wtap
*wth
, int64_t seek_off
,
39 wtap_rec
*rec
, Buffer
*buf
, int *err
, char **err_info
);
41 static bool iptrace_read_rec_data(FILE_T fh
, Buffer
*buf
,
42 wtap_rec
*rec
, int *err
, char **err_info
);
43 static void fill_in_pseudo_header(int encap
,
44 union wtap_pseudo_header
*pseudo_header
, const char *pkt_text
);
45 static int wtap_encap_ift(unsigned int ift
);
48 * Size of the version string in the file header.
50 #define VERSION_STRING_SIZE 11
53 * Hash table to map interface name and description, and link-layer
54 * type, to interface ID.
59 char prefix
[PREFIX_SIZE
+1];
64 static int iptrace_1_0_file_type_subtype
= -1;
65 static int iptrace_2_0_file_type_subtype
= -1;
67 void register_iptrace(void);
69 static gboolean
destroy_if_info(void *key
, void *value _U_
,
72 if_info
*info
= (if_info
*)key
;
79 static unsigned if_info_hash(const void *info_arg
)
81 if_info
*info
= (if_info
*)info_arg
;
83 return g_str_hash(info
->prefix
) + info
->unit
+ info
->if_type
;
86 static gboolean
if_info_equal(const void *info1_arg
, const void *info2_arg
)
88 if_info
*info1
= (if_info
*)info1_arg
;
89 if_info
*info2
= (if_info
*)info2_arg
;
91 return strcmp(info1
->prefix
, info2
->prefix
) == 0 &&
92 info1
->unit
== info2
->unit
&&
93 info1
->if_type
== info2
->if_type
;
96 wtap_open_return_val
iptrace_open(wtap
*wth
, int *err
, char **err_info
)
98 char version_string
[VERSION_STRING_SIZE
+1];
101 if (!wtap_read_bytes(wth
->fh
, version_string
, VERSION_STRING_SIZE
,
103 if (*err
!= WTAP_ERR_SHORT_READ
)
104 return WTAP_OPEN_ERROR
;
105 return WTAP_OPEN_NOT_MINE
;
107 version_string
[VERSION_STRING_SIZE
] = '\0';
109 if (strcmp(version_string
, "iptrace 1.0") == 0) {
110 wth
->file_type_subtype
= iptrace_1_0_file_type_subtype
;
111 wth
->subtype_read
= iptrace_read_1_0
;
112 wth
->subtype_seek_read
= iptrace_seek_read_1_0
;
113 wth
->file_tsprec
= WTAP_TSPREC_SEC
;
115 else if (strcmp(version_string
, "iptrace 2.0") == 0) {
116 wth
->file_type_subtype
= iptrace_2_0_file_type_subtype
;
117 wth
->subtype_read
= iptrace_read_2_0
;
118 wth
->subtype_seek_read
= iptrace_seek_read_2_0
;
119 wth
->file_tsprec
= WTAP_TSPREC_NSEC
;
122 return WTAP_OPEN_NOT_MINE
;
125 /* This is an iptrace file */
126 wth
->subtype_close
= iptrace_close
;
127 iptrace
= g_new(iptrace_t
, 1);
128 iptrace
->interface_ids
= g_hash_table_new(if_info_hash
, if_info_equal
);
129 iptrace
->num_interface_ids
= 0;
130 wth
->priv
= (void *)iptrace
;
132 return WTAP_OPEN_MINE
;
135 static void iptrace_close(wtap
*wth
)
137 iptrace_t
*iptrace
= (iptrace_t
*)wth
->priv
;
139 g_hash_table_foreach_remove(iptrace
->interface_ids
, destroy_if_info
, NULL
);
140 g_hash_table_destroy(iptrace
->interface_ids
);
143 static void add_new_if_info(iptrace_t
*iptrace
, if_info
*info
, void * *result
)
145 if_info
*new_info
= g_new(if_info
, 1);
147 *result
= GUINT_TO_POINTER(iptrace
->num_interface_ids
);
148 g_hash_table_insert(iptrace
->interface_ids
, (void *)new_info
, *result
);
149 iptrace
->num_interface_ids
++;
152 /***********************************************************
154 ***********************************************************/
157 * iptrace 1.0, discovered through inspection
159 * Packet record contains:
161 * an initial header, with a length field and a time stamp, in
162 * seconds since the Epoch;
164 * data, with the specified length.
168 * a bunch of information about the packet;
170 * padding, at least for FDDI;
172 * the raw packet data.
176 * Offsets of fields in the initial header.
178 #define IPTRACE_1_0_REC_LENGTH_OFFSET 0 /* 0-3: size of record data */
179 #define IPTRACE_1_0_TV_SEC_OFFSET 4 /* 4-7: time stamp, seconds since the Epoch */
181 #define IPTRACE_1_0_PHDR_SIZE 8 /* initial header */
184 * Offsets of fields in the packet information.
186 /* Bytes 0-2 unknown */
187 #define IPTRACE_1_0_UNIT_OFFSET 3 /* 3: interface unit number */
188 #define IPTRACE_1_0_PREFIX_OFFSET 4 /* 4-7: null-terminated name prefix */
189 #define IPTRACE_1_0_PKT_TEXT_OFFSET 8 /* 8-19: text in 2.0; what is it in 1.0? */
190 #define IPTRACE_1_0_IF_TYPE_OFFSET 20 /* 20: SNMP ifType value */
191 #define IPTRACE_1_0_TX_FLAGS_OFFSET 21 /* 21: 0=receive, 1=transmit */
193 #define IPTRACE_1_0_PINFO_SIZE 22 /* packet information */
196 iptrace_read_rec_1_0(wtap
*wth
, FILE_T fh
, wtap_rec
*rec
, Buffer
*buf
,
197 int *err
, char **err_info
)
199 iptrace_t
*iptrace
= (iptrace_t
*)wth
->priv
;
200 uint8_t header
[IPTRACE_1_0_PHDR_SIZE
];
201 uint32_t record_length
;
202 uint8_t pkt_info
[IPTRACE_1_0_PINFO_SIZE
];
204 uint32_t packet_size
;
207 if (!wtap_read_bytes_or_eof(fh
, header
, IPTRACE_1_0_PHDR_SIZE
, err
,
209 /* Read error or EOF */
213 /* Get the record length */
214 record_length
= pntoh32(&header
[IPTRACE_1_0_REC_LENGTH_OFFSET
]);
215 if (record_length
< IPTRACE_1_0_PINFO_SIZE
) {
217 * Uh-oh, the record isn't big enough to even have a
218 * packet information header.
220 *err
= WTAP_ERR_BAD_FILE
;
221 *err_info
= ws_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet information header",
227 * Get the packet information.
229 if (!wtap_read_bytes(fh
, pkt_info
, IPTRACE_1_0_PINFO_SIZE
, err
,
231 /* Read error or EOF */
236 * The if_type field of the frame header appears to be an SNMP
237 * ifType value giving the type of the interface. Check out the
238 * <net/if_types.h> header file.
240 info
.if_type
= pkt_info
[IPTRACE_1_0_IF_TYPE_OFFSET
];
241 rec
->rec_header
.packet_header
.pkt_encap
= wtap_encap_ift(info
.if_type
);
242 if (rec
->rec_header
.packet_header
.pkt_encap
== WTAP_ENCAP_UNKNOWN
) {
243 *err
= WTAP_ERR_UNSUPPORTED
;
244 *err_info
= ws_strdup_printf("iptrace: interface type IFT=0x%02x unknown or unsupported",
249 /* Get the packet data size */
250 packet_size
= record_length
- IPTRACE_1_0_PINFO_SIZE
;
253 * AIX appears to put 3 bytes of padding in front of FDDI
254 * frames; strip that crap off.
256 if (rec
->rec_header
.packet_header
.pkt_encap
== WTAP_ENCAP_FDDI_BITSWAPPED
) {
258 * The packet size is really a record size and includes
261 if (packet_size
< 3) {
263 * Uh-oh, the record isn't big enough to even have
266 *err
= WTAP_ERR_BAD_FILE
;
267 *err_info
= ws_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
276 if (!wtap_read_bytes(fh
, NULL
, 3, err
, err_info
))
279 if (packet_size
> WTAP_MAX_PACKET_SIZE_STANDARD
) {
281 * Probably a corrupt capture file; don't blow up trying
282 * to allocate space for an immensely-large packet.
284 *err
= WTAP_ERR_BAD_FILE
;
285 *err_info
= ws_strdup_printf("iptrace: File has %u-byte packet, bigger than maximum of %u",
286 packet_size
, WTAP_MAX_PACKET_SIZE_STANDARD
);
290 rec
->rec_type
= REC_TYPE_PACKET
;
291 rec
->block
= wtap_block_create(WTAP_BLOCK_PACKET
);
292 rec
->presence_flags
= WTAP_HAS_TS
| WTAP_HAS_INTERFACE_ID
;
293 rec
->rec_header
.packet_header
.len
= packet_size
;
294 rec
->rec_header
.packet_header
.caplen
= packet_size
;
295 rec
->ts
.secs
= pntoh32(&header
[IPTRACE_1_0_TV_SEC_OFFSET
]);
297 wtap_block_add_uint32_option(rec
->block
, OPT_PKT_FLAGS
,
298 pkt_info
[IPTRACE_1_0_TX_FLAGS_OFFSET
] ?
299 (PACK_FLAGS_DIRECTION_OUTBOUND
<< PACK_FLAGS_DIRECTION_SHIFT
) :
300 (PACK_FLAGS_DIRECTION_INBOUND
<< PACK_FLAGS_DIRECTION_SHIFT
));
302 /* Fill in the pseudo-header. */
303 fill_in_pseudo_header(rec
->rec_header
.packet_header
.pkt_encap
,
304 &rec
->rec_header
.packet_header
.pseudo_header
,
305 (const char *)&pkt_info
[IPTRACE_1_0_PKT_TEXT_OFFSET
]);
307 /* Get the packet data */
308 if (!iptrace_read_rec_data(fh
, buf
, rec
, err
, err_info
))
312 * No errors - get the interface ID.
314 * We do *not* trust the name to be null-terminated.
316 memcpy(info
.prefix
, &pkt_info
[IPTRACE_1_0_PREFIX_OFFSET
],
318 info
.prefix
[PREFIX_SIZE
] = '\0';
319 info
.unit
= pkt_info
[IPTRACE_1_0_UNIT_OFFSET
];
322 * Try to find the entry with that name, description, and
325 if (!g_hash_table_lookup_extended(iptrace
->interface_ids
,
326 (const void *)&info
, NULL
, &result
)) {
327 wtap_block_t int_data
;
328 wtapng_if_descr_mandatory_t
*int_data_mand
;
331 * Not found; make a new entry.
333 add_new_if_info(iptrace
, &info
, &result
);
336 * Now make a new IDB and add it.
338 int_data
= wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO
);
339 int_data_mand
= (wtapng_if_descr_mandatory_t
*)wtap_block_get_mandatory_data(int_data
);
341 int_data_mand
->wtap_encap
= rec
->rec_header
.packet_header
.pkt_encap
;
342 int_data_mand
->tsprecision
= WTAP_TSPREC_SEC
;
343 int_data_mand
->time_units_per_second
= 1; /* No fractional time stamp */
344 int_data_mand
->snap_len
= WTAP_MAX_PACKET_SIZE_STANDARD
; /* XXX - not known */
346 wtap_block_add_uint8_option(int_data
, OPT_IDB_TSRESOL
, 0); /* 1-second resolution */
347 /* Interface statistics */
348 int_data_mand
->num_stat_entries
= 0;
349 int_data_mand
->interface_statistics
= NULL
;
351 wtap_block_set_string_option_value_format(int_data
,
352 OPT_IDB_NAME
, "%s%u", info
.prefix
, info
.unit
);
353 wtap_add_idb(wth
, int_data
);
355 rec
->rec_header
.packet_header
.interface_id
= GPOINTER_TO_UINT(result
);
359 /* Read the next packet */
360 static bool iptrace_read_1_0(wtap
*wth
, wtap_rec
*rec
,
361 Buffer
*buf
, int *err
, char **err_info
, int64_t *data_offset
)
363 *data_offset
= file_tell(wth
->fh
);
365 /* Read the packet */
366 if (!iptrace_read_rec_1_0(wth
, wth
->fh
, rec
, buf
, err
, err_info
)) {
367 /* Read error or EOF */
371 /* If the per-file encapsulation isn't known, set it to this
372 packet's encapsulation.
374 If it *is* known, and it isn't this packet's encapsulation,
375 set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
376 have a single encapsulation for all packets in the file. */
377 if (wth
->file_encap
== WTAP_ENCAP_UNKNOWN
)
378 wth
->file_encap
= rec
->rec_header
.packet_header
.pkt_encap
;
380 if (wth
->file_encap
!= rec
->rec_header
.packet_header
.pkt_encap
)
381 wth
->file_encap
= WTAP_ENCAP_PER_PACKET
;
387 static bool iptrace_seek_read_1_0(wtap
*wth
, int64_t seek_off
,
388 wtap_rec
*rec
, Buffer
*buf
, int *err
, char **err_info
)
390 if (file_seek(wth
->random_fh
, seek_off
, SEEK_SET
, err
) == -1)
393 /* Read the packet */
394 if (!iptrace_read_rec_1_0(wth
, wth
->random_fh
, rec
, buf
, err
,
397 *err
= WTAP_ERR_SHORT_READ
;
403 /***********************************************************
405 ***********************************************************/
408 * iptrace 2.0, discovered through inspection
410 * Packet record contains:
412 * an initial header, with a length field and a time stamp, in
413 * seconds since the Epoch;
415 * data, with the specified length.
419 * a bunch of information about the packet;
421 * padding, at least for FDDI;
423 * the raw packet data.
427 * Offsets of fields in the initial header.
429 #define IPTRACE_2_0_REC_LENGTH_OFFSET 0 /* 0-3: size of record data */
430 #define IPTRACE_2_0_TV_SEC0_OFFSET 4 /* 4-7: time stamp, seconds since the Epoch */
432 #define IPTRACE_2_0_PHDR_SIZE 8 /* initial header */
435 * Offsets of fields in the packet information.
437 /* Bytes 0-2 unknown */
438 #define IPTRACE_2_0_UNIT_OFFSET 3 /* 3: interface unit number */
439 #define IPTRACE_2_0_PREFIX_OFFSET 4 /* 4-7: null-terminated name prefix */
440 #define IPTRACE_2_0_PKT_TEXT_OFFSET 8 /* 8-19: text stuff */
441 #define IPTRACE_2_0_IF_TYPE_OFFSET 20 /* 20: SNMP ifType value */
442 #define IPTRACE_2_0_TX_FLAGS_OFFSET 21 /* 21: 0=receive, 1=transmit */
443 /* Bytes 22-23 unknown */
444 #define IPTRACE_2_0_TV_SEC_OFFSET 24 /* 24-27: time stamp, seconds since the Epoch */
445 #define IPTRACE_2_0_TV_NSEC_OFFSET 28 /* 28-31: nanoseconds since that second */
447 #define IPTRACE_2_0_PINFO_SIZE 32 /* packet information */
450 iptrace_read_rec_2_0(wtap
*wth
, FILE_T fh
, wtap_rec
*rec
, Buffer
*buf
,
451 int *err
, char **err_info
)
453 iptrace_t
*iptrace
= (iptrace_t
*)wth
->priv
;
454 uint8_t header
[IPTRACE_2_0_PHDR_SIZE
];
455 uint32_t record_length
;
456 uint8_t pkt_info
[IPTRACE_2_0_PINFO_SIZE
];
458 uint32_t packet_size
;
461 if (!wtap_read_bytes_or_eof(fh
, header
, IPTRACE_2_0_PHDR_SIZE
, err
,
463 /* Read error or EOF */
467 /* Get the record length */
468 record_length
= pntoh32(&header
[IPTRACE_2_0_REC_LENGTH_OFFSET
]);
469 if (record_length
< IPTRACE_2_0_PINFO_SIZE
) {
471 * Uh-oh, the record isn't big enough to even have a
472 * packet information header.
474 *err
= WTAP_ERR_BAD_FILE
;
475 *err_info
= ws_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet information header",
481 * Get the packet information.
483 if (!wtap_read_bytes(fh
, pkt_info
, IPTRACE_2_0_PINFO_SIZE
, err
,
485 /* Read error or EOF */
490 * The if_type field of the frame header appears to be an SNMP
491 * ifType value giving the type of the interface. Check out the
492 * <net/if_types.h> header file.
494 info
.if_type
= pkt_info
[IPTRACE_2_0_IF_TYPE_OFFSET
];
495 rec
->rec_header
.packet_header
.pkt_encap
= wtap_encap_ift(info
.if_type
);
498 * We used to error out if the interface type in iptrace was
499 * unknown/unhandled, but an iptrace may contain packets
500 * from a variety of interfaces, some known, and others
503 * It is better to display the data even for unknown interface
504 * types, isntead of erroring out. In the future, it would be
505 * nice to be able to flag which frames are shown as data
506 * because their interface type is unknown, and also present
507 * the interface type number to the user so that it can be
508 * reported easily back to the Wireshark developer.
510 * XXX - what types are there that are used in files but
511 * that we don't handle?
513 if (rec
->rec_header
.packet_header
.pkt_encap
== WTAP_ENCAP_UNKNOWN
) {
514 *err
= WTAP_ERR_UNSUPPORTED
;
515 *err_info
= ws_strdup_printf("iptrace: interface type IFT=0x%02x unknown or unsupported",
521 /* Get the packet data size */
522 packet_size
= record_length
- IPTRACE_2_0_PINFO_SIZE
;
525 * AIX appears to put 3 bytes of padding in front of FDDI
526 * frames; strip that crap off.
528 if (rec
->rec_header
.packet_header
.pkt_encap
== WTAP_ENCAP_FDDI_BITSWAPPED
) {
530 * The packet size is really a record size and includes
533 if (packet_size
< 3) {
535 * Uh-oh, the record isn't big enough to even have
538 *err
= WTAP_ERR_BAD_FILE
;
539 *err_info
= ws_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
548 if (!wtap_read_bytes(fh
, NULL
, 3, err
, err_info
))
551 if (packet_size
> WTAP_MAX_PACKET_SIZE_STANDARD
) {
553 * Probably a corrupt capture file; don't blow up trying
554 * to allocate space for an immensely-large packet.
556 *err
= WTAP_ERR_BAD_FILE
;
557 *err_info
= ws_strdup_printf("iptrace: File has %u-byte packet, bigger than maximum of %u",
558 packet_size
, WTAP_MAX_PACKET_SIZE_STANDARD
);
562 rec
->rec_type
= REC_TYPE_PACKET
;
563 rec
->block
= wtap_block_create(WTAP_BLOCK_PACKET
);
564 rec
->presence_flags
= WTAP_HAS_TS
| WTAP_HAS_INTERFACE_ID
;
565 rec
->rec_header
.packet_header
.len
= packet_size
;
566 rec
->rec_header
.packet_header
.caplen
= packet_size
;
567 rec
->ts
.secs
= pntoh32(&pkt_info
[IPTRACE_2_0_TV_SEC_OFFSET
]);
568 rec
->ts
.nsecs
= pntoh32(&pkt_info
[IPTRACE_2_0_TV_NSEC_OFFSET
]);
569 wtap_block_add_uint32_option(rec
->block
, OPT_PKT_FLAGS
,
570 pkt_info
[IPTRACE_2_0_TX_FLAGS_OFFSET
] ?
571 (PACK_FLAGS_DIRECTION_OUTBOUND
<< PACK_FLAGS_DIRECTION_SHIFT
) :
572 (PACK_FLAGS_DIRECTION_INBOUND
<< PACK_FLAGS_DIRECTION_SHIFT
));
574 /* Fill in the pseudo-header. */
575 fill_in_pseudo_header(rec
->rec_header
.packet_header
.pkt_encap
,
576 &rec
->rec_header
.packet_header
.pseudo_header
,
577 (const char *)&pkt_info
[IPTRACE_1_0_PKT_TEXT_OFFSET
]);
579 /* Get the packet data */
580 if (!iptrace_read_rec_data(fh
, buf
, rec
, err
, err_info
))
584 * No errors - get the interface ID.
586 * We do *not* trust the name to be null-terminated.
588 memcpy(info
.prefix
, &pkt_info
[IPTRACE_2_0_PREFIX_OFFSET
],
590 info
.prefix
[PREFIX_SIZE
] = '\0';
591 info
.unit
= pkt_info
[IPTRACE_2_0_UNIT_OFFSET
];
594 * Try to find the entry with that name, description, and
597 if (!g_hash_table_lookup_extended(iptrace
->interface_ids
,
598 (const void *)&info
, NULL
, &result
)) {
599 wtap_block_t int_data
;
600 wtapng_if_descr_mandatory_t
*int_data_mand
;
603 * Not found; make a new entry.
605 add_new_if_info(iptrace
, &info
, &result
);
608 * Now make a new IDB and add it.
610 int_data
= wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO
);
611 int_data_mand
= (wtapng_if_descr_mandatory_t
*)wtap_block_get_mandatory_data(int_data
);
613 int_data_mand
->wtap_encap
= rec
->rec_header
.packet_header
.pkt_encap
;
614 int_data_mand
->tsprecision
= WTAP_TSPREC_NSEC
;
615 int_data_mand
->time_units_per_second
= 1000000000; /* Nanosecond resolution */
616 int_data_mand
->snap_len
= WTAP_MAX_PACKET_SIZE_STANDARD
; /* XXX - not known */
618 wtap_block_add_uint8_option(int_data
, OPT_IDB_TSRESOL
, 0x09); /* nanosecond resolution */
619 /* Interface statistics */
620 int_data_mand
->num_stat_entries
= 0;
621 int_data_mand
->interface_statistics
= NULL
;
623 wtap_block_set_string_option_value_format(int_data
,
624 OPT_IDB_NAME
, "%s%u", info
.prefix
, info
.unit
);
625 wtap_add_idb(wth
, int_data
);
627 rec
->rec_header
.packet_header
.interface_id
= GPOINTER_TO_UINT(result
);
631 /* Read the next packet */
632 static bool iptrace_read_2_0(wtap
*wth
, wtap_rec
*rec
,
633 Buffer
*buf
, int *err
, char **err_info
, int64_t *data_offset
)
635 *data_offset
= file_tell(wth
->fh
);
637 /* Read the packet */
638 if (!iptrace_read_rec_2_0(wth
, wth
->fh
, rec
, buf
, err
, err_info
)) {
639 /* Read error or EOF */
643 /* If the per-file encapsulation isn't known, set it to this
644 packet's encapsulation.
646 If it *is* known, and it isn't this packet's encapsulation,
647 set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
648 have a single encapsulation for all packets in the file. */
649 if (wth
->file_encap
== WTAP_ENCAP_UNKNOWN
)
650 wth
->file_encap
= rec
->rec_header
.packet_header
.pkt_encap
;
652 if (wth
->file_encap
!= rec
->rec_header
.packet_header
.pkt_encap
)
653 wth
->file_encap
= WTAP_ENCAP_PER_PACKET
;
659 static bool iptrace_seek_read_2_0(wtap
*wth
, int64_t seek_off
,
660 wtap_rec
*rec
, Buffer
*buf
, int *err
, char **err_info
)
662 if (file_seek(wth
->random_fh
, seek_off
, SEEK_SET
, err
) == -1)
665 /* Read the packet */
666 if (!iptrace_read_rec_2_0(wth
, wth
->random_fh
, rec
, buf
, err
,
669 *err
= WTAP_ERR_SHORT_READ
;
676 iptrace_read_rec_data(FILE_T fh
, Buffer
*buf
, wtap_rec
*rec
,
677 int *err
, char **err_info
)
679 if (!wtap_read_packet_bytes(fh
, buf
, rec
->rec_header
.packet_header
.caplen
, err
, err_info
))
682 if (rec
->rec_header
.packet_header
.pkt_encap
== WTAP_ENCAP_ATM_PDUS
) {
684 * Attempt to guess from the packet data, the VPI,
685 * and the VCI information about the type of traffic.
687 atm_guess_traffic_type(rec
, ws_buffer_start_ptr(buf
));
694 * Fill in the pseudo-header information we can.
696 * For ATM traffic, "iptrace", alas, doesn't tell us what type of traffic
697 * is in the packet - it was presumably run on a machine that was one of
698 * the endpoints of the connection, so in theory it could presumably have
699 * told us, but, for whatever reason, it failed to do so - perhaps the
700 * low-level mechanism that feeds the presumably-AAL5 frames to us doesn't
701 * have access to that information (e.g., because it's in the ATM driver,
702 * and the ATM driver merely knows that stuff on VPI/VCI X.Y should be
703 * handed up to some particular client, it doesn't know what that client is).
705 * We let our caller try to figure out what kind of traffic it is, either
706 * by guessing based on the VPI/VCI, guessing based on the header of the
707 * packet, seeing earlier traffic that set up the circuit and specified
708 * in some fashion what sort of traffic it is, or being told by the user.
711 fill_in_pseudo_header(int encap
, union wtap_pseudo_header
*pseudo_header
,
712 const char *pkt_text
)
721 case WTAP_ENCAP_ATM_PDUS
:
722 /* Rip apart the "x.y" text into Vpi/Vci numbers */
723 memcpy(if_text
, &pkt_text
[4], 8);
725 decimal
= strchr(if_text
, '.');
728 Vpi
= (int)strtoul(if_text
, NULL
, 10);
730 Vci
= (int)strtoul(decimal
, NULL
, 10);
734 * OK, which value means "DTE->DCE" and which value means
737 pseudo_header
->atm
.channel
= pkt_text
[13];
739 pseudo_header
->atm
.vpi
= Vpi
;
740 pseudo_header
->atm
.vci
= Vci
;
742 /* We don't have this information */
743 pseudo_header
->atm
.flags
= 0;
744 pseudo_header
->atm
.cells
= 0;
745 pseudo_header
->atm
.aal5t_u2u
= 0;
746 pseudo_header
->atm
.aal5t_len
= 0;
747 pseudo_header
->atm
.aal5t_chksum
= 0;
750 case WTAP_ENCAP_ETHERNET
:
751 /* We assume there's no FCS in this frame. */
752 pseudo_header
->eth
.fcs_len
= 0;
757 /* Given an RFC1573 (SNMP ifType) interface type,
758 * return the appropriate Wiretap Encapsulation Type.
761 wtap_encap_ift(unsigned int ift
)
764 static const int ift_encap
[] = {
765 /* 0x0 */ WTAP_ENCAP_UNKNOWN
, /* nothing */
766 /* 0x1 */ WTAP_ENCAP_UNKNOWN
, /* IFT_OTHER */
767 /* 0x2 */ WTAP_ENCAP_UNKNOWN
, /* IFT_1822 */
768 /* 0x3 */ WTAP_ENCAP_UNKNOWN
, /* IFT_HDH1822 */
769 /* 0x4 */ WTAP_ENCAP_RAW_IP
, /* IFT_X25DDN */
770 /* 0x5 */ WTAP_ENCAP_UNKNOWN
, /* IFT_X25 */
771 /* 0x6 */ WTAP_ENCAP_ETHERNET
, /* IFT_ETHER */
772 /* 0x7 */ WTAP_ENCAP_ETHERNET
, /* IFT_ISO88023 */
773 /* 0x8 */ WTAP_ENCAP_UNKNOWN
, /* IFT_ISO88024 */
774 /* 0x9 */ WTAP_ENCAP_TOKEN_RING
, /* IFT_ISO88025 */
775 /* 0xa */ WTAP_ENCAP_UNKNOWN
, /* IFT_ISO88026 */
776 /* 0xb */ WTAP_ENCAP_UNKNOWN
, /* IFT_STARLAN */
777 /* 0xc */ WTAP_ENCAP_RAW_IP
, /* IFT_P10, IBM SP switch */
778 /* 0xd */ WTAP_ENCAP_UNKNOWN
, /* IFT_P80 */
779 /* 0xe */ WTAP_ENCAP_UNKNOWN
, /* IFT_HY */
780 /* 0xf */ WTAP_ENCAP_FDDI_BITSWAPPED
, /* IFT_FDDI */
781 /* 0x10 */ WTAP_ENCAP_LAPB
, /* IFT_LAPB */ /* no data to back this up */
782 /* 0x11 */ WTAP_ENCAP_UNKNOWN
, /* IFT_SDLC */
783 /* 0x12 */ WTAP_ENCAP_UNKNOWN
, /* IFT_T1 */
784 /* 0x13 */ WTAP_ENCAP_UNKNOWN
, /* IFT_CEPT */
785 /* 0x14 */ WTAP_ENCAP_UNKNOWN
, /* IFT_ISDNBASIC */
786 /* 0x15 */ WTAP_ENCAP_UNKNOWN
, /* IFT_ISDNPRIMARY */
787 /* 0x16 */ WTAP_ENCAP_UNKNOWN
, /* IFT_PTPSERIAL */
788 /* 0x17 */ WTAP_ENCAP_UNKNOWN
, /* IFT_PPP */
789 /* 0x18 */ WTAP_ENCAP_RAW_IP
, /* IFT_LOOP */
790 /* 0x19 */ WTAP_ENCAP_UNKNOWN
, /* IFT_EON */
791 /* 0x1a */ WTAP_ENCAP_UNKNOWN
, /* IFT_XETHER */
792 /* 0x1b */ WTAP_ENCAP_UNKNOWN
, /* IFT_NSIP */
793 /* 0x1c */ WTAP_ENCAP_UNKNOWN
, /* IFT_SLIP */
794 /* 0x1d */ WTAP_ENCAP_UNKNOWN
, /* IFT_ULTRA */
795 /* 0x1e */ WTAP_ENCAP_UNKNOWN
, /* IFT_DS3 */
796 /* 0x1f */ WTAP_ENCAP_UNKNOWN
, /* IFT_SIP */
797 /* 0x20 */ WTAP_ENCAP_UNKNOWN
, /* IFT_FRELAY */
798 /* 0x21 */ WTAP_ENCAP_UNKNOWN
, /* IFT_RS232 */
799 /* 0x22 */ WTAP_ENCAP_UNKNOWN
, /* IFT_PARA */
800 /* 0x23 */ WTAP_ENCAP_UNKNOWN
, /* IFT_ARCNET */
801 /* 0x24 */ WTAP_ENCAP_UNKNOWN
, /* IFT_ARCNETPLUS */
802 /* 0x25 */ WTAP_ENCAP_ATM_PDUS
, /* IFT_ATM */
804 #define NUM_IFT_ENCAPS array_length(ift_encap)
806 if (ift
< NUM_IFT_ENCAPS
) {
807 return ift_encap
[ift
];
813 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
;
829 return WTAP_ENCAP_UNKNOWN
;
834 /* Options for interface blocks. */
835 static const struct supported_option_type interface_block_options_supported
[] = {
836 /* No comments, just an interface name. */
837 { OPT_IDB_NAME
, ONE_OPTION_SUPPORTED
}
840 static const struct supported_block_type iptrace_1_0_blocks_supported
[] = {
842 * iptrace supports multiple interfaces, with descriptions, and
843 * supports associating packets with interfaces. Interface
844 * description blocks are used for that.
846 { WTAP_BLOCK_IF_ID_AND_INFO
, MULTIPLE_BLOCKS_SUPPORTED
, OPTION_TYPES_SUPPORTED(interface_block_options_supported
) },
849 * iptrace is a capture format, so it obviously supports packets.
850 * It supports no packet options, however.
852 { WTAP_BLOCK_PACKET
, MULTIPLE_BLOCKS_SUPPORTED
, NO_OPTIONS_SUPPORTED
}
855 static const struct file_type_subtype_info iptrace_1_0_info
= {
856 "AIX iptrace 1.0", "iptrace_1", NULL
, NULL
,
857 false, BLOCKS_SUPPORTED(iptrace_1_0_blocks_supported
),
861 static const struct supported_block_type iptrace_2_0_blocks_supported
[] = {
863 * iptrace supports multiple interfaces, with descriptions, and
864 * supports associating packets with interfaces. Interface
865 * description blocks are used for that.
867 { WTAP_BLOCK_IF_ID_AND_INFO
, MULTIPLE_BLOCKS_SUPPORTED
, OPTION_TYPES_SUPPORTED(interface_block_options_supported
) },
870 * iptrace is a capture format, so it obviously supports packets.
871 * It supports no packet options, however.
873 { WTAP_BLOCK_PACKET
, MULTIPLE_BLOCKS_SUPPORTED
, NO_OPTIONS_SUPPORTED
}
876 static const struct file_type_subtype_info iptrace_2_0_info
= {
877 "AIX iptrace 2.0", "iptrace_2", NULL
, NULL
,
878 false, BLOCKS_SUPPORTED(iptrace_2_0_blocks_supported
),
882 void register_iptrace(void)
884 iptrace_1_0_file_type_subtype
= wtap_register_file_type_subtype(&iptrace_1_0_info
);
885 iptrace_2_0_file_type_subtype
= wtap_register_file_type_subtype(&iptrace_2_0_info
);
888 * Register names for backwards compatibility with the
889 * wtap_filetypes table in Lua.
891 wtap_register_backwards_compatibility_lua_name("IPTRACE_1_0",
892 iptrace_1_0_file_type_subtype
);
893 wtap_register_backwards_compatibility_lua_name("IPTRACE_2_0",
894 iptrace_2_0_file_type_subtype
);
898 * Editor modelines - https://www.wireshark.org/tools/modelines.html
903 * indent-tabs-mode: t
906 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
907 * :indentSize=8:tabSize=8:noTabs=false: