summaryrefslogtreecommitdiff
path: root/src/helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/helper.c')
-rw-r--r--src/helper.c57
1 files changed, 53 insertions, 4 deletions
diff --git a/src/helper.c b/src/helper.c
index 455a68c..d7c7dbd 100644
--- a/src/helper.c
+++ b/src/helper.c
@@ -233,8 +233,13 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
is6 = (data.flags != AF_INET);
data.action = ACTION_ARP;
}
- else
- continue;
+ else if (data.action == ACTION_RELAY_SNOOP)
+ {
+ is6 = 1;
+ action_str = "relay-snoop";
+ }
+ else
+ continue;
/* stringify MAC into dhcp_buff */
p = daemon->dhcp_buff;
@@ -286,7 +291,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
char *dot;
hostname = (char *)buf;
hostname[data.hostname_len - 1] = 0;
- if (data.action != ACTION_TFTP)
+ if (data.action != ACTION_TFTP && data.action != ACTION_RELAY_SNOOP)
{
if (!legal_hostname(hostname))
hostname = NULL;
@@ -332,6 +337,24 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
lua_call(lua, 2, 0); /* pass 2 values, expect 0 */
}
}
+ else if (data.action == ACTION_RELAY_SNOOP)
+ {
+ lua_getglobal(lua, "snoop");
+ if (lua_type(lua, -1) != LUA_TFUNCTION)
+ lua_pop(lua, 1); /* tftp function optional */
+ else
+ {
+ lua_pushstring(lua, action_str); /* arg1 - action */
+ lua_newtable(lua); /* arg2 - data table */
+ lua_pushstring(lua, daemon->addrbuff);
+ lua_setfield(lua, -2, "client_address");
+ lua_pushstring(lua, hostname);
+ lua_setfield(lua, -2, "prefix");
+ lua_pushstring(lua, data.interface);
+ lua_setfield(lua, -2, "client_interface");
+ lua_call(lua, 2, 0); /* pass 2 values, expect 0 */
+ }
+ }
else if (data.action == ACTION_ARP)
{
lua_getglobal(lua, "arp");
@@ -553,7 +576,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
close(pipeout[1]);
}
- if (data.action != ACTION_TFTP && data.action != ACTION_ARP)
+ if (data.action != ACTION_TFTP && data.action != ACTION_ARP && data.action != ACTION_RELAY_SNOOP)
{
#ifdef HAVE_DHCP6
my_setenv("DNSMASQ_IAID", is6 ? daemon->dhcp_buff3 : NULL, &err);
@@ -640,6 +663,9 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
fcntl(event_fd, F_SETFD, i | FD_CLOEXEC);
close(pipefd[0]);
+ if (data.action == ACTION_RELAY_SNOOP)
+ strcpy(daemon->packet, data.interface);
+
p = strrchr(daemon->lease_change_command, '/');
if (err == 0)
{
@@ -810,6 +836,29 @@ void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t n
bytes_in_buf = p - (unsigned char *)buf;
}
+#ifdef HAVE_DHCP6
+void queue_relay_snoop(struct in6_addr *client, int if_index, struct in6_addr *prefix, int prefix_len)
+{
+ /* no script */
+ if (daemon->helperfd == -1)
+ return;
+
+ inet_ntop(AF_INET6, prefix, daemon->addrbuff, ADDRSTRLEN);
+
+ /* 5 for /nnn and zero on the end of the prefix. */
+ buff_alloc(sizeof(struct script_data) + ADDRSTRLEN + 5);
+ memset(buf, 0, sizeof(struct script_data));
+
+ buf->action = ACTION_RELAY_SNOOP;
+ buf->addr6 = *client;
+ buf->hostname_len = sprintf((char *)(buf+1), "%s/%u", daemon->addrbuff, prefix_len) + 1;
+
+ indextoname(daemon->dhcp6fd, if_index, buf->interface);
+
+ bytes_in_buf = sizeof(struct script_data) + buf->hostname_len;
+}
+#endif
+
#ifdef HAVE_TFTP
/* This nastily re-uses DHCP-fields for TFTP stuff */
void queue_tftp(off_t file_len, char *filename, union mysockaddr *peer)