utils_debug.c utils_debug.h \
utils_mount.c utils_mount.h \
common.c common.h \
- multicast.c multicast.h \
network.c network.h \
plugin.c plugin.h \
configfile.c configfile.h
#include "common.h"
#include "utils_debug.h"
-#include "multicast.h"
+#include "network.h"
#include "plugin.h"
#include "configfile.h"
#if HAVE_LIBRRD
static int start_server (void)
{
+ /* FIXME use stack here! */
char *host;
char *type;
char *instance;
while (loop == 0)
{
- if (multicast_receive (&host, &type, &instance, &values) == 0)
+ if (network_receive (&host, &type, &instance, &values) == 0)
plugin_write (host, type, instance, values);
if (host != NULL) free (host); host = NULL;
#include "libconfig/libconfig.h"
+#include "common.h"
#include "plugin.h"
#include "configfile.h"
+#include "network.h"
#include "utils_debug.h"
#define SHORTOPT_NONE 0
return (LC_CBRET_OKAY);
}
+int cf_callback_socket (const char *shortvar, const char *var,
+ const char *arguments, const char *value, lc_flags_t flags,
+ void *extra)
+{
+ char *buffer;
+
+ char *fields[3];
+ int numfields;
+
+ char *node;
+ char *service = NET_DEFAULT_PORT;
+
+ DBG ("shortvar = %s, var = %s, arguments = %s, value = %s, ...",
+ shortvar, var, arguments, value);
+
+ buffer = strdup (value);
+ if (buffer == NULL)
+ return (LC_CBRET_ERROR);
+
+ numfields = strsplit (buffer, fields, 3);
+
+ if ((numfields != 1) && (numfields != 2))
+ {
+ syslog (LOG_ERR, "Invalid number of arguments to `%s'",
+ shortvar);
+ free (buffer);
+ return (LC_CBRET_ERROR);
+ }
+
+ node = fields[0];
+ if (numfields == 2)
+ service = fields[1];
+
+ /* Still return `LC_CBRET_OKAY' because this is not an syntax error */
+ if (network_create_socket (node, service) < 1)
+ syslog (LOG_ERR, "network_create_socket (%s, %s) failed",
+ node, service);
+
+ free (buffer);
+
+ return (LC_CBRET_OKAY);
+}
+
/*
* `cf_callback_plugin'
* Start/end section `plugin'
lc_register_callback ("LoadPlugin", SHORTOPT_NONE,
LC_VAR_STRING, cf_callback_mode_loadmodule, NULL);
+ lc_register_callback ("Listen", SHORTOPT_NONE,
+ LC_VAR_STRING, cf_callback_socket, NULL);
+ lc_register_callback ("Server", SHORTOPT_NONE,
+ LC_VAR_STRING, cf_callback_socket, NULL);
+
for (i = 0; i < cf_mode_num; i++)
{
cf_mode_item_t *item;
#include "common.h"
#include "utils_debug.h"
-/*
- * From RFC2365:
- *
- * The IPv4 Organization Local Scope -- 239.192.0.0/14
- *
- * 239.192.0.0/14 is defined to be the IPv4 Organization Local Scope, and is
- * the space from which an organization should allocate sub-ranges when
- * defining scopes for private use.
- *
- * Port 25826 is not assigned as of 2005-09-12
- */
-
-#define IPV4_MCAST_GROUP "239.192.74.66"
-#define UDP_PORT 25826
-
/* 1500 - 40 - 8 = Ethernet packet - IPv6 header - UDP header */
/* #define BUFF_SIZE 1452 */
typedef struct sockent
{
int fd;
+ int mode;
struct sockaddr_storage *addr;
socklen_t addrlen;
struct sockent *next;
{
int loop = 1;
+ DBG ("fd = %i; calling `bind'", se->fd);
+
if (bind (se->fd, ai->ai_addr, ai->ai_addrlen) == -1)
{
syslog (LOG_ERR, "bind: %s", strerror (errno));
{
struct ip_mreq mreq;
+ DBG ("fd = %i; IPv4 multicast address found", se->fd);
+
mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
mreq.imr_interface.s_addr = htonl (INADDR_ANY);
{
struct ipv6_mreq mreq;
+ DBG ("fd = %i; IPv6 multicast address found", se->fd);
+
memcpy (&mreq.ipv6mr_multiaddr,
&addr->sin6_addr,
sizeof (addr->sin6_addr));
memcpy (se->addr, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
se->addrlen = ai_ptr->ai_addrlen;
+ se->mode = operating_mode;
se->fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol);
se->next = NULL;
if (socklist_tail == NULL)
{
- socklist_head = socklist_tail = se;
+ socklist_head = se;
+ socklist_tail = se;
}
else
{
return (num_added);
}
+static int network_connect_default (void)
+{
+ int ret;
+
+ if (socklist_head != NULL)
+ return (0);
+
+ DBG ("socklist_head is NULL");
+
+ ret = 0;
+
+ if (network_create_socket (NET_DEFAULT_V4_ADDR, NET_DEFAULT_PORT) > 0)
+ ret++;
+
+ if (network_create_socket (NET_DEFAULT_V6_ADDR, NET_DEFAULT_PORT) > 0)
+ ret++;
+
+ if (ret == 0)
+ ret = -1;
+
+ return (ret);
+}
+
static int network_get_listen_socket (void)
{
int fd;
fd_set readfds;
sockent_t *se;
+ if (socklist_head == NULL)
+ network_connect_default ();
+
while (1)
{
FD_ZERO (&readfds);
max_fd = -1;
for (se = socklist_head; se != NULL; se = se->next)
{
+ if (se->mode != operating_mode)
+ continue;
+
FD_SET (se->fd, &readfds);
if (se->fd >= max_fd)
max_fd = se->fd + 1;
fd = -1;
for (se = socklist_head; se != NULL; se = se->next)
+ {
+ if (se->mode != operating_mode)
+ continue;
+
if (FD_ISSET (se->fd, &readfds))
{
fd = se->fd;
break;
}
+ }
if (fd == -1)
syslog (LOG_WARNING, "No socket ready..?");
buf[buflen] = '\0';
buflen++;
+ if (socklist_head == NULL)
+ network_connect_default ();
+
ret = 0;
for (se = socklist_head; se != NULL; se = se->next)
{
+ if (se->mode != operating_mode)
+ continue;
+
DBG ("fd = %i", se->fd);
while (1)
#ifndef NETWORK_H
#define NETWORK_H
+/*
+ * From RFC2365: Administratively Scoped IP Multicast
+ *
+ * The IPv4 Organization Local Scope -- 239.192.0.0/14
+ *
+ * 239.192.0.0/14 is defined to be the IPv4 Organization Local Scope, and is
+ * the space from which an organization should allocate sub-ranges when
+ * defining scopes for private use.
+ *
+ * Port 25826 is not assigned as of 2005-09-12
+ */
+
+/*
+ * From RFC2373: IP Version 6 Addressing Architecture
+ *
+ * 2.7 Multicast Addresses
+ *
+ * | 8 | 4 | 4 | 80 bits | 32 bits |
+ * +--------+----+----+---------------------------+-----------------+
+ * |11111111|flgs|scop| reserved must be zero | group ID |
+ * +--------+----+----+---------------------------+-----------------+
+ *
+ * flgs = 1 => non-permanently-assigned ("transient") multicast address.
+ * scop = 8 => organization-local scope
+ *
+ * group = efc0:4a42 = 239.192.74.66
+ */
+
+#define NET_DEFAULT_V4_ADDR "239.192.74.66"
+#define NET_DEFAULT_V6_ADDR "ff18::efc0:4a42"
+#define NET_DEFAULT_PORT "25826"
+
int network_create_socket (const char *node, const char *service);
int network_receive (char **host, char **type, char **instance, char **value);
int network_send (char *type, char *instance, char *value);
#include <ltdl.h>
#include "plugin.h"
-#include "multicast.h"
+#include "network.h"
typedef struct plugin
{
/*
* Receive data from the plugin/module and get it somehow to ``plugin_write'':
- * Either using ``multicast_send'' (when in network/client mode) or call it
+ * Either using ``network_send'' (when in network/client mode) or call it
* directly (in local mode).
*/
void plugin_submit (char *type, char *inst, char *val)
if (operating_mode == MODE_LOCAL)
plugin_write (NULL, type, inst, val);
else if (operating_mode == MODE_CLIENT)
- multicast_send (type, inst, val);
+ network_send (type, inst, val);
else /* operating_mode == MODE_SERVER */
syslog (LOG_ERR, "WTF is the server doing in ``plugin_submit''?!?\n");
#else
- multicast_send (type, inst, val);
+ network_send (type, inst, val);
#endif
}