Opened 14 years ago

Closed 14 years ago

#230 closed defect (fixed)

Endianness of trace files for Mac OSX

Reported by: j.ridoux@… Owned by: perry
Priority: major Milestone: libtrace3
Component: libtrace-library Version: 3.0
Keywords: Cc:

Description

It seems the endianness is not checked when reading trace files on Mac OSX (PPC) using libtrace_io_read(). This obviously leads to wrong packets be read.

Change History (8)

comment:1 Changed 14 years ago by perry

  • Status changed from new to assigned

I assume you're talking about the pcapfile: format uri. I can't reproduce this bug, and by eye the code appears to use swap{s,l} to correctly convert between trace and host endianness.

What information in particular is using the wrong endianness? The packet length?

comment:2 Changed 14 years ago by j.ridoux@…

Thanks for your reply Perry, I am trying to be more precise :)

Typically, we have this problem when using trace files captured on Linux or FreeBSD hosts and trying to read the same trace files on Mac OSX (PPC). The version of libtrace used there is libtrace-3.0.0-beta3 (the beta4 does not compile in a straightforward manner on Mac). But I guess the problem is still present in the latest version of the library.

So you are right, I am talking about the pcapfile format you mentioned. In lib/format_pcapfile.c, pcapfile_read_packet(*) calls libtrace_io_read(*), and I can't find a check at this point about endianness. The libtrace informations about a packet are correct, but the payload is not. Usually when processing packets later on with our own software, packets are not recognised as IP packets due to the endianness.

My understanding of the problem is that the libtrace_io_read does not check for endianness, and is the cause of the problem we have. Of course this is only a suggestion, I haven't dived further in the code :).

comment:3 Changed 14 years ago by perry

Correct, we read the data into memory unmodified and then byteswap as we need it. we can't byteswap stuff without knowing the field widths which means we need to fully decode each packet which would be slow. We expect you to call htonl(3)/htons(3) on each field as you need it?

Does this answer your question?

comment:4 Changed 14 years ago by j.ridoux@…

I understand your comment for the payload and the use of htonl/htons, for other fields, makes sense.

Nevertheless, a call to trace_get_ip() always returns NULL on a mac, while working fine on other architectures. I guess this is not an expected behavior. Am I right?

comment:5 Changed 14 years ago by perry

I tested this with this program:

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

#include "libtrace.h"

void iferr(libtrace_t *trace)
{
        libtrace_err_t err = trace_get_err(trace);
        if (err.err_num==0)
                return;
        printf("Error: %s\n",err.problem);
        exit(1);
}

int main(int argc, char *argv[]) {
        int psize = 0;
        int error = 0;
        int ip = 0;
        int nonip = 0;
        libtrace_t *trace;
        libtrace_packet_t *packet;

        trace = trace_create("pcapfile:traces/100_packets.pcap");
        iferr(trace);

        trace_start(trace);
        iferr(trace);

        packet=trace_create_packet();
        for (;;) {
                if ((psize = trace_read_packet(trace, packet)) <0) {
                        error = 1;
                        iferr(trace);
                        break;
                }
                if (psize == 0) {
                        error = 0;
                        break;
                }

                if (trace_get_ip(packet)) {
                        ++ip;
                }
                else
                        ++nonip;

        }
        trace_destroy_packet(packet);
        if (error == 0) {
                printf("%d/%d ip packets\n",ip,ip+nonip);
        } else {
                iferr(trace);
        }
        trace_destroy(trace);
        return error;
}

and could not reproduce this -- the number of ip packets was fine. What link types were you using?

comment:6 Changed 14 years ago by anonymous

I think the problem only happens when you capture using a cooked sll header on intel on a pcap trace, then move it to PPC.

So the example code, probably needs a set_direction to promote the packet for testing.

Its the packet type thats in the cooked header that is wrong I believe.

comment:7 Changed 14 years ago by perry

Ah ha! That makes sense. I believe this was fixed in r1014, but I'll spend some time testing this and writing up a test case so this doesn't reappear.

comment:8 Changed 14 years ago by perry

  • Resolution set to fixed
  • Status changed from assigned to closed
Note: See TracTickets for help on using tickets.