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
faafb3f7
Commit
faafb3f7
authored
Sep 20, 2012
by
Simon Kelley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add SetServersEX method in DBus interface.
parent
2b127a1e
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
371 additions
and
165 deletions
+371
-165
CHANGELOG
CHANGELOG
+3
-0
dbus/DBus-interface
dbus/DBus-interface
+42
-0
src/dbus.c
src/dbus.c
+233
-87
src/dnsmasq.h
src/dnsmasq.h
+2
-0
src/option.c
src/option.c
+91
-78
No files found.
CHANGELOG
View file @
faafb3f7
...
@@ -19,6 +19,9 @@ version 2.64
...
@@ -19,6 +19,9 @@ version 2.64
Flag DHCP or DHCPv6 in starup logging. Thanks to
Flag DHCP or DHCPv6 in starup logging. Thanks to
Vladislav Grishenko for the patch.
Vladislav Grishenko for the patch.
Add SetServersEX method in DBus interface. Thanks to Dan
Williams for the patch.
version 2.63
version 2.63
Do duplicate dhcp-host address check in --test mode.
Do duplicate dhcp-host address check in --test mode.
...
...
dbus/DBus-interface
View file @
faafb3f7
...
@@ -95,6 +95,48 @@ Each call to SetServers completely replaces the set of servers
...
@@ -95,6 +95,48 @@ Each call to SetServers completely replaces the set of servers
specified by via the DBus, but it leaves any servers specified via the
specified by via the DBus, but it leaves any servers specified via the
command line or /etc/dnsmasq.conf or /etc/resolv.conf alone.
command line or /etc/dnsmasq.conf or /etc/resolv.conf alone.
SetServersEx
------------
This function is more flexible and the SetServers function, in that it can
handle address scoping, port numbers, and is easier for clients to use.
Returns nothing. Takes a set of arguments representing the new
upstream DNS servers to be used by dnsmasq. All addresses (both IPv4 and IPv6)
are represented as STRINGS. Each server address may be followed by one or more
STRINGS, which are the domains for which the preceding server should be used.
This function takes an array of STRING arrays, where each inner array represents
a set of DNS servers and domains for which those servers may be used. Each
string represents a list of upstream DNS servers first, and domains second.
Mixing of domains and servers within a the string array is not allowed.
Examples.
[
["1.2.3.4", "foobar.com"],
["1003:1234:abcd::1%eth0", "eng.mycorp.com", "lab.mycorp.com"]
]
is equivalent to
--server=/foobar.com/1.2.3.4 \
--server=/eng.mycorp.com/lab.mycorp.com/1003:1234:abcd::1%eth0
An IPv4 address of 0.0.0.0 is interpreted as "no address, local only",
so
[ ["0.0.0.0", "local.domain"] ]
is equivalent to
--local=/local.domain/
Each call to SetServersEx completely replaces the set of servers
specified by via the DBus, but it leaves any servers specified via the
command line or /etc/dnsmasq.conf or /etc/resolv.conf alone.
2. SIGNALS
2. SIGNALS
----------
----------
...
...
src/dbus.c
View file @
faafb3f7
...
@@ -38,6 +38,9 @@ const char* introspection_xml_template =
...
@@ -38,6 +38,9 @@ const char* introspection_xml_template =
" <method name=
\"
SetServers
\"
>
\n
"
" <method name=
\"
SetServers
\"
>
\n
"
" <arg name=
\"
servers
\"
direction=
\"
in
\"
type=
\"
av
\"
/>
\n
"
" <arg name=
\"
servers
\"
direction=
\"
in
\"
type=
\"
av
\"
/>
\n
"
" </method>
\n
"
" </method>
\n
"
" <method name=
\"
SetServersEx
\"
>
\n
"
" <arg name=
\"
servers
\"
direction=
\"
in
\"
type=
\"
aas
\"
/>
\n
"
" </method>
\n
"
" <signal name=
\"
DhcpLeaseAdded
\"
>
\n
"
" <signal name=
\"
DhcpLeaseAdded
\"
>
\n
"
" <arg name=
\"
ipaddr
\"
type=
\"
s
\"
/>
\n
"
" <arg name=
\"
ipaddr
\"
type=
\"
s
\"
/>
\n
"
" <arg name=
\"
hwaddr
\"
type=
\"
s
\"
/>
\n
"
" <arg name=
\"
hwaddr
\"
type=
\"
s
\"
/>
\n
"
...
@@ -99,20 +102,118 @@ static void remove_watch(DBusWatch *watch, void *data)
...
@@ -99,20 +102,118 @@ static void remove_watch(DBusWatch *watch, void *data)
w
=
data
;
/* no warning */
w
=
data
;
/* no warning */
}
}
static
void
dbus_read_servers
(
DBusMessage
*
message
)
static
void
add_update_server
(
union
mysockaddr
*
addr
,
union
mysockaddr
*
source_addr
,
const
char
*
interface
,
const
char
*
domain
)
{
{
struct
server
*
serv
,
*
tmp
,
**
up
;
struct
server
*
serv
;
DBusMessageIter
iter
;
union
mysockaddr
addr
,
source_addr
;
/* See if there is a suitable candidate, and unmark */
char
*
domain
;
for
(
serv
=
daemon
->
servers
;
serv
;
serv
=
serv
->
next
)
if
((
serv
->
flags
&
SERV_FROM_DBUS
)
&&
(
serv
->
flags
&
SERV_MARK
))
{
if
(
domain
)
{
if
(
!
(
serv
->
flags
&
SERV_HAS_DOMAIN
)
||
!
hostname_isequal
(
domain
,
serv
->
domain
))
continue
;
}
else
{
if
(
serv
->
flags
&
SERV_HAS_DOMAIN
)
continue
;
}
serv
->
flags
&=
~
SERV_MARK
;
break
;
}
dbus_message_iter_init
(
message
,
&
iter
);
if
(
!
serv
&&
(
serv
=
whine_malloc
(
sizeof
(
struct
server
))))
{
/* Not found, create a new one. */
memset
(
serv
,
0
,
sizeof
(
struct
server
));
if
(
domain
&&
!
(
serv
->
domain
=
whine_malloc
(
strlen
(
domain
)
+
1
)))
{
free
(
serv
);
serv
=
NULL
;
}
else
{
serv
->
next
=
daemon
->
servers
;
daemon
->
servers
=
serv
;
serv
->
flags
=
SERV_FROM_DBUS
;
if
(
domain
)
{
strcpy
(
serv
->
domain
,
domain
);
serv
->
flags
|=
SERV_HAS_DOMAIN
;
}
}
}
if
(
serv
)
{
if
(
interface
)
strcpy
(
serv
->
interface
,
interface
);
else
serv
->
interface
[
0
]
=
0
;
if
(
source_addr
->
in
.
sin_family
==
AF_INET
&&
addr
->
in
.
sin_addr
.
s_addr
==
0
&&
serv
->
domain
)
serv
->
flags
|=
SERV_NO_ADDR
;
else
{
serv
->
flags
&=
~
SERV_NO_ADDR
;
serv
->
addr
=
*
addr
;
serv
->
source_addr
=
*
source_addr
;
}
}
}
static
void
mark_dbus
(
void
)
{
struct
server
*
serv
;
/* mark everything from DBUS */
/* mark everything from DBUS */
for
(
serv
=
daemon
->
servers
;
serv
;
serv
=
serv
->
next
)
for
(
serv
=
daemon
->
servers
;
serv
;
serv
=
serv
->
next
)
if
(
serv
->
flags
&
SERV_FROM_DBUS
)
if
(
serv
->
flags
&
SERV_FROM_DBUS
)
serv
->
flags
|=
SERV_MARK
;
serv
->
flags
|=
SERV_MARK
;
}
static
void
cleanup_dbus
()
{
struct
server
*
serv
,
*
tmp
,
**
up
;
/* unlink and free anything still marked. */
for
(
serv
=
daemon
->
servers
,
up
=
&
daemon
->
servers
;
serv
;
serv
=
tmp
)
{
tmp
=
serv
->
next
;
if
(
serv
->
flags
&
SERV_MARK
)
{
server_gone
(
serv
);
*
up
=
serv
->
next
;
if
(
serv
->
domain
)
free
(
serv
->
domain
);
free
(
serv
);
}
else
up
=
&
serv
->
next
;
}
}
static
void
dbus_read_servers
(
DBusMessage
*
message
)
{
DBusMessageIter
iter
;
union
mysockaddr
addr
,
source_addr
;
char
*
domain
;
dbus_message_iter_init
(
message
,
&
iter
);
mark_dbus
();
while
(
1
)
while
(
1
)
{
{
int
skip
=
0
;
int
skip
=
0
;
...
@@ -171,6 +272,7 @@ static void dbus_read_servers(DBusMessage *message)
...
@@ -171,6 +272,7 @@ static void dbus_read_servers(DBusMessage *message)
/* At the end */
/* At the end */
break
;
break
;
/* process each domain */
do
{
do
{
if
(
dbus_message_iter_get_arg_type
(
&
iter
)
==
DBUS_TYPE_STRING
)
if
(
dbus_message_iter_get_arg_type
(
&
iter
)
==
DBUS_TYPE_STRING
)
{
{
...
@@ -181,83 +283,118 @@ static void dbus_read_servers(DBusMessage *message)
...
@@ -181,83 +283,118 @@ static void dbus_read_servers(DBusMessage *message)
domain
=
NULL
;
domain
=
NULL
;
if
(
!
skip
)
if
(
!
skip
)
{
add_update_server
(
&
addr
,
&
source_addr
,
NULL
,
domain
);
/* See if this is already there, and unmark */
for
(
serv
=
daemon
->
servers
;
serv
;
serv
=
serv
->
next
)
}
while
(
dbus_message_iter_get_arg_type
(
&
iter
)
==
DBUS_TYPE_STRING
);
if
((
serv
->
flags
&
SERV_FROM_DBUS
)
&&
(
serv
->
flags
&
SERV_MARK
))
{
if
(
!
(
serv
->
flags
&
SERV_HAS_DOMAIN
)
&&
!
domain
)
{
serv
->
flags
&=
~
SERV_MARK
;
break
;
}
if
((
serv
->
flags
&
SERV_HAS_DOMAIN
)
&&
domain
&&
hostname_isequal
(
domain
,
serv
->
domain
))
{
serv
->
flags
&=
~
SERV_MARK
;
break
;
}
}
if
(
!
serv
&&
(
serv
=
whine_malloc
(
sizeof
(
struct
server
))))
{
/* Not found, create a new one. */
memset
(
serv
,
0
,
sizeof
(
struct
server
));
if
(
domain
)
serv
->
domain
=
whine_malloc
(
strlen
(
domain
)
+
1
);
if
(
domain
&&
!
serv
->
domain
)
{
free
(
serv
);
serv
=
NULL
;
}
else
{
serv
->
next
=
daemon
->
servers
;
daemon
->
servers
=
serv
;
serv
->
flags
=
SERV_FROM_DBUS
;
if
(
domain
)
{
strcpy
(
serv
->
domain
,
domain
);
serv
->
flags
|=
SERV_HAS_DOMAIN
;
}
}
}
if
(
serv
)
{
if
(
source_addr
.
in
.
sin_family
==
AF_INET
&&
addr
.
in
.
sin_addr
.
s_addr
==
0
&&
serv
->
domain
)
serv
->
flags
|=
SERV_NO_ADDR
;
else
{
serv
->
flags
&=
~
SERV_NO_ADDR
;
serv
->
addr
=
addr
;
serv
->
source_addr
=
source_addr
;
}
}
}
}
while
(
dbus_message_iter_get_arg_type
(
&
iter
)
==
DBUS_TYPE_STRING
);
}
}
/* unlink and free anything still marked. */
/* unlink and free anything still marked. */
for
(
serv
=
daemon
->
servers
,
up
=
&
daemon
->
servers
;
serv
;
serv
=
tmp
)
cleanup_dbus
();
}
static
DBusMessage
*
dbus_read_servers_ex
(
DBusMessage
*
message
)
{
DBusMessageIter
iter
,
array_iter
,
string_iter
;
DBusMessage
*
error
=
NULL
;
const
char
*
addr_err
;
if
(
!
dbus_message_iter_init
(
message
,
&
iter
))
{
{
tmp
=
serv
->
next
;
return
dbus_message_new_error
(
message
,
DBUS_ERROR_INVALID_ARGS
,
if
(
serv
->
flags
&
SERV_MARK
)
"Failed to initialize dbus message iter"
);
{
server_gone
(
serv
);
*
up
=
serv
->
next
;
free
(
serv
);
}
else
up
=
&
serv
->
next
;
}
}
/* check that the message contains an array of arrays */
if
((
dbus_message_iter_get_arg_type
(
&
iter
)
!=
DBUS_TYPE_ARRAY
)
||
(
dbus_message_iter_get_element_type
(
&
iter
)
!=
DBUS_TYPE_ARRAY
))
{
return
dbus_message_new_error
(
message
,
DBUS_ERROR_INVALID_ARGS
,
"Expected array of string arrays"
);
}
mark_dbus
();
/* array_iter points to each "as" element in the outer array */
dbus_message_iter_recurse
(
&
iter
,
&
array_iter
);
while
(
dbus_message_iter_get_arg_type
(
&
array_iter
)
!=
DBUS_TYPE_INVALID
)
{
const
char
*
str
=
NULL
;
union
mysockaddr
addr
,
source_addr
;
char
interface
[
IF_NAMESIZE
];
char
*
str_addr
;
/* check the types of the struct and its elements */
if
((
dbus_message_iter_get_arg_type
(
&
array_iter
)
!=
DBUS_TYPE_ARRAY
)
||
(
dbus_message_iter_get_element_type
(
&
array_iter
)
!=
DBUS_TYPE_STRING
))
{
error
=
dbus_message_new_error
(
message
,
DBUS_ERROR_INVALID_ARGS
,
"Expected inner array of strings"
);
break
;
}
/* string_iter points to each "s" element in the inner array */
dbus_message_iter_recurse
(
&
array_iter
,
&
string_iter
);
if
(
dbus_message_iter_get_arg_type
(
&
string_iter
)
!=
DBUS_TYPE_STRING
)
{
/* no IP address given */
error
=
dbus_message_new_error
(
message
,
DBUS_ERROR_INVALID_ARGS
,
"Expected IP address"
);
break
;
}
dbus_message_iter_get_basic
(
&
string_iter
,
&
str
);
if
(
!
str
||
!
strlen
(
str
))
{
error
=
dbus_message_new_error
(
message
,
DBUS_ERROR_INVALID_ARGS
,
"Empty IP address"
);
break
;
}
memset
(
&
addr
,
0
,
sizeof
(
addr
));
memset
(
&
source_addr
,
0
,
sizeof
(
source_addr
));
memset
(
&
interface
,
0
,
sizeof
(
interface
));
/* dup the string because it gets modified during parsing */
str_addr
=
strdup
(
str
);
if
(
!
str_addr
)
{
error
=
dbus_message_new_error
(
message
,
DBUS_ERROR_INVALID_ARGS
,
"Out of memory parsing IP address"
);
break
;
}
/* parse the IP address */
addr_err
=
parse_server
(
str_addr
,
&
addr
,
&
source_addr
,
&
interface
,
NULL
);
free
(
str_addr
);
if
(
addr_err
)
{
error
=
dbus_message_new_error_printf
(
message
,
DBUS_ERROR_INVALID_ARGS
,
"Invalid IP address '%s': %s"
,
str
,
addr_err
);
break
;
}
/* jump past the address to the domain list (if any) */
dbus_message_iter_next
(
&
string_iter
);
/* parse domains and add each server/domain pair to the list */
do
{
str
=
NULL
;
if
(
dbus_message_iter_get_arg_type
(
&
string_iter
)
==
DBUS_TYPE_STRING
)
dbus_message_iter_get_basic
(
&
string_iter
,
&
str
);
dbus_message_iter_next
(
&
string_iter
);
add_update_server
(
&
addr
,
&
source_addr
,
interface
,
str
);
}
while
(
dbus_message_iter_get_arg_type
(
&
string_iter
)
==
DBUS_TYPE_STRING
);
/* jump to next element in outer array */
dbus_message_iter_next
(
&
array_iter
);
}
cleanup_dbus
();
return
error
;
}
}
DBusHandlerResult
message_handler
(
DBusConnection
*
connection
,
DBusHandlerResult
message_handler
(
DBusConnection
*
connection
,
...
@@ -265,11 +402,10 @@ DBusHandlerResult message_handler(DBusConnection *connection,
...
@@ -265,11 +402,10 @@ DBusHandlerResult message_handler(DBusConnection *connection,
void
*
user_data
)
void
*
user_data
)
{
{
char
*
method
=
(
char
*
)
dbus_message_get_member
(
message
);
char
*
method
=
(
char
*
)
dbus_message_get_member
(
message
);
DBusMessage
*
reply
=
NULL
;
if
(
dbus_message_is_method_call
(
message
,
DBUS_INTERFACE_INTROSPECTABLE
,
"Introspect"
))
if
(
dbus_message_is_method_call
(
message
,
DBUS_INTERFACE_INTROSPECTABLE
,
"Introspect"
))
{
{
DBusMessage
*
reply
;
/* string length: "%s" provides space for termination zero */
/* string length: "%s" provides space for termination zero */
if
(
!
introspection_xml
&&
if
(
!
introspection_xml
&&
(
introspection_xml
=
whine_malloc
(
strlen
(
introspection_xml_template
)
+
strlen
(
daemon
->
dbus_name
))))
(
introspection_xml
=
whine_malloc
(
strlen
(
introspection_xml_template
)
+
strlen
(
daemon
->
dbus_name
))))
...
@@ -278,20 +414,15 @@ DBusHandlerResult message_handler(DBusConnection *connection,
...
@@ -278,20 +414,15 @@ DBusHandlerResult message_handler(DBusConnection *connection,
if
(
introspection_xml
)
if
(
introspection_xml
)
{
{
reply
=
dbus_message_new_method_return
(
message
);
reply
=
dbus_message_new_method_return
(
message
);
dbus_message_append_args
(
reply
,
DBUS_TYPE_STRING
,
&
introspection_xml
,
DBUS_TYPE_INVALID
);
dbus_message_append_args
(
reply
,
DBUS_TYPE_STRING
,
&
introspection_xml
,
DBUS_TYPE_INVALID
);
dbus_connection_send
(
connection
,
reply
,
NULL
);
dbus_message_unref
(
reply
);
}
}
}
}
else
if
(
strcmp
(
method
,
"GetVersion"
)
==
0
)
else
if
(
strcmp
(
method
,
"GetVersion"
)
==
0
)
{
{
char
*
v
=
VERSION
;
char
*
v
=
VERSION
;
DBusMessage
*
reply
=
dbus_message_new_method_return
(
message
);
reply
=
dbus_message_new_method_return
(
message
);
dbus_message_append_args
(
reply
,
DBUS_TYPE_STRING
,
&
v
,
DBUS_TYPE_INVALID
);
dbus_message_append_args
(
reply
,
DBUS_TYPE_STRING
,
&
v
,
DBUS_TYPE_INVALID
);
dbus_connection_send
(
connection
,
reply
,
NULL
);
dbus_message_unref
(
reply
);
}
}
else
if
(
strcmp
(
method
,
"SetServers"
)
==
0
)
else
if
(
strcmp
(
method
,
"SetServers"
)
==
0
)
{
{
...
@@ -299,6 +430,12 @@ DBusHandlerResult message_handler(DBusConnection *connection,
...
@@ -299,6 +430,12 @@ DBusHandlerResult message_handler(DBusConnection *connection,
dbus_read_servers
(
message
);
dbus_read_servers
(
message
);
check_servers
();
check_servers
();
}
}
else
if
(
strcmp
(
method
,
"SetServersEx"
)
==
0
)
{
my_syslog
(
LOG_INFO
,
_
(
"setting upstream servers from DBus"
));
reply
=
dbus_read_servers_ex
(
message
);
check_servers
();
}
else
if
(
strcmp
(
method
,
"ClearCache"
)
==
0
)
else
if
(
strcmp
(
method
,
"ClearCache"
)
==
0
)
clear_cache_and_reload
(
dnsmasq_time
());
clear_cache_and_reload
(
dnsmasq_time
());
else
else
...
@@ -306,8 +443,17 @@ DBusHandlerResult message_handler(DBusConnection *connection,
...
@@ -306,8 +443,17 @@ DBusHandlerResult message_handler(DBusConnection *connection,
method
=
user_data
;
/* no warning */
method
=
user_data
;
/* no warning */
/* If no reply or no error, return nothing */
if
(
!
reply
)
reply
=
dbus_message_new_method_return
(
message
);
if
(
reply
)
{
dbus_connection_send
(
connection
,
reply
,
NULL
);
dbus_message_unref
(
reply
);
}
return
(
DBUS_HANDLER_RESULT_HANDLED
);
return
(
DBUS_HANDLER_RESULT_HANDLED
);
}
}
...
...
src/dnsmasq.h
View file @
faafb3f7
...
@@ -928,6 +928,8 @@ void reread_dhcp(void);
...
@@ -928,6 +928,8 @@ void reread_dhcp(void);
void
set_option_bool
(
unsigned
int
opt
);
void
set_option_bool
(
unsigned
int
opt
);
void
reset_option_bool
(
unsigned
int
opt
);
void
reset_option_bool
(
unsigned
int
opt
);
struct
hostsfile
*
expand_filelist
(
struct
hostsfile
*
list
);
struct
hostsfile
*
expand_filelist
(
struct
hostsfile
*
list
);
char
*
parse_server
(
char
*
arg
,
union
mysockaddr
*
addr
,
union
mysockaddr
*
source_addr
,
char
*
interface
,
int
*
flags
);
/* forward.c */
/* forward.c */
void
reply_query
(
int
fd
,
int
family
,
time_t
now
);
void
reply_query
(
int
fd
,
int
family
,
time_t
now
);
...
...
src/option.c
View file @
faafb3f7
...
@@ -621,6 +621,93 @@ static char *set_prefix(char *arg)
...
@@ -621,6 +621,93 @@ static char *set_prefix(char *arg)
return
arg
;
return
arg
;
}
}
char
*
parse_server
(
char
*
arg
,
union
mysockaddr
*
addr
,
union
mysockaddr
*
source_addr
,
char
*
interface
,
int
*
flags
)
{
int
source_port
=
0
,
serv_port
=
NAMESERVER_PORT
;
char
*
portno
,
*
source
;
#ifdef HAVE_IPV6
int
scope_index
=
0
;
char
*
scope_id
;
#endif
if
((
source
=
split_chr
(
arg
,
'@'
))
&&
/* is there a source. */
(
portno
=
split_chr
(
source
,
'#'
))
&&
!
atoi_check16
(
portno
,
&
source_port
))
return
_
(
"bad port"
);
if
((
portno
=
split_chr
(
arg
,
'#'
))
&&
/* is there a port no. */
!
atoi_check16
(
portno
,
&
serv_port
))
return
_
(
"bad port"
);
#ifdef HAVE_IPV6
scope_id
=
split_chr
(
arg
,
'%'
);
#endif
if
((
addr
->
in
.
sin_addr
.
s_addr
=
inet_addr
(
arg
))
!=
(
in_addr_t
)
-
1
)
{
addr
->
in
.
sin_port
=
htons
(
serv_port
);
addr
->
sa
.
sa_family
=
source_addr
->
sa
.
sa_family
=
AF_INET
;
#ifdef HAVE_SOCKADDR_SA_LEN
source_addr
->
in
.
sin_len
=
addr
->
in
.
sin_len
=
sizeof
(
struct
sockaddr_in
);
#endif
source_addr
->
in
.
sin_addr
.
s_addr
=
INADDR_ANY
;
source_addr
->
in
.
sin_port
=
htons
(
daemon
->
query_port
);
if
(
source
)
{
if
(
flags
)
*
flags
|=
SERV_HAS_SOURCE
;
source_addr
->
in
.
sin_port
=
htons
(
source_port
);
if
((
source_addr
->
in
.
sin_addr
.
s_addr
=
inet_addr
(
source
))
==
(
in_addr_t
)
-
1
)
{
#if defined(SO_BINDTODEVICE)
source_addr
->
in
.
sin_addr
.
s_addr
=
INADDR_ANY
;
strncpy
(
interface
,
source
,
IF_NAMESIZE
-
1
);
#else
return
_
(
"interface binding not supported"
);
#endif
}
}
}
#ifdef HAVE_IPV6
else
if
(
inet_pton
(
AF_INET6
,
arg
,
&
addr
->
in6
.
sin6_addr
)
>
0
)
{
if
(
scope_id
&&
(
scope_index
=
if_nametoindex
(
scope_id
))
==
0
)
return
_
(
"bad interface name"
);
addr
->
in6
.
sin6_port
=
htons
(
serv_port
);
addr
->
in6
.
sin6_scope_id
=
scope_index
;
source_addr
->
in6
.
sin6_addr
=
in6addr_any
;
source_addr
->
in6
.
sin6_port
=
htons
(
daemon
->
query_port
);
source_addr
->
in6
.
sin6_scope_id
=
0
;
addr
->
sa
.
sa_family
=
source_addr
->
sa
.
sa_family
=
AF_INET6
;
addr
->
in6
.
sin6_flowinfo
=
source_addr
->
in6
.
sin6_flowinfo
=
0
;
#ifdef HAVE_SOCKADDR_SA_LEN
addr
->
in6
.
sin6_len
=
source_addr
->
in6
.
sin6_len
=
sizeof
(
addr
->
in6
);
#endif
if
(
source
)
{
if
(
flags
)
*
flags
|=
SERV_HAS_SOURCE
;
source_addr
->
in6
.
sin6_port
=
htons
(
source_port
);
if
(
inet_pton
(
AF_INET6
,
source
,
&
source_addr
->
in6
.
sin6_addr
)
==
0
)
{
#if defined(SO_BINDTODEVICE)
source_addr
->
in6
.
sin6_addr
=
in6addr_any
;
strncpy
(
interface
,
source
,
IF_NAMESIZE
-
1
);
#else
return
_
(
"interface binding not supported"
);
#endif
}
}
}
#endif
else
return
_
(
"bad address"
);
return
NULL
;
}
/* This is too insanely large to keep in-line in the switch */
/* This is too insanely large to keep in-line in the switch */
static
int
parse_dhcp_opt
(
char
*
errstr
,
char
*
arg
,
int
flags
)
static
int
parse_dhcp_opt
(
char
*
errstr
,
char
*
arg
,
int
flags
)
{
{
...
@@ -1760,84 +1847,9 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
...
@@ -1760,84 +1847,9 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
}
else
else
{
{
int
source_port
=
0
,
serv_port
=
NAMESERVER_PORT
;
char
*
err
=
parse_server
(
arg
,
&
newlist
->
addr
,
&
newlist
->
source_addr
,
newlist
->
interface
,
&
newlist
->
flags
);
char
*
portno
,
*
source
;
if
(
err
)
#ifdef HAVE_IPV6
ret_err
(
err
);
int
scope_index
=
0
;
char
*
scope_id
;
#endif
if
((
source
=
split_chr
(
arg
,
'@'
))
&&
/* is there a source. */
(
portno
=
split_chr
(
source
,
'#'
))
&&
!
atoi_check16
(
portno
,
&
source_port
))
ret_err
(
_
(
"bad port"
));
if
((
portno
=
split_chr
(
arg
,
'#'
))
&&
/* is there a port no. */
!
atoi_check16
(
portno
,
&
serv_port
))
ret_err
(
_
(
"bad port"
));
#ifdef HAVE_IPV6
scope_id
=
split_chr
(
arg
,
'%'
);
#endif
if
((
newlist
->
addr
.
in
.
sin_addr
.
s_addr
=
inet_addr
(
arg
))
!=
(
in_addr_t
)
-
1
)
{
newlist
->
addr
.
in
.
sin_port
=
htons
(
serv_port
);
newlist
->
source_addr
.
in
.
sin_port
=
htons
(
source_port
);
newlist
->
addr
.
sa
.
sa_family
=
newlist
->
source_addr
.
sa
.
sa_family
=
AF_INET
;
#ifdef HAVE_SOCKADDR_SA_LEN
newlist
->
source_addr
.
in
.
sin_len
=
newlist
->
addr
.
in
.
sin_len
=
sizeof
(
struct
sockaddr_in
);
#endif
if
(
source
)
{
newlist
->
flags
|=
SERV_HAS_SOURCE
;
if
((
newlist
->
source_addr
.
in
.
sin_addr
.
s_addr
=
inet_addr
(
source
))
==
(
in_addr_t
)
-
1
)
{
#if defined(SO_BINDTODEVICE)
newlist
->
source_addr
.
in
.
sin_addr
.
s_addr
=
INADDR_ANY
;
strncpy
(
newlist
->
interface
,
source
,
IF_NAMESIZE
-
1
);
#else
ret_err
(
_
(
"interface binding not supported"
));
#endif
}
}
else
newlist
->
source_addr
.
in
.
sin_addr
.
s_addr
=
INADDR_ANY
;
}
#ifdef HAVE_IPV6
else
if
(
inet_pton
(
AF_INET6
,
arg
,
&
newlist
->
addr
.
in6
.
sin6_addr
)
>
0
)
{
if
(
scope_id
&&
(
scope_index
=
if_nametoindex
(
scope_id
))
==
0
)
ret_err
(
_
(
"bad interface name"
));
newlist
->
addr
.
in6
.
sin6_port
=
htons
(
serv_port
);
newlist
->
addr
.
in6
.
sin6_scope_id
=
scope_index
;
newlist
->
source_addr
.
in6
.
sin6_port
=
htons
(
source_port
);
newlist
->
source_addr
.
in6
.
sin6_scope_id
=
0
;
newlist
->
addr
.
sa
.
sa_family
=
newlist
->
source_addr
.
sa
.
sa_family
=
AF_INET6
;
newlist
->
addr
.
in6
.
sin6_flowinfo
=
newlist
->
source_addr
.
in6
.
sin6_flowinfo
=
0
;
#ifdef HAVE_SOCKADDR_SA_LEN
newlist
->
addr
.
in6
.
sin6_len
=
newlist
->
source_addr
.
in6
.
sin6_len
=
sizeof
(
newlist
->
addr
.
in6
);
#endif
if
(
source
)
{
newlist
->
flags
|=
SERV_HAS_SOURCE
;
if
(
inet_pton
(
AF_INET6
,
source
,
&
newlist
->
source_addr
.
in6
.
sin6_addr
)
==
0
)
{
#if defined(SO_BINDTODEVICE)
newlist
->
source_addr
.
in6
.
sin6_addr
=
in6addr_any
;
strncpy
(
newlist
->
interface
,
source
,
IF_NAMESIZE
-
1
);
#else
ret_err
(
_
(
"interface binding not supported"
));
#endif
}
}
else
newlist
->
source_addr
.
in6
.
sin6_addr
=
in6addr_any
;
}
#endif
else
ret_err
(
gen_err
);
}
}
serv
=
newlist
;
serv
=
newlist
;
...
@@ -1846,6 +1858,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
...
@@ -1846,6 +1858,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
serv
->
next
->
flags
=
serv
->
flags
;
serv
->
next
->
flags
=
serv
->
flags
;
serv
->
next
->
addr
=
serv
->
addr
;
serv
->
next
->
addr
=
serv
->
addr
;
serv
->
next
->
source_addr
=
serv
->
source_addr
;
serv
->
next
->
source_addr
=
serv
->
source_addr
;
strcpy
(
serv
->
next
->
interface
,
serv
->
interface
);
serv
=
serv
->
next
;
serv
=
serv
->
next
;
}
}
serv
->
next
=
daemon
->
servers
;
serv
->
next
=
daemon
->
servers
;
...
...
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