2 * collectd - src/named.c
3 * Copyright (C) 2006 Florian octo Forster
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * Florian octo Forster <octo at verplant.org>
26 #include "configfile.h"
27 #include "utils_debug.h"
30 # include <sys/poll.h>
33 #define MODULE_NAME "named"
36 # define NAMED_HAVE_CONFIG 1
38 # define NAMED_HAVE_CONFIG 0
43 # define NAMED_HAVE_READ 1
45 # define NAMED_HAVE_READ 0
48 static char *qtype_file = "named/qtype-%s.rrd";
50 static char *qtype_ds_def[] =
52 "DS:value:COUNTER:"COLLECTD_HEARTBEAT":0:U",
55 static int qtype_ds_num = 1;
59 static char *config_keys[] =
64 static int config_keys_num = 1;
65 #endif /* HAVE_LIBPCAP */
66 #endif /* NAMED_HAVE_CONFIG */
69 #define PCAP_SNAPLEN 1460
70 static char *pcap_device = NULL;
75 static int named_config (char *key, char *value)
78 if (strcasecmp (key, "Interface") == 0)
80 if (pcap_device != NULL)
82 if ((pcap_device = strdup (value)) == NULL)
91 #endif /* HAVE_LIBPCAP */
93 #endif /* NAMED_HAVE_CONFIG */
95 static int named_child_send_data (void)
97 int values[2 * T_MAX];
102 for (i = 0; i < T_MAX; i++)
104 if (qtype_counts[i] != 0)
106 values[2 * values_num] = i;
107 values[(2 * values_num) + 1] = qtype_counts[i];
112 if (swrite (pipe_fd, (const void *) &values_num, sizeof (values_num)) != 0)
114 syslog (LOG_ERR, "named plugin: Writing to pipe failed: %s",
119 if (swrite (pipe_fd, (const void *) values, 2 * sizeof (int) * values_num) != 0)
121 syslog (LOG_ERR, "named plugin: Writing to pipe failed: %s",
129 static void named_child_loop (void)
132 char pcap_error[PCAP_ERRBUF_SIZE];
134 struct pollfd poll_fds[2];
137 /* Passing `pcap_device == NULL' is okay and the same as passign "any" */
138 pcap_obj = pcap_open_live (pcap_device,
140 0 /* Not promiscuous */,
141 0 /* no read timeout */,
143 if (pcap_obj == NULL)
145 syslog (LOG_ERR, "named plugin: Opening interface `%s' failed: %s",
146 (pcap_device != NULL) ? pcap_device : "any",
152 /* Set up pipe end */
153 poll_fds[0].fd = pipe_fd;
154 poll_fds[0].events = POLLOUT;
156 /* Set up pcap device */
157 poll_fds[1].fd = pcap_fileno (pcap_obj);
158 poll_fds[1].events = POLLIN | POLLPRI;
162 status = poll (poll_fds, 2, -1 /* wait forever for a change */);
166 syslog (LOG_ERR, "named plugin: poll(2) failed: %s",
171 if (poll_fds[0].revents & (POLLERR | POLLHUP | POLLNVAL))
173 syslog (LOG_NOTICE, "named plugin: Pipe closed. Exiting.");
176 else if (poll_fds[0].revents & POLLOUT)
178 if (named_child_send_data () < 0)
184 if (poll_fds[1].revents & (POLLERR | POLLHUP | POLLNVAL))
186 syslog (LOG_ERR, "named plugin: pcap-device closed. Exiting.");
189 else if (poll_fds[1].revents & (POLLIN | POLLPRI))
191 /* TODO: Read and analyse packet */
192 status = pcap_dispatch (pcap_obj,
193 10 /* Only handle 10 packets at a time */,
194 handle_pcap /* callback */,
195 NULL /* Whatever this means.. */);
198 syslog (LOG_ERR, "named plugin: pcap_dispatch failed: %s",
199 pcap_geterr (pcap_obj));
206 pcap_close (pcap_obj);
207 } /* static void named_child_loop (void) */
209 static void named_init (void)
215 if (pipe (pipe_fds) != 0)
217 syslog (LOG_ERR, "named plugin: pipe(2) failed: %s",
226 syslog (LOG_ERR, "named plugin: fork(2) failed: %s",
232 else if (pid_child != 0)
234 /* parent: Close the writing end, keep the reading end. */
235 pipe_fd = pipe_fds[0];
240 /* child: Close the reading end, keep the writing end. */
241 pipe_fd = pipe_fds[1];
248 fcntl (pipe_fd, F_SETFL, O_NONBLOCK);
253 static void named_read (void)
255 int values[2 * T_MAX];
261 if (sread (pipe_fd, (void *) &values_num, sizeof (values_num)) != 0)
263 syslog (LOG_ERR, "named plugin: Reading from the pipe failed: %s",
268 assert ((values_num >= 0) && (values_num <= T_MAX));
270 if (sread (pipe_fd, (void *) values, 2 * sizeof (int) * values_num) != 0)
272 syslog (LOG_ERR, "named plugin: Reading from the pipe failed: %s",
277 for (i = 0; i < values_num; i++)
279 qtype = values[2 * i];
280 counter = values[(2 * i) + 1];
282 DBG ("qtype = %i; counter = %i;", qtype, counter);
285 #else /* if !NAMED_HAVE_READ */
286 # define named_read NULL
289 void module_register (void)
291 plugin_register (MODULE_NAME, named_init, named_read, NULL);
293 cf_register (MODULE_NAME, named_config, config_keys, config_keys_num);