1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// Local Imports
use types::*;
use utils::ReadBytesLocal;
use flow_records::FlowRecord;
use error::Result;

// Std Lib Imports
use std::io::SeekFrom;

#[derive(Debug, Clone)]
pub enum SampleRecord {
    FlowSample(FlowSample),
    Unknown,
}

add_decoder!{
#[derive(Debug, Clone, Default)]
pub struct FlowSample {
    // Incremented with each flow sample generated by this source_id. Note: If the agent resets the
    // sample_pool then it must also reset the sequence_number.
    pub sequence_number: u32,

    // sFlowDataSource
    pub sflow_data_source: SourceID,

    // sFlowPacketSamplingRate
    pub sampling_rate: u32,

    // Total number of packets that could have been sampled (i.e. packets skipped by sampling
    // process + total number of samples)
    pub sample_pool: u32,

    // Number of times that the sFlow agent detected that a packet marked to be sampled was dropped
    // due to lack of resources. The drops counter reports the total number of drops detected since
    // the agent was last reset. A high drop rate indicates that the management agent is unable to
    // process samples as fast as they are being generated by hardware. Increasing sampling_rate
    // will reduce the drop rate. Note: An agent that cannot detect drops will always report zero.
    pub drops: u32,

    // Interface packet was received on.
    pub input_id: Interface,

    // Interface packet was sent on.
    pub output_id: Interface,

    // Information about a sampled packet */
    pub flow_records: Vec<FlowRecord>,
}
}

impl ::utils::Decodeable for Vec<SampleRecord> {
    fn read_and_decode(stream: &mut ReadSeeker) -> Result<Vec<SampleRecord>> {
        // First we need to figure out how many samples there are.
        let count = try!(stream.be_read_u32());
        let mut results: Vec<SampleRecord> = Vec::new();

        for _ in 0..count {
            let format = try!(stream.be_read_u32());
            let length = try!(stream.be_read_u32());

            match format {
                1 => {
                    let fs: FlowSample = try!(::utils::Decodeable::read_and_decode(stream));
                    results.push(SampleRecord::FlowSample(fs));
                }
                // Skip unknown samples.
                _ => {
                    results.push(SampleRecord::Unknown);
                    try!(stream.seek(SeekFrom::Current(length as i64)));
                }
            }
        }

        Ok(results)
    }
}