Changeset 3197b50 in mainline for uspace/app/pcapcat/main.c


Ignore:
Timestamp:
2024-12-21T19:18:04Z (10 months ago)
Author:
Nataliia Korop <n.corop08@…>
Children:
373dded
Parents:
fc632e8
Message:

pcapcat utility, without docs and with literals

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/pcapcat/main.c

    rfc632e8 r3197b50  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 //qemu-system-x86_64 -m 256m  -nic   bridge,id=n1,mac=52:54:00:BE:EF:01,br=br0 -boot order=d -cdrom image.iso  -serial stdio
     28
    2929
    3030#include <stdint.h>
     
    3535#include <errno.h>
    3636#include <str.h>
     37#include <getopt.h>
    3738#include <io/log.h>
    38 #include "pcap.h"
     39#include <pcap.h>
     40
     41#include "linktype_parser.h"
     42#include "eth_parser.h"
    3943
    4044#define NAME "pcapcat"
    4145
    42 typedef struct {
    43     uint32_t linktype;
    44     void (*parse)(const char *);
    45 } linktype_parser_t;
     46static const linktype_parser_t eth_parser = {
     47    .parse_packets = &eth_parse_packets,
     48    .parse_file_header = &eth_parse_header,
     49    .linktype = PCAP_LINKTYPE_ETHERNET
     50};
    4651
    47 #define PRINT_IP(msg, ip_addr, spaces) printf("%s IP: %d.%d.%d.%d%s", msg, ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3], spaces)
    48 #define PRINT_MAC(msg, mac, spaces) printf("%s MAC: %x:%x:%x:%x:%x:%x%s", msg, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], spaces)
     52static const linktype_parser_t parsers[1] = {eth_parser};
    4953
    50 static void parse_arp(unsigned char *byte_source, size_t size)
    51 {
    52     uint8_t sender_mac[6];
    53     uint8_t sender_ip[4];
    54     uint8_t target_mac[6];
    55     uint8_t target_ip[4];
    56 
    57     for (int i = 22; i < 28; ++i) {
    58         sender_mac[i - 22] = byte_source[i];
    59     }
    60 
    61     for (int i = 28; i < 32; ++i) {
    62         sender_ip[i - 28] = byte_source[i];
    63     }
    64 
    65     for (int i = 32; i < 38; ++i) {
    66         target_mac[i - 32] = byte_source[i];
    67     }
    68 
    69     for (int i = 38; i < 42; ++i) {
    70         target_ip[i - 38] = byte_source[i];
    71     }
    72 
    73     PRINT_MAC("Sender", sender_mac, ", ");
    74     PRINT_IP("Sender", sender_ip, "  ");
    75     PRINT_MAC("Target", target_mac, ", ");
    76     PRINT_IP("Target", target_ip, "\n");
    77 
    78 }
    79 
    80 static void parse_tcp(unsigned char *byte_source, size_t size)
    81 {
    82     uint16_t src_port = byte_source[34] << 8 | byte_source[35];
    83     uint16_t dst_port = byte_source[36] << 8 | byte_source[37];
    84     printf("      [TCP] source port: %d, destination port: %d\n", src_port, dst_port);
    85 }
    86 
    87 static void parse_ip(unsigned char *byte_source, size_t size)
    88 {
    89     uint16_t total_length;
    90     uint8_t header_length;
    91     uint16_t payload_length;
    92     uint8_t protocol;
    93     uint8_t src_ip[4];
    94     uint8_t dst_ip[4];
    95 
    96     header_length = (byte_source[14] & 0xf) * 4;
    97     total_length = byte_source[16] << 8 | byte_source[17];
    98     payload_length = total_length - header_length;
    99     protocol = byte_source[23];
    100 
    101     for (int i = 26; i < 30; ++i) {
    102         src_ip[i - 26] = byte_source[i];
    103     }
    104     for (int i = 30; i < 34; ++i) {
    105         dst_ip[i - 30] = byte_source[i];
    106     }
    107     printf("IP header: %dB, payload: %dB, protocol: 0x%x, ", header_length, payload_length, protocol);
    108     PRINT_IP("Source", src_ip, ", ");
    109     PRINT_IP("Destination", dst_ip, "\n");
    110 
    111     if (protocol == 0x6) {
    112         parse_tcp(byte_source, size);
    113     }
    114 }
    115 
    116 
    117 static void parse_packet(void *data, size_t size)
    118 {
    119     unsigned char* byte_source = (unsigned char*)data;
    120 
    121     // Read the 12th and 13th bytes (indices 11 and 12)
    122     unsigned char high_byte = byte_source[12]; // MSB
    123     unsigned char low_byte = byte_source[13];  // LSB
    124 
    125     // Combine bytes in big-endian order
    126     uint16_t value = (high_byte << 8) | low_byte;
    127 
    128     switch (value){
    129         case 0x0806:
    130             printf("[ARP] ");
    131             parse_arp(byte_source, size);
    132             break;
    133         case 0x0800:
    134             printf("[IPv4] ");
    135             parse_ip(byte_source, size);
    136             break;
    137         case 0x86DD:
    138             printf("IPv6\n");
    139             break;
    140         default:
    141             printf("0x%x\n", value);
    142             break;
    143     }
    144     //printf("Ethernet Type of packet: 0x%x\n", hdr->etype_len);
    145 }
    146 
    147 static void read_head(FILE *file)
    148 {
    149     pcap_file_header_t data;
    150     memset(&data, 0, sizeof(pcap_file_header_t));
    151 
    152     size_t bytesRead = fread(&data, 1, sizeof(pcap_file_header_t), file);
    153     if (bytesRead < sizeof(pcap_file_header_t)) {
    154         printf("Error: Could not read enough bytes (read %zu bytes)\n", bytesRead);
    155         fclose(file);
    156         return;
    157     }
    158 
    159     printf("LinkType: %d\n", data.additional);
    160     printf("Magic number:  0x%x\n", data.magic_number);
    161     return;
    162 }
    163 
    164 static void eth_parse(const char *file_path)
     54static int parse_file(const char *file_path, int packet_count, bool verbose_flag)
    16555{
    16656    FILE *f = fopen(file_path, "rb");
    16757    if (f == NULL){
    16858        printf("File %s does not exist.\n", file_path);
    169         return;
     59        return 1;
    17060    }
    17161
    172     read_head(f);
     62    pcap_file_header_t hdr;
     63    memset(&hdr, 0, sizeof(pcap_file_header_t));
    17364
    174     pcap_packet_header_t hdr;
    175 
    176     memset(&hdr, 0, sizeof(pcap_packet_header_t));
    177     size_t read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), f);
    178     int index = 1;
    179     while (read_bytes > 0)
    180     {
    181         if (read_bytes < sizeof(pcap_packet_header_t)) {
    182             printf("Error: Could not read enough bytes (read %zu bytes)\n", read_bytes);
    183             return;
    184         }
    185         printf("%04d) ", index);
    186         index++;
    187         //printf("0x%x: %d, %d\n", hdr.magic_stamp, hdr.captured_length, hdr.original_length);
    188         void *data = malloc(hdr.captured_length);
    189         fread(data, 1, (size_t)hdr.captured_length, f);
    190         parse_packet(data, (size_t)hdr.captured_length);
    191         free(data);
    192         read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), f);
     65    size_t bytes_read = fread(&hdr, 1, sizeof(pcap_file_header_t), f);
     66    if (bytes_read < sizeof(pcap_file_header_t)) {
     67        printf("Error: Could not read enough bytes (read %zu bytes)\n", bytes_read);
     68        fclose(f);
     69        return 1;
    19370    }
    19471
    195     fclose(f);
     72    int parser_count = sizeof(parsers) / sizeof(linktype_parser_t);
     73    int parser_index = -1;
     74    for (int i = 0; i < parser_count; ++i) {
     75        if (parsers[i].linktype == hdr.additional) {
     76            parser_index = i;
     77            break;
     78        }
     79    }
     80
     81    if (parser_index == -1) {
     82        printf("There is no parser for Linktype %d.\n", hdr.additional);
     83        return 1;
     84    }
     85
     86    parsers[parser_index].parse_file_header(&hdr);
     87    parsers[parser_index].parse_packets(f, packet_count, verbose_flag);
     88    return 0;
    19689}
    19790
    198 static const linktype_parser_t eth_parser = {
    199     .parse = &eth_parse,
    200     .linktype = PCAP_LINKTYPE_ETHERNET
     91static void usage()
     92{
     93    printf("HelenOS cat utility for PCAP file format.\n"
     94    "Can run during dumping process.\n"
     95    "Usage:\n"
     96    NAME " <filename>\n"
     97    "\tPrint all packets from file <filename>.\n"
     98    NAME " --count= | -c <number> <filename>\n"
     99    "\tPrint first <number> packets from <filename>.\n"
     100    NAME " --verbose | -v <filename>\n"
     101    "\tPrint verbose description (with TCP ports) of packets.\n"
     102    );
     103}
     104
     105static struct option options[] = {
     106    {"count", required_argument, 0, 'c'},
     107    {"verbose", no_argument, 0, 'v'},
     108    {0, 0, 0, 0}
    201109};
    202110
     
    204112int main(int argc, char *argv[])
    205113{
    206     if (argc != 2)
     114    int ret = 0;
     115    int idx = 0;
     116    int count = -1;
     117    bool verbose = false;
     118    const char *filename = "";
     119    if (argc == 1)
    207120    {
    208         return 1;
     121        usage();
     122        return 0;
    209123    }
    210124
    211     eth_parser.parse(argv[1]);
     125    while (ret != -1) {
     126        ret = getopt_long(argc, argv, "c:v", options, &idx);
     127        switch (ret)
     128        {
     129        case 'c':
     130            count = atoi(optarg);
     131            break;
     132        case 'v':
     133            verbose = true;
     134            break;
     135        case '?':
     136            printf("Unknown option or missing argument.\n");
     137            return 1;
     138        default:
     139            break;
     140        }
     141    }
    212142
    213     return 0;
     143    if (optind < argc) {
     144        filename = argv[optind];
     145    }
     146
     147    int ret_val = parse_file(filename, count, verbose);
     148
     149    return ret_val;
    214150}
Note: See TracChangeset for help on using the changeset viewer.