summaryrefslogtreecommitdiff
path: root/cesar/lib/seq_check.h
blob: 5e0916ce294682ba8336a881e58b57ea74f7ec33 (plain)
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#ifndef lib_seq_check_h
#define lib_seq_check_h
/* Cesar project {{{
 *
 * Copyright (C) 2011 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    lib/seq_check.h
 * \brief   Check sequence number in data packets
 * \ingroup lib
 *
 * This lib is used to check sequence number in data packets generated by
 * IPerf or Ixia. It supports VLAN if packets are tagged.
 *
 * De-sequence is stored in traces (no assert is done).
 *
 * You can configure:
 *  - position of the sequence number in the packet,
 *  - Ethernet type to inspect.
 *
 * This lib has some limitations:
 *  - you can not ignore some packets: for example during an IPerf traffic, if
 *  they are some pings, they will be inspected. If there is video traffic, it
 *  will be inspected too,
 *  - having different kind of throughput at the same time is not possible: an
 *  IPerf, an Ixia and video. You can only configure for one throughput,
 *  - you can not specify the first sequence number value,
 *  - you can not specify the size/length of the sequence number,
 *  - it can not support VLAN and non VLAN traffic at the same time (sequence
 *  position is the same for both).
 *
 * This lib should only be enabled when needed as it will probably impact
 * performance (it needs to inspect packets).
 */

#include "config/seq/check.h"

#if CONFIG_SEQ_CHECK

/**
 * Callback used when there is a de-sequencing in the packets.
 * \param  user  an user pointer
 * \param  vlan  the VLAN id which in the packet or 0 if there is none
 * \param  seq_expected  the sequence number expected
 * \param  seq_actual  the sequence actually in the packet
 *
 * This function is called by lib_seq_check_packet when there the sequence
 * number is not the one expected.
 */
typedef void
(*lib_seq_check_error_cb_t) (void *user, uint vlan, uint seq_expected,
                             uint seq_actual);

/**
 * Ethernet type IP.
 */
#define SEQ_CHECK_ET_IP 0x8000

/**
 * Sequence counters.
 * This structure is used to store states of the sequence counter. There is
 * one for each VLAN.
 */
typedef struct lib_seq_check_t
{
    /**
     * Sequence counters, for each VLAN id.
     * \note if no VLAN is present on frames, first index of the table is
     * used. There should be no problem, as VLAN 0 is for management.
     */
    uint seq[CONFIG_SEQ_CHECK_VLAN_MAX];
    /**
     * Callback when sequence is wrong.
     */
    lib_seq_check_error_cb_t cb;
    /**
     * The user pointer used when calling the callback.
     */
    void *cb_user;
} lib_seq_check_t;

/**
 * Configuration structure.
 */
typedef struct lib_seq_check_config_t
{
    /**
     * Sequence number size.
     * It only support 16 for the moment.
     */
    u8 seq_size;
    /**
     * Position of the sequence number in the packet.
     * The position start at first bit of the Ethernet frame.
     * This counter is expressed in byte.
     */
    uint seq_pos;
    /**
     * Ethernet type the packet has to have.
     */
    uint ethertype;
} lib_seq_check_config_t;

BEGIN_DECLS

/**
 * Configure lib sequencer check.
 * \param  config  the new configuration structure to use.
 *
 * All fields are copied to the configuration. If you only want to setup one
 * field, you need to use lib_seq_check_config_get before.
 */
void
lib_seq_check_config_set (lib_seq_check_config_t *config);

/**
 * Get current configuration.
 * \param  config  a configuration which will be set to the current one of the
 * sequencer check of the lib.
 */
void
lib_seq_check_config_get (lib_seq_check_config_t *config);

/**
 * Initialize lib sequencer check configuration.
 * You need to do this only one time in the life of the station.
 */
void
lib_seq_check_config_init (void);

/**
 * Initialize lib sequencer check.
 * \param  ctx  the context to initialize
 * \param  cb  the callback to use when there is an problem of sequence in the
 * packet
 * \param  user  an user pointer used when calling the callback
 *
 * This need to be done for each entry point to inspect.
 */
void
lib_seq_check_init (lib_seq_check_t *ctx, lib_seq_check_error_cb_t cb,
                    void *user);

/**
 * Data packet to inspect.
 * \param  ctx  the context of lib seq check
 * \param  buffer  the packet buffer
 * \param  len  the packet length (in byte)
 * \return  true if there is a de-sequencing in the packet and callback was
 * called, false otherwise (this include packets which can not be inspected).
 */
bool
lib_seq_check_packet (lib_seq_check_t *ctx, u8 *buffer, uint len);

END_DECLS

#else /* !CONFIG_SEQ_CHECK */

# define lib_seq_check_config_get() ((void) 0)
# define lib_seq_check_config_set() ((void) 0)
# define lib_seq_check_config_init() ((void) 0)
# define lib_seq_check_init(args...) ((void) 0)
# define lib_seq_check_packet(args...) ((void) 0)

#endif /* !CONFIG_SEQ_CHECK */

#endif /* lib_seq_check_h */