summaryrefslogtreecommitdiffstats
path: root/lib/libpcap/libpcap/tests/ngofflinereadtest/ngofflinereadtest.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libpcap/libpcap/tests/ngofflinereadtest/ngofflinereadtest.c')
-rw-r--r--lib/libpcap/libpcap/tests/ngofflinereadtest/ngofflinereadtest.c710
1 files changed, 710 insertions, 0 deletions
diff --git a/lib/libpcap/libpcap/tests/ngofflinereadtest/ngofflinereadtest.c b/lib/libpcap/libpcap/tests/ngofflinereadtest/ngofflinereadtest.c
new file mode 100644
index 0000000..7dbb0e9
--- /dev/null
+++ b/lib/libpcap/libpcap/tests/ngofflinereadtest/ngofflinereadtest.c
@@ -0,0 +1,710 @@
+/*
+ * Copyright (c) 2012-2018 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
+#include "pcap/pcap-ng.h"
+#include <stdio.h>
+#include <err.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libgen.h>
+#include <sysexits.h>
+
+struct section_info {
+ struct section_info *next;
+ struct pcapng_section_header_fields shb;
+ pcap_t *pcap;
+ u_int32_t if_count;
+ struct interface_info *if_list;
+};
+
+struct interface_info {
+ struct interface_info *next;
+ struct pcapng_interface_description_fields idb;
+ struct section_info *section_info;
+ u_int32_t interface_id;
+ char *if_name;
+ char *if_desc;
+};
+
+struct section_info *section_list = NULL;
+struct section_info *current_section = NULL;
+
+int mode_raw = 0;
+int mode_block = 0;
+int mode_pcap = 0;
+int mode_test = 0;
+
+#define PAD32(x) (((x) + 3) & ~3)
+
+void hex_and_ascii_print(const char *, const void *, size_t, const char *);
+
+struct section_info *
+new_section_info(pcap_t *pcap, struct pcapng_section_header_fields *shb)
+{
+ struct section_info *section_info = calloc(1, sizeof(struct section_info));
+
+ if (section_info == NULL)
+ return NULL;
+
+ section_info->pcap = pcap;
+ section_info->shb = *shb;
+
+ if (section_list == NULL) {
+ section_list = section_info;
+ } else {
+ section_info->next = section_list;
+ section_list = section_info;
+ }
+ current_section = section_info;
+
+ return section_info;
+}
+
+void
+interface_option_iterator(pcapng_block_t block, struct pcapng_option_info *option_info, void *context)
+{
+ struct interface_info *interface_info = (struct interface_info *)context;
+
+ switch (option_info->code) {
+ case 0:
+ break;
+
+ case 1:
+ break;
+
+ case 2:
+ interface_info->if_name = malloc(option_info->length + 1);
+ if (interface_info->if_name == NULL)
+ break;
+ snprintf(interface_info->if_name, option_info->length + 1, "%s", option_info->value);
+ break;
+ case 3:
+ interface_info->if_desc = malloc(option_info->length + 1);
+ if (interface_info->if_desc == NULL)
+ break;
+ snprintf(interface_info->if_desc, option_info->length + 1, "%s", option_info->value);
+ break;
+ case 4:
+ break;
+ case 5:
+ break;
+ case 6:
+ break;
+ case 7:
+ break;
+ case 8:
+ break;
+ case 9:
+ break;
+ case 10:
+ break;
+ case 11:
+ break;
+ case 12:
+ break;
+ case 13:
+ break;
+ case 14:
+ break;
+ default:
+ break;
+ }
+}
+
+struct interface_info *
+new_interface_info(struct section_info *section_info, pcapng_block_t block)
+{
+ if (section_info == NULL)
+ return NULL;
+
+ struct interface_info *interface_info = calloc(1, sizeof(struct interface_info));
+
+ if (interface_info == NULL)
+ return NULL;
+
+ interface_info->section_info = section_info;
+ interface_info->interface_id = section_info->if_count;
+ section_info->if_count++;
+ if (section_info->if_list == NULL) {
+ section_info->if_list = interface_info;
+ } else {
+ interface_info->next = section_info->if_list;
+ section_info->if_list = interface_info;
+ }
+ (void) pcnapng_block_iterate_options(block,
+ interface_option_iterator,
+ interface_info);
+
+ return interface_info;
+}
+
+struct interface_info *
+find_interface_info_by_id(u_int16_t interface_id)
+{
+ struct interface_info *interface_info;
+
+ if (current_section == NULL)
+ return (NULL);
+
+ if (interface_id + 1 > current_section->if_count)
+ return (NULL);
+
+ for (interface_info = current_section->if_list;
+ interface_info != NULL;
+ interface_info = interface_info->next) {
+ if (interface_info->interface_id == interface_id)
+ return (interface_info);
+ }
+ return (NULL);
+}
+
+void
+block_option_iterator(pcapng_block_t block, struct pcapng_option_info *option_info, void *context)
+{
+ printf(" block_type %u context %p option_code %u value_len %u value_ptr %p\n",
+ pcap_ng_block_get_type(block), context,
+ option_info->code, option_info->length,
+ option_info->value
+ );
+ switch (option_info->code) {
+ case 0:
+ printf(" opt_endofopt\n");
+ break;
+
+ case 1:
+ printf(" opt_comment: %-*s\n",
+ option_info->length, option_info->value);
+ break;
+
+ default:
+ /*
+ * Each block type has its own option code space
+ */
+ switch (pcap_ng_block_get_type(block)) {
+ case PCAPNG_BT_SHB:
+ switch (option_info->code) {
+ case 2:
+ printf(" shb_hardware: %-*s\n",
+ option_info->length, option_info->value);
+ break;
+ case 3:
+ printf(" shb_os: %-*s\n",
+ option_info->length, option_info->value);
+ break;
+ case 4:
+ printf(" shb_userappl: %-*s\n",
+ option_info->length, option_info->value);
+ break;
+ default:
+ printf(" <unkown shb option>\n");
+ break;
+ }
+ break;
+
+ case PCAPNG_BT_IDB:
+ switch (option_info->code) {
+ case 2:
+ printf(" if_name: %-*s\n",
+ option_info->length, option_info->value);
+ break;
+ case 3:
+ printf(" if_desc: %-*s\n",
+ option_info->length, option_info->value);
+ break;
+ case 4:
+ printf(" if_IPv4addr\n");
+ break;
+ case 5:
+ printf(" if_IPv6addr\n");
+ break;
+ case 6:
+ printf(" if_MACaddr\n");
+ break;
+ case 7:
+ printf(" if_EUIaddr\n");
+ break;
+ case 8:
+ printf(" if_speed\n");
+ break;
+ case 9:
+ printf(" if_tsresol\n");
+ break;
+ case 10:
+ printf(" if_tzone\n");
+ break;
+ case 11:
+ printf(" if_filter %-*s\n",
+ option_info->length, option_info->value);
+ break;
+ case 12:
+ printf(" if_os %-*s\n",
+ option_info->length, option_info->value);
+ break;
+ case 13:
+ printf(" if_fcslen\n");
+ break;
+ case 14:
+ printf(" if_tsoffset\n");
+ break;
+ default:
+ printf(" <unkown idb option>\n");
+ break;
+ }
+ break;
+
+ case PCAPNG_BT_EPB:
+ switch (option_info->code) {
+ case 2:
+ printf(" epb_flags\n");
+ break;
+ case 3:
+ printf(" epb_hash\n");
+ break;
+ case 4:
+ printf(" epb_dropcount\n");
+ break;
+ case PCAPNG_EPB_PIB_INDEX:
+ printf(" epb_pib\n");
+ break;
+ case PCAPNG_EPB_SVC:
+ printf(" epb_svc\n");
+ break;
+ case PCAPNG_EPB_PMD_FLAGS:
+ printf(" epb_pmd_flags\n");
+ break;
+ default:
+ printf(" <unkown epb option>\n");
+ break;
+ }
+ break;
+
+ case PCAPNG_BT_SPB:
+ printf(" <invalid spb option>\n");
+ break;
+
+ case PCAPNG_BT_PB:
+ switch (option_info->code) {
+ case 2:
+ printf(" pack_flags\n");
+ break;
+ case 3:
+ printf(" pack_hash\n");
+ break;
+ default:
+ printf(" <unkown pb option>\n");
+ break;
+ }
+ break;
+
+ case PCAPNG_BT_PIB: {
+ switch (option_info->code) {
+ case 2:
+ printf(" proc_name\n");
+ break;
+ case 3:
+ printf(" proc_path\n");
+ break;
+ case 4:
+ printf(" proc_uuid\n");
+ break;
+ default:
+ printf(" <unkown pib option>\n");
+ break;
+ }
+ break;
+ }
+ case PCAPNG_BT_ISB: {
+ break;
+ }
+ case PCAPNG_BT_NRB: {
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ if (option_info->value) {
+ hex_and_ascii_print(" ", option_info->value, option_info->length, "\n");
+ }
+}
+
+void
+read_callback(u_char *user, const struct pcap_pkthdr *hdr, const u_char *bytes)
+{
+ pcap_t *pcap = (pcap_t *)user;
+ struct pcapng_option_info option_info;
+ u_char *optptr = NULL;
+
+ /* Access the raw block */
+ if (mode_raw) {
+ struct pcapng_block_header *block_header = (struct pcapng_block_header*)bytes;
+
+ printf("raw hdr caplen %u len %u\n", hdr->caplen, hdr->len);
+
+ printf("#\n# user %p hdr.caplen %u hdr.len %u block_header.blocktype 0x%x block_header.totallength %u\n",
+ user, hdr->caplen, hdr->len,
+ block_header->block_type, block_header->total_length);
+
+ hex_and_ascii_print("", bytes, block_header->total_length, "\n");
+
+ switch (block_header->block_type) {
+ case PCAPNG_BT_SHB: {
+ struct pcapng_section_header_fields *shb = (struct pcapng_section_header_fields *)(block_header + 1);
+ printf("# Section Header Block\n");
+ printf(" byte_order_magic 0x%x major_version %u minor_version %u section_length %llu\n",
+ shb->byte_order_magic, shb->major_version, shb->minor_version, shb->section_length);
+
+ hex_and_ascii_print("", shb, sizeof(struct pcapng_section_header_fields), "\n");
+
+ optptr = (u_char *)(shb + 1);
+
+ break;
+ }
+ case PCAPNG_BT_IDB: {
+ struct pcapng_interface_description_fields *idb = (struct pcapng_interface_description_fields *)(block_header + 1);
+ printf("# Interface Description Block\n");
+ printf(" linktype %u reserved %u snaplen %u\n",
+ idb->idb_linktype, idb->idb_reserved, idb->idb_snaplen);
+
+ hex_and_ascii_print("", idb, sizeof(struct pcapng_interface_description_fields), "\n");
+ optptr = (u_char *)(idb + 1);
+
+ break;
+ }
+ case PCAPNG_BT_EPB: {
+ struct pcapng_enhanced_packet_fields *epb = (struct pcapng_enhanced_packet_fields *)(block_header + 1);
+ printf("# Enhanced Packet Block\n");
+ printf(" interface_id %u timestamp_high %u timestamp_low %u caplen %u len %u\n",
+ epb->interface_id, epb->timestamp_high, epb->timestamp_low, epb->caplen, epb->len);
+
+ hex_and_ascii_print("", epb, sizeof(struct pcapng_enhanced_packet_fields), "\n");
+ hex_and_ascii_print("", epb + 1, epb->caplen, "\n");
+
+ optptr = (u_char *)(epb + 1);
+ optptr += PAD32(epb->caplen);
+
+ break;
+ }
+ case PCAPNG_BT_SPB: {
+ struct pcapng_simple_packet_fields *spb = (struct pcapng_simple_packet_fields *)(block_header + 1);
+ printf("# Simple Packet Block\n");
+ printf(" len %u\n",
+ spb->len);
+
+ hex_and_ascii_print("", spb, sizeof(struct pcapng_simple_packet_fields), "\n");
+ hex_and_ascii_print("", spb + 1, spb->len, "\n");
+ break;
+ }
+ case PCAPNG_BT_PB: {
+ struct pcapng_packet_fields *pb = (struct pcapng_packet_fields *)(block_header + 1);
+ printf("# Packet Block\n");
+ printf(" interface_id %u drops_count %u timestamp_high %u timestamp_low %u caplen %u len %u\n",
+ pb->interface_id, pb->drops_count, pb->timestamp_high, pb->timestamp_low, pb->caplen, pb->len);
+
+ hex_and_ascii_print("", pb, sizeof(struct pcapng_packet_fields), "\n");
+
+ hex_and_ascii_print("", pb + 1, pb->caplen, "\n");
+
+ break;
+ }
+ case PCAPNG_BT_PIB: {
+ struct pcapng_process_information_fields *pib = (struct pcapng_process_information_fields *)(block_header + 1);
+ printf("# Process Information Block\n");
+ printf(" process_id %u\n",
+ pib->process_id);
+ hex_and_ascii_print("", pib, sizeof(struct pcapng_process_information_fields), "\n");
+ break;
+ }
+ case PCAPNG_BT_ISB: {
+ printf("# Interface Statistics Block\n");
+ break;
+ }
+ case PCAPNG_BT_NRB: {
+ printf("# Name Record Block\n");
+ break;
+ }
+ case PCAPNG_BT_OSEV: {
+ printf("# Name Record Block\n");
+ break;
+ }
+ case PCAPNG_BT_DSB: {
+ printf("# Decryption Secrets Block\n");
+ break;
+ }
+ default:
+ printf("# Unknown Block\n");
+ break;
+ }
+ if (optptr) {
+ size_t optlen = block_header->total_length - (optptr - bytes);
+
+ hex_and_ascii_print("", optptr, optlen, "\n");
+ }
+
+ }
+ /* Create block object */
+ if (mode_block) {
+ pcapng_block_t block = pcap_ng_block_alloc_with_raw_block(pcap, (u_char *)bytes);
+
+ if (block == NULL) {
+ printf(" pcap_ng_block_alloc_with_raw_block() failed: %s\n", pcap_geterr(pcap));
+ return;
+ }
+
+ switch (pcap_ng_block_get_type(block)) {
+ case PCAPNG_BT_SHB: {
+ struct pcapng_section_header_fields *shb = pcap_ng_get_section_header_fields(block);
+ printf("# Section Header Block\n");
+ printf(" byte_order_magic 0x%x major_version %u minor_version %u section_length %llu\n",
+ shb->byte_order_magic, shb->major_version, shb->minor_version, shb->section_length);
+
+ (void)new_section_info(pcap, shb);
+ break;
+ }
+ case PCAPNG_BT_IDB: {
+ struct pcapng_interface_description_fields *idb = pcap_ng_get_interface_description_fields(block);
+ printf("# Interface Description Block\n");
+ printf(" linktype %u reserved %u snaplen %u\n",
+ idb->idb_linktype, idb->idb_reserved, idb->idb_snaplen);
+ if (pcap_ng_block_get_option(block, PCAPNG_IF_NAME, &option_info) == 1)
+ if (option_info.value)
+ printf(" interface name: %s\n", option_info.value);
+
+ (void)new_interface_info(current_section, block);
+ break;
+ }
+ case PCAPNG_BT_EPB: {
+ struct pcapng_enhanced_packet_fields *epb = pcap_ng_get_enhanced_packet_fields(block);
+ printf("# Enhanced Packet Block\n");
+ printf(" interface_id %u timestamp_high %u timestamp_low %u caplen %u len %u\n",
+ epb->interface_id, epb->timestamp_high, epb->timestamp_low, epb->caplen, epb->len);
+ break;
+ }
+ case PCAPNG_BT_SPB: {
+ struct pcapng_simple_packet_fields *spb = pcap_ng_get_simple_packet_fields(block);
+ printf("# Simple Packet Block\n");
+ printf(" len %u\n",
+ spb->len);
+ break;
+ }
+ case PCAPNG_BT_PB: {
+ struct pcapng_packet_fields *pb = pcap_ng_get_packet_fields(block);
+ printf("# Packet Block\n");
+ printf(" interface_id %u drops_count %u timestamp_high %u timestamp_low %u caplen %u len %u\n",
+ pb->interface_id, pb->drops_count, pb->timestamp_high, pb->timestamp_low, pb->caplen, pb->len);
+ break;
+ }
+ case PCAPNG_BT_PIB: {
+ struct pcapng_process_information_fields *pib = pcap_ng_get_process_information_fields(block);
+ printf("# Process Information Block\n");
+ printf(" process_id %u\n",
+ pib->process_id);
+
+ if (pcap_ng_block_get_option(block, PCAPNG_PIB_NAME, &option_info) == 1) {
+ if (option_info.value)
+ printf(" process name: %s\n", option_info.value);
+ }
+ if (pcap_ng_block_get_option(block, PCAPNG_PIB_UUID, &option_info) == 1) {
+ if (option_info.value) {
+ uuid_string_t uu_str;
+
+ uuid_unparse_lower(option_info.value, uu_str);
+
+ printf(" process uuid: %s\n", uu_str);
+ }
+ }
+break;
+ }
+ case PCAPNG_BT_ISB: {
+ printf("# Interface Statistics Block\n");
+ break;
+ }
+ case PCAPNG_BT_NRB: {
+ printf("# Name Record Block\n");
+ break;
+ }
+ case PCAPNG_BT_OSEV: {
+ struct pcapng_os_event_fields *osev_fields;
+
+ printf("# OS Event Block\n");
+
+ osev_fields = pcap_ng_get_os_event_fields(block);
+
+ printf(" type %u timestamp_high %u timestamp_low %u len %u\n",
+ osev_fields->type,
+ osev_fields->timestamp_high,
+ osev_fields->timestamp_low,
+ osev_fields->len);
+ break;
+ }
+ case PCAPNG_BT_DSB: {
+ struct pcapng_decryption_secrets_fields *dsb_fields;
+
+ printf("# Decryption Secrets Block\n");
+
+ dsb_fields = pcap_ng_get_decryption_secrets_fields(block);
+
+ printf(" secrets_type 0x%x secrets_length %u\n",
+ dsb_fields->secrets_type,
+ dsb_fields->secrets_length);
+
+ break;
+ }
+ default:
+ printf("# Unknown Block\n");
+ break;
+ }
+ if (pcap_ng_block_does_support_data(block)) {
+ hex_and_ascii_print("", pcap_ng_block_packet_get_data_ptr(block), pcap_ng_block_packet_get_data_len(block), "\n");
+ }
+
+ pcnapng_block_iterate_options(block, block_option_iterator, NULL);
+ }
+}
+
+#define SWAPLONG(y) \
+((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
+#define SWAPSHORT(y) \
+( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) )
+#define SWAPLONGLONG(y) \
+(SWAPLONG((unsigned long)(y)) << 32 | SWAPLONG((unsigned long)((y) >> 32)))
+
+void
+test_pcap_ng_fopen_offline(const char *filename, char *errbuf)
+{
+ FILE *fp;
+ off_t offset;
+ pcap_t *pcap;
+
+ fp = fopen(filename, "r");
+ if (fp == NULL) {
+ warn("fopen(%s) failed", filename);
+ return;
+ }
+ offset = ftello(fp);
+
+ pcap = pcap_ng_fopen_offline(fp, errbuf);
+ if (pcap == NULL) {
+ warnx("pcap_ng_fopen_offline(%s) failed: %s\n",
+ filename, errbuf);
+ if (ftello(fp) != offset)
+ errx(EX_OSERR, "pcap_ng_fopen_offline(%s) ftello(fp) (%llu) != offset (%llu)",
+ filename, ftello(fp), offset);
+ } else {
+ pcap_close(pcap);
+ }
+
+ fp = fopen(filename, "r");
+ if (fp == NULL) {
+ warn("fopen(%s) failed", filename);
+ return;
+ }
+ offset = ftello(fp);
+
+ pcap = pcap_fopen_offline(fp, errbuf);
+ if (pcap == NULL) {
+ warnx("pcap_fopen_offline(%s) failed: %s\n",
+ filename, errbuf);
+ if (ftello(fp) != offset)
+ errx(EX_OSERR, "pcap_fopen_offline(%s) ftello(fp) (%llu) != offset (%llu)",
+ filename, ftello(fp), offset);
+ } else {
+ pcap_close(pcap);
+ }
+
+ fclose(fp);
+
+ fprintf(stderr, "TEST PASSED\n");
+}
+
+int
+main(int argc, const char * argv[])
+{
+ int i;
+ char errbuf[PCAP_ERRBUF_SIZE];
+
+ for (i = 1; i < argc; i++) {
+ pcap_t *pcap;
+
+ if (strcmp(argv[i], "-h") == 0) {
+ char *path = strdup((argv[0]));
+ printf("# usage: %s [-raw] [-block] [-pcap] [-test] file\n", getprogname());
+ if (path != NULL)
+ free(path);
+ exit(0);
+ } else if (strcmp(argv[i], "-raw") == 0) {
+ mode_raw = 1;
+ continue;
+ } else if (strcmp(argv[i], "-block") == 0) {
+ mode_block = 1;
+ continue;
+ } else if (strcmp(argv[i], "-pcap") == 0) {
+ mode_pcap = 1;
+ continue;
+ } else if (strcmp(argv[i], "-test") == 0) {
+ mode_test = 1;
+ continue;
+ }
+
+ printf("#\n# opening %s\n#\n", argv[i]);
+
+ if (mode_test != 0) {
+ test_pcap_ng_fopen_offline(argv[i], errbuf);
+ continue;
+ }
+
+ if (mode_block == 0 && mode_raw == 0) {
+ mode_block = 1;
+ }
+ if (mode_pcap == 0) {
+ pcap = pcap_ng_open_offline(argv[i], errbuf);
+ if (pcap == NULL) {
+ warnx("pcap_ng_open_offline(%s) failed: %s\n",
+ argv[i], errbuf);
+ continue;
+ }
+ } else {
+ pcap = pcap_open_offline(argv[i], errbuf);
+ if (pcap == NULL) {
+ warnx("pcap_open_offline(%s) failed: %s\n",
+ argv[i], errbuf);
+ continue;
+ }
+ }
+ int result = pcap_dispatch(pcap, -1, read_callback, (u_char *)pcap);
+ if (result < 0) {
+ warnx("pcap_dispatch failed: %s\n",
+ pcap_statustostr(result));
+ } else {
+ printf("# read %d packets\n", result);
+ }
+ pcap_close(pcap);
+ }
+ return 0;
+}