Changeset caac052 in mainline


Ignore:
Timestamp:
2024-12-22T16:47:50Z (10 months ago)
Author:
Nataliia Korop <n.corop08@…>
Children:
46e2152
Parents:
373dded
Message:

pcapcat: docs, no literals, time fix in pcap lib

Location:
uspace
Files:
1 added
8 edited

Legend:

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

    r373dded rcaac052  
    2727 */
    2828
     29/** @addtogroup pcapcat
     30 * @{
     31 */
     32/** @file Implementation of functions for parsing PCAP file of LinkType 1 (LINKTYPE_ETHERNET).
     33 */
    2934
    3035#include <stdint.h>
    3136#include <stdio.h>
    3237#include <stdlib.h>
    33 #include <time.h>
    3438#include <stdbool.h>
    35 #include <errno.h>
    3639#include <str.h>
    37 #include <io/log.h>
    38 #include "pcap.h"
     40#include <pcap.h>
    3941#include "eth_parser.h"
    4042
    4143#define ETH_ADDR_SIZE       6
    4244#define IPV4_ADDR_SIZE      4
     45#define TCP_PORT_SIZE       2
    4346
    4447#define ETHER_TYPE_ARP      0x0806
     
    4750
    4851#define BYTE_SIZE           8
     52#define HDR_SIZE_COEF       4
     53#define LOWER_4_BITS        0xf
    4954
    5055#define IP_PROTOCOL_TCP     0x06
     
    5863#define IPV4_TEXT           "IPv4"
    5964#define IPV6_TEXT           "IPv6"
     65#define MALFORMED_PACKET    "packet is malformed.\n"
    6066
    6167#define PRINT_IP(msg, ip_addr, spaces) printf("%s %s: %d.%d.%d.%d%s", msg, IP_TEXT, ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3], spaces)
     
    6369#define BIG_END_16(buffer, idx) buffer[idx] << BYTE_SIZE | buffer[idx + 1]
    6470
    65 
    66 static void read_from_buffer(unsigned char *buffer, int start_idx, int count, uint8_t *dst)
    67 {
    68     for (int i = start_idx; i < start_idx + count; ++i) {
     71/** Read count bytes from char buffer.
     72 *  @param buffer       of bytes to read from.
     73 *  @param start_idx    index of the first byte to read.
     74 *  @param count        number of byte to read.
     75 *  @param dst          destination buffer.
     76 */
     77static void read_from_buffer(unsigned char *buffer, size_t start_idx, size_t count, uint8_t *dst)
     78{
     79    for (size_t i = start_idx; i < start_idx + count; ++i) {
    6980        dst[i - start_idx] = buffer[i];
    7081    }
    7182}
    7283
    73 static void parse_arp(unsigned char *byte_source, size_t size)
    74 {
     84/** Parse ARP packet and print out addresses.
     85 *  @param buffer   ARP packet.
     86 *  @param size     Size of the packet.
     87 */
     88static void parse_arp(unsigned char *buffer, size_t size)
     89{
     90    size_t sender_mac_offset = 22;
     91    size_t sender_ip_offset = 28;
     92    size_t target_mac_offset = 32;
     93    size_t target_ip_offset = 38;
     94    if (size < target_ip_offset + IPV4_ADDR_SIZE) {
     95        printf("%s %s", ARP_TEXT, MALFORMED_PACKET);
     96        return;
     97    }
     98
    7599    uint8_t sender_mac[ETH_ADDR_SIZE];
    76100    uint8_t sender_ip[IPV4_ADDR_SIZE];
     
    78102    uint8_t target_ip[IPV4_ADDR_SIZE];
    79103
    80     read_from_buffer(byte_source, 22, ETH_ADDR_SIZE, sender_mac);
    81     read_from_buffer(byte_source, 28, IPV4_ADDR_SIZE, sender_ip);
    82     read_from_buffer(byte_source, 32, ETH_ADDR_SIZE, target_mac);
    83     read_from_buffer(byte_source, 36, IPV4_ADDR_SIZE, target_ip);
     104    read_from_buffer(buffer, sender_mac_offset, ETH_ADDR_SIZE, sender_mac);
     105    read_from_buffer(buffer, sender_ip_offset, IPV4_ADDR_SIZE, sender_ip);
     106    read_from_buffer(buffer, target_mac_offset, ETH_ADDR_SIZE, target_mac);
     107    read_from_buffer(buffer, target_ip_offset, IPV4_ADDR_SIZE, target_ip);
    84108
    85109    PRINT_MAC("Sender", sender_mac, ", ");
     
    87111    PRINT_MAC("Target", target_mac, ", ");
    88112    PRINT_IP("Target", target_ip, "\n");
    89 
    90 }
    91 
    92 static void parse_tcp(unsigned char *byte_source, size_t size)
    93 {
    94     uint16_t src_port = BIG_END_16(byte_source, 34);
    95     uint16_t dst_port = BIG_END_16(byte_source, 36);
     113}
     114
     115/** Parce TCP and print ports.
     116 *  @param buffer   TCP segment.
     117 *  @param size     of the buffer.
     118 */
     119static void parse_tcp(unsigned char *buffer, size_t size)
     120{
     121    size_t src_port_offset = 34;
     122    size_t dst_port_offset = 36;
     123
     124    if (size < dst_port_offset + TCP_PORT_SIZE) {
     125        printf("%s %s\n", TCP_TEXT, MALFORMED_PACKET);
     126        return;
     127    }
     128
     129    uint16_t src_port = BIG_END_16(buffer, src_port_offset);
     130    uint16_t dst_port = BIG_END_16(buffer, dst_port_offset);
    96131    printf("      [%s] source port: %d, destination port: %d\n", TCP_TEXT, src_port, dst_port);
    97132}
    98133
    99 static void parse_ip(unsigned char *byte_source, size_t size, bool verbose)
     134/** Parse IP and print interesting parts.
     135 *  @param buffer   IP packet.
     136 *  @param size     size of the buffer.
     137 *  @param verbose  verbosity flag.
     138 */
     139static void parse_ip(unsigned char *buffer, size_t size, bool verbose)
    100140{
    101141    uint16_t total_length;
     
    106146    uint8_t dst_ip[IPV4_ADDR_SIZE];
    107147
    108     header_length = (byte_source[14] & 0xf) * 4;
    109     total_length = BIG_END_16(byte_source, 16);
     148    size_t hdr_length_offset = 14;
     149    size_t total_len_offset = 16;
     150    size_t protocol_offset = 23;
     151    size_t src_ip_offset = 26;
     152    size_t dst_ip_offset = 30;
     153
     154    if (size < dst_ip_offset + IPV4_ADDR_SIZE) {
     155        printf("%s %s", IP_TEXT, MALFORMED_PACKET);
     156        return;
     157    }
     158
     159    header_length = (buffer[hdr_length_offset] & LOWER_4_BITS) * HDR_SIZE_COEF;
     160    total_length = BIG_END_16(buffer, total_len_offset);
    110161    payload_length = total_length - header_length;
    111     ip_protocol = byte_source[23];
    112 
    113     read_from_buffer(byte_source, 26, IPV4_ADDR_SIZE, src_ip);
    114     read_from_buffer(byte_source, 28, IPV4_ADDR_SIZE, dst_ip);
     162    ip_protocol = buffer[protocol_offset];
     163
     164    read_from_buffer(buffer, src_ip_offset, IPV4_ADDR_SIZE, src_ip);
     165    read_from_buffer(buffer, dst_ip_offset, IPV4_ADDR_SIZE, dst_ip);
    115166
    116167    printf("%s header: %dB, payload: %dB, protocol: 0x%x, ", IP_TEXT, header_length, payload_length, ip_protocol);
     
    119170
    120171    if (verbose && ip_protocol == IP_PROTOCOL_TCP) {
    121         parse_tcp(byte_source, size);
    122     }
    123 }
    124 
    125 static void parse_eth_packet(void *data, size_t size, bool verbose_flag)
    126 {
    127     unsigned char* byte_source = (unsigned char*)data;
    128 
    129     uint16_t protocol = BIG_END_16(byte_source, 12);
     172        parse_tcp(buffer, size);
     173    }
     174}
     175
     176/** Parse ethernnet frame based on eth_type of the frame.
     177 *  @param data         Ethernet frame.
     178 *  @param size         Size of the frame.
     179 *  @param verbose_flag Verbosity flag.
     180 */
     181static void parse_eth_frame(void *data, size_t size, bool verbose_flag)
     182{
     183    unsigned char* buffer = (unsigned char*)data;
     184
     185    size_t eth_type_offset = 12;
     186    uint16_t protocol = BIG_END_16(buffer, eth_type_offset);
    130187
    131188    switch (protocol){
    132189        case ETHER_TYPE_ARP:
    133190            printf("[%s] ", ARP_TEXT);
    134             parse_arp(byte_source, size);
     191            parse_arp(buffer, size);
    135192            break;
    136193        case ETHER_TYPE_IP4:
    137194            printf("[%s] ", IPV4_TEXT);
    138             parse_ip(byte_source, size, verbose_flag);
     195            parse_ip(buffer, size, verbose_flag);
    139196            break;
    140197        case ETHER_TYPE_IP6:
     
    147204}
    148205
     206/** Parse file header of PCAP file.
     207 *  @param hdr  PCAP header structure.
     208 */
    149209void eth_parse_header(pcap_file_header_t *hdr)
    150210{
     
    153213}
    154214
    155 void eth_parse_packets(FILE *f, int count, bool verbose_flag)
     215/** Parse PCAP file.
     216 *  @param pcap_file    file of PCAP format with dumped packets.
     217 *  @param count        number of packets to be parsed and printed from file (if -1 all packets are printed).
     218 *  @param verbose_flag verbosity flag.
     219 */
     220void eth_parse_frames(FILE *pcap_file, int count, bool verbose_flag)
    156221{
    157222    pcap_packet_header_t hdr;
    158223
    159     size_t read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), f);
     224    size_t read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), pcap_file);
    160225    int packet_index = 1;
    161226    while (read_bytes > 0)
     
    169234
    170235        void *data = malloc(hdr.captured_length);
    171         read_bytes = fread(data, 1, (size_t)hdr.captured_length, f);
     236        read_bytes = fread(data, 1, (size_t)hdr.captured_length, pcap_file);
    172237        if (read_bytes < (size_t)hdr.captured_length) {
    173238            printf("Error: Could not read enough bytes (read %zu bytes)\n", read_bytes);
    174239            return;
    175240        }
    176         parse_eth_packet(data, (size_t)hdr.captured_length, verbose_flag);
     241        parse_eth_frame(data, (size_t)hdr.captured_length, verbose_flag);
    177242        free(data);
    178243
    179         //Read first count packets
     244        //Read first count packets from file.
    180245        if (count != -1 && count == packet_index - 1) {
    181246            return;
     
    183248
    184249        memset(&hdr, 0, sizeof(pcap_packet_header_t));
    185         read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), f);
    186     }
    187 
    188     fclose(f);
    189 }
     250        read_bytes = fread(&hdr, 1, sizeof(pcap_packet_header_t), pcap_file);
     251    }
     252
     253    fclose(pcap_file);
     254}
     255
     256/** @}
     257 */
  • uspace/app/pcapcat/eth_parser.h

    r373dded rcaac052  
    2727 */
    2828
     29/** @addtogroup pcapcat
     30 * @{
     31 */
     32/** @file Functions for parsing PCAP file of LinkType 1 (LINKTYPE_ETHERNET).
     33 */
    2934
    3035#include <stdint.h>
     
    3540#include <errno.h>
    3641#include <str.h>
    37 #include <io/log.h>
    3842#include <pcap.h>
    3943
    40 extern void eth_parse_packets(FILE *, int, bool);
     44extern void eth_parse_frames(FILE *, int, bool);
    4145extern void eth_parse_header(pcap_file_header_t *);
     46
     47/** @}
     48 */
  • uspace/app/pcapcat/linktype_parser.h

    r373dded rcaac052  
    2727 */
    2828
    29 #include <stdint.h>
    30 #include <stdio.h>
     29/** @addtogroup pcapcat
     30 * @{
     31 */
     32/** @file Structure for parsing PCAP file.
     33 */
     34
    3135#include <stdlib.h>
    32 #include <time.h>
    3336#include <stdbool.h>
    34 #include <errno.h>
    3537#include <str.h>
    36 #include <io/log.h>
    3738#include <pcap.h>
    38 
    3939
    4040typedef struct {
     
    4343    void (*parse_packets)(FILE *, int, bool);
    4444} linktype_parser_t;
     45
     46/** @}
     47 */
  • uspace/app/pcapcat/main.c

    r373dded rcaac052  
    4545
    4646static const linktype_parser_t eth_parser = {
    47     .parse_packets = &eth_parse_packets,
     47    .parse_packets = &eth_parse_frames,
    4848    .parse_file_header = &eth_parse_header,
    4949    .linktype = PCAP_LINKTYPE_ETHERNET
  • uspace/app/pcapctl/doc/doxygroups.h

    r373dded rcaac052  
    11/** @addtogroup pcapctl pcapctl
    2  * @brief Dump network packets
     2 * @brief Command-line utility for dumping packets.
    33 * @ingroup apps
    44 */
  • uspace/lib/pcap/include/pcap.h

    r373dded rcaac052  
    9595};
    9696
    97 extern void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype, bool nano);
     97extern void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype);
    9898extern void pcap_writer_add_packet(pcap_writer_t *writer, const void *captured_packet, size_t size);
    9999extern void pcap_set_time(pcap_packet_header_t *header);
  • uspace/lib/pcap/src/pcap.c

    r373dded rcaac052  
    4848        getrealtime(&ts);
    4949        header->seconds_stamp = (uint32_t)ts.tv_sec;
    50         header->magic_stamp = (uint32_t)ts.tv_nsec;
     50        header->magic_stamp = (uint32_t)ts.tv_sec / 1000;
    5151}
    5252
     
    5555 * @param writer        Writer that has destination buffer and ops to write to destination buffer.
    5656 * @param linktype      Linktype for the file header.
    57  * @param nano          True for nanoseconds, false for microseconds in timestamp.
    5857 */
    59 void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype, bool nano)
     58void pcap_writer_add_header(pcap_writer_t *writer, uint32_t linktype)
    6059{
    61         uint32_t magic_version = PCAP_MAGIC_MICRO;
    62         if (nano) {
    63                 magic_version = PCAP_MAGIC_NANO;
    64         }
    65         pcap_file_header_t file_header = { magic_version, PCAP_MAJOR_VERSION, PCAP_MINOR_VERSION,
     60        pcap_file_header_t file_header = { (uint32_t)PCAP_MAGIC_MICRO, PCAP_MAJOR_VERSION, PCAP_MINOR_VERSION,
    6661                0x00000000, 0x00000000, (uint32_t)PCAP_SNAP_LEN, linktype };
    6762        writer->ops->write_buffer(writer, &file_header, sizeof(file_header));
  • uspace/lib/pcap/src/pcap_dumper.c

    r373dded rcaac052  
    6060                return EINVAL;
    6161        }
    62         pcap_writer_add_header(writer, (uint32_t)PCAP_LINKTYPE_ETHERNET, false);
     62        pcap_writer_add_header(writer, (uint32_t)PCAP_LINKTYPE_ETHERNET);
    6363
    6464        return EOK;
     
    9898                return EINVAL;
    9999        }
    100         pcap_writer_add_header(writer, (uint32_t)PCAP_LINKTYPE_USB_LINUX_MMAPPED, false);
     100        pcap_writer_add_header(writer, (uint32_t)PCAP_LINKTYPE_USB_LINUX_MMAPPED);
    101101
    102102        return EOK;
Note: See TracChangeset for help on using the changeset viewer.