X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fpcap-file.c;h=191e690e637815801269054bc286e9580a5cbbab;hb=003ce655b7116d18c86a74c50391e54990346931;hp=fdff33ca0f33c78afd9436b372c2e9291b7187f6;hpb=50aa0364d0740b2158f48d40a5be04d47354a1e9;p=sliver-openvswitch.git diff --git a/lib/pcap-file.c b/lib/pcap-file.c index fdff33ca0..191e690e6 100644 --- a/lib/pcap-file.c +++ b/lib/pcap-file.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2012, 2013 Nicira, Inc. + * Copyright (c) 2009, 2010, 2012, 2013, 2014 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -198,10 +198,10 @@ ovs_pcap_write(FILE *file, struct ofpbuf *buf) xgettimeofday(&tv); prh.ts_sec = tv.tv_sec; prh.ts_usec = tv.tv_usec; - prh.incl_len = buf->size; - prh.orig_len = buf->size; + prh.incl_len = ofpbuf_size(buf); + prh.orig_len = ofpbuf_size(buf); ignore(fwrite(&prh, sizeof prh, 1, file)); - ignore(fwrite(buf->data, buf->size, 1, file)); + ignore(fwrite(ofpbuf_data(buf), ofpbuf_size(buf), 1, file)); } struct tcp_key { @@ -254,28 +254,27 @@ tcp_reader_close(struct tcp_reader *r) } static struct tcp_stream * -tcp_stream_lookup(struct tcp_reader *r, const struct flow *flow) +tcp_stream_lookup(struct tcp_reader *r, + const struct tcp_key *key, uint32_t hash) { struct tcp_stream *stream; - struct tcp_key key; - uint32_t hash; - - memset(&key, 0, sizeof key); - key.nw_src = flow->nw_src; - key.nw_dst = flow->nw_dst; - key.tp_src = flow->tp_src; - key.tp_dst = flow->tp_dst; - hash = hash_bytes(&key, sizeof key, 0); HMAP_FOR_EACH_WITH_HASH (stream, hmap_node, hash, &r->streams) { - if (!memcmp(&stream->key, &key, sizeof key)) { + if (!memcmp(&stream->key, key, sizeof *key)) { return stream; } } + return NULL; +} + +static struct tcp_stream * +tcp_stream_new(struct tcp_reader *r, const struct tcp_key *key, uint32_t hash) +{ + struct tcp_stream *stream; stream = xmalloc(sizeof *stream); hmap_insert(&r->streams, &stream->hmap_node, hash); - memcpy(&stream->key, &key, sizeof key); + memcpy(&stream->key, key, sizeof *key); stream->seq_no = 0; ofpbuf_init(&stream->payload, 2048); return stream; @@ -299,22 +298,44 @@ tcp_reader_run(struct tcp_reader *r, const struct flow *flow, struct tcp_stream *stream; struct tcp_header *tcp; struct ofpbuf *payload; + unsigned int l7_length; + struct tcp_key key; + uint32_t hash; uint32_t seq; uint8_t flags; + const char *l7 = ofpbuf_get_tcp_payload(packet); if (flow->dl_type != htons(ETH_TYPE_IP) || flow->nw_proto != IPPROTO_TCP - || !packet->l7) { + || !l7) { return NULL; } - - stream = tcp_stream_lookup(r, flow); - payload = &stream->payload; - - tcp = packet->l4; + tcp = ofpbuf_l4(packet); flags = TCP_FLAGS(tcp->tcp_ctl); + l7_length = (char *) ofpbuf_tail(packet) - l7; seq = ntohl(get_16aligned_be32(&tcp->tcp_seq)); - if (flags & TCP_SYN) { + + /* Construct key. */ + memset(&key, 0, sizeof key); + key.nw_src = flow->nw_src; + key.nw_dst = flow->nw_dst; + key.tp_src = flow->tp_src; + key.tp_dst = flow->tp_dst; + hash = hash_bytes(&key, sizeof key, 0); + + /* Find existing stream or start a new one for a SYN or if there's data. */ + stream = tcp_stream_lookup(r, &key, hash); + if (!stream) { + if (flags & TCP_SYN || l7_length) { + stream = tcp_stream_new(r, &key, hash); + stream->seq_no = flags & TCP_SYN ? seq + 1 : seq; + } else { + return NULL; + } + } + + payload = &stream->payload; + if (flags & TCP_SYN || !stream->seq_no) { ofpbuf_clear(payload); stream->seq_no = seq + 1; return NULL; @@ -322,16 +343,13 @@ tcp_reader_run(struct tcp_reader *r, const struct flow *flow, tcp_stream_destroy(r, stream); return NULL; } else if (seq == stream->seq_no) { - size_t length; - /* Shift all of the existing payload to the very beginning of the * allocated space, so that we reuse allocated space instead of * continually expanding it. */ - ofpbuf_shift(payload, (char *) payload->base - (char *) payload->data); + ofpbuf_shift(payload, (char *) ofpbuf_base(payload) - (char *) ofpbuf_data(payload)); - length = (char *) ofpbuf_end(packet) - (char *) packet->l7; - ofpbuf_put(payload, packet->l7, length); - stream->seq_no += length; + ofpbuf_put(payload, l7, l7_length); + stream->seq_no += l7_length; return payload; } else { return NULL;