forked from Cacti/spine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
spine.h
636 lines (588 loc) · 17.7 KB
/
spine.h
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
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
/*
ex: set tabstop=4 shiftwidth=4 autoindent:
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2023 The Cacti Group |
| |
| This program is free software; you can redistribute it and/or |
| modify it under the terms of the GNU Lesser General Public |
| License as published by the Free Software Foundation; either |
| version 2.1 of the License, or (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Lesser General Public License for more details. |
| |
| You should have received a copy of the GNU Lesser General Public |
| License along with this library; if not, write to the Free Software |
| Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| 02110-1301, USA |
| |
+-------------------------------------------------------------------------+
| spine: a backend data gatherer for cacti |
+-------------------------------------------------------------------------+
| This poller would not have been possible without: |
| - Larry Adams (current development and enhancements) |
| - Rivo Nurges (rrd support, mysql poller cache, misc functions) |
| - RTG (core poller code, pthreads, snmp, autoconf examples) |
| - Brady Alleman/Doug Warner (threading ideas, implimentation details) |
+-------------------------------------------------------------------------+
| - Cacti - http://www.cacti.net/ |
+-------------------------------------------------------------------------+
*/
#ifndef _SPINE_H_
#define _SPINE_H_
/* Defines */
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#define LOCAL 0
#define REMOTE 1
#define SPINE_NONE 0
#define SPINE_IPV4 1
#define SPINE_IPV6 2
#ifndef __GNUC__
# define __attribute__(x) /* NOTHING */
#endif
/* Windows does not support stderr. Therefore, don't use it. */
#ifdef __CYGWIN__
#define DISABLE_STDERR
#endif
#ifdef HAS_EXECINFO_H
#include <execinfo.h>
#endif
/* if a host is legal, return TRUE */
#define HOSTID_DEFINED(x) ((x) >= 0)
/* warning-suppression macros
*
* There are times when we cannot avoid using a parameter or variable which
* is not used, and these correctly generate compiler warnings. But when we
* *know* that the variable is actually intended to be unused, we can use one
* of these macros inside the function to suppress it. This has the effect
* of suppressing the warning (a good thing), plus documenting to the reader
* that this is intentional.
*
* Both do the same thing - they're just for different semantics.
*/
#define UNUSED_VARIABLE(p) (void)(p)
#define UNUSED_PARAMETER(p) (void)(p)
/* logging macros
*
* These all perform conditional logging based on the current runtime logging
* level, and it relies on a bit of tricky (but entirely portable) preprocessor
* techniques.
*
* Standard C does not support variadic macros (macros with a variable number
* of parameters), and though GNU C does, it's not at all portable. So we instead
* rely on the fact that putting parens around something turn multiple params
* into one:
*
* SPINE_LOG_DEBUG(("n=%d string=%s foo=%f", n, string, foo));
*
* This macros has *one* parameter:
*
* ("n=%d string=%s foo=%f", n, string, foo)
*
* and the parentheses are part of it. When we call this macro, we pass the
* "single" parameter unadorned, so that
*
* spine_log args
*
* expands to
*
* spine_log ("n=%d string=%s foo=%f", n, string, foo)
*
* Voila: it's a normal printf-like call.
*
* The second part of this is the conditional test, and the obvious approach
* of using an "if" statement is exceptionally bad form: there are all kinds
* of pitfalls which arise in this case. Instead, we should try to use an
* *expression*, which has none of these problems.
*
* The conditional tests are modelled after the assert() mechanism, which
* checks the first parameter, and if it's true, it evaluates the second
* paramater. If the test is not true, then the second part is *guaranteed*
* not to be evaluated.
*
* The (void) prefix is to forestall compiler warnings about expressions
* not being used.
*/
#define SPINE_LOG(format_and_args) (spine_log format_and_args)
#define SPINE_LOG_LOW(format_and_args) (void)(set.log_level >= POLLER_VERBOSITY_LOW && spine_log format_and_args)
#define SPINE_LOG_MEDIUM(format_and_args) (void)(set.log_level >= POLLER_VERBOSITY_MEDIUM && spine_log format_and_args)
#define SPINE_LOG_HIGH(format_and_args) (void)(set.log_level >= POLLER_VERBOSITY_HIGH && spine_log format_and_args)
#define SPINE_LOG_DEBUG(format_and_args) (void)(set.log_level >= POLLER_VERBOSITY_DEBUG && spine_log format_and_args)
#define SPINE_LOG_DEVDBG(format_and_args) (void)(set.log_level >= POLLER_VERBOSITY_DEVDBG && spine_log format_and_args)
/* general constants */
#define MAX_THREADS 100
#define TINY_BUFSIZE 16
#define SMALL_BUFSIZE 256
#define MEDIUM_BUFSIZE 512
#define BUFSIZE 1024
#define DBL_BUFSIZE 2048
#define LRG_BUFSIZE 8096
#define BIG_BUFSIZE 65535
#define MEGA_BUFSIZE 1024000
#define HUGE_BUFSIZE 2048000
#define LOGSIZE 65535
#define LRG_LOGSIZE 1024000
#define BITSINBYTE 8
#define THIRTYTWO 4294967295ul
#define SIXTYFOUR 18446744073709551615ul
#define STAT_DESCRIP_ERROR 99
#define SPINE_PARENT 1
#define SPINE_FORK 0
/* locations to search for the config file */
#define CONFIG_PATHS 4
#define CONFIG_PATH_1 ""
#define CONFIG_PATH_2 "/etc/"
#define CONFIG_PATH_3 "/etc/cacti/"
#define CONFIG_PATH_4 "../etc/"
/* config file defaults */
#define DEFAULT_CONF_FILE "spine.conf"
#define DEFAULT_THREADS 5
#define DEFAULT_DB_HOST "localhost"
#define DEFAULT_DB_DB "cacti"
#define DEFAULT_DB_USER "cactiuser"
#define DEFAULT_DB_PASS "cactiuser"
#define DEFAULT_DB_PORT 3306
#define DEFAULT_DB_PREG 0
#define DEFAULT_LOGFILE "/var/www/html/cacti/log/cacti.log"
#define DEFAULT_TIMEOUT 294000000
/* threads constants */
#define LOCK_SNMP 0
#define LOCK_SETEUID 2
#define LOCK_GHBN 3
#define LOCK_POOL 4
#define LOCK_SYSLOG 5
#define LOCK_PHP 6
#define LOCK_PHP_PROC_0 7
#define LOCK_PHP_PROC_1 8
#define LOCK_PHP_PROC_2 9
#define LOCK_PHP_PROC_3 10
#define LOCK_PHP_PROC_4 11
#define LOCK_PHP_PROC_5 12
#define LOCK_PHP_PROC_6 13
#define LOCK_PHP_PROC_7 14
#define LOCK_PHP_PROC_8 15
#define LOCK_PHP_PROC_9 16
#define LOCK_PHP_PROC_10 17
#define LOCK_PHP_PROC_11 18
#define LOCK_PHP_PROC_12 19
#define LOCK_PHP_PROC_13 20
#define LOCK_PHP_PROC_14 21
#define LOCK_THDET 40
#define LOCK_HOST_TIME 41
#define LOCK_SNMP_O 0
#define LOCK_SETEUID_O 2
#define LOCK_GHBN_O 3
#define LOCK_POOL_O 4
#define LOCK_SYSLOG_O 5
#define LOCK_PHP_O 6
#define LOCK_PHP_PROC_0_O 7
#define LOCK_PHP_PROC_1_O 8
#define LOCK_PHP_PROC_2_O 9
#define LOCK_PHP_PROC_3_O 10
#define LOCK_PHP_PROC_4_O 11
#define LOCK_PHP_PROC_5_O 12
#define LOCK_PHP_PROC_6_O 13
#define LOCK_PHP_PROC_7_O 14
#define LOCK_PHP_PROC_8_O 15
#define LOCK_PHP_PROC_9_O 16
#define LOCK_PHP_PROC_10_O 17
#define LOCK_PHP_PROC_11_O 18
#define LOCK_PHP_PROC_12_O 19
#define LOCK_PHP_PROC_13_O 20
#define LOCK_PHP_PROC_14_O 21
#define LOCK_THDET_O 40
#define LOCK_HOST_TIME_O 41
/* poller actions */
#define POLLER_ACTION_SNMP 0
#define POLLER_ACTION_SCRIPT 1
#define POLLER_ACTION_PHP_SCRIPT_SERVER 2
#define POLLER_ACTION_SNMP_COUNT 10
#define POLLER_ACTION_SCRIPT_COUNT 11
#define POLLER_ACTION_PHP_SCRIPT_SERVER_COUNT 12
/* reindex constants */
#define POLLER_COMMAND_REINDEX 1
/* log destinations */
#define LOGDEST_FILE 1
#define LOGDEST_BOTH 2
#define LOGDEST_SYSLOG 3
#define LOGDEST_STDOUT 4
#define IS_LOGGING_TO_FILE() ((set.log_destination) == LOGDEST_FILE || (set.log_destination) == LOGDEST_BOTH)
#define IS_LOGGING_TO_SYSLOG() ((set.log_destination) == LOGDEST_SYSLOG || (set.log_destination) == LOGDEST_BOTH)
#define IS_LOGGING_TO_STDOUT() ((set.log_destination) == LOGDEST_STDOUT )
#define SPINE_FREE(s) do { if (s) { free((void *)s); s = NULL; } } while(0)
/* logging levels */
#define POLLER_VERBOSITY_NONE 1
#define POLLER_VERBOSITY_LOW 2
#define POLLER_VERBOSITY_MEDIUM 3
#define POLLER_VERBOSITY_HIGH 4
#define POLLER_VERBOSITY_DEBUG 5
#define POLLER_VERBOSITY_DEVDBG 6
/* logging separator constants */
#define GDC_MIN 0
#define GDC_HYPHEN 0
#define GDC_SLASH 1
#define GDC_DOT 2
#define GDC_MAX 2
#define GDC_DEFAULT 1
/* logging format constants */
#define GD_FMT_SIZE 21
#define GD_MIN 0
#define GD_MO_D_Y 0
#define GD_MN_D_Y 1
#define GD_D_MO_Y 2
#define GD_D_MN_Y 3
#define GD_Y_MO_D 4
#define GD_Y_MN_D 5
#define GD_MAX 5
#define GD_DEFAULT 5
/* host availability statics */
#define AVAIL_NONE 0
#define AVAIL_SNMP_AND_PING 1
#define AVAIL_SNMP 2
#define AVAIL_PING 3
#define AVAIL_SNMP_OR_PING 4
#define AVAIL_SNMP_GET_SYSDESC 5
#define AVAIL_SNMP_GET_NEXT 6
#define PING_ICMP 1
#define PING_UDP 2
#define PING_TCP 3
#define HOST_UNKNOWN 0
#define HOST_DOWN 1
#define HOST_RECOVERING 2
#define HOST_UP 3
/* required for ICMP and UDP ping */
#define ICMP_ECHO 8
#define ICMP_HDR_SIZE 8
/* required for PHP Script Server */
#define MAX_PHP_SERVERS 15
#define PHP_READY 0
#define PHP_BUSY 1
#define PHP_INIT 999
#define PHP_ERROR 99
/* required for validation of script results */
#define RESULT_INIT 0
#define RESULT_ARGX 1
#define RESULT_VALX 2
#define RESULT_SEPARATOR 3
#define RESULT_SPACE 4
#define RESULT_ALPHA 5
#define RESULT_DIGIT 6
/* snmp session status */
#define SNMP_1 0
#define SNMP_2c 1
#define SNMP_3 3
#define SNMP_NONE 4
/* Constants for remote polling */
#define REMOTE_ONLINE 0
#define REMOTE_OFFLINE 1
#define REMOTE_RECOVERY 2
/* These are used to perform string matches, returning TRUE/VALUE values.
* For strcmp() this is not really that useful, but the case-insensitive
* one has slight portability issues. Better to abstract them here.
*/
#define STRMATCH(a,b) (strcmp((a),(b)) == 0)
#define STRIMATCH(a,b) (strcasecmp((a),(b)) == 0)
/* When any kind of poller wants to set an undefined value; this particular
* value used ('U') springs from the requirements of rrdupdate. We also
* include the corresponding test macro which looks for the literal string
* "U". This *could* use strcmp(), but this is more efficient.
*/
#define SET_UNDEFINED(buf) ( (buf)[0] = 'U', (buf)[1] = '\0' )
#define IS_UNDEFINED(buf) ( (buf)[0] == 'U' && (buf)[1] == '\0' )
/*! Config Structure
*
* This structure holds Spine database configuration information and/or override values
* obtained via either accessing the database or reading the runtime options. In addition,
* it contains runtime status information.
*
*/
typedef struct config_struct {
/* stdout, stderr TTY protection */
int stdout_notty;
int stderr_notty;
/* general configuration/runtime settings */
int poller_id;
int poller_id_exists;
int device_threads_exists;
int poller_interval;
int parent_fork;
int num_parent_processes;
int script_timeout;
int active_profiles;
int total_snmp_ports;;
int threads;
int threads_set;
int logfile_processed;
int boost_enabled;
int boost_redirect;
int cygwinshloc;
/* debugging options */
int snmponly;
int SQL_readonly;
/* host range to be poller with this spine process */
int start_host_id;
int end_host_id;
char host_id_list[BIG_BUFSIZE];
int has_device_0;
/* database connection information */
char db_host[SMALL_BUFSIZE];
char db_db[SMALL_BUFSIZE];
char db_user[SMALL_BUFSIZE];
char db_pass[SMALL_BUFSIZE];
int db_ssl;
char db_ssl_key[BIG_BUFSIZE];
char db_ssl_cert[BIG_BUFSIZE];
char db_ssl_ca[BIG_BUFSIZE];
int d_b;
unsigned int db_port;
char dbversion[SMALL_BUFSIZE];
int dbonupdate;
int cacti_version;
/* path information */
char path_logfile[DBL_BUFSIZE];
char path_php[BUFSIZE];
char path_php_server[BUFSIZE];
/* logging options */
int log_level;
int log_destination;
int log_perror;
int log_pwarn;
int log_pstats;
char selective_device_debug[SMALL_BUFSIZE];
int spine_log_level;
int log_datetime_separator;
int log_datetime_format;
/* ping settings */
int icmp_avail;
int availability_method;
int ping_method;
int ping_retries;
int ping_timeout;
int ping_failure_count;
int ping_recovery_count;
int ping_only;
/* snmp options */
int snmp_max_get_size;
int snmp_retries;
char snmp_clientaddr[SMALL_BUFSIZE];
int mibs;
/* PHP Script Server Options */
int php_required;
int php_initialized;
int php_servers;
int php_current_server;
/* Exit code if we need it */
int exit_code;
size_t exit_size;
void* exit_stack[10];
/* Remote polling mode */
int mode;
/* remote database connection information */
char rdb_host[SMALL_BUFSIZE];
char rdb_db[SMALL_BUFSIZE];
char rdb_user[SMALL_BUFSIZE];
char rdb_pass[SMALL_BUFSIZE];
int rdb_ssl;
char rdb_ssl_key[BIG_BUFSIZE];
char rdb_ssl_cert[BIG_BUFSIZE];
char rdb_ssl_ca[BIG_BUFSIZE];
unsigned int rdb_port;
char rdbversion[SMALL_BUFSIZE];
int rdbonupdate;
} config_t;
/*! Target Structure
*
* This structure holds the contents of the Poller Items table and the results
* of each polling action.
*
*/
typedef struct target_struct {
int target_id;
char result[RESULTS_BUFFER];
int local_data_id;
int action;
char command[256];
char hostname[250];
char snmp_community[100];
int snmp_version;
char snmp_username[50];
char snmp_password[50];
char snmp_auth_protocol[7];
char snmp_priv_passphrase[200];
char snmp_priv_protocol[8];
char snmp_context[65];
char snmp_engine_id[30];
int snmp_port;
int snmp_timeout;
int availability_method;
int ping_method;
int ping_port;
int ping_timeout;
int ping_retries;
char rrd_name[30];
char rrd_path[255];
int rrd_num;
char arg1[512];
char arg2[255];
char arg3[255];
} target_t;
/*! SNMP OID's Structure
*
* This structure holds SNMP get results temporarily while polling is taking place.
*
*/
typedef struct snmp_oids {
int array_position;
char oid[512];
char result[RESULTS_BUFFER];
} snmp_oids_t;
/*! Poller Structure
*
* This structure holds thread polling instructions.
*
*/
typedef struct poller_thread {
int device_counter;
int host_id;
int host_thread;
int host_threads;
int host_data_ids;
int threads_complete;
int complete;
char host_time[40];
double host_time_double;
sem_t *thread_init_sem;
} poller_thread_t;
/*! PHP Script Server Structure
*
* This structure holds status and PID information for all the running
* PHP Script Server processes.
*
*/
typedef struct php_processes {
int php_state;
pid_t php_pid;
int php_write_fd;
int php_read_fd;
} php_t;
/*! Host Structure
*
* This structure holds host information from the host table and is used throughout
* the application.
*
*/
typedef struct host_struct {
int id;
char hostname[250];
char snmp_community[100];
int snmp_version;
char snmp_username[50];
char snmp_password[50];
char snmp_auth_protocol[7];
char snmp_priv_passphrase[200];
char snmp_priv_protocol[8];
char snmp_context[65];
char snmp_engine_id[30];
int snmp_port;
int snmp_timeout;
int snmp_retries;
char snmp_sysDescr[600];
char snmp_sysObjectID[160];
unsigned long long snmp_sysUpTimeInstance;
char snmp_sysContact[300];
char snmp_sysName[300];
char snmp_sysLocation[600];
int max_oids;
int availability_method;
int ping_method;
int ping_port;
int ping_timeout;
int ping_retries;
int status;
int status_event_count;
char status_fail_date[40];
char status_rec_date[40];
char status_last_error[BUFSIZE];
double min_time;
double max_time;
double cur_time;
double avg_time;
int total_polls;
int failed_polls;
double availability;
int ignore_host;
void *snmp_session;
int snmp_status;
} host_t;
/*! Host Reindex Structure
*
* This structure holds the results of the host re-index checks and values.
*
*/
typedef struct host_reindex_struct {
char op[4];
char assert_value[100];
char arg1[512];
int data_query_id;
int action;
} reindex_t;
/*! Ping Result Structure
*
* This structure holds the results of a host ping.
*
*/
typedef struct ping_results {
char hostname[SMALL_BUFSIZE];
char ping_status[50];
char ping_response[SMALL_BUFSIZE];
char snmp_status[50];
char snmp_response[SMALL_BUFSIZE];
} ping_t;
/*! Name Result Structure
*
* This structure holds the results of a name/port split
*
*/
typedef struct name_port {
// Method = 0 - default, 1 - tcp, 2 - udp
char hostname[SMALL_BUFSIZE];
int method;
int port;
} name_t;
/*! MySQL Connection Pool Structure
*
* This structure holds the mysql connetion pool object.
*/
typedef struct db_connection {
int id;
int free;
MYSQL mysql;
} pool_t;
/* Include all Standard Spine Headers */
#include "poller.h"
#include "locks.h"
#include "keywords.h"
#include "snmp.h"
#include "php.h"
#include "ping.h"
#include "sql.h"
#include "util.h"
#include "nft_popen.h"
#include "error.h"
/* Globals */
extern config_t set;
extern php_t *php_processes;
extern char start_datetime[20];
extern char config_paths[CONFIG_PATHS][BUFSIZE];
extern sem_t available_threads;
extern sem_t available_scripts;
extern pool_t *db_pool_remote;
extern pool_t *db_pool_local;
#endif /* not _SPINE_H_ */