All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
radsniff.h
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 #ifndef _FR_RADSNIFF_H
17 #define _FR_RADSNIFF_H
18 /**
19  * $Id: 686605e0800f88bd8bbdf20014ae866b05f58dc6 $
20  *
21  * @file include/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  */
28 RCSIDH(radsniff_h, "$Id: 686605e0800f88bd8bbdf20014ae866b05f58dc6 $")
29 
30 #include <sys/types.h>
31 
32 #include <freeradius-devel/libradius.h>
33 #include <freeradius-devel/pcap.h>
34 #include <freeradius-devel/event.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 
69 typedef enum {
70  RS_NORMAL = 0x01,
71  RS_UNLINKED = 0x02,
72  RS_RTX = 0x04,
73  RS_REUSED = 0x08,
74  RS_ERROR = 0x10,
75  RS_LOST = 0x20
76 } rs_status_t;
77 
78 typedef void (*rs_packet_logger_t)(uint64_t count, rs_status_t status, fr_pcap_t *handle, RADIUS_PACKET *packet,
79  struct timeval *elapsed, struct timeval *latency, bool response, bool body);
80 typedef enum {
81 #ifdef HAVE_COLLECTDC_H
82  RS_STATS_OUT_COLLECTD = 1,
83 #endif
86 } stats_out_t;
87 
88 typedef struct rs rs_t;
89 
90 #ifdef HAVE_COLLECTDC_H
91 typedef struct rs_stats_tmpl rs_stats_tmpl_t;
92 typedef struct rs_stats_value_tmpl rs_stats_value_tmpl_t;
93 #endif
94 
95 typedef struct rs_counters {
96  uint64_t type[PW_CODE_MAX];
98 
99 /** Stats for a single interval
100  *
101  * And interval is defined as the time between a call to the stats output function.
102  */
103 typedef struct rs_latency {
104  int intervals; //!< Number of stats intervals.
105 
106  double latency_smoothed; //!< Smoothed moving average.
107  uint64_t latency_smoothed_count; //!< Number of CMA datapoints processed.
108 
109  struct {
110  uint64_t received_total; //!< Total received over interval.
111  uint64_t linked_total; //!< Total request/response pairs over interval.
112  uint64_t unlinked_total; //!< Total unlinked over interval.
113  uint64_t reused_total; //!< Total reused over interval.
114  uint64_t lost_total; //!< Total packets definitely lost in this interval.
115  uint64_t rt_total[RS_RETRANSMIT_MAX + 1]; //!< Number of RTX until complete
116  //!< over interval.
117 
118 
119  double received; //!< Number of this type of packet we've received.
120  double linked; //!< Number of request/response pairs
121  double unlinked; //!< Response with no request.
122  double reused; //!< ID re-used too quickly.
123  double lost; //!< Never got a response to a request.
124  double rt[RS_RETRANSMIT_MAX + 1]; //!< Number of times we saw the same
125  //!< request packet.
126 
127  long double latency_total; //!< Total latency between requests/responses in the
128  //!< interval.
129  double latency_average; //!< Average latency (this iteration).
130 
131  double latency_high; //!< Latency high water mark.
132  double latency_low; //!< Latency low water mark.
133  } interval;
134 } rs_latency_t;
135 
136 typedef struct rs_malformed {
140  uint64_t header_overflow;
147  uint64_t ma_missing;
149 
150 /** One set of statistics
151  *
152  */
153 typedef struct rs_stats {
154  int intervals; //!< Number of stats intervals.
155 
156  rs_latency_t exchange[PW_CODE_MAX]; //!< We end up allocating ~16K, but memory is cheap so
157  //!< what the hell. This is required because instances of
158  //!< FreeRADIUS delay Access-Rejects, which would artificially
159  //!< increase latency stats for Access-Requests.
160 
161  struct timeval quiet; //!< We may need to 'mute' the stats if libpcap starts
162  //!< dropping packets, or we run out of memory.
163 } rs_stats_t;
164 
165 typedef struct rs_capture {
166  struct pcap_pkthdr *header; //!< PCAP packet header.
167  uint8_t *data; //!< PCAP packet data.
168 } rs_capture_t;
169 
170 /** Wrapper for RADIUS_PACKET
171  *
172  * Allows an event to be associated with a request packet. This is required because we need to disarm
173  * the event timer when a response is received, so we don't erroneously log the response as lost.
174  */
175 typedef struct rs_request {
176  uint64_t id; //!< Monotonically increasing packet counter.
177  fr_event_t *event; //!< Event created when we received the original request.
178 
179  bool logged; //!< Whether any messages regarding this request were logged.
180 
181  struct timeval when; //!< Time when the packet was received, or next time an event
182  //!< is scheduled.
183  fr_pcap_t *in; //!< PCAP handle the original request was received on.
184  RADIUS_PACKET *packet; //!< The original packet.
185  RADIUS_PACKET *expect; //!< Request/response.
186  RADIUS_PACKET *linked; //!< The subsequent response or forwarded request the packet
187  //!< was linked against.
188 
189 
190  rs_capture_t capture[RS_RETRANSMIT_MAX]; //!< Buffered request packets (if a response filter
191  //!< has been applied).
192  rs_capture_t *capture_p; //!< Next packet slot.
193 
194  uint64_t rt_req; //!< Number of times we saw the same request packet.
195  uint64_t rt_rsp; //!< Number of times we saw a retransmitted response
196  //!< packet.
197  rs_latency_t *stats_req; //!< Latency entry for the request type.
198  rs_latency_t *stats_rsp; //!< Latency entry for the request type.
199 
200  bool silent_cleanup; //!< Cleanup was forced before normal expiry period,
201  //!< ignore stats about packet loss.
202 
203  VALUE_PAIR *link_vps; //!< VALUE_PAIRs used to link retransmissions.
204 
205  bool in_request_tree; //!< Whether the request is currently in the request tree.
206  bool in_link_tree; //!< Whether the request is currently in the linked tree.
207 } rs_request_t;
208 
209 /** Statistic write/print event
210  *
211  */
212 typedef struct rs_event {
213  fr_event_list_t *list; //!< The event list.
214 
215  fr_pcap_t *in; //!< PCAP handle event occurred on.
216  fr_pcap_t *out; //!< Where to write output.
217 
218  rs_stats_t *stats; //!< Where to write stats.
219 } rs_event_t;
220 
221 typedef struct rs_update rs_update_t;
222 
223 /** Callback for printing stats header.
224  *
225  */
227 
228 /** Callback for printing stats values.
229  *
230  */
231 typedef void (*rs_stats_print_cb_t)(rs_update_t *this, rs_stats_t *stats, struct timeval *now);
232 
233 
234 /** FD data which gets passed to callbacks
235  *
236  */
237 struct rs_update {
238  bool done_header; //!< Have we printed the stats header?
239  fr_event_list_t *list; //!< List to insert new event into.
240 
241  fr_pcap_t *in; //!< Linked list of PCAP handles to check for drops.
242  rs_stats_t *stats; //!< Stats to process.
243  rs_stats_print_header_cb_t head; //!< Print header.
244  rs_stats_print_cb_t body; //!< Print body.
245 };
246 
247 struct rs {
248  bool from_file; //!< Were reading pcap data from files.
249  bool from_dev; //!< Were reading pcap data from devices.
250  bool from_stdin; //!< Were reading pcap data from stdin.
251  bool to_file; //!< Were writing pcap data to files.
252  bool to_stdout; //!< Were writing pcap data to stdout.
253 
254  bool daemonize; //!< Daemonize and write PID out to file.
255  char const *pidfile; //!< File to write PID to.
256 
257  bool from_auto; //!< From list was auto-generated.
258  bool promiscuous; //!< Capture in promiscuous mode.
259  bool print_packet; //!< Print packet info, disabled with -W
260  bool decode_attrs; //!< Whether we should decode attributes in the request
261  //!< and response.
262  bool verify_udp_checksum; //!< Check UDP checksum in packets.
263 
264  char const *radius_secret; //!< Secret to decode encrypted attributes.
265 
266  char *pcap_filter; //!< PCAP filter string applied to live capture devices.
267 
268  char *list_attributes; //!< Raw attribute filter string.
269  fr_dict_attr_t const *list_da[RS_MAX_ATTRS]; //!< Output CSV with these attribute values.
271 
272  char *link_attributes; //!< Names of fr_dict_attr_ts to use for rtx.
273  fr_dict_attr_t const *link_da[RS_MAX_ATTRS]; //!< fr_dict_attr_ts to link on.
274  int link_da_num; //!< Number of rtx fr_dict_attr_ts.
275 
276  char const *filter_request; //!< Raw request filter string.
277  char const *filter_response; //!< Raw response filter string.
278 
279  VALUE_PAIR *filter_request_vps; //!< Sorted filter vps.
280  VALUE_PAIR *filter_response_vps; //!< Sorted filter vps.
281  PW_CODE filter_request_code; //!< Filter request packets by code.
282  PW_CODE filter_response_code; //!< Filter response packets by code.
283 
284  rs_status_t event_flags; //!< Events we log and capture on.
285  rs_packet_logger_t logger; //!< Packet logger
286 
287  int buffer_pkts; //!< Size of the ring buffer to setup for live capture.
288  uint64_t limit; //!< Maximum number of packets to capture
289 
290  struct {
291  int interval; //!< Time between stats updates in seconds.
292  stats_out_t out; //!< Where to write stats.
293  int timeout; //!< Maximum length of time we wait for a response.
294 
295 #ifdef HAVE_COLLECTDC_H
296  char const *collectd; //!< Collectd server/port/unixsocket
297  char const *prefix; //!< Prefix collectd stats with this value.
298  lcc_connection_t *handle; //!< Collectd client handle.
299  rs_stats_tmpl_t *tmpl; //!< The stats templates we created on startup.
300 #endif
301  } stats;
302 };
303 
304 #ifdef HAVE_COLLECTDC_H
305 
306 /** Callback for processing stats values.
307  *
308  */
309 typedef void (*rs_stats_cb_t)(rs_t *conf, rs_stats_value_tmpl_t *tmpl);
310 
311 struct rs_stats_value_tmpl {
312  void *src; //!< Pointer to source field in struct. Must be set by
313  //!< stats_collectdc_init caller.
314  int type; //!< Stats type.
315  rs_stats_cb_t cb; //!< Callback used to process stats
316  void *dst; //!< Pointer to dst field in value struct. Must be set
317  //!< by stats_collectdc_init caller.
318 };
319 
320 /** Stats templates
321  *
322  * This gets processed to turn radsniff stats structures into collectd lcc_value_list_t structures.
323  */
324 struct rs_stats_tmpl
325 {
326  rs_stats_value_tmpl_t *value_tmpl; //!< Value template
327  void *stats; //!< Struct containing the raw stats to process
328  lcc_value_list_t *value; //!< Collectd stats struct to populate
329 
330  rs_stats_tmpl_t *next; //!< Next...
331 };
332 
333 /*
334  * collectd.c - Registration and processing functions
335  */
336 rs_stats_tmpl_t *rs_stats_collectd_init_latency(TALLOC_CTX *ctx, rs_stats_tmpl_t **out, rs_t *conf,
337  char const *type, rs_latency_t *stats, PW_CODE code);
338 void rs_stats_collectd_do_stats(rs_t *conf, rs_stats_tmpl_t *tmpls, struct timeval *now);
339 int rs_stats_collectd_open(rs_t *conf);
340 int rs_stats_collectd_close(rs_t *conf);
341 
342 #endif
343 #endif
bool logged
Whether any messages regarding this request were logged.
Definition: radsniff.h:179
rs_stats_t * stats
Stats to process.
Definition: radsniff.h:242
struct rs_capture rs_capture_t
rs_stats_t * stats
Where to write stats.
Definition: radsniff.h:218
bool decode_attrs
Whether we should decode attributes in the request and response.
Definition: radsniff.h:260
#define RCSIDH(h, id)
Definition: build.h:136
fr_dict_attr_t const * link_da[RS_MAX_ATTRS]
fr_dict_attr_ts to link on.
Definition: radsniff.h:273
bool to_stdout
Were writing pcap data to stdout.
Definition: radsniff.h:252
int link_da_num
Number of rtx fr_dict_attr_ts.
Definition: radsniff.h:274
fr_pcap_t * in
Linked list of PCAP handles to check for drops.
Definition: radsniff.h:241
bool daemonize
Daemonize and write PID out to file.
Definition: radsniff.h:254
bool done_header
Have we printed the stats header?
Definition: radsniff.h:238
VALUE_PAIR * link_vps
VALUE_PAIRs used to link retransmissions.
Definition: radsniff.h:203
char const * radius_secret
Secret to decode encrypted attributes.
Definition: radsniff.h:264
Dictionary attribute.
Definition: dict.h:77
rs_latency_t * stats_req
Latency entry for the request type.
Definition: radsniff.h:197
struct rs::@9 stats
uint64_t invalid_attribute
Definition: radsniff.h:141
stats_out_t
Definition: radsniff.h:80
bool verify_udp_checksum
Check UDP checksum in packets.
Definition: radsniff.h:262
char * pcap_filter
PCAP filter string applied to live capture devices.
Definition: radsniff.h:266
uint64_t too_many_attributes
Definition: radsniff.h:146
fr_event_t * event
Event created when we received the original request.
Definition: radsniff.h:177
char const * pidfile
File to write PID to.
Definition: radsniff.h:255
Wrapper for RADIUS_PACKET.
Definition: radsniff.h:175
fr_pcap_t * in
PCAP handle the original request was received on.
Definition: radsniff.h:183
rs_capture_t * capture_p
Next packet slot.
Definition: radsniff.h:192
static float timeout
Definition: radclient.c:43
uint64_t min_length_mimatch
Definition: radsniff.h:139
char * link_attributes
Names of fr_dict_attr_ts to use for rtx.
Definition: radsniff.h:272
bool from_stdin
Were reading pcap data from stdin.
Definition: radsniff.h:250
bool promiscuous
Capture in promiscuous mode.
Definition: radsniff.h:258
struct rs_counters rs_counters_t
struct rs_latency::@8 interval
rs_latency_t exchange[PW_CODE_MAX]
We end up allocating ~16K, but memory is cheap so what the hell.
Definition: radsniff.h:156
bool from_dev
Were reading pcap data from devices.
Definition: radsniff.h:249
uint64_t ma_missing
Definition: radsniff.h:147
struct rs_latency rs_latency_t
Stats for a single interval.
uint64_t attribute_overflow
Definition: radsniff.h:143
RADIUS_PACKET * packet
The original packet.
Definition: radsniff.h:184
RADIUS_PACKET * linked
The subsequent response or forwarded request the packet was linked against.
Definition: radsniff.h:186
uint64_t latency_smoothed_count
Number of CMA datapoints processed.
Definition: radsniff.h:107
uint8_t * data
PCAP packet data.
Definition: radsniff.h:167
struct rs_request rs_request_t
Wrapper for RADIUS_PACKET.
uint64_t id
Monotonically increasing packet counter.
Definition: radsniff.h:176
int intervals
Number of stats intervals.
Definition: radsniff.h:104
fr_pcap_t * in
PCAP handle event occurred on.
Definition: radsniff.h:215
PW_CODE filter_request_code
Filter request packets by code.
Definition: radsniff.h:281
rs_stats_print_header_cb_t head
Print header.
Definition: radsniff.h:243
rs_latency_t * stats_rsp
Latency entry for the request type.
Definition: radsniff.h:198
static rc_stats_t stats
Definition: radclient.c:47
bool in_link_tree
Whether the request is currently in the linked tree.
Definition: radsniff.h:206
int buffer_pkts
Size of the ring buffer to setup for live capture.
Definition: radsniff.h:287
uint64_t attribute_underflow
Definition: radsniff.h:145
int list_da_num
Definition: radsniff.h:270
fr_dict_attr_t const * list_da[RS_MAX_ATTRS]
Output CSV with these attribute values.
Definition: radsniff.h:269
uint64_t ma_invalid_length
Definition: radsniff.h:144
void(* rs_packet_logger_t)(uint64_t count, rs_status_t status, fr_pcap_t *handle, RADIUS_PACKET *packet, struct timeval *elapsed, struct timeval *latency, bool response, bool body)
Definition: radsniff.h:78
FD data which gets passed to callbacks.
Definition: radsniff.h:237
Stores an attribute, a value and various bits of other data.
Definition: pair.h:112
bool silent_cleanup
Cleanup was forced before normal expiry period, ignore stats about packet loss.
Definition: radsniff.h:200
char const * filter_response
Raw response filter string.
Definition: radsniff.h:277
uint64_t min_length_field
Definition: radsniff.h:138
uint64_t type[PW_CODE_MAX]
Definition: radsniff.h:96
static rs_t * conf
Definition: radsniff.c:46
struct pcap_pkthdr * header
PCAP packet header.
Definition: radsniff.h:166
rs_stats_print_cb_t body
Print body.
Definition: radsniff.h:244
PW_CODE filter_response_code
Filter response packets by code.
Definition: radsniff.h:282
rs_status_t event_flags
Events we log and capture on.
Definition: radsniff.h:284
uint64_t rt_rsp
Number of times we saw a retransmitted response packet.
Definition: radsniff.h:195
uint64_t min_length_packet
Definition: radsniff.h:137
static char const * prefix
Definition: mainconfig.c:81
bool to_file
Were writing pcap data to files.
Definition: radsniff.h:251
VALUE_PAIR * filter_response_vps
Sorted filter vps.
Definition: radsniff.h:280
#define RS_RETRANSMIT_MAX
Maximum number of times we expect to see a packet retransmitted.
Definition: radsniff.h:44
char * list_attributes
Raw attribute filter string.
Definition: radsniff.h:268
RADIUS_PACKET * expect
Request/response.
Definition: radsniff.h:185
struct timeval quiet
We may need to 'mute' the stats if libpcap starts dropping packets, or we run out of memory...
Definition: radsniff.h:161
rs_capture_t capture[RS_RETRANSMIT_MAX]
Buffered request packets (if a response filter has been applied).
Definition: radsniff.h:190
bool print_packet
Print packet info, disabled with -W.
Definition: radsniff.h:259
VALUE_PAIR * filter_request_vps
Sorted filter vps.
Definition: radsniff.h:279
struct rs_event rs_event_t
Statistic write/print event.
rs_packet_logger_t logger
Packet logger.
Definition: radsniff.h:285
struct timeval when
Time when the packet was received, or next time an event is scheduled.
Definition: radsniff.h:181
uint64_t limit
Maximum number of packets to capture.
Definition: radsniff.h:288
rs_status_t
Definition: radsniff.h:69
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:231
One set of statistics.
Definition: radsniff.h:153
fr_pcap_t * out
Where to write output.
Definition: radsniff.h:216
char const * filter_request
Raw request filter string.
Definition: radsniff.h:276
fr_event_list_t * list
List to insert new event into.
Definition: radsniff.h:239
uint64_t header_overflow
Definition: radsniff.h:140
double latency_smoothed
Smoothed moving average.
Definition: radsniff.h:106
PW_CODE
RADIUS packet codes.
Definition: radius.h:90
int intervals
Number of stats intervals.
Definition: radsniff.h:154
Statistic write/print event.
Definition: radsniff.h:212
struct rs_malformed rs_malformed_t
bool from_auto
From list was auto-generated.
Definition: radsniff.h:257
Definition: radsniff.h:247
bool in_request_tree
Whether the request is currently in the request tree.
Definition: radsniff.h:205
uint64_t rt_req
Number of times we saw the same request packet.
Definition: radsniff.h:194
Stats for a single interval.
Definition: radsniff.h:103
#define RS_MAX_ATTRS
Maximum number of attributes we can filter on.
Definition: radsniff.h:45
bool from_file
Were reading pcap data from files.
Definition: radsniff.h:248
uint64_t attribute_too_short
Definition: radsniff.h:142
Maximum possible code.
Definition: radius.h:111
fr_event_list_t * list
The event list.
Definition: radsniff.h:213
void(* rs_stats_print_header_cb_t)(rs_update_t *this)
Callback for printing stats header.
Definition: radsniff.h:226
struct rs_stats rs_stats_t
One set of statistics.