rvelea / LightPcapNg

PcapNg read, write and manipulation API.
MIT License
31 stars 19 forks source link

Does current implementation supports nanosecond precision when writing to file? #4

Open rychale opened 6 years ago

rychale commented 6 years ago

Does current implementation support nanosecond precision when writing to file?

tpruzina commented 6 years ago

Looks like it:

https://github.com/rvelea/LightPcapNg/blob/327249953a9e4f2c2c0171d3397e90ca9454f0a6/src/light_pcapng_ext.c#L152

rychale commented 6 years ago

Yes, but then:

https://github.com/rvelea/LightPcapNg/blob/327249953a9e4f2c2c0171d3397e90ca9454f0a6/src/light_pcapng_ext.c#L467

converts two timestamp fields into single 64-bit int assuming microseconds precision.

koomisov commented 1 year ago

Looks like it's not supported now because of the logic above. Also if_tsresol option is not set to the interface description block.

I have a simple patch that makes nanoseconds timestamp precision instead of microseconds. Probably will be useful for someone

diff --git a/src/light_manipulate.c b/src/light_manipulate.c
index 503beb7..13fa97c 100644
--- a/src/light_manipulate.c
+++ b/src/light_manipulate.c
@@ -120,9 +120,6 @@ int light_add_option(light_pcapng section, light_pcapng pcapng, light_option opt
        struct _light_section_header *shb = (struct _light_section_header *)section->block_body;
        shb->section_length += option_size;
    }
-   else if (section != NULL) {
-       PCAPNG_WARNING("PCAPNG block is not section header!");
-   }

    return LIGHT_SUCCESS;
 }
diff --git a/src/light_pcapng_ext.c b/src/light_pcapng_ext.c
index 7b4bb92..b35d814 100644
--- a/src/light_pcapng_ext.c
+++ b/src/light_pcapng_ext.c
@@ -383,12 +383,10 @@ int light_get_next_packet(light_pcapng_t *pcapng, light_packet_header *packet_he
        packet_header->interface_id = epb->interface_id;
        packet_header->captured_length = epb->capture_packet_length;
        packet_header->original_length = epb->original_capture_length;
-       uint64_t timestamp = epb->timestamp_high;
-       timestamp = timestamp << 32;
-       timestamp += epb->timestamp_low;
-       double timestamp_res = pcapng->file_info->timestamp_resolution[epb->interface_id];
-       packet_header->timestamp.tv_sec = timestamp * timestamp_res;
-       packet_header->timestamp.tv_usec = (timestamp - (packet_header->timestamp.tv_sec / timestamp_res))*timestamp_res*1000000;
+
+       packet_header->timestamp.tv_sec = epb->timestamp_high;
+       packet_header->timestamp.tv_usec = epb->timestamp_low;
+
        if (epb->interface_id < pcapng->file_info->interface_block_count)
            packet_header->data_link = pcapng->file_info->link_types[epb->interface_id];

@@ -451,6 +449,11 @@ void light_write_packet(light_pcapng_t *pcapng, const light_packet_header *packe
        interface_block.snapshot_length = 0;

        light_pcapng iface_block_pcapng = light_alloc_block(LIGHT_INTERFACE_BLOCK, (const uint32_t*)&interface_block, sizeof(struct _light_interface_description_block)+3*sizeof(uint32_t));
+
+        uint8_t tsresol_option_value = 9; // Timestamp precision. 9 means nanoseconds, 6 microseconds
+        light_option tsresol_option = light_create_option(LIGHT_OPTION_IF_TSRESOL, sizeof(uint8_t), &tsresol_option_value);
+        light_add_option(iface_block_pcapng, iface_block_pcapng, tsresol_option, LIGHT_TRUE);
+
        light_add_block(pcapng->pcapng_iter, iface_block_pcapng);
        pcapng->pcapng_iter = iface_block_pcapng;

@@ -464,9 +467,8 @@ void light_write_packet(light_pcapng_t *pcapng, const light_packet_header *packe
    memset(epb_memory, 0, option_size);
    struct _light_enhanced_packet_block *epb = (struct _light_enhanced_packet_block *)epb_memory;
    epb->interface_id = iface_id;
-   uint64_t timestamp_usec = (uint64_t)packet_header->timestamp.tv_sec * (uint64_t)1000000 + (uint64_t)packet_header->timestamp.tv_usec;
-   epb->timestamp_high = timestamp_usec >> 32;
-   epb->timestamp_low = timestamp_usec & 0xFFFFFFFF;
+   epb->timestamp_high = packet_header->timestamp.tv_sec;
+   epb->timestamp_low = packet_header->timestamp.tv_usec;
    epb->capture_packet_length = packet_header->captured_length;
    epb->original_capture_length = packet_header->original_length;