diff options
Diffstat (limited to 'src/helper.c')
-rw-r--r-- | src/helper.c | 57 |
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) |