aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-f5ethtrailer.h
blob: b3c7bf01b9e1e3f4d49b08a65518d03ba92b1385 (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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
/* packet-f5ethtrailer.h
 *
 * F5 Ethernet Trailer Copyright 2008-2018 F5 Networks
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

/* How to use the fileinfo version tap
 *
 * Captures taken on an F5 device in versions 11.2.0 and later contain an
 * initial packet that has information about how the capture was taken and
 * about the device it was taken on (tcpdump command line, platform, version,
 * etc.).  This tap allows other dissectors to obtain the version of BIG-IP
 * software (if it is available).
 *
 * There are two functions defined in this header file (f5fileinfo_tap_reset()
 * and f5fileinfo_tap_pkt()).  These functions are registered with the tap and
 * will populate a structure provided by you with the version information.
 *
 * Step 1: Define a static variable of type "struct f5fileinfo".  This is where
 * the version information will be stored.
 *   static struct f5fileinfo myver = F5FILEINFO_TAP_DATA_INIT;
 *
 * Step 2: Register with the tap listener using the macro provided in your
 * proto_reg_handoff function:
 *   F5FILEINFO_TAP_LISTEN(&myver);
 *
 * Step 3: Use the version information in other parts of your code.
 *   if(myver.ver[0] == 11) {
 *      ...
 *   }
 *
 * If you need to do something additional when you run into a version, you can
 * define the F5FILEINFO_TAP_POST_FUNC macro before including this header file
 * to be the name of a fuction to call at the end of the tap function.  This
 * function must have a prototype of
 *   static void F5FILEINFO_TAP_POST_FUNC(struct f5fileinfo_tap_data *);
 * Note that this function also gets called with version of all zeroes when the
 * tap gets reset (reload file).
 * Note that this function does not get called if the version number does not
 * change.
 * Example:
 *   #define F5FILEINFO_TAP_POST_FUNC f5info_tap_local
 *   #include <epan/dissectors/packet-f5ethtrailer.h>
 *   ...
 *   static void f5info_tap_local(struct f5fileinfo_tap_data *tap_data)
 *   {
 *       ...
 *   }
 */

#ifndef _PACKETH_F5ETHTRAILER_H_
#define _PACKETH_F5ETHTRAILER_H_

#include <glib.h>

#define F5ETH_TAP_TMM_MAX   G_MAXUINT16
#define F5ETH_TAP_TMM_BITS  16
#define F5ETH_TAP_SLOT_MAX  G_MAXUINT16
#define F5ETH_TAP_SLOT_BITS 16

/** Magic number for Ethernet trailer tap data to ensure that any tap and the dissector were both
 *  compiled from the same source.  No need to htonl this since the dissector and the tap should
 *  both be compiled on the same platform.
 *
 *  Increment this value when the struct f5eth_tap_data (below) is changed.
 */
#define F5ETH_TAP_MAGIC     0x68744521

/** Data structure to hold data returned by the f5ethtrailer tap.  Magic has to be first. */
typedef struct f5eth_tap_data {
    guint32 magic;        /**< Verify proper version of dissector */
    guint32 trailer_len;  /**< Overall length of the F5 trailer */
    /* 64 bit align */
    guint64 flow;         /**< Flow ID */
    guint64 peer_flow;    /**< Peer Flow ID */
    /* 64 bit align */
    gchar  *virtual_name; /**< Virtual server name */
    guint16 slot;         /**< The slot the handled the packet (F5ETH_TAP_TMM_MAX == unknown) */
    guint16 tmm;          /**< The tmm that handled the packet (F5ETH_TAP_sLOT_MAX == unknown) */
    guint8  noise_low:1;  /**< If the frame has low noise(1) or not(0) */
    guint8  noise_med:1;  /**< If the frame has medium noise(1) or not(0) */
    guint8  noise_high:1; /**< If the frame has high noise(1) or not(0) */
    guint8  flows_set:1;  /**< If the frame has flow/peerflow fields(1) or not(0) */
    guint8  ingress:2;    /**< Whether the packet was ingress(1), egress(0) or unknown(3) */
} f5eth_tap_data_t;

/** \brief Tap data version matches compiled version
 *
 *  @param tdata Pointer to tapdata from f5ethtrailer
 *  @return 1 if the version of the tapdata matches the compiled version of the tap. 0 otherwise.
 *
 *  Use this function to ensure that the data from the f5ethtrailer tap is the same as the
 *  structure used when your tap was compiled.  Use this to protect your tap from running against
 *  a newer/older version of the f5ethtrailer dissector.
 *
 *  For example, at the top of your tap packet function, you can use:
 *    if(check_f5eth_tap_magic(tdata) == 0) return 0;
 */
inline static int check_f5eth_tap_magic(f5eth_tap_data_t *tdata)
{
    return(tdata->magic == F5ETH_TAP_MAGIC ? 1 : 0);
} /* check_f5eth_tap_magic() */

#define F5FILEINFO_TAP_MAGIC 0x46350001

/** Data structure to hold data returned by the f5fileinfo tap. */
struct f5fileinfo_tap_data {
    guint32 magic;  /**< Just to make sure that we have the same version. */
    guint32 ver[6]; /**< Array for version and build elements. */
};

#define F5FILEINFO_TAP_DATA_INIT { 0, { 0, 0, 0, 0, 0, 0 } }

#define F5VER_KNOWN(v) ((v)->ver[0] > 0)


#define F5VER_GE_11_2(v) (((v)->ver[0] > 11) \
    || ((v)->ver[0] == 11 && (v)->ver[1] >= 2))

#define F5VER_GE_11_2_1(v) (((v)->ver[0] > 11) \
    || ((v)->ver[0] == 11 && (v)->ver[1] > 2) \
    || ((v)->ver[0] == 11 && (v)->ver[1] == 2 && (v)->ver[2] >= 1))

#define F5VER_GE_11_3(v) (((v)->ver[0] > 11) \
    || ((v)->ver[0] == 11 && (v)->ver[1] >= 3))

#define F5VER_GE_11_4(v) (((v)->ver[0] > 11) \
    || ((v)->ver[0] == 11 && (v)->ver[1] >= 4))

#define F5VER_GE_11_4_1(v) (((v)->ver[0] > 11) \
    || ((v)->ver[0] == 11 && (v)->ver[1] > 4) \
    || ((v)->ver[0] == 11 && (v)->ver[1] == 4 && (v)->ver[2] >= 1))

#define F5VER_GE_11_5(v) (((v)->ver[0] > 11) \
    || ((v)->ver[0] == 11 && (v)->ver[1] >= 5))

#define F5VER_GE_11_5_1(v) (((v)->ver[0] > 11) \
    || ((v)->ver[0] == 11 && (v)->ver[1] > 5) \
    || ((v)->ver[0] == 11 && (v)->ver[1] == 5 && (v)->ver[2] >= 1))

#define F5VER_GE_11_6(v) (((v)->ver[0] > 11) \
    || ((v)->ver[0] == 11 && (v)->ver[1] >= 6))

#define F5VER_GE_12_0(v) (((v)->ver[0] >= 12))


#ifndef F5FILEINFOTAP_SRC

#ifdef F5FILEINFO_TAP_POST_FUNC
static void F5FILEINFO_TAP_POST_FUNC(struct f5fileinfo_tap_data *);
#endif

static void f5fileinfo_tap_reset(void *p)
{
    struct f5fileinfo_tap_data *s;

    s = (struct f5fileinfo_tap_data *)p;
    s->ver[0] = 0;
    s->ver[1] = 0;
    s->ver[2] = 0;
    s->ver[3] = 0;
    s->ver[4] = 0;
    s->ver[5] = 0;
#   ifdef F5FILEINFO_TAP_POST_FUNC
        F5FILEINFO_TAP_POST_FUNC(s);
#   endif
} /* f5fileinfo_tap_reset() */

static tap_packet_status f5fileinfo_tap_pkt(
    void *tapdata,
    packet_info *pinfo _U_,
    epan_dissect_t *edt _U_,
    const void *data,
    tap_flags_t flags _U_
) {
    struct f5fileinfo_tap_data *s;
    struct f5fileinfo_tap_data *fromtap;

    s = (struct f5fileinfo_tap_data *)tapdata;
    fromtap = (struct f5fileinfo_tap_data *)data;
    if(fromtap->magic != F5FILEINFO_TAP_MAGIC) {
        /* Magic numbers do not match.  f5ethtrailer plugin was compiled from
         * different source than this plugin. */
        return(TAP_PACKET_DONT_REDRAW);
    }
    if (s->ver[0] == fromtap->ver[0] &&
        s->ver[1] == fromtap->ver[1] &&
        s->ver[2] == fromtap->ver[2] &&
        s->ver[3] == fromtap->ver[3] &&
        s->ver[4] == fromtap->ver[4] &&
        s->ver[5] == fromtap->ver[5])
    {
        return(TAP_PACKET_DONT_REDRAW);
    }
    s->ver[0] = fromtap->ver[0];
    s->ver[1] = fromtap->ver[1];
    s->ver[2] = fromtap->ver[2];
    s->ver[3] = fromtap->ver[3];
    s->ver[4] = fromtap->ver[4];
    s->ver[5] = fromtap->ver[5];
#   ifdef F5FILEINFO_TAP_POST_FUNC
        F5FILEINFO_TAP_POST_FUNC(s);
#   endif
    return(TAP_PACKET_REDRAW);
} /* f5fileinfo_tap_pkt() */


#define F5FILEINFO_TAP_LISTEN(a) \
    register_tap_listener("f5fileinfo", (a), NULL, TL_REQUIRES_NOTHING, f5fileinfo_tap_reset, f5fileinfo_tap_pkt, NULL, NULL)


#endif /* ifndef F5INFOTAP_SRC */


#endif /* ifndef _PACKETH_F5ETHTRAILER_H_ */

/*
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
 *
 * Local variables:
 * c-basic-offset: 4
 * tab-width: 8
 * indent-tabs-mode: nil
 * End:
 *
 * vi: set shiftwidth=4 tabstop=8 expandtab:
 * :indentSize=4:tabSize=8:noTabs=true:
 */