The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
radsniff.h
Go to the documentation of this file.
1#pragma once
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16 */
17
18/**
19 * $Id: 2069fc2f4663963b3c87c2006b2357abf740757a $
20 *
21 * @file radsniff.h
22 * @brief Structures and prototypes for the RADIUS sniffer.
23 *
24 * @copyright 2013 Arran Cudbard-Bell (arran.cudbardb@freeradius.org)
25 * @copyright 2006 The FreeRADIUS server project
26 * @copyright 2006 Nicolas Baradakis (nicolas.baradakis@cegetel.net)
27 */
28RCSIDH(radsniff_h, "$Id: 2069fc2f4663963b3c87c2006b2357abf740757a $")
29
30#include <sys/types.h>
31
32#include <freeradius-devel/util/pcap.h>
33#include <freeradius-devel/util/event.h>
34#include <freeradius-devel/radius/radius.h>
35
36#ifdef HAVE_COLLECTDC_H
37# include <collectd/client.h>
38#endif
39
40#define RS_DEFAULT_PREFIX "radsniff" //!< Default instance
41#define RS_DEFAULT_SECRET "testing123" //!< Default secret
42#define RS_DEFAULT_TIMEOUT 5200 //!< Standard timeout of 5s + 300ms to cover network latency
43#define RS_FORCE_YIELD 1000 //!< Service another descriptor every X number of packets
44#define RS_RETRANSMIT_MAX 5 //!< Maximum number of times we expect to see a packet retransmitted
45#define RS_MAX_ATTRS 50 //!< Maximum number of attributes we can filter on.
46#define RS_SOCKET_REOPEN_DELAY 5000 //!< How long we delay re-opening a collectd socket.
47
48/*
49 * Logging macros
50 */
51#undef DEBUG2
52#define DEBUG2(fmt, ...) if (fr_debug_lvl > 2) fprintf(fr_log_fp , fmt "\n", ## __VA_ARGS__)
53#undef DEBUG
54#define DEBUG(fmt, ...) if (fr_debug_lvl > 1) fprintf(fr_log_fp , fmt "\n", ## __VA_ARGS__)
55#undef INFO
56#define INFO(fmt, ...) if (fr_debug_lvl > 0) fprintf(fr_log_fp , fmt "\n", ## __VA_ARGS__)
57
58#define ERROR(fmt, ...) fr_perror("radsniff: " fmt, ## __VA_ARGS__)
59
60#define RIDEBUG_ENABLED() (conf->print_packet && (fr_debug_lvl > 0))
61#define RDEBUG_ENABLED() (conf->print_packet && (fr_debug_lvl > 1))
62#define RDEBUG_ENABLED2() (conf->print_packet && (fr_debug_lvl > 2))
63
64#define REDEBUG(fmt, ...) if (conf->print_packet) fr_perror("%s (%" PRIu64 ") " fmt , timestr, count, ## __VA_ARGS__)
65#define RIDEBUG(fmt, ...) if (conf->print_packet && (fr_debug_lvl > 0)) fprintf(fr_log_fp , "%s (%" PRIu64 ") " fmt "\n", timestr, count, ## __VA_ARGS__)
66#define RDEBUG(fmt, ...) if (conf->print_packet && (fr_debug_lvl > 1)) fprintf(fr_log_fp , "%s (%" PRIu64 ") " fmt "\n", timestr, count, ## __VA_ARGS__)
67#define RDEBUG2(fmt, ...) if (conf->print_packet && (fr_debug_lvl > 2)) fprintf(fr_log_fp , "%s (%" PRIu64 ") " fmt "\n", timestr, count, ## __VA_ARGS__)
68
69typedef enum {
70 RS_NORMAL = 0x01,
72 RS_RTX = 0x04,
73 RS_REUSED = 0x08,
74 RS_ERROR = 0x10,
75 RS_LOST = 0x20
77
78typedef void (*rs_packet_logger_t)(uint64_t count, rs_status_t status, fr_pcap_t *handle,
79 fr_packet_t *packet, fr_pair_list_t *list,
80 struct timeval *elapsed, struct timeval *latency, bool response, bool body);
81typedef enum {
82#ifdef HAVE_COLLECTDC_H
83 RS_STATS_OUT_COLLECTD = 1,
84#endif
88
89typedef struct rs rs_t;
90
91#ifdef HAVE_COLLECTDC_H
92typedef struct rs_stats_tmpl rs_stats_tmpl_t;
93typedef struct rs_stats_value_tmpl rs_stats_value_tmpl_t;
94#endif
95
96typedef struct {
99
100/** Stats for a single interval
101 *
102 * And interval is defined as the time between a call to the stats output function.
103 */
104typedef struct {
105 int intervals; //!< Number of stats intervals.
106
107 double latency_smoothed; //!< Smoothed moving average.
108 uint64_t latency_smoothed_count; //!< Number of CMA datapoints processed.
109
110 struct {
111 uint64_t received_total; //!< Total received over interval.
112 uint64_t linked_total; //!< Total request/response pairs over interval.
113 uint64_t unlinked_total; //!< Total unlinked over interval.
114 uint64_t reused_total; //!< Total reused over interval.
115 uint64_t lost_total; //!< Total packets definitely lost in this interval.
116 uint64_t rt_total[RS_RETRANSMIT_MAX + 1]; //!< Number of RTX until complete
117 //!< over interval.
118
119
120 double received; //!< Number of this type of packet we've received.
121 double linked; //!< Number of request/response pairs
122 double unlinked; //!< Response with no request.
123 double reused; //!< ID re-used too quickly.
124 double lost; //!< Never got a response to a request.
125 double rt[RS_RETRANSMIT_MAX + 1]; //!< Number of times we saw the same
126 //!< request packet.
127
128 long double latency_total; //!< Total latency between requests/responses in the
129 //!< interval.
130 double latency_average; //!< Average latency (this iteration).
131
132 double latency_high; //!< Latency high water mark.
133 double latency_low; //!< Latency low water mark.
134 } interval;
136
150
151/** One set of statistics
152 *
153 */
154typedef struct {
155 int intervals; //!< Number of stats intervals.
156
157 rs_latency_t exchange[FR_RADIUS_CODE_MAX+ 1]; //!< We end up allocating ~16K, but memory is cheap so
158 //!< what the hell. This is required because instances of
159 //!< FreeRADIUS delay Access-Rejects, which would artificially
160 //!< increase latency stats for Access-Requests.
161
162 struct timeval quiet; //!< We may need to 'mute' the stats if libpcap starts
163 //!< dropping packets, or we run out of memory.
164} rs_stats_t;
165
166typedef struct {
167 struct pcap_pkthdr *header; //!< PCAP packet header.
168 uint8_t *data; //!< PCAP packet data.
170
171/** Wrapper for fr_packet_t
172 *
173 * Allows an event to be associated with a request packet. This is required because we need to disarm
174 * the event timer when a response is received, so we don't erroneously log the response as lost.
175 */
176typedef struct {
177 uint64_t id; //!< Monotonically increasing packet counter.
178 fr_timer_t *event; //!< Event created when we received the original request.
179
180 bool logged; //!< Whether any messages regarding this request were logged.
181
182 struct timeval when; //!< Time when the packet was received, or next time an event
183 //!< is scheduled.
184 fr_pcap_t *in; //!< PCAP handle the original request was received on.
185 fr_packet_t *packet; //!< The original packet.
187 fr_packet_t *expect; //!< Request/response.
189 fr_packet_t *linked; //!< The subsequent response or forwarded request the packet
190 //!< was linked against.
191 fr_pair_list_t link_vps; //!< fr_pair_ts used to link retransmissions.
192
193 rs_capture_t capture[RS_RETRANSMIT_MAX]; //!< Buffered request packets (if a response filter
194 //!< has been applied).
195 rs_capture_t *capture_p; //!< Next packet slot.
196
197 uint64_t rt_req; //!< Number of times we saw the same request packet.
198 uint64_t rt_rsp; //!< Number of times we saw a retransmitted response
199 //!< packet.
200 rs_latency_t *stats_req; //!< Latency entry for the request type.
201 rs_latency_t *stats_rsp; //!< Latency entry for the request type.
202
203 bool silent_cleanup; //!< Cleanup was forced before normal expiry period,
204 //!< ignore stats about packet loss.
205
206
209 bool in_request_tree; //!< Whether the request is currently in the request tree.
210 bool in_link_tree; //!< Whether the request is currently in the linked tree.
212
213/** Statistic write/print event
214 *
215 */
216typedef struct {
217 fr_event_list_t *list; //!< The event list.
218
219 fr_pcap_t *in; //!< PCAP handle event occurred on.
220 fr_pcap_t *out; //!< Where to write output.
221
222 rs_stats_t *stats; //!< Where to write stats.
223} rs_event_t;
224
225typedef struct rs_update rs_update_t;
226
227/** Callback for printing stats header.
228 *
229 */
231
232/** Callback for printing stats values.
233 *
234 */
235typedef void (*rs_stats_print_cb_t)(rs_update_t *this, rs_stats_t *stats, struct timeval *now);
236
237
238/** FD data which gets passed to callbacks
239 *
240 */
241struct rs_update {
242 bool done_header; //!< Have we printed the stats header?
243 fr_event_list_t *list; //!< List to insert new event into.
244
245 fr_pcap_t *in; //!< Linked list of PCAP handles to check for drops.
246 rs_stats_t *stats; //!< Stats to process.
248 rs_stats_print_cb_t body; //!< Print body.
249};
250
251struct rs {
252 bool from_file; //!< Were reading pcap data from files.
253 bool from_dev; //!< Were reading pcap data from devices.
254 bool from_stdin; //!< Were reading pcap data from stdin.
255 bool to_file; //!< Were writing pcap data to files.
256 bool to_stdout; //!< Were writing pcap data to stdout.
257
258 bool to_output_dir; //!< Were writing attributes into directory.
259 char const *output_dir; //!< Where we should save the files $PATH/requests.txt and $PATH/reply.txt
260
261 bool daemonize; //!< Daemonize and write PID out to file.
262 char const *pidfile; //!< File to write PID to.
263
264 bool from_auto; //!< From list was auto-generated.
265 bool promiscuous; //!< Capture in promiscuous mode.
266 bool print_packet; //!< Print packet info, disabled with -W
267 bool decode_attrs; //!< Whether we should decode attributes in the request
268 //!< and response.
269 bool verify_udp_checksum; //!< Check UDP checksum in packets.
270 bool verify_radius_authenticator; //!< Check RADIUS authenticator in packets.
271
272 char *radius_secret; //!< Secret to decode encrypted attributes.
273
274 char *pcap_filter; //!< PCAP filter string applied to live capture devices.
275 char *pcap_filter_vlan; //!< Variant of the normal filter to apply to devices
276 ///< which support VLAN tags.
277
278 char *list_attributes; //!< Raw attribute filter string.
279 fr_dict_attr_t const *list_da[RS_MAX_ATTRS]; //!< Output CSV with these attribute values.
281
282 char *link_attributes; //!< Names of fr_dict_attr_ts to use for rtx.
283 fr_dict_attr_t const *link_da[RS_MAX_ATTRS]; //!< fr_dict_attr_ts to link on.
284 int link_da_num; //!< Number of rtx fr_dict_attr_ts.
285
286 char const *filter_request; //!< Raw request filter string.
287 char const *filter_response; //!< Raw response filter string.
288
289 fr_pair_list_t filter_request_vps; //!< Sorted filter vps.
290 fr_pair_list_t filter_response_vps; //!< Sorted filter vps.
291 fr_radius_packet_code_t filter_request_code; //!< Filter request packets by code.
292 fr_radius_packet_code_t filter_response_code; //!< Filter response packets by code.
293
294 rs_status_t event_flags; //!< Events we log and capture on.
295 rs_packet_logger_t logger; //!< Packet logger
296
297 int buffer_pkts; //!< Size of the ring buffer to setup for live capture.
298 uint64_t limit; //!< Maximum number of packets to capture
299
300 struct {
301 int interval; //!< Time between stats updates in seconds.
302 stats_out_t out; //!< Where to write stats.
303 int timeout; //!< Maximum length of time we wait for a response.
304
305#ifdef HAVE_COLLECTDC_H
306 char const *collectd; //!< Collectd server/port/unixsocket
307 char const *prefix; //!< Prefix collectd stats with this value.
308 lcc_connection_t *handle; //!< Collectd client handle.
309 rs_stats_tmpl_t *tmpl; //!< The stats templates we created on startup.
310#endif
312};
313
314#ifdef HAVE_COLLECTDC_H
315
316/** Callback for processing stats values.
317 *
318 */
319typedef void (*rs_stats_cb_t)(rs_t *conf, rs_stats_value_tmpl_t *tmpl);
320
321struct rs_stats_value_tmpl {
322 void *src; //!< Pointer to source field in struct. Must be set by
323 //!< stats_collectdc_init caller.
324 int type; //!< Stats type.
325 rs_stats_cb_t cb; //!< Callback used to process stats
326 void *dst; //!< Pointer to dst field in value struct. Must be set
327 //!< by stats_collectdc_init caller.
328};
329
330/** Stats templates
331 *
332 * This gets processed to turn radsniff stats structures into collectd lcc_value_list_t structures.
333 */
334struct rs_stats_tmpl
335{
336 rs_stats_value_tmpl_t *value_tmpl; //!< Value template
337 void *stats; //!< Struct containing the raw stats to process
338 lcc_value_list_t *value; //!< Collectd stats struct to populate
339
340 rs_stats_tmpl_t *next; //!< Next...
341};
342
343/*
344 * collectd.c - Registration and processing functions
345 */
346rs_stats_tmpl_t *rs_stats_collectd_init_latency(TALLOC_CTX *ctx, rs_stats_tmpl_t **out, rs_t *conf,
347 char const *type, rs_latency_t *stats, fr_radius_packet_code_t code);
348void rs_stats_collectd_do_stats(rs_t *conf, rs_stats_tmpl_t *tmpls, struct timeval *now);
349int rs_stats_collectd_open(rs_t *conf);
350int rs_stats_collectd_close(rs_t *conf);
351#endif
#define RCSIDH(h, id)
Definition build.h:486
fr_radius_packet_code_t
RADIUS packet codes.
Definition defs.h:31
@ FR_RADIUS_CODE_MAX
Maximum possible protocol code.
Definition defs.h:53
Test enumeration values.
Definition dict_test.h:92
Stores all information relating to an event list.
Definition event.c:377
unsigned char uint8_t
static rs_t * conf
Definition radsniff.c:53
rs_stats_t * stats
Where to write stats.
Definition radsniff.h:222
fr_radius_packet_code_t filter_response_code
Filter response packets by code.
Definition radsniff.h:292
fr_pcap_t * in
PCAP handle event occurred on.
Definition radsniff.h:219
fr_packet_t * expect
Request/response.
Definition radsniff.h:187
bool to_output_dir
Were writing attributes into directory.
Definition radsniff.h:258
struct rs::@1 stats
uint64_t attribute_underflow
Definition radsniff.h:146
rs_stats_print_cb_t body
Print body.
Definition radsniff.h:248
bool print_packet
Print packet info, disabled with -W.
Definition radsniff.h:266
uint64_t min_length_field
Definition radsniff.h:139
uint8_t * data
PCAP packet data.
Definition radsniff.h:168
fr_dict_attr_t const * list_da[RS_MAX_ATTRS]
Output CSV with these attribute values.
Definition radsniff.h:279
char const * output_dir
Where we should save the files $PATH/requests.txt and $PATH/reply.txt.
Definition radsniff.h:259
fr_timer_t * event
Event created when we received the original request.
Definition radsniff.h:178
stats_out_t
Definition radsniff.h:81
@ RS_STATS_OUT_STDIO_CSV
Definition radsniff.h:86
@ RS_STATS_OUT_STDIO_FANCY
Definition radsniff.h:85
bool in_request_tree
Whether the request is currently in the request tree.
Definition radsniff.h:209
rs_status_t event_flags
Events we log and capture on.
Definition radsniff.h:294
fr_dict_attr_t const * link_da[RS_MAX_ATTRS]
fr_dict_attr_ts to link on.
Definition radsniff.h:283
uint64_t latency_smoothed_count
Number of CMA datapoints processed.
Definition radsniff.h:108
fr_rb_node_t link_node
Definition radsniff.h:208
int link_da_num
Number of rtx fr_dict_attr_ts.
Definition radsniff.h:284
fr_radius_packet_code_t filter_request_code
Filter request packets by code.
Definition radsniff.h:291
rs_stats_t * stats
Stats to process.
Definition radsniff.h:246
int buffer_pkts
Size of the ring buffer to setup for live capture.
Definition radsniff.h:297
char const * filter_response
Raw response filter string.
Definition radsniff.h:287
fr_event_list_t * list
List to insert new event into.
Definition radsniff.h:243
int list_da_num
Definition radsniff.h:280
bool from_dev
Were reading pcap data from devices.
Definition radsniff.h:253
uint64_t min_length_packet
Definition radsniff.h:138
rs_packet_logger_t logger
Packet logger.
Definition radsniff.h:295
char * pcap_filter_vlan
Variant of the normal filter to apply to devices which support VLAN tags.
Definition radsniff.h:275
char * pcap_filter
PCAP filter string applied to live capture devices.
Definition radsniff.h:274
int intervals
Number of stats intervals.
Definition radsniff.h:105
#define RS_MAX_ATTRS
Maximum number of attributes we can filter on.
Definition radsniff.h:45
bool from_auto
From list was auto-generated.
Definition radsniff.h:264
rs_latency_t * stats_req
Latency entry for the request type.
Definition radsniff.h:200
bool done_header
Have we printed the stats header?
Definition radsniff.h:242
uint64_t attribute_too_short
Definition radsniff.h:143
bool decode_attrs
Whether we should decode attributes in the request and response.
Definition radsniff.h:267
uint64_t id
Monotonically increasing packet counter.
Definition radsniff.h:177
void(* rs_stats_print_header_cb_t)(rs_update_t *this)
Callback for printing stats header.
Definition radsniff.h:230
rs_latency_t * stats_rsp
Latency entry for the request type.
Definition radsniff.h:201
bool to_file
Were writing pcap data to files.
Definition radsniff.h:255
uint64_t ma_invalid_length
Definition radsniff.h:145
fr_pair_list_t link_vps
fr_pair_ts used to link retransmissions.
Definition radsniff.h:191
fr_rb_node_t request_node
Definition radsniff.h:207
fr_packet_t * packet
The original packet.
Definition radsniff.h:185
#define RS_RETRANSMIT_MAX
Maximum number of times we expect to see a packet retransmitted.
Definition radsniff.h:44
rs_stats_print_header_cb_t head
Print header.
Definition radsniff.h:247
char * list_attributes
Raw attribute filter string.
Definition radsniff.h:278
char * radius_secret
Secret to decode encrypted attributes.
Definition radsniff.h:272
bool from_file
Were reading pcap data from files.
Definition radsniff.h:252
fr_pcap_t * out
Where to write output.
Definition radsniff.h:220
uint64_t attribute_overflow
Definition radsniff.h:144
uint64_t header_overflow
Definition radsniff.h:141
fr_pcap_t * in
PCAP handle the original request was received on.
Definition radsniff.h:184
uint64_t invalid_attribute
Definition radsniff.h:142
fr_pcap_t * in
Linked list of PCAP handles to check for drops.
Definition radsniff.h:245
rs_capture_t * capture_p
Next packet slot.
Definition radsniff.h:195
void(* rs_stats_print_cb_t)(rs_update_t *this, rs_stats_t *stats, struct timeval *now)
Callback for printing stats values.
Definition radsniff.h:235
bool in_link_tree
Whether the request is currently in the linked tree.
Definition radsniff.h:210
int intervals
Number of stats intervals.
Definition radsniff.h:155
fr_event_list_t * list
The event list.
Definition radsniff.h:217
fr_packet_t * linked
The subsequent response or forwarded request the packet was linked against.
Definition radsniff.h:189
bool verify_radius_authenticator
Check RADIUS authenticator in packets.
Definition radsniff.h:270
uint64_t limit
Maximum number of packets to capture.
Definition radsniff.h:298
char const * pidfile
File to write PID to.
Definition radsniff.h:262
uint64_t min_length_mimatch
Definition radsniff.h:140
uint64_t rt_rsp
Number of times we saw a retransmitted response packet.
Definition radsniff.h:198
bool from_stdin
Were reading pcap data from stdin.
Definition radsniff.h:254
bool daemonize
Daemonize and write PID out to file.
Definition radsniff.h:261
double latency_smoothed
Smoothed moving average.
Definition radsniff.h:107
uint64_t rt_req
Number of times we saw the same request packet.
Definition radsniff.h:197
fr_pair_list_t filter_response_vps
Sorted filter vps.
Definition radsniff.h:290
bool promiscuous
Capture in promiscuous mode.
Definition radsniff.h:265
fr_pair_list_t expect_vps
Definition radsniff.h:188
fr_pair_list_t packet_vps
Definition radsniff.h:186
bool logged
Whether any messages regarding this request were logged.
Definition radsniff.h:180
char * link_attributes
Names of fr_dict_attr_ts to use for rtx.
Definition radsniff.h:282
bool silent_cleanup
Cleanup was forced before normal expiry period, ignore stats about packet loss.
Definition radsniff.h:203
char const * filter_request
Raw request filter string.
Definition radsniff.h:286
void(* rs_packet_logger_t)(uint64_t count, rs_status_t status, fr_pcap_t *handle, fr_packet_t *packet, fr_pair_list_t *list, struct timeval *elapsed, struct timeval *latency, bool response, bool body)
Definition radsniff.h:78
rs_status_t
Definition radsniff.h:69
@ RS_ERROR
Definition radsniff.h:74
@ RS_UNLINKED
Definition radsniff.h:71
@ RS_REUSED
Definition radsniff.h:73
@ RS_LOST
Definition radsniff.h:75
@ RS_NORMAL
Definition radsniff.h:70
@ RS_RTX
Definition radsniff.h:72
struct pcap_pkthdr * header
PCAP packet header.
Definition radsniff.h:167
uint64_t ma_missing
Definition radsniff.h:148
uint64_t too_many_attributes
Definition radsniff.h:147
bool verify_udp_checksum
Check UDP checksum in packets.
Definition radsniff.h:269
bool to_stdout
Were writing pcap data to stdout.
Definition radsniff.h:256
fr_pair_list_t filter_request_vps
Sorted filter vps.
Definition radsniff.h:289
Definition radsniff.h:251
Statistic write/print event.
Definition radsniff.h:216
Stats for a single interval.
Definition radsniff.h:104
Wrapper for fr_packet_t.
Definition radsniff.h:176
One set of statistics.
Definition radsniff.h:154
FD data which gets passed to callbacks.
Definition radsniff.h:241
return count
Definition module.c:155
fr_aka_sim_id_type_t type
A timer event.
Definition timer.c:84
static size_t char ** out
Definition value.h:1023