Changeset 1aa4bf7 for lib/format_linux.c


Ignore:
Timestamp:
04/03/09 14:22:52 (12 years ago)
Author:
Perry Lorier <perry@…>
Branches:
4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, getfragoff, help, libtrace4, master, ndag_format, pfring, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
Children:
327b1df
Parents:
af0918a
Message:

Support using timespec's for dealing with traces

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/format_linux.c

    r013de36e r1aa4bf7  
    6464};
    6565
     66typedef enum { TS_NONE, TS_TIMEVAL, TS_TIMESPEC } timestamptype_t;
     67
    6668struct libtrace_format_data_t {
    6769        int fd;
    6870        int snaplen;
    6971        int promisc;
     72        timestamptype_t timestamptype;
    7073        libtrace_filter_t *filter;
    7174        struct tpacket_stats stats;
     
    7376};
    7477
     78
    7579struct libtrace_linuxnative_header {
    76         struct timeval ts;
     80        struct timeval tv;
     81        struct timespec ts;
     82        timestamptype_t timestamptype;
    7783        int wirelen;
    7884        int caplen;
     
    8995static int linuxnative_probe_filename(const char *filename)
    9096{
    91         int sock;
    92 
    9397        /* Is this an interface? */
    9498        return (if_nametoindex(filename) != 0);
     
    177181                }
    178182        }
    179 
     183#ifdef SO_TIMESTAMPNS
     184        if (setsockopt(FORMAT(libtrace->format_data)->fd,
     185                        SOL_SOCKET,
     186                        SO_TIMESTAMPNS,
     187                        &one,
     188                        (socklen_t)sizeof(one))!=-1) {
     189                FORMAT(libtrace->format_data)->timestamptype = TS_TIMESPEC;
     190        }
     191        else
     192        /* DANGER: This is a dangling else to only do the next setsockopt() if we fail the first! */
     193#endif
    180194        if (setsockopt(FORMAT(libtrace->format_data)->fd,
    181195                        SOL_SOCKET,
    182196                        SO_TIMESTAMP,
    183197                        &one,
    184                         (socklen_t)sizeof(one))==-1) {
    185                 perror("setsockopt(SO_TIMESTAMP)");
    186         }
     198                        (socklen_t)sizeof(one))!=-1) {
     199                FORMAT(libtrace->format_data)->timestamptype = TS_TIMEVAL;
     200        }
     201        else
     202                FORMAT(libtrace->format_data)->timestamptype = TS_NONE;
    187203
    188204        /* Push BPF filter into the kernel. At this stage we can safely assume
     
    436452                        && cmsg->cmsg_type == SO_TIMESTAMP
    437453                        && cmsg->cmsg_len <= CMSG_LEN(sizeof(struct timeval))) {
     454                        memcpy(&hdr->tv, CMSG_DATA(cmsg),
     455                                        sizeof(struct timeval));
     456                        hdr->timestamptype = TS_TIMEVAL;
     457                        break;
     458                }
     459#ifdef SO_TIMESTAMPNS
     460                else if (cmsg->cmsg_level == SOL_SOCKET
     461                        && cmsg->cmsg_type == SO_TIMESTAMPNS
     462                        && cmsg->cmsg_len <= CMSG_LEN(sizeof(struct timespec))) {
    438463                        memcpy(&hdr->ts, CMSG_DATA(cmsg),
    439464                                        sizeof(struct timeval));
     465                        hdr->timestamptype = TS_TIMESPEC;
    440466                        break;
    441467                }
    442         }
    443 
    444         if (cmsg == NULL && ioctl(FORMAT(libtrace->format_data)->fd,
    445                                 SIOCGSTAMP,&hdr->ts)==-1)
    446                 perror("ioctl(SIOCGSTAMP)");
     468#endif
     469        }
     470
     471        /* Did we not get given a timestamp? */
     472        if (cmsg == NULL) {
     473                if (ioctl(FORMAT(libtrace->format_data)->fd,
     474                                  SIOCGSTAMP,&hdr->tv)==0) {
     475                        hdr->timestamptype = TS_TIMEVAL;
     476                }
     477                else {
     478                        hdr->timestamptype = TS_NONE;
     479                }
     480        }
    447481
    448482        if (linuxnative_prepare_packet(libtrace, packet, packet->buffer,
     
    521555}
    522556
     557static struct timespec linuxnative_get_timespec(const libtrace_packet_t *packet)
     558{
     559        struct libtrace_linuxnative_header *hdr =
     560                (struct libtrace_linuxnative_header*) packet->buffer;
     561        /* We have to upconvert from timeval to timespec */
     562        if (hdr->timestamptype == TS_TIMEVAL) {
     563                struct timespec ts;
     564                ts.tv_sec = hdr->tv.tv_sec;
     565                ts.tv_nsec = hdr->tv.tv_usec*1000;
     566                return ts;
     567        }
     568        else
     569                return hdr->ts;
     570}
     571
    523572static struct timeval linuxnative_get_timeval(const libtrace_packet_t *packet)
    524573{
    525         return ((struct libtrace_linuxnative_header*)(packet->buffer))->ts;
     574        struct libtrace_linuxnative_header *hdr =
     575                (struct libtrace_linuxnative_header*) packet->buffer;
     576        /* We have to downconvert from timespec to timeval */
     577        if (hdr->timestamptype == TS_TIMESPEC) {
     578                struct timeval tv;
     579                tv.tv_sec = hdr->ts.tv_sec;
     580                tv.tv_usec = hdr->ts.tv_nsec/1000;
     581                return tv;
     582        }
     583        else
     584                return hdr->tv;
    526585}
    527586
     
    643702        NULL,                           /* get_erf_timestamp */
    644703        linuxnative_get_timeval,        /* get_timeval */
     704        linuxnative_get_timespec,       /* get_timespec */
    645705        NULL,                           /* get_seconds */
    646706        NULL,                           /* seek_erf */
Note: See TracChangeset for help on using the changeset viewer.