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>
27 #define MODULE_NAME "named"
30 # define NAMED_HAVE_CONFIG 1
32 # define NAMED_HAVE_CONFIG 0
37 # define NAMED_HAVE_READ 1
39 # define NAMED_HAVE_READ 0
42 static char qtype_file = "named/qtype-%s.rrd";
44 static char *qtype_ds_def[] =
46 "DS:value:COUNTER:"COLLECTD_HEARTBEAT":0:U",
49 static int qtype_ds_num = 1;
53 static char *config_keys[] =
58 static int config_keys_num = 1;
59 #endif /* HAVE_LIBPCAP */
60 #endif /* NAMED_HAVE_CONFIG */
63 static char *pcap_device = NULL;
68 static int traffic_config (char *key, char *value)
71 if (strcasecmp (key, "Interface") == 0)
73 if (pcap_device != NULL)
75 if ((pcap_device = strdup (value)) == NULL)
84 #endif /* HAVE_LIBPCAP */
86 #endif /* NAMED_HAVE_CONFIG */
88 static int named_child_send_data (void)
90 int values[2 * T_MAX];
95 for (i = 0; i < T_MAX; i++)
97 if (qtype_counts[i] != 0)
99 values[2 * values_num] = i;
100 values[(2 * values_num) + 1] = qtype_counts[i];
105 if (swrite (pipe_fd, (const void *) &values_num, sizeof (values_num)) != 0)
107 syslog (LOG_ERR, "named plugin: Writing to pipe failed: %s",
112 if (swrite (pipe_fd, (const void *) values, 2 * sizeof (int) * values_num) != 0)
114 syslog (LOG_ERR, "named plugin: Writing to pipe failed: %s",
122 static void named_child_loop (void)
125 char pcap_error[PCAP_ERRBUF_SIZE];
127 struct pollfd poll_fds[2];
130 /* Passing `pcap_device == NULL' is okay and the same as passign "any" */
131 pcap_obj = pcap_open_live (pcap_device, /* Not promiscuous */ 0,
132 /* no read timeout */ 0, pcap_error);
133 if (pcap_obj == NULL)
135 syslog (LOG_ERR, "named plugin: Opening interface `%s' failed: %s",
136 (pcap_device != NULL) ? pcap_device : "any",
142 /* Set up pipe end */
143 poll_fds[0].fd = pipe_fd;
144 poll_fds[0].events = POLLOUT;
146 /* Set up pcap device */
147 poll_fds[1].fd = pcap_fileno (pcap_obj);
148 poll_fds[1].events = POLLIN | POLLPRI;
152 status = poll (poll_fds, 2, -1 /* wait forever for a change */);
156 syslog (LOG_ERR, "named plugin: poll(2) failed: %s",
161 if (poll_fds[0].revents & (POLLERR | POLLHUP | POLLNVAL))
163 syslog (LOG_NOTICE, "named plugin: Pipe closed. Exiting.");
166 else if (poss_fds[0].revents & POLLOUT)
168 if (named_child_send_data () < 0)
174 if (poll_fds[1].revents & (POLLERR | POLLHUP | POLLNVAL))
176 syslog (LOG_ERR, "named plugin: pcap-device closed. Exiting.");
179 else if (poll_fds[1].revents & (POLLIN | POLLPRI))
181 /* TODO: Read and analyse packet */
182 status = pcap_dispatch (pcap_obj,
183 10 /* Only handle 10 packets at a time */,
184 handle_pcap /* callback */,
185 NULL /* Whatever this means.. */);
188 syslog (LOG_ERR, "named plugin: pcap_dispatch failed: %s",
189 pcap_geterr (pcap_obj));
196 pcap_close (pcap_obj);
197 } /* static void named_child_loop (void) */
199 static void named_init (void)
205 if (pipe (pipe_fds) != 0)
207 syslog (LOG_ERR, "named plugin: pipe(2) failed: %s",
216 syslog (LOG_ERR, "named plugin: fork(2) failed: %s",
220 pcap_close (pcap_obj);
223 else if (pid_child != 0)
225 /* parent: Close the writing end, keep the reading end. */
226 pipe_fd = pipe_fds[0];
231 /* child: Close the reading end, keep the writing end. */
232 pipe_fd = pipe_fds[1];
239 fcntl (pipe_fd, F_SETFL, O_NONBLOCK);
244 static void named_read (void)
246 int values[2 * T_MAX];
252 if (sread (pipe_fd, (void *) &values_num, sizeof (values_num)) != 0)
254 syslog (LOG_ERR, "named plugin: Reading from the pipe failed: %s",
259 assert ((values_num >= 0) && (values_num <= T_MAX));
261 if (sread (pipe_fd, (void *) values, 2 * sizeof (int) * values_num) != 0)
263 syslog (LOG_ERR, "named plugin: Reading from the pipe failed: %s",
268 for (i = 0; i < values_num; i++)
270 qtype = values[2 * i];
271 counter = values[(2 * i) + 1];
273 DBG ("qtype = %i; counter = %i;", qtype, counter);
276 #else /* if !NAMED_HAVE_READ */
277 # define named_read NULL
280 void module_register (void)
282 plugin_register (MODULE_NAME, named_init, named_read, NULL);
284 cf_register (MODULE_NAME, named_config, config_keys, config_keys_num);