Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
D
Dnsmasq
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
Dnsmasq
Commits
a9530964
Commit
a9530964
authored
Mar 20, 2012
by
Simon Kelley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Send "FTP transfer complete" events to the DHCP lease script.
parent
884a6dfe
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
355 additions
and
194 deletions
+355
-194
CHANGELOG
CHANGELOG
+18
-0
contrib/port-forward/dnsmasq-portforward
contrib/port-forward/dnsmasq-portforward
+10
-0
man/dnsmasq.8
man/dnsmasq.8
+31
-4
src/dnsmasq.c
src/dnsmasq.c
+9
-0
src/dnsmasq.h
src/dnsmasq.h
+6
-1
src/helper.c
src/helper.c
+261
-188
src/tftp.c
src/tftp.c
+20
-1
No files found.
CHANGELOG
View file @
a9530964
...
...
@@ -24,6 +24,24 @@ version 2.61
Add --host-record. Thanks to Rob Zwissler for the
suggestion.
Invoke the DHCP script with action "tftp" when a TFTP file
transfer completes. The size of the file, address to which
it was sent and complete pathname are supplied. Note that
version 2.60 introduced some script incompatibilties
associated with DHCPv6, and this is a further change. To
be safe, scripts should ignore unknown actions, and if
not IPv6-aware, should exit if the environment
variable DNSMASQ_IAID is set. The use-case for this is
to track netboot/install. Suggestion from Shantanu
Gadgil.
Update contrib/port-forward/dnsmasq-portforward to reflect
the above.
Set the environment variable DNSMASQ_LOG_DHCP when running
the script id --log-dhcp is in effect, so that script can
taylor their logging verbosity. Suggestion from Malte Forkel.
version 2.60
Fix compilation problem in Mac OS X Lion. Thanks to Olaf
...
...
contrib/port-forward/dnsmasq-portforward
View file @
a9530964
...
...
@@ -34,11 +34,21 @@ if [ ${DNSMASQ_OLD_HOSTNAME} ] && [ ${action} = old ] ; then
hostname
=
${
DNSMASQ_OLD_HOSTNAME
}
fi
# IPv6 leases are not our concern. no NAT there!
if
[
${
DNSMASQ_IAID
}
]
;
then
exit
0
fi
# action init is not relevant, and will only be seen when leasefile-ro is set.
if
[
${
action
}
=
init
]
;
then
exit
0
fi
# action tftp is not relevant.
if
[
${
action
}
=
tftp
]
;
then
exit
0
fi
if
[
${
hostname
}
]
;
then
ports
=
$(
sed
-n
-e
"/^
${
hostname
}
\
.*/ s/^.* //p"
${
PORTSFILE
}
)
...
...
man/dnsmasq.8
View file @
a9530964
...
...
@@ -1069,7 +1069,8 @@ re-intialised. The enterprise-id is assigned by IANA, and the uid is a
string of hex octets unique to a particular device.
.TP
.B \-6 --dhcp-script=<path>
Whenever a new DHCP lease is created, or an old one destroyed, the
Whenever a new DHCP lease is created, or an old one destroyed, or a
TFTP file transfer completes, the
executable specified by this option is run. <path>
must be an absolute pathname, no PATH search occurs.
The arguments to the process
...
...
@@ -1119,6 +1120,8 @@ is known.
DNSMASQ_TAGS contains all the tags set during the
DHCP transaction, separated by spaces.
DNSMASQ_LOG_DHCP is set if --log-dhcp is in effect.
For IPv4 only:
DNSMASQ_CLIENT_ID if the host provided a client-id.
...
...
@@ -1145,6 +1148,8 @@ only supplied for
since these data are not held in dnsmasq's lease
database.
All file descriptors are
closed except stdin, stdout and stderr which are open to /dev/null
(except in debug mode).
...
...
@@ -1163,6 +1168,17 @@ all existing leases as they are read from the lease file. Expired
leases will be called with "del" and others with "old". When dnsmasq
receives a HUP signal, the script will be invoked for existing leases
with an "old " event.
There are two further actions which may appear as the first argument
to the script, "init" and "tftp". More may be added in the future, so
scripts should be written to ignore unknown actions. "init" is
decsribed below in
.B --leasefile-ro
The "tftp" action is invoked when a TFTP file transfer completes: the
arguments are the file size in bytes, the address to which the file
was sent, and the complete pathname of the file.
.TP
.B --dhcp-luascript=<path>
Specify a script written in Lua, to be run when leases are created,
...
...
@@ -1176,11 +1192,13 @@ function, and may provide
and
.B shutdown
functions, which are called, without arguments when dnsmasq starts up
and terminates.
and terminates. It may also provide a
.B tftp
function.
The
.B lease
method
receives the information detailed in
function
receives the information detailed in
.B --dhcp-script.
It gets two arguments, firstly the action, which is a string
containing, "add", "old" or "del", and secondly a table of tag value
...
...
@@ -1197,7 +1215,16 @@ for IPv4, and
.B client_duid, ip_address
and
.B hostname
for IPv6.
for IPv6.
The
.B tftp
function is called in the same way as the lease function, and the
table holds the tags
.B destination_address,
.B file_name
and
.B file_size.
.TP
.B --dhcp-scriptuser
Specify the user as which to run the lease-change script or Lua script. This defaults to root, but can be changed to another user using this flag.
...
...
src/dnsmasq.c
View file @
a9530964
...
...
@@ -721,6 +721,10 @@ int main (int argc, char **argv)
# ifdef HAVE_SCRIPT
while
(
helper_buf_empty
()
&&
do_script_run
(
now
));
# ifdef HAVE_TFTP
while
(
helper_buf_empty
()
&&
do_tftp_script_run
());
# endif
if
(
!
helper_buf_empty
())
{
FD_SET
(
daemon
->
helperfd
,
&
wset
);
...
...
@@ -729,6 +733,11 @@ int main (int argc, char **argv)
# else
/* need this for other side-effects */
while
(
do_script_run
(
now
));
# ifdef HAVE_TFTP
while
(
do_tftp_script_run
());
# endif
# endif
#endif
...
...
src/dnsmasq.h
View file @
a9530964
...
...
@@ -458,6 +458,7 @@ struct frec {
#define ACTION_OLD_HOSTNAME 2
#define ACTION_OLD 3
#define ACTION_ADD 4
#define ACTION_TFTP 5
#define LEASE_NEW 1
/* newly created */
#define LEASE_CHANGED 2
/* modified */
...
...
@@ -803,7 +804,7 @@ extern struct daemon {
#endif
/* TFTP stuff */
struct
tftp_transfer
*
tftp_trans
;
struct
tftp_transfer
*
tftp_trans
,
*
tftp_done_trans
;
/* utility string buffer, hold max sized IP address as string */
char
*
addrbuff
;
...
...
@@ -1040,6 +1041,9 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd);
void
helper_write
(
void
);
void
queue_script
(
int
action
,
struct
dhcp_lease
*
lease
,
char
*
hostname
,
time_t
now
);
#ifdef HAVE_TFTP
void
queue_tftp
(
off_t
file_len
,
char
*
filename
,
union
mysockaddr
*
peer
);
#endif
int
helper_buf_empty
(
void
);
#endif
...
...
@@ -1047,6 +1051,7 @@ int helper_buf_empty(void);
#ifdef HAVE_TFTP
void
tftp_request
(
struct
listener
*
listen
,
time_t
now
);
void
check_tftp_listeners
(
fd_set
*
rset
,
time_t
now
);
int
do_tftp_script_run
(
void
);
#endif
/* conntrack.c */
...
...
src/helper.c
View file @
a9530964
...
...
@@ -192,18 +192,24 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
#endif
_exit
(
0
);
}
is6
=
!!
(
data
.
flags
&
(
LEASE_TA
|
LEASE_NA
));
if
(
data
.
action
==
ACTION_DEL
)
action_str
=
"del"
;
else
if
(
data
.
action
==
ACTION_ADD
)
action_str
=
"add"
;
else
if
(
data
.
action
==
ACTION_OLD
||
data
.
action
==
ACTION_OLD_HOSTNAME
)
action_str
=
"old"
;
else
if
(
data
.
action
==
ACTION_TFTP
)
{
action_str
=
"tftp"
;
is6
=
(
data
.
flags
!=
AF_INET
);
}
else
continue
;
is6
=
!!
(
data
.
flags
&
(
LEASE_TA
|
LEASE_NA
));
if
(
!
is6
)
{
/* stringify MAC into dhcp_buff */
...
...
@@ -271,13 +277,16 @@ 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
(
!
legal_hostname
(
hostname
))
hostname
=
NULL
;
else
if
((
dot
=
strchr
(
hostname
,
'.'
)))
if
(
data
.
action
!=
ACTION_TFTP
)
{
domain
=
dot
+
1
;
*
dot
=
0
;
}
if
(
!
legal_hostname
(
hostname
))
hostname
=
NULL
;
else
if
((
dot
=
strchr
(
hostname
,
'.'
)))
{
domain
=
dot
+
1
;
*
dot
=
0
;
}
}
}
extradata
=
buf
+
data
.
hostname_len
;
...
...
@@ -289,116 +298,141 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
inet_ntop
(
AF_INET6
,
&
data
.
hwaddr
,
daemon
->
addrbuff
,
ADDRSTRLEN
);
#endif
/* file length */
if
(
data
.
action
==
ACTION_TFTP
)
sprintf
(
daemon
->
dhcp_buff
,
"%u"
,
data
.
hwaddr_len
);
#ifdef HAVE_LUASCRIPT
if
(
daemon
->
luascript
)
{
lua_getglobal
(
lua
,
"lease"
);
/* function to call */
lua_pushstring
(
lua
,
action_str
);
/* arg1 - action */
lua_newtable
(
lua
);
/* arg2 - data table */
if
(
is6
)
if
(
data
.
action
==
ACTION_TFTP
)
{
lua_pushstring
(
lua
,
daemon
->
dhcp_buff
);
lua_setfield
(
lua
,
-
2
,
"client_duid"
);
lua_pushstring
(
lua
,
daemon
->
packet
);
lua_setfield
(
lua
,
-
2
,
"server_duid"
);
lua_pushstring
(
lua
,
daemon
->
dhcp_buff3
);
lua_setfield
(
lua
,
-
2
,
"iaid"
);
}
if
(
!
is6
&&
data
.
clid_len
!=
0
)
{
lua_pushstring
(
lua
,
daemon
->
packet
);
lua_setfield
(
lua
,
-
2
,
"client_id"
);
lua_getglobal
(
lua
,
"tftp"
);
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
,
"destination_address"
);
lua_pushstring
(
lua
,
hostname
);
lua_setfield
(
lua
,
-
2
,
"file_name"
);
lua_pushstring
(
lua
,
daemon
->
dhcp_buff
);
lua_setfield
(
lua
,
-
2
,
"file_size"
);
lua_call
(
lua
,
2
,
0
);
/* pass 2 values, expect 0 */
}
}
if
(
strlen
(
data
.
interface
)
!=
0
)
else
{
lua_pushstring
(
lua
,
data
.
interface
);
lua_setfield
(
lua
,
-
2
,
"interface"
);
}
lua_getglobal
(
lua
,
"lease"
);
/* function to call */
lua_pushstring
(
lua
,
action_str
);
/* arg1 - action */
lua_newtable
(
lua
);
/* arg2 - data table */
if
(
is6
)
{
lua_pushstring
(
lua
,
daemon
->
dhcp_buff
);
lua_setfield
(
lua
,
-
2
,
"client_duid"
);
lua_pushstring
(
lua
,
daemon
->
packet
);
lua_setfield
(
lua
,
-
2
,
"server_duid"
);
lua_pushstring
(
lua
,
daemon
->
dhcp_buff3
);
lua_setfield
(
lua
,
-
2
,
"iaid"
);
}
if
(
!
is6
&&
data
.
clid_len
!=
0
)
{
lua_pushstring
(
lua
,
daemon
->
packet
);
lua_setfield
(
lua
,
-
2
,
"client_id"
);
}
if
(
strlen
(
data
.
interface
)
!=
0
)
{
lua_pushstring
(
lua
,
data
.
interface
);
lua_setfield
(
lua
,
-
2
,
"interface"
);
}
#ifdef HAVE_BROKEN_RTC
lua_pushnumber
(
lua
,
data
.
length
);
lua_setfield
(
lua
,
-
2
,
"lease_length"
);
lua_pushnumber
(
lua
,
data
.
length
);
lua_setfield
(
lua
,
-
2
,
"lease_length"
);
#else
lua_pushnumber
(
lua
,
data
.
expires
);
lua_setfield
(
lua
,
-
2
,
"lease_expires"
);
lua_pushnumber
(
lua
,
data
.
expires
);
lua_setfield
(
lua
,
-
2
,
"lease_expires"
);
#endif
if
(
hostname
)
{
lua_pushstring
(
lua
,
hostname
);
lua_setfield
(
lua
,
-
2
,
"hostname"
);
}
if
(
domain
)
{
lua_pushstring
(
lua
,
domain
);
lua_setfield
(
lua
,
-
2
,
"domain"
);
}
end
=
extradata
+
data
.
ed_len
;
buf
=
extradata
;
if
(
!
is6
)
buf
=
grab_extradata_lua
(
buf
,
end
,
"vendor_class"
);
if
(
hostname
)
{
lua_pushstring
(
lua
,
hostname
);
lua_setfield
(
lua
,
-
2
,
"hostname"
);
}
if
(
domain
)
{
lua_pushstring
(
lua
,
domain
);
lua_setfield
(
lua
,
-
2
,
"domain"
);
}
end
=
extradata
+
data
.
ed_len
;
buf
=
extradata
;
if
(
!
is6
)
buf
=
grab_extradata_lua
(
buf
,
end
,
"vendor_class"
);
#ifdef HAVE_DHCP6
else
for
(
i
=
0
;
i
<
data
.
hwaddr_len
;
i
++
)
{
sprintf
(
daemon
->
dhcp_buff2
,
"vendor_class%i"
,
i
);
buf
=
grab_extradata_lua
(
buf
,
end
,
daemon
->
dhcp_buff2
);
}
else
for
(
i
=
0
;
i
<
data
.
hwaddr_len
;
i
++
)
{
sprintf
(
daemon
->
dhcp_buff2
,
"vendor_class%i"
,
i
);
buf
=
grab_extradata_lua
(
buf
,
end
,
daemon
->
dhcp_buff2
);
}
#endif
buf
=
grab_extradata_lua
(
buf
,
end
,
"supplied_hostname"
);
if
(
!
is6
)
{
buf
=
grab_extradata_lua
(
buf
,
end
,
"cpewan_oui"
);
buf
=
grab_extradata_lua
(
buf
,
end
,
"cpewan_serial"
);
buf
=
grab_extradata_lua
(
buf
,
end
,
"cpewan_class"
);
}
buf
=
grab_extradata_lua
(
buf
,
end
,
"tags"
);
if
(
is6
)
buf
=
grab_extradata_lua
(
buf
,
end
,
"relay_address"
);
else
if
(
data
.
giaddr
.
s_addr
!=
0
)
{
lua_pushstring
(
lua
,
inet_ntoa
(
data
.
giaddr
));
lua_setfield
(
lua
,
-
2
,
"relay_address"
);
}
for
(
i
=
0
;
buf
;
i
++
)
{
sprintf
(
daemon
->
dhcp_buff2
,
"user_class%i"
,
i
);
buf
=
grab_extradata_lua
(
buf
,
end
,
daemon
->
dhcp_buff2
);
}
if
(
data
.
action
!=
ACTION_DEL
&&
data
.
remaining_time
!=
0
)
{
lua_pushnumber
(
lua
,
data
.
remaining_time
);
lua_setfield
(
lua
,
-
2
,
"time_remaining"
);
}
if
(
data
.
action
==
ACTION_OLD_HOSTNAME
&&
hostname
)
{
lua_pushstring
(
lua
,
hostname
);
lua_setfield
(
lua
,
-
2
,
"old_hostname"
);
}
if
(
!
is6
)
{
lua_pushstring
(
lua
,
daemon
->
dhcp_buff
);
lua_setfield
(
lua
,
-
2
,
"mac_address"
);
buf
=
grab_extradata_lua
(
buf
,
end
,
"supplied_hostname"
);
if
(
!
is6
)
{
buf
=
grab_extradata_lua
(
buf
,
end
,
"cpewan_oui"
);
buf
=
grab_extradata_lua
(
buf
,
end
,
"cpewan_serial"
);
buf
=
grab_extradata_lua
(
buf
,
end
,
"cpewan_class"
);
}
buf
=
grab_extradata_lua
(
buf
,
end
,
"tags"
);
if
(
is6
)
buf
=
grab_extradata_lua
(
buf
,
end
,
"relay_address"
);
else
if
(
data
.
giaddr
.
s_addr
!=
0
)
{
lua_pushstring
(
lua
,
inet_ntoa
(
data
.
giaddr
));
lua_setfield
(
lua
,
-
2
,
"relay_address"
);
}
for
(
i
=
0
;
buf
;
i
++
)
{
sprintf
(
daemon
->
dhcp_buff2
,
"user_class%i"
,
i
);
buf
=
grab_extradata_lua
(
buf
,
end
,
daemon
->
dhcp_buff2
);
}
if
(
data
.
action
!=
ACTION_DEL
&&
data
.
remaining_time
!=
0
)
{
lua_pushnumber
(
lua
,
data
.
remaining_time
);
lua_setfield
(
lua
,
-
2
,
"time_remaining"
);
}
if
(
data
.
action
==
ACTION_OLD_HOSTNAME
&&
hostname
)
{
lua_pushstring
(
lua
,
hostname
);
lua_setfield
(
lua
,
-
2
,
"old_hostname"
);
}
if
(
!
is6
)
{
lua_pushstring
(
lua
,
daemon
->
dhcp_buff
);
lua_setfield
(
lua
,
-
2
,
"mac_address"
);
}
lua_pushstring
(
lua
,
daemon
->
addrbuff
);
lua_setfield
(
lua
,
-
2
,
"ip_address"
);
lua_call
(
lua
,
2
,
0
);
/* pass 2 values, expect 0 */
}
lua_pushstring
(
lua
,
daemon
->
addrbuff
);
lua_setfield
(
lua
,
-
2
,
"ip_address"
);
lua_call
(
lua
,
2
,
0
);
/* pass 2 values, expect 0 */
}
#endif
...
...
@@ -439,81 +473,87 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
continue
;
}
if
(
is6
)
if
(
data
.
action
!=
ACTION_TFTP
)
{
my_setenv
(
"DNSMASQ_IAID"
,
daemon
->
dhcp_buff3
,
&
err
);
my_setenv
(
"DNSMASQ_SERVER_DUID"
,
daemon
->
packet
,
&
err
);
}
if
(
!
is6
&&
data
.
clid_len
!=
0
)
my_setenv
(
"DNSMASQ_CLIENT_ID"
,
daemon
->
packet
,
&
err
);
if
(
strlen
(
data
.
interface
)
!=
0
)
my_setenv
(
"DNSMASQ_INTERFACE"
,
data
.
interface
,
&
err
);
if
(
is6
)
{
my_setenv
(
"DNSMASQ_IAID"
,
daemon
->
dhcp_buff3
,
&
err
);
my_setenv
(
"DNSMASQ_SERVER_DUID"
,
daemon
->
packet
,
&
err
);
}
if
(
!
is6
&&
data
.
clid_len
!=
0
)
my_setenv
(
"DNSMASQ_CLIENT_ID"
,
daemon
->
packet
,
&
err
);
if
(
strlen
(
data
.
interface
)
!=
0
)
my_setenv
(
"DNSMASQ_INTERFACE"
,
data
.
interface
,
&
err
);
#ifdef HAVE_BROKEN_RTC
my_setenv
(
"DNSMASQ_LEASE_LENGTH"
,
daemon
->
dhcp_buff2
,
&
err
);
my_setenv
(
"DNSMASQ_LEASE_LENGTH"
,
daemon
->
dhcp_buff2
,
&
err
);
#else
my_setenv
(
"DNSMASQ_LEASE_EXPIRES"
,
daemon
->
dhcp_buff2
,
&
err
);
my_setenv
(
"DNSMASQ_LEASE_EXPIRES"
,
daemon
->
dhcp_buff2
,
&
err
);
#endif
if
(
domain
)
my_setenv
(
"DNSMASQ_DOMAIN"
,
domain
,
&
err
);
end
=
extradata
+
data
.
ed_len
;
buf
=
extradata
;
if
(
!
is6
)
buf
=
grab_extradata
(
buf
,
end
,
"DNSMASQ_VENDOR_CLASS"
,
&
err
);
if
(
domain
)
my_setenv
(
"DNSMASQ_DOMAIN"
,
domain
,
&
err
);
end
=
extradata
+
data
.
ed_len
;
buf
=
extradata
;
if
(
!
is6
)
buf
=
grab_extradata
(
buf
,
end
,
"DNSMASQ_VENDOR_CLASS"
,
&
err
);
#ifdef HAVE_DHCP6
else
{
if
(
data
.
hwaddr_len
!=
0
)
else
{
buf
=
grab_extradata
(
buf
,
end
,
"DNSMASQ_VENDOR_CLASS_ID"
,
&
err
);
for
(
i
=
0
;
i
<
data
.
hwaddr_len
-
1
;
i
++
)
if
(
data
.
hwaddr_len
!=
0
)
{
sprintf
(
daemon
->
dhcp_buff2
,
"DNSMASQ_VENDOR_CLASS%i"
,
i
);
buf
=
grab_extradata
(
buf
,
end
,
daemon
->
dhcp_buff2
,
&
err
);
buf
=
grab_extradata
(
buf
,
end
,
"DNSMASQ_VENDOR_CLASS_ID"
,
&
err
);
for
(
i
=
0
;
i
<
data
.
hwaddr_len
-
1
;
i
++
)
{
sprintf
(
daemon
->
dhcp_buff2
,
"DNSMASQ_VENDOR_CLASS%i"
,
i
);
buf
=
grab_extradata
(
buf
,
end
,
daemon
->
dhcp_buff2
,
&
err
);
}
}
}
}
#endif
buf
=
grab_extradata
(
buf
,
end
,
"DNSMASQ_SUPPLIED_HOSTNAME"
,
&
err
);
if
(
!
is6
)
{
buf
=
grab_extradata
(
buf
,
end
,
"DNSMASQ_CPEWAN_OUI"
,
&
err
);
buf
=
grab_extradata
(
buf
,
end
,
"DNSMASQ_CPEWAN_SERIAL"
,
&
err
);
buf
=
grab_extradata
(
buf
,
end
,
"DNSMASQ_CPEWAN_CLASS"
,
&
err
);
}
buf
=
grab_extradata
(
buf
,
end
,
"DNSMASQ_TAGS"
,
&
err
);
if
(
is6
)
buf
=
grab_extradata
(
buf
,
end
,
"DNSMASQ_RELAY_ADDRESS"
,
&
err
);
else
if
(
data
.
giaddr
.
s_addr
!=
0
)
my_setenv
(
"DNSMASQ_RELAY_ADDRESS"
,
inet_ntoa
(
data
.
giaddr
),
&
err
);
for
(
i
=
0
;
buf
;
i
++
)
{
sprintf
(
daemon
->
dhcp_buff2
,
"DNSMASQ_USER_CLASS%i"
,
i
);
buf
=
grab_extradata
(
buf
,
end
,
daemon
->
dhcp_buff2
,
&
err
);
}
if
(
data
.
action
!=
ACTION_DEL
&&
data
.
remaining_time
!=
0
)
{
sprintf
(
daemon
->
dhcp_buff2
,
"%u"
,
data
.
remaining_time
);
my_setenv
(
"DNSMASQ_TIME_REMAINING"
,
daemon
->
dhcp_buff2
,
&
err
);
}
if
(
data
.
action
==
ACTION_OLD_HOSTNAME
&&
hostname
)
{
my_setenv
(
"DNSMASQ_OLD_HOSTNAME"
,
hostname
,
&
err
);
hostname
=
NULL
;
buf
=
grab_extradata
(
buf
,
end
,
"DNSMASQ_SUPPLIED_HOSTNAME"
,
&
err
);
if
(
!
is6
)
{
buf
=
grab_extradata
(
buf
,
end
,
"DNSMASQ_CPEWAN_OUI"
,
&
err
);
buf
=
grab_extradata
(
buf
,
end
,
"DNSMASQ_CPEWAN_SERIAL"
,
&
err
);
buf
=
grab_extradata
(
buf
,
end
,
"DNSMASQ_CPEWAN_CLASS"
,
&
err
);
}
buf
=
grab_extradata
(
buf
,
end
,
"DNSMASQ_TAGS"
,
&
err
);
if
(
is6
)
buf
=
grab_extradata
(
buf
,
end
,
"DNSMASQ_RELAY_ADDRESS"
,
&
err
);
else
if
(
data
.
giaddr
.
s_addr
!=
0
)
my_setenv
(
"DNSMASQ_RELAY_ADDRESS"
,
inet_ntoa
(
data
.
giaddr
),
&
err
);
for
(
i
=
0
;
buf
;
i
++
)
{
sprintf
(
daemon
->
dhcp_buff2
,
"DNSMASQ_USER_CLASS%i"
,
i
);
buf
=
grab_extradata
(
buf
,
end
,
daemon
->
dhcp_buff2
,
&
err
);
}
if
(
data
.
action
!=
ACTION_DEL
&&
data
.
remaining_time
!=
0
)
{
sprintf
(
daemon
->
dhcp_buff2
,
"%u"
,
data
.
remaining_time
);
my_setenv
(
"DNSMASQ_TIME_REMAINING"
,
daemon
->
dhcp_buff2
,
&
err
);
}
if
(
data
.
action
==
ACTION_OLD_HOSTNAME
&&
hostname
)
{
my_setenv
(
"DNSMASQ_OLD_HOSTNAME"
,
hostname
,
&
err
);
hostname
=
NULL
;
}
}
if
(
option_bool
(
OPT_LOG_OPTS
))
my_setenv
(
"DNSMASQ_LOG_DHCP"
,
"1"
,
&
err
);
/* we need to have the event_fd around if exec fails */
if
((
i
=
fcntl
(
event_fd
,
F_GETFD
))
!=
-
1
)
fcntl
(
event_fd
,
F_SETFD
,
i
|
FD_CLOEXEC
);
...
...
@@ -584,11 +624,29 @@ static unsigned char *grab_extradata_lua(unsigned char *buf, unsigned char *end,
}
#endif
static
void
buff_alloc
(
size_t
size
)
{
if
(
size
>
buf_size
)
{
struct
script_data
*
new
;
/* start with reasonable size, will almost never need extending. */
if
(
size
<
sizeof
(
struct
script_data
)
+
200
)
size
=
sizeof
(
struct
script_data
)
+
200
;
if
(
!
(
new
=
whine_malloc
(
size
)))
return
;
if
(
buf
)
free
(
buf
);
buf
=
new
;
buf_size
=
size
;
}
}
/* pack up lease data into a buffer */
void
queue_script
(
int
action
,
struct
dhcp_lease
*
lease
,
char
*
hostname
,
time_t
now
)
{
unsigned
char
*
p
;
size_t
size
;
unsigned
int
hostname_len
=
0
,
clid_len
=
0
,
ed_len
=
0
;
int
fd
=
daemon
->
dhcpfd
;
...
...
@@ -608,23 +666,7 @@ void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t n
if
(
hostname
)
hostname_len
=
strlen
(
hostname
)
+
1
;
size
=
sizeof
(
struct
script_data
)
+
clid_len
+
ed_len
+
hostname_len
;
if
(
size
>
buf_size
)
{
struct
script_data
*
new
;
/* start with reasonable size, will almost never need extending. */
if
(
size
<
sizeof
(
struct
script_data
)
+
200
)
size
=
sizeof
(
struct
script_data
)
+
200
;
if
(
!
(
new
=
whine_malloc
(
size
)))
return
;
if
(
buf
)
free
(
buf
);
buf
=
new
;
buf_size
=
size
;
}
buff_alloc
(
sizeof
(
struct
script_data
)
+
clid_len
+
ed_len
+
hostname_len
);
buf
->
action
=
action
;
buf
->
flags
=
lease
->
flags
;
...
...
@@ -669,6 +711,37 @@ void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t n
bytes_in_buf
=
p
-
(
unsigned
char
*
)
buf
;
}
#ifdef HAVE_TFTP
/* This nastily re-uses DHCP-fields for TFTP stuff */
void
queue_tftp
(
off_t
file_len
,
char
*
filename
,
union
mysockaddr
*
peer
)
{
unsigned
int
filename_len
;
/* no script */
if
(
daemon
->
helperfd
==
-
1
)
return
;
filename_len
=
strlen
(
filename
)
+
1
;
buff_alloc
(
sizeof
(
struct
script_data
)
+
filename_len
);
memset
(
buf
,
0
,
sizeof
(
struct
script_data
));
buf
->
action
=
ACTION_TFTP
;
buf
->
hostname_len
=
filename_len
;
buf
->
hwaddr_len
=
file_len
;
if
((
buf
->
flags
=
peer
->
sa
.
sa_family
)
==
AF_INET
)
buf
->
addr
=
peer
->
in
.
sin_addr
;
#ifdef HAVE_IPV6
else
memcpy
(
buf
->
hwaddr
,
&
peer
->
in6
.
sin6_addr
,
IN6ADDRSZ
);
#endif
memcpy
((
unsigned
char
*
)(
buf
+
1
),
filename
,
filename_len
);
bytes_in_buf
=
sizeof
(
struct
script_data
)
+
filename_len
;
}
#endif
int
helper_buf_empty
(
void
)
{
return
bytes_in_buf
==
0
;
...
...
src/tftp.c
View file @
a9530964
...
...
@@ -571,7 +571,9 @@ void check_tftp_listeners(fd_set *rset, time_t now)
my_syslog
(
MS_TFTP
|
LOG_INFO
,
_
(
"sent %s to %s"
),
transfer
->
file
->
filename
,
daemon
->
addrbuff
);
/* unlink */
*
up
=
tmp
;
free_transfer
(
transfer
);
/* put on queue to be sent to script and deleted */
transfer
->
next
=
daemon
->
tftp_done_trans
;
daemon
->
tftp_done_trans
=
transfer
;
continue
;
}
}
...
...
@@ -709,4 +711,21 @@ static ssize_t get_block(char *packet, struct tftp_transfer *transfer)
}
}
int
do_tftp_script_run
(
void
)
{
struct
tftp_transfer
*
transfer
;
if
((
transfer
=
daemon
->
tftp_done_trans
))
{
daemon
->
tftp_done_trans
=
transfer
->
next
;
#ifdef HAVE_SCRIPT
queue_tftp
(
transfer
->
file
->
size
,
transfer
->
file
->
filename
,
&
transfer
->
peer
);
#endif
free_transfer
(
transfer
);
return
1
;
}
return
0
;
}
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment