/* * Copyright (c) 2024 Nataliia Korop * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include "linktype_parser.h" #include "eth_parser.h" #define NAME "pcapcat" static const linktype_parser_t eth_parser = { .parse_packets = ð_parse_packets, .parse_file_header = ð_parse_header, .linktype = PCAP_LINKTYPE_ETHERNET }; static const linktype_parser_t parsers[1] = {eth_parser}; static int parse_file(const char *file_path, int packet_count, bool verbose_flag) { FILE *f = fopen(file_path, "rb"); if (f == NULL){ printf("File %s does not exist.\n", file_path); return 1; } pcap_file_header_t hdr; memset(&hdr, 0, sizeof(pcap_file_header_t)); size_t bytes_read = fread(&hdr, 1, sizeof(pcap_file_header_t), f); if (bytes_read < sizeof(pcap_file_header_t)) { printf("Error: Could not read enough bytes (read %zu bytes)\n", bytes_read); fclose(f); return 1; } int parser_count = sizeof(parsers) / sizeof(linktype_parser_t); int parser_index = -1; for (int i = 0; i < parser_count; ++i) { if (parsers[i].linktype == hdr.additional) { parser_index = i; break; } } if (parser_index == -1) { printf("There is no parser for Linktype %d.\n", hdr.additional); return 1; } parsers[parser_index].parse_file_header(&hdr); parsers[parser_index].parse_packets(f, packet_count, verbose_flag); return 0; } static void usage() { printf("HelenOS cat utility for PCAP file format.\n" "Can run during dumping process.\n" "Usage:\n" NAME " \n" "\tPrint all packets from file .\n" NAME " --count= | -c \n" "\tPrint first packets from .\n" NAME " --verbose | -v \n" "\tPrint verbose description (with TCP ports) of packets.\n" ); } static struct option options[] = { {"count", required_argument, 0, 'c'}, {"verbose", no_argument, 0, 'v'}, {0, 0, 0, 0} }; int main(int argc, char *argv[]) { int ret = 0; int idx = 0; int count = -1; bool verbose = false; const char *filename = ""; if (argc == 1) { usage(); return 0; } while (ret != -1) { ret = getopt_long(argc, argv, "c:v", options, &idx); switch (ret) { case 'c': count = atoi(optarg); break; case 'v': verbose = true; break; case '?': printf("Unknown option or missing argument.\n"); return 1; default: break; } } if (optind < argc) { filename = argv[optind]; } int ret_val = parse_file(filename, count, verbose); return ret_val; }