/* Extracts DUCK information from the DAG card and produces a DUCK packet */ static int dag_get_duckinfo(libtrace_t *libtrace, libtrace_packet_t *packet) { dag_inf lt_dag_inf; /* Allocate memory for the DUCK data */ if (packet->buf_control == TRACE_CTRL_EXTERNAL || !packet->buffer) { packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE); packet->buf_control = TRACE_CTRL_PACKET; if (!packet->buffer) { trace_set_err(libtrace, errno, "Cannot allocate packet buffer"); return -1; } } /* DUCK doesn't actually have a format header, as such */ packet->header = 0; packet->payload = packet->buffer; /* Check that the DAG card supports DUCK */ if ((ioctl(FORMAT_DATA->fd, DAG_IOINF, <_dag_inf) < 0)) { trace_set_err(libtrace, errno, "Error using DAG_IOINF"); return -1; } if (!IsDUCK(<_dag_inf)) { printf("WARNING: %s does not have modern clock support - No DUCK information will be gathered\n", libtrace->uridata); return 0; } /* Get the DUCK information from the card */ if ((ioctl(FORMAT_DATA->fd, DAG_IOGETDUCK, (duck_inf *)packet->payload) < 0)) { trace_set_err(libtrace, errno, "Error using DAG_IOGETDUCK"); return -1; } /* Set the type */ packet->type = TRACE_RT_DUCK_2_4; /* Set the packet's trace to point at a DUCK trace, so that the * DUCK format functions will be called on the packet rather than the * DAG ones */ if (!DUCK.dummy_duck) DUCK.dummy_duck = trace_create_dead("duck:dummy"); packet->trace = DUCK.dummy_duck; return sizeof(duck_inf); }
/* Sets the trace format for the packet to match the format it was originally * captured in, rather than the RT format */ static int rt_set_format(libtrace_t *libtrace, libtrace_packet_t *packet) { /* We need to assign the packet to a "dead" trace */ /* Try to minimize the number of corrupt packets that slip through * while making it easy to identify new pcap DLTs */ if (packet->type > TRACE_RT_DATA_DLT && packet->type < TRACE_RT_DATA_DLT_END) { if (!RT_INFO->dummy_pcap) { RT_INFO->dummy_pcap = trace_create_dead("pcap:-"); } packet->trace = RT_INFO->dummy_pcap; return 0; } if (packet->type > TRACE_RT_DATA_BPF && packet->type < TRACE_RT_DATA_BPF_END) { if (!RT_INFO->dummy_bpf) { RT_INFO->dummy_bpf = trace_create_dead("bpf:-"); /* This may fail on a non-BSD machine */ if (trace_is_err(RT_INFO->dummy_bpf)) { trace_perror(RT_INFO->dummy_bpf, "Creating dead bpf trace"); return -1; } } packet->trace = RT_INFO->dummy_bpf; return 0; } switch (packet->type) { case TRACE_RT_DUCK_2_4: case TRACE_RT_DUCK_2_5: if (!RT_INFO->dummy_duck) { RT_INFO->dummy_duck = trace_create_dead("duck:dummy"); } packet->trace = RT_INFO->dummy_duck; break; case TRACE_RT_DATA_ERF: if (!RT_INFO->dummy_erf) { RT_INFO->dummy_erf = trace_create_dead("erf:-"); } packet->trace = RT_INFO->dummy_erf; break; case TRACE_RT_DATA_LINUX_NATIVE: if (!RT_INFO->dummy_linux) { RT_INFO->dummy_linux = trace_create_dead("int:"); /* This may fail on a non-Linux machine */ if (trace_is_err(RT_INFO->dummy_linux)) { trace_perror(RT_INFO->dummy_linux, "Creating dead int trace"); return -1; } } packet->trace = RT_INFO->dummy_linux; break; case TRACE_RT_DATA_LINUX_RING: if (!RT_INFO->dummy_ring) { RT_INFO->dummy_ring = trace_create_dead("ring:"); /* This may fail on a non-Linux machine */ if (trace_is_err(RT_INFO->dummy_ring)) { trace_perror(RT_INFO->dummy_ring, "Creating dead int trace"); return -1; } } packet->trace = RT_INFO->dummy_ring; break; case TRACE_RT_STATUS: case TRACE_RT_METADATA: /* Just use the RT trace! */ packet->trace = libtrace; break; case TRACE_RT_DATA_LEGACY_ETH: case TRACE_RT_DATA_LEGACY_ATM: case TRACE_RT_DATA_LEGACY_POS: printf("Sending legacy over RT is currently not supported\n"); trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, "Legacy packet cannot be sent over rt"); return -1; default: printf("Unrecognised format: %u\n", packet->type); trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, "Unrecognised packet format"); return -1; } return 0; /* success */ }