version 1.1.1.4, 2021/03/17 00:56:46
|
version 1.1.1.5, 2023/09/27 11:02:07
|
Line 1
|
Line 1
|
/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley | /* dnsmasq is Copyright (c) 2000-2022 Simon Kelley |
|
|
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
Line 14
|
Line 14
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
along with this program. If not, see <http://www.gnu.org/licenses/>. |
*/ |
*/ |
|
|
#define COPYRIGHT "Copyright (c) 2000-2021 Simon Kelley" | #define COPYRIGHT "Copyright (c) 2000-2022 Simon Kelley" |
|
|
/* We do defines that influence behavior of stdio.h, so complain |
/* We do defines that influence behavior of stdio.h, so complain |
if included too early. */ |
if included too early. */ |
Line 95 typedef unsigned long long u64;
|
Line 95 typedef unsigned long long u64;
|
#if defined(HAVE_SOLARIS_NETWORK) |
#if defined(HAVE_SOLARIS_NETWORK) |
# include <sys/sockio.h> |
# include <sys/sockio.h> |
#endif |
#endif |
#if defined(HAVE_POLL_H) | #include <poll.h> |
# include <poll.h> | |
#else | |
# include <sys/poll.h> | |
#endif | |
#include <sys/wait.h> |
#include <sys/wait.h> |
#include <sys/time.h> |
#include <sys/time.h> |
#include <sys/un.h> |
#include <sys/un.h> |
Line 111 typedef unsigned long long u64;
|
Line 107 typedef unsigned long long u64;
|
#endif |
#endif |
#include <unistd.h> |
#include <unistd.h> |
#include <stdio.h> |
#include <stdio.h> |
|
#include <stdint.h> |
#include <string.h> |
#include <string.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <fcntl.h> |
#include <fcntl.h> |
Line 136 typedef unsigned long long u64;
|
Line 133 typedef unsigned long long u64;
|
#include <sys/uio.h> |
#include <sys/uio.h> |
#include <syslog.h> |
#include <syslog.h> |
#include <dirent.h> |
#include <dirent.h> |
|
#include <netdb.h> |
#ifndef HAVE_LINUX_NETWORK |
#ifndef HAVE_LINUX_NETWORK |
# include <net/if_dl.h> |
# include <net/if_dl.h> |
#endif |
#endif |
Line 273 struct event_desc {
|
Line 271 struct event_desc {
|
#define OPT_IGNORE_CLID 59 |
#define OPT_IGNORE_CLID 59 |
#define OPT_SINGLE_PORT 60 |
#define OPT_SINGLE_PORT 60 |
#define OPT_LEASE_RENEW 61 |
#define OPT_LEASE_RENEW 61 |
#define OPT_LAST 62 | #define OPT_LOG_DEBUG 62 |
| #define OPT_UMBRELLA 63 |
| #define OPT_UMBRELLA_DEVID 64 |
| #define OPT_CMARK_ALST_EN 65 |
| #define OPT_QUIET_TFTP 66 |
| #define OPT_FILTER_A 67 |
| #define OPT_FILTER_AAAA 68 |
| #define OPT_STRIP_ECS 69 |
| #define OPT_STRIP_MAC 70 |
| #define OPT_NORR 71 |
| #define OPT_NO_IDENT 72 |
| #define OPT_LAST 73 |
|
|
#define OPTION_BITS (sizeof(unsigned int)*8) |
#define OPTION_BITS (sizeof(unsigned int)*8) |
#define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) ) |
#define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) ) |
Line 281 struct event_desc {
|
Line 290 struct event_desc {
|
#define option_val(x) ((1u) << ((x) % OPTION_BITS)) |
#define option_val(x) ((1u) << ((x) % OPTION_BITS)) |
#define option_bool(x) (option_var(x) & option_val(x)) |
#define option_bool(x) (option_var(x) & option_val(x)) |
|
|
/* extra flags for my_syslog, we use a couple of facilities since they are known | /* extra flags for my_syslog, we use facilities since they are known |
not to occupy the same bits as priorities, no matter how syslog.h is set up. */ | not to occupy the same bits as priorities, no matter how syslog.h is set up. |
| MS_DEBUG messages are suppressed unless --log-debug is set. */ |
#define MS_TFTP LOG_USER |
#define MS_TFTP LOG_USER |
#define MS_DHCP LOG_DAEMON |
#define MS_DHCP LOG_DAEMON |
#define MS_SCRIPT LOG_MAIL |
#define MS_SCRIPT LOG_MAIL |
|
#define MS_DEBUG LOG_NEWS |
|
|
/* Note that this is used widely as a container for IPv4/IPv6 addresses, |
/* Note that this is used widely as a container for IPv4/IPv6 addresses, |
so for that reason, was well as to avoid wasting memory in almost every |
so for that reason, was well as to avoid wasting memory in almost every |
Line 321 union all_addr {
|
Line 332 union all_addr {
|
/* for log_query */ |
/* for log_query */ |
struct { |
struct { |
unsigned short keytag, algo, digest, rcode; |
unsigned short keytag, algo, digest, rcode; |
|
int ede; |
} log; |
} log; |
}; |
}; |
|
|
|
|
struct bogus_addr { |
struct bogus_addr { |
struct in_addr addr; | int is6, prefix; |
| union all_addr addr; |
struct bogus_addr *next; |
struct bogus_addr *next; |
}; |
}; |
|
|
Line 427 struct host_record {
|
Line 440 struct host_record {
|
struct host_record *next; |
struct host_record *next; |
}; |
}; |
|
|
|
#define IN4 1 |
|
#define IN6 2 |
|
#define INP4 4 |
|
#define INP6 8 |
|
|
struct interface_name { |
struct interface_name { |
char *name; /* domain name */ |
char *name; /* domain name */ |
char *intr; /* interface name */ |
char *intr; /* interface name */ |
int family; /* AF_INET, AF_INET6 or zero for both */ | int flags; |
| struct in_addr proto4; |
| struct in6_addr proto6; |
struct addrlist *addr; |
struct addrlist *addr; |
struct interface_name *next; |
struct interface_name *next; |
}; |
}; |
Line 490 struct crec {
|
Line 510 struct crec {
|
#define F_NO_RR (1u<<25) |
#define F_NO_RR (1u<<25) |
#define F_IPSET (1u<<26) |
#define F_IPSET (1u<<26) |
#define F_NOEXTRA (1u<<27) |
#define F_NOEXTRA (1u<<27) |
#define F_SERVFAIL (1u<<28) /* currently unused. */ | #define F_DOMAINSRV (1u<<28) |
#define F_RCODE (1u<<29) |
#define F_RCODE (1u<<29) |
#define F_SRV (1u<<30) |
#define F_SRV (1u<<30) |
|
#define F_STALE (1u<<31) |
|
|
#define UID_NONE 0 |
#define UID_NONE 0 |
/* Values of uid in crecs with F_CONFIG bit set. */ |
/* Values of uid in crecs with F_CONFIG bit set. */ |
Line 516 union mysockaddr {
|
Line 537 union mysockaddr {
|
#define IFACE_PERMANENT 4 |
#define IFACE_PERMANENT 4 |
|
|
|
|
#define SERV_FROM_RESOLV 1 /* 1 for servers from resolv, 0 for command line. */ | /* The actual values here matter, since we sort on them to get records in the order |
#define SERV_NO_ADDR 2 /* no server, this domain is local only */ | IPv6 addr, IPv4 addr, all zero return, resolvconf servers, upstream server, no-data return */ |
#define SERV_LITERAL_ADDRESS 4 /* addr is the answer, not the server */ | #define SERV_LITERAL_ADDRESS 1 /* addr is the answer, or NoDATA is the answer, depending on the next four flags */ |
#define SERV_HAS_DOMAIN 8 /* server for one domain only */ | #define SERV_USE_RESOLV 2 /* forward this domain in the normal way */ |
#define SERV_HAS_SOURCE 16 /* source address defined */ | #define SERV_ALL_ZEROS 4 /* return all zeros for A and AAAA */ |
#define SERV_FOR_NODOTS 32 /* server for names with no domain part only */ | #define SERV_4ADDR 8 /* addr is IPv4 */ |
#define SERV_WARNED_RECURSIVE 64 /* avoid warning spam */ | #define SERV_6ADDR 16 /* addr is IPv6 */ |
#define SERV_FROM_DBUS 128 /* 1 if source is DBus */ | #define SERV_HAS_SOURCE 32 /* source address defined */ |
#define SERV_MARK 256 /* for mark-and-delete */ | #define SERV_FOR_NODOTS 64 /* server for names with no domain part only */ |
#define SERV_TYPE (SERV_HAS_DOMAIN | SERV_FOR_NODOTS) | #define SERV_WARNED_RECURSIVE 128 /* avoid warning spam */ |
#define SERV_COUNTED 512 /* workspace for log code */ | #define SERV_FROM_DBUS 256 /* 1 if source is DBus */ |
#define SERV_USE_RESOLV 1024 /* forward this domain in the normal way */ | #define SERV_MARK 512 /* for mark-and-delete and log code */ |
#define SERV_NO_REBIND 2048 /* inhibit dns-rebind protection */ | #define SERV_WILDCARD 1024 /* domain has leading '*' */ |
#define SERV_FROM_FILE 4096 /* read from --servers-file */ | #define SERV_FROM_RESOLV 2048 /* 1 for servers from resolv, 0 for command line. */ |
#define SERV_LOOP 8192 /* server causes forwarding loop */ | #define SERV_FROM_FILE 4096 /* read from --servers-file */ |
#define SERV_DO_DNSSEC 16384 /* Validate DNSSEC when using this server */ | #define SERV_LOOP 8192 /* server causes forwarding loop */ |
#define SERV_GOT_TCP 32768 /* Got some data from the TCP connection */ | #define SERV_DO_DNSSEC 16384 /* Validate DNSSEC when using this server */ |
| #define SERV_GOT_TCP 32768 /* Got some data from the TCP connection */ |
|
|
struct serverfd { |
struct serverfd { |
int fd; |
int fd; |
Line 543 struct serverfd {
|
Line 565 struct serverfd {
|
}; |
}; |
|
|
struct randfd { |
struct randfd { |
|
struct server *serv; |
int fd; |
int fd; |
unsigned short refcount, family; | unsigned short refcount; /* refcount == 0xffff means overflow record. */ |
}; |
}; |
| |
| struct randfd_list { |
| struct randfd *rfd; |
| struct randfd_list *next; |
| }; |
| |
| |
struct server { |
struct server { |
|
u16 flags, domain_len; |
|
char *domain; |
|
struct server *next; |
|
int serial, arrayposn; |
|
int last_server; |
union mysockaddr addr, source_addr; |
union mysockaddr addr, source_addr; |
char interface[IF_NAMESIZE+1]; |
char interface[IF_NAMESIZE+1]; |
|
unsigned int ifindex; /* corresponding to interface, above */ |
struct serverfd *sfd; |
struct serverfd *sfd; |
char *domain; /* set if this server only handles a domain. */ | int tcpfd, edns_pktsz; |
int flags, tcpfd, edns_pktsz; | |
time_t pktsz_reduced; |
time_t pktsz_reduced; |
unsigned int queries, failed_queries; | unsigned int queries, failed_queries, nxdomain_replies, retrys; |
| unsigned int query_latency, mma_latency; |
| time_t forwardtime; |
| int forwardcount; |
#ifdef HAVE_LOOP |
#ifdef HAVE_LOOP |
u32 uid; |
u32 uid; |
#endif |
#endif |
struct server *next; |
|
}; |
}; |
|
|
|
/* First four fields must match struct server in next three definitions.. */ |
|
struct serv_addr4 { |
|
u16 flags, domain_len; |
|
char *domain; |
|
struct server *next; |
|
struct in_addr addr; |
|
}; |
|
|
|
struct serv_addr6 { |
|
u16 flags, domain_len; |
|
char *domain; |
|
struct server *next; |
|
struct in6_addr addr; |
|
}; |
|
|
|
struct serv_local { |
|
u16 flags, domain_len; |
|
char *domain; |
|
struct server *next; |
|
}; |
|
|
|
struct rebind_domain { |
|
char *domain; |
|
struct rebind_domain *next; |
|
}; |
|
|
struct ipsets { |
struct ipsets { |
char **sets; |
char **sets; |
char *domain; |
char *domain; |
struct ipsets *next; |
struct ipsets *next; |
}; |
}; |
|
|
|
struct allowlist { |
|
u32 mark, mask; |
|
char **patterns; |
|
struct allowlist *next; |
|
}; |
|
|
struct irec { |
struct irec { |
union mysockaddr addr; |
union mysockaddr addr; |
struct in_addr netmask; /* only valid for IPv4 */ |
struct in_addr netmask; /* only valid for IPv4 */ |
Line 602 struct resolvc {
|
Line 670 struct resolvc {
|
struct resolvc *next; |
struct resolvc *next; |
int is_default, logged; |
int is_default, logged; |
time_t mtime; |
time_t mtime; |
|
ino_t ino; |
char *name; |
char *name; |
#ifdef HAVE_INOTIFY |
#ifdef HAVE_INOTIFY |
int wd; /* inotify watch descriptor */ |
int wd; /* inotify watch descriptor */ |
Line 620 struct hostsfile {
|
Line 689 struct hostsfile {
|
struct hostsfile *next; |
struct hostsfile *next; |
int flags; |
int flags; |
char *fname; |
char *fname; |
|
unsigned int index; /* matches to cache entries for logging */ |
|
}; |
|
|
|
struct dyndir { |
|
struct dyndir *next; |
|
struct hostsfile *files; |
|
int flags; |
|
char *dname; |
#ifdef HAVE_INOTIFY |
#ifdef HAVE_INOTIFY |
int wd; /* inotify watch descriptor */ |
int wd; /* inotify watch descriptor */ |
#endif |
#endif |
unsigned int index; /* matches to cache entries for logging */ |
|
}; |
}; |
|
|
/* packet-dump flags */ |
/* packet-dump flags */ |
#define DUMP_QUERY 0x0001 | #define DUMP_QUERY 0x0001 |
#define DUMP_REPLY 0x0002 | #define DUMP_REPLY 0x0002 |
#define DUMP_UP_QUERY 0x0004 | #define DUMP_UP_QUERY 0x0004 |
#define DUMP_UP_REPLY 0x0008 | #define DUMP_UP_REPLY 0x0008 |
#define DUMP_SEC_QUERY 0x0010 | #define DUMP_SEC_QUERY 0x0010 |
#define DUMP_SEC_REPLY 0x0020 | #define DUMP_SEC_REPLY 0x0020 |
#define DUMP_BOGUS 0x0040 | #define DUMP_BOGUS 0x0040 |
#define DUMP_SEC_BOGUS 0x0080 | #define DUMP_SEC_BOGUS 0x0080 |
| #define DUMP_DHCP 0x1000 |
| #define DUMP_DHCPV6 0x2000 |
| #define DUMP_RA 0x4000 |
| #define DUMP_TFTP 0x8000 |
|
|
|
|
/* DNSSEC status values. */ |
/* DNSSEC status values. */ |
#define STAT_SECURE 1 | #define STAT_SECURE 0x10000 |
#define STAT_INSECURE 2 | #define STAT_INSECURE 0x20000 |
#define STAT_BOGUS 3 | #define STAT_BOGUS 0x30000 |
#define STAT_NEED_DS 4 | #define STAT_NEED_DS 0x40000 |
#define STAT_NEED_KEY 5 | #define STAT_NEED_KEY 0x50000 |
#define STAT_TRUNCATED 6 | #define STAT_TRUNCATED 0x60000 |
#define STAT_SECURE_WILDCARD 7 | #define STAT_SECURE_WILDCARD 0x70000 |
#define STAT_OK 8 | #define STAT_OK 0x80000 |
#define STAT_ABANDONED 9 | #define STAT_ABANDONED 0x90000 |
|
|
|
#define DNSSEC_FAIL_NYV 0x0001 /* key not yet valid */ |
|
#define DNSSEC_FAIL_EXP 0x0002 /* key expired */ |
|
#define DNSSEC_FAIL_INDET 0x0004 /* indetermined */ |
|
#define DNSSEC_FAIL_NOKEYSUP 0x0008 /* no supported key algo. */ |
|
#define DNSSEC_FAIL_NOSIG 0x0010 /* No RRsigs */ |
|
#define DNSSEC_FAIL_NOZONE 0x0020 /* No Zone bit set */ |
|
#define DNSSEC_FAIL_NONSEC 0x0040 /* No NSEC */ |
|
#define DNSSEC_FAIL_NODSSUP 0x0080 /* no supported DS algo. */ |
|
#define DNSSEC_FAIL_NOKEY 0x0100 /* no DNSKEY */ |
|
|
|
#define STAT_ISEQUAL(a, b) (((a) & 0xffff0000) == (b)) |
|
|
#define FREC_NOREBIND 1 |
#define FREC_NOREBIND 1 |
#define FREC_CHECKING_DISABLED 2 |
#define FREC_CHECKING_DISABLED 2 |
#define FREC_HAS_SUBNET 4 | #define FREC_NO_CACHE 4 |
#define FREC_DNSKEY_QUERY 8 |
#define FREC_DNSKEY_QUERY 8 |
#define FREC_DS_QUERY 16 |
#define FREC_DS_QUERY 16 |
#define FREC_AD_QUESTION 32 |
#define FREC_AD_QUESTION 32 |
Line 659 struct hostsfile {
|
Line 750 struct hostsfile {
|
#define FREC_TEST_PKTSZ 256 |
#define FREC_TEST_PKTSZ 256 |
#define FREC_HAS_EXTRADATA 512 |
#define FREC_HAS_EXTRADATA 512 |
#define FREC_HAS_PHEADER 1024 |
#define FREC_HAS_PHEADER 1024 |
#define FREC_NO_CACHE 2048 |
|
|
|
#define HASH_SIZE 32 /* SHA-256 digest size */ |
#define HASH_SIZE 32 /* SHA-256 digest size */ |
|
|
Line 673 struct frec {
|
Line 763 struct frec {
|
struct frec_src *next; |
struct frec_src *next; |
} frec_src; |
} frec_src; |
struct server *sentto; /* NULL means free */ |
struct server *sentto; /* NULL means free */ |
struct randfd *rfd4; | struct randfd_list *rfds; |
struct randfd *rfd6; | |
unsigned short new_id; |
unsigned short new_id; |
int forwardall, flags; |
int forwardall, flags; |
time_t time; |
time_t time; |
|
u32 forward_timestamp; |
|
int forward_delay; |
unsigned char *hash[HASH_SIZE]; |
unsigned char *hash[HASH_SIZE]; |
#ifdef HAVE_DNSSEC |
|
int class, work_counter; |
|
struct blockdata *stash; /* Saved reply, whilst we validate */ |
struct blockdata *stash; /* Saved reply, whilst we validate */ |
size_t stash_len; |
size_t stash_len; |
|
#ifdef HAVE_DNSSEC |
|
int class, work_counter; |
struct frec *dependent; /* Query awaiting internally-generated DNSKEY or DS query */ |
struct frec *dependent; /* Query awaiting internally-generated DNSKEY or DS query */ |
|
struct frec *next_dependent; /* list of above. */ |
struct frec *blocking_query; /* Query which is blocking us. */ |
struct frec *blocking_query; /* Query which is blocking us. */ |
#endif |
#endif |
struct frec *next; |
struct frec *next; |
Line 706 struct frec {
|
Line 798 struct frec {
|
#define ACTION_TFTP 5 |
#define ACTION_TFTP 5 |
#define ACTION_ARP 6 |
#define ACTION_ARP 6 |
#define ACTION_ARP_DEL 7 |
#define ACTION_ARP_DEL 7 |
|
#define ACTION_RELAY_SNOOP 8 |
|
|
#define LEASE_NEW 1 /* newly created */ |
#define LEASE_NEW 1 /* newly created */ |
#define LEASE_CHANGED 2 /* modified */ |
#define LEASE_CHANGED 2 /* modified */ |
Line 896 struct dhcp_bridge {
|
Line 989 struct dhcp_bridge {
|
}; |
}; |
|
|
struct cond_domain { |
struct cond_domain { |
char *domain, *prefix; | char *domain, *prefix; /* prefix is text-prefix on domain name */ |
| char *interface; /* These two set when domain comes from interface. */ |
| struct addrlist *al; |
struct in_addr start, end; |
struct in_addr start, end; |
struct in6_addr start6, end6; |
struct in6_addr start6, end6; |
int is6, indexed; | int is6, indexed, prefixlen; |
struct cond_domain *next; |
struct cond_domain *next; |
}; |
}; |
|
|
Line 1004 struct dhcp_relay {
|
Line 1099 struct dhcp_relay {
|
union all_addr local, server; |
union all_addr local, server; |
char *interface; /* Allowable interface for replies from server, and dest for IPv6 multicast */ |
char *interface; /* Allowable interface for replies from server, and dest for IPv6 multicast */ |
int iface_index; /* working - interface in which requests arrived, for return */ |
int iface_index; /* working - interface in which requests arrived, for return */ |
struct dhcp_relay *current, *next; | int port; /* Port of relay we forward to. */ |
| #ifdef HAVE_SCRIPT |
| struct snoop_record { |
| struct in6_addr client, prefix; |
| int prefix_len; |
| struct snoop_record *next; |
| } *snoop_records; |
| #endif |
| struct dhcp_relay *next; |
}; |
}; |
|
|
extern struct daemon { |
extern struct daemon { |
Line 1040 extern struct daemon {
|
Line 1143 extern struct daemon {
|
char *lease_change_command; |
char *lease_change_command; |
struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces; |
struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces; |
struct bogus_addr *bogus_addr, *ignore_addr; |
struct bogus_addr *bogus_addr, *ignore_addr; |
struct server *servers; | struct server *servers, *servers_tail, *local_domains, **serverarray; |
struct ipsets *ipsets; | struct rebind_domain *no_rebind; |
| int server_has_wildcard; |
| int serverarraysz, serverarrayhwm; |
| struct ipsets *ipsets, *nftsets; |
| u32 allowlist_mask; |
| struct allowlist *allowlists; |
int log_fac; /* log facility */ |
int log_fac; /* log facility */ |
char *log_file; /* optional log file */ |
char *log_file; /* optional log file */ |
int max_logs; /* queue limit */ |
int max_logs; /* queue limit */ |
|
int randport_limit; /* Maximum number of source ports for query. */ |
int cachesize, ftabsize; |
int cachesize, ftabsize; |
int port, query_port, min_port, max_port; |
int port, query_port, min_port, max_port; |
unsigned long local_ttl, neg_ttl, max_ttl, min_cache_ttl, max_cache_ttl, auth_ttl, dhcp_ttl, use_dhcp_ttl; |
unsigned long local_ttl, neg_ttl, max_ttl, min_cache_ttl, max_cache_ttl, auth_ttl, dhcp_ttl, use_dhcp_ttl; |
char *dns_client_id; |
char *dns_client_id; |
|
u32 umbrella_org; |
|
u32 umbrella_asset; |
|
u8 umbrella_device[8]; |
|
int host_index; |
struct hostsfile *addn_hosts; |
struct hostsfile *addn_hosts; |
struct dhcp_context *dhcp, *dhcp6; |
struct dhcp_context *dhcp, *dhcp6; |
struct ra_interface *ra_interfaces; |
struct ra_interface *ra_interfaces; |
Line 1069 extern struct daemon {
|
Line 1182 extern struct daemon {
|
int doing_ra, doing_dhcp6; |
int doing_ra, doing_dhcp6; |
struct dhcp_netid_list *dhcp_ignore, *dhcp_ignore_names, *dhcp_gen_names; |
struct dhcp_netid_list *dhcp_ignore, *dhcp_ignore_names, *dhcp_gen_names; |
struct dhcp_netid_list *force_broadcast, *bootp_dynamic; |
struct dhcp_netid_list *force_broadcast, *bootp_dynamic; |
struct hostsfile *dhcp_hosts_file, *dhcp_opts_file, *dynamic_dirs; | struct hostsfile *dhcp_hosts_file, *dhcp_opts_file; |
| struct dyndir *dynamic_dirs; |
int dhcp_max, tftp_max, tftp_mtu; |
int dhcp_max, tftp_max, tftp_mtu; |
int dhcp_server_port, dhcp_client_port; |
int dhcp_server_port, dhcp_client_port; |
int start_tftp_port, end_tftp_port; |
int start_tftp_port, end_tftp_port; |
Line 1086 extern struct daemon {
|
Line 1200 extern struct daemon {
|
int dump_mask; |
int dump_mask; |
unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry; |
unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry; |
u32 metrics[__METRIC_MAX]; |
u32 metrics[__METRIC_MAX]; |
|
int fast_retry_time, fast_retry_timeout; |
|
int cache_max_expiry; |
#ifdef HAVE_DNSSEC |
#ifdef HAVE_DNSSEC |
struct ds_config *ds; |
struct ds_config *ds; |
char *timestamp_file; |
char *timestamp_file; |
Line 1095 extern struct daemon {
|
Line 1211 extern struct daemon {
|
char *packet; /* packet buffer */ |
char *packet; /* packet buffer */ |
int packet_buff_sz; /* size of above */ |
int packet_buff_sz; /* size of above */ |
char *namebuff; /* MAXDNAME size buffer */ |
char *namebuff; /* MAXDNAME size buffer */ |
|
#if (defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)) || defined(HAVE_DNSSEC) |
|
/* CONNTRACK UBUS code uses this buffer, as well as DNSSEC code. */ |
|
char *workspacename; |
|
#endif |
#ifdef HAVE_DNSSEC |
#ifdef HAVE_DNSSEC |
char *keyname; /* MAXDNAME size buffer */ |
char *keyname; /* MAXDNAME size buffer */ |
char *workspacename; /* ditto */ |
|
unsigned long *rr_status; /* ceiling in TTL from DNSSEC or zero for insecure */ |
unsigned long *rr_status; /* ceiling in TTL from DNSSEC or zero for insecure */ |
int rr_status_sz; |
int rr_status_sz; |
int dnssec_no_time_check; |
int dnssec_no_time_check; |
Line 1109 extern struct daemon {
|
Line 1228 extern struct daemon {
|
struct serverfd *sfds; |
struct serverfd *sfds; |
struct irec *interfaces; |
struct irec *interfaces; |
struct listener *listeners; |
struct listener *listeners; |
struct server *last_server; |
|
time_t forwardtime; |
|
int forwardcount; |
|
struct server *srv_save; /* Used for resend on DoD */ |
struct server *srv_save; /* Used for resend on DoD */ |
size_t packet_len; /* " " */ |
size_t packet_len; /* " " */ |
struct randfd *rfd_save; /* " " */ | int fd_save; /* " " */ |
pid_t tcp_pids[MAX_PROCS]; |
pid_t tcp_pids[MAX_PROCS]; |
int tcp_pipes[MAX_PROCS]; |
int tcp_pipes[MAX_PROCS]; |
int pipe_to_parent; |
int pipe_to_parent; |
struct randfd randomsocks[RANDOM_SOCKS]; | int numrrand; |
| struct randfd *randomsocks; |
| struct randfd_list *rfl_spare, *rfl_poll; |
int v6pktinfo; |
int v6pktinfo; |
struct addrlist *interface_addrs; /* list of all addresses/prefix lengths associated with all local interfaces */ |
struct addrlist *interface_addrs; /* list of all addresses/prefix lengths associated with all local interfaces */ |
int log_id, log_display_id; /* ids of transactions for logging */ |
int log_id, log_display_id; /* ids of transactions for logging */ |
Line 1145 extern struct daemon {
|
Line 1263 extern struct daemon {
|
unsigned char *duid; |
unsigned char *duid; |
struct iovec outpacket; |
struct iovec outpacket; |
int dhcp6fd, icmp6fd; |
int dhcp6fd, icmp6fd; |
|
# ifdef HAVE_SCRIPT |
|
struct snoop_record *free_snoops; |
|
# endif |
#endif |
#endif |
|
|
/* DBus stuff */ |
/* DBus stuff */ |
/* void * here to avoid depending on dbus headers outside dbus.c */ |
/* void * here to avoid depending on dbus headers outside dbus.c */ |
void *dbus; |
void *dbus; |
#ifdef HAVE_DBUS |
#ifdef HAVE_DBUS |
struct watch *watches; |
struct watch *watches; |
#endif |
#endif |
|
|
/* UBus stuff */ |
/* UBus stuff */ |
#ifdef HAVE_UBUS |
#ifdef HAVE_UBUS |
/* void * here to avoid depending on ubus headers outside ubus.c */ |
/* void * here to avoid depending on ubus headers outside ubus.c */ |
Line 1171 extern struct daemon {
|
Line 1294 extern struct daemon {
|
#endif |
#endif |
} *daemon; |
} *daemon; |
|
|
|
struct server_details { |
|
union mysockaddr *addr, *source_addr; |
|
struct addrinfo *hostinfo, *orig_hostinfo; |
|
char *interface, *source, *scope_id, *interface_opt; |
|
int serv_port, source_port, addr_type, scope_index, valid; |
|
u16 *flags; |
|
}; |
|
|
/* cache.c */ |
/* cache.c */ |
void cache_init(void); |
void cache_init(void); |
void next_uid(struct crec *crecp); |
void next_uid(struct crec *crecp); |
void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg); | void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg, unsigned short type); |
char *record_source(unsigned int index); |
char *record_source(unsigned int index); |
char *querystr(char *desc, unsigned short type); |
|
int cache_find_non_terminal(char *name, time_t now); |
int cache_find_non_terminal(char *name, time_t now); |
struct crec *cache_find_by_addr(struct crec *crecp, |
struct crec *cache_find_by_addr(struct crec *crecp, |
union all_addr *addr, time_t now, |
union all_addr *addr, time_t now, |
Line 1185 struct crec *cache_find_by_name(struct crec *crecp,
|
Line 1315 struct crec *cache_find_by_name(struct crec *crecp,
|
char *name, time_t now, unsigned int prot); |
char *name, time_t now, unsigned int prot); |
void cache_end_insert(void); |
void cache_end_insert(void); |
void cache_start_insert(void); |
void cache_start_insert(void); |
|
unsigned int cache_remove_uid(const unsigned int uid); |
int cache_recv_insert(time_t now, int fd); |
int cache_recv_insert(time_t now, int fd); |
struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class, |
struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class, |
time_t now, unsigned long ttl, unsigned int flags); |
time_t now, unsigned long ttl, unsigned int flags); |
Line 1225 unsigned char *skip_questions(struct dns_header *heade
|
Line 1356 unsigned char *skip_questions(struct dns_header *heade
|
unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *header, size_t plen); |
unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *header, size_t plen); |
unsigned int extract_request(struct dns_header *header, size_t qlen, |
unsigned int extract_request(struct dns_header *header, size_t qlen, |
char *name, unsigned short *typep); |
char *name, unsigned short *typep); |
size_t setup_reply(struct dns_header *header, size_t qlen, | void setup_reply(struct dns_header *header, unsigned int flags, int ede); |
union all_addr *addrp, unsigned int flags, | |
unsigned long ttl); | |
int extract_addresses(struct dns_header *header, size_t qlen, char *name, |
int extract_addresses(struct dns_header *header, size_t qlen, char *name, |
time_t now, char **ipsets, int is_sign, int check_rebind, | time_t now, struct ipsets *ipsets, struct ipsets *nftsets, int is_sign, |
int no_cache_dnssec, int secure, int *doctored); | int check_rebind, int no_cache_dnssec, int secure, int *doctored); |
| #if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS) |
| void report_addresses(struct dns_header *header, size_t len, u32 mark); |
| #endif |
size_t answer_request(struct dns_header *header, char *limit, size_t qlen, |
size_t answer_request(struct dns_header *header, char *limit, size_t qlen, |
struct in_addr local_addr, struct in_addr local_netmask, |
struct in_addr local_addr, struct in_addr local_netmask, |
time_t now, int ad_reqd, int do_bit, int have_pseudoheader); | time_t now, int ad_reqd, int do_bit, int have_pseudoheader, |
| int *stale); |
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name, |
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name, |
struct bogus_addr *baddr, time_t now); | time_t now); |
int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr); | int check_for_ignored_address(struct dns_header *header, size_t qlen); |
int check_for_local_domain(char *name, time_t now); |
int check_for_local_domain(char *name, time_t now); |
size_t resize_packet(struct dns_header *header, size_t plen, |
size_t resize_packet(struct dns_header *header, size_t plen, |
unsigned char *pheader, size_t hlen); |
unsigned char *pheader, size_t hlen); |
Line 1255 int in_zone(struct auth_zone *zone, char *name, char *
|
Line 1388 int in_zone(struct auth_zone *zone, char *name, char *
|
#endif |
#endif |
|
|
/* dnssec.c */ |
/* dnssec.c */ |
|
#ifdef HAVE_DNSSEC |
size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char *name, int class, int type, int edns_pktsz); |
size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char *name, int class, int type, int edns_pktsz); |
int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class); |
int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class); |
int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class); |
int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class); |
Line 1263 int dnssec_validate_reply(time_t now, struct dns_heade
|
Line 1397 int dnssec_validate_reply(time_t now, struct dns_heade
|
int dnskey_keytag(int alg, int flags, unsigned char *key, int keylen); |
int dnskey_keytag(int alg, int flags, unsigned char *key, int keylen); |
size_t filter_rrsigs(struct dns_header *header, size_t plen); |
size_t filter_rrsigs(struct dns_header *header, size_t plen); |
int setup_timestamp(void); |
int setup_timestamp(void); |
|
int errflags_to_ede(int status); |
|
#endif |
|
|
/* hash_questions.c */ |
/* hash_questions.c */ |
void hash_questions_init(void); |
void hash_questions_init(void); |
Line 1289 void *safe_malloc(size_t size);
|
Line 1425 void *safe_malloc(size_t size);
|
void safe_strncpy(char *dest, const char *src, size_t size); |
void safe_strncpy(char *dest, const char *src, size_t size); |
void safe_pipe(int *fd, int read_noblock); |
void safe_pipe(int *fd, int read_noblock); |
void *whine_malloc(size_t size); |
void *whine_malloc(size_t size); |
|
void *whine_realloc(void *ptr, size_t size); |
int sa_len(union mysockaddr *addr); |
int sa_len(union mysockaddr *addr); |
int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2); | int sockaddr_isequal(const union mysockaddr *s1, const union mysockaddr *s2); |
| int sockaddr_isnull(const union mysockaddr *s); |
| int hostname_order(const char *a, const char *b); |
int hostname_isequal(const char *a, const char *b); |
int hostname_isequal(const char *a, const char *b); |
int hostname_issubdomain(char *a, char *b); |
int hostname_issubdomain(char *a, char *b); |
time_t dnsmasq_time(void); |
time_t dnsmasq_time(void); |
|
u32 dnsmasq_milliseconds(void); |
int netmask_length(struct in_addr mask); |
int netmask_length(struct in_addr mask); |
int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask); |
int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask); |
|
int is_same_net_prefix(struct in_addr a, struct in_addr b, int prefix); |
int is_same_net6(struct in6_addr *a, struct in6_addr *b, int prefixlen); |
int is_same_net6(struct in6_addr *a, struct in6_addr *b, int prefixlen); |
u64 addr6part(struct in6_addr *addr); |
u64 addr6part(struct in6_addr *addr); |
void setaddr6part(struct in6_addr *addr, u64 host); |
void setaddr6part(struct in6_addr *addr, u64 host); |
Line 1336 void read_servers_file(void);
|
Line 1477 void read_servers_file(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, | char *parse_server(char *arg, struct server_details *sdetails); |
union mysockaddr *source_addr, char *interface, int *flags); | char *parse_server_addr(struct server_details *sdetails); |
| int parse_server_next(struct server_details *sdetails); |
int option_read_dynfile(char *file, int flags); |
int option_read_dynfile(char *file, int flags); |
|
|
/* forward.c */ |
/* forward.c */ |
void reply_query(int fd, int family, time_t now); | void reply_query(int fd, time_t now); |
void receive_query(struct listener *listen, time_t now); |
void receive_query(struct listener *listen, time_t now); |
unsigned char *tcp_request(int confd, time_t now, |
unsigned char *tcp_request(int confd, time_t now, |
union mysockaddr *local_addr, struct in_addr netmask, int auth_dns); |
union mysockaddr *local_addr, struct in_addr netmask, int auth_dns); |
void server_gone(struct server *server); |
void server_gone(struct server *server); |
struct frec *get_new_frec(time_t now, int *wait, struct frec *force); |
|
int send_from(int fd, int nowild, char *packet, size_t len, |
int send_from(int fd, int nowild, char *packet, size_t len, |
union mysockaddr *to, union all_addr *source, |
union mysockaddr *to, union all_addr *source, |
unsigned int iface); |
unsigned int iface); |
void resend_query(void); |
void resend_query(void); |
struct randfd *allocate_rfd(int family); | int allocate_rfd(struct randfd_list **fdlp, struct server *serv); |
void free_rfd(struct randfd *rfd); | void free_rfds(struct randfd_list **fdlp); |
| int fast_retry(time_t now); |
|
|
/* network.c */ |
/* network.c */ |
int indextoname(int fd, int index, char *name); |
int indextoname(int fd, int index, char *name); |
int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifindex, int is_tcp); |
int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifindex, int is_tcp); |
int random_sock(int family); |
|
void pre_allocate_sfds(void); |
void pre_allocate_sfds(void); |
int reload_servers(char *fname); |
int reload_servers(char *fname); |
void mark_servers(int flag); | void check_servers(int no_loop_call); |
void cleanup_servers(void); | |
void add_update_server(int flags, | |
union mysockaddr *addr, | |
union mysockaddr *source_addr, | |
const char *interface, | |
const char *domain); | |
void check_servers(void); | |
int enumerate_interfaces(int reset); |
int enumerate_interfaces(int reset); |
void create_wildcard_listeners(void); |
void create_wildcard_listeners(void); |
void create_bound_listeners(int dienow); |
void create_bound_listeners(int dienow); |
Line 1500 void emit_dbus_signal(int action, struct dhcp_lease *l
|
Line 1634 void emit_dbus_signal(int action, struct dhcp_lease *l
|
|
|
/* ubus.c */ |
/* ubus.c */ |
#ifdef HAVE_UBUS |
#ifdef HAVE_UBUS |
void ubus_init(void); | char *ubus_init(void); |
void set_ubus_listeners(void); |
void set_ubus_listeners(void); |
void check_ubus_listeners(void); |
void check_ubus_listeners(void); |
void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface); |
void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface); |
|
# ifdef HAVE_CONNTRACK |
|
void ubus_event_bcast_connmark_allowlist_refused(u32 mark, const char *name); |
|
void ubus_event_bcast_connmark_allowlist_resolved(u32 mark, const char *pattern, const char *ip, u32 ttl); |
|
# endif |
#endif |
#endif |
|
|
/* ipset.c */ |
/* ipset.c */ |
Line 1512 void ipset_init(void);
|
Line 1650 void ipset_init(void);
|
int add_to_ipset(const char *setname, const union all_addr *ipaddr, int flags, int remove); |
int add_to_ipset(const char *setname, const union all_addr *ipaddr, int flags, int remove); |
#endif |
#endif |
|
|
|
/* nftset.c */ |
|
#ifdef HAVE_NFTSET |
|
void nftset_init(void); |
|
int add_to_nftset(const char *setpath, const union all_addr *ipaddr, int flags, int remove); |
|
#endif |
|
|
|
/* pattern.c */ |
|
#ifdef HAVE_CONNTRACK |
|
int is_valid_dns_name(const char *value); |
|
int is_valid_dns_name_pattern(const char *value); |
|
int is_dns_name_matching_pattern(const char *name, const char *pattern); |
|
#endif |
|
|
/* helper.c */ |
/* helper.c */ |
#if defined(HAVE_SCRIPT) |
#if defined(HAVE_SCRIPT) |
int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd); |
int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd); |
Line 1524 void queue_tftp(off_t file_len, char *filename, union
|
Line 1675 void queue_tftp(off_t file_len, char *filename, union
|
void queue_arp(int action, unsigned char *mac, int maclen, |
void queue_arp(int action, unsigned char *mac, int maclen, |
int family, union all_addr *addr); |
int family, union all_addr *addr); |
int helper_buf_empty(void); |
int helper_buf_empty(void); |
|
#ifdef HAVE_DHCP6 |
|
void queue_relay_snoop(struct in6_addr *client, int if_index, struct in6_addr *prefix, int prefix_len); |
#endif |
#endif |
|
#endif |
|
|
/* tftp.c */ |
/* tftp.c */ |
#ifdef HAVE_TFTP |
#ifdef HAVE_TFTP |
Line 1566 void get_client_mac(struct in6_addr *client, int iface
|
Line 1720 void get_client_mac(struct in6_addr *client, int iface
|
unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name, |
unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name, |
struct in6_addr *fallback, struct in6_addr *ll_addr, struct in6_addr *ula_addr, |
struct in6_addr *fallback, struct in6_addr *ll_addr, struct in6_addr *ula_addr, |
size_t sz, struct in6_addr *client_addr, time_t now); |
size_t sz, struct in6_addr *client_addr, time_t now); |
void relay_upstream6(struct dhcp_relay *relay, ssize_t sz, struct in6_addr *peer_address, | int relay_upstream6(int iface_index, ssize_t sz, struct in6_addr *peer_address, |
u32 scope_id, time_t now); |
u32 scope_id, time_t now); |
|
|
unsigned short relay_reply6( struct sockaddr_in6 *peer, ssize_t sz, char *arrival_interface); | int relay_reply6( struct sockaddr_in6 *peer, ssize_t sz, char *arrival_interface); |
| # ifdef HAVE_SCRIPT |
| int do_snoop_script_run(void); |
| # endif |
#endif |
#endif |
|
|
/* dhcp-common.c */ |
/* dhcp-common.c */ |
Line 1596 struct dhcp_config *find_config(struct dhcp_config *co
|
Line 1753 struct dhcp_config *find_config(struct dhcp_config *co
|
int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type); |
int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type); |
#ifdef HAVE_LINUX_NETWORK |
#ifdef HAVE_LINUX_NETWORK |
char *whichdevice(void); |
char *whichdevice(void); |
void bindtodevice(char *device, int fd); | int bind_dhcp_devices(char *bound_device); |
#endif |
#endif |
# ifdef HAVE_DHCP6 |
# ifdef HAVE_DHCP6 |
void display_opts6(void); |
void display_opts6(void); |
Line 1657 int do_poll(int timeout);
|
Line 1814 int do_poll(int timeout);
|
size_t rrfilter(struct dns_header *header, size_t plen, int mode); |
size_t rrfilter(struct dns_header *header, size_t plen, int mode); |
u16 *rrfilter_desc(int type); |
u16 *rrfilter_desc(int type); |
int expand_workspace(unsigned char ***wkspc, int *szp, int new); |
int expand_workspace(unsigned char ***wkspc, int *szp, int new); |
| /* modes. */ |
| #define RRFILTER_EDNS0 0 |
| #define RRFILTER_DNSSEC 1 |
| #define RRFILTER_A 2 |
| #define RRFILTER_AAAA 3 |
/* edns0.c */ |
/* edns0.c */ |
unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, |
unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, |
size_t *len, unsigned char **p, int *is_sign, int *is_last); |
size_t *len, unsigned char **p, int *is_sign, int *is_last); |
Line 1665 size_t add_pseudoheader(struct dns_header *header, siz
|
Line 1826 size_t add_pseudoheader(struct dns_header *header, siz
|
unsigned short udp_sz, int optno, unsigned char *opt, size_t optlen, int set_do, int replace); |
unsigned short udp_sz, int optno, unsigned char *opt, size_t optlen, int set_do, int replace); |
size_t add_do_bit(struct dns_header *header, size_t plen, unsigned char *limit); |
size_t add_do_bit(struct dns_header *header, size_t plen, unsigned char *limit); |
size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *limit, |
size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *limit, |
union mysockaddr *source, time_t now, int *check_subnet, int *cacheable); | union mysockaddr *source, time_t now, int *cacheable); |
int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer); |
int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer); |
|
|
/* arp.c */ |
/* arp.c */ |
Line 1675 int do_arp_script_run(void);
|
Line 1836 int do_arp_script_run(void);
|
/* dump.c */ |
/* dump.c */ |
#ifdef HAVE_DUMPFILE |
#ifdef HAVE_DUMPFILE |
void dump_init(void); |
void dump_init(void); |
void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src, union mysockaddr *dst); | void dump_packet_udp(int mask, void *packet, size_t len, union mysockaddr *src, |
| union mysockaddr *dst, int fd); |
| void dump_packet_icmp(int mask, void *packet, size_t len, union mysockaddr *src, |
| union mysockaddr *dst); |
#endif |
#endif |
|
|
|
/* domain-match.c */ |
|
void build_server_array(void); |
|
int lookup_domain(char *qdomain, int flags, int *lowout, int *highout); |
|
int filter_servers(int seed, int flags, int *lowout, int *highout); |
|
int is_local_answer(time_t now, int first, char *name); |
|
size_t make_local_answer(int flags, int gotname, size_t size, struct dns_header *header, |
|
char *name, char *limit, int first, int last, int ede); |
|
int server_samegroup(struct server *a, struct server *b); |
|
#ifdef HAVE_DNSSEC |
|
int dnssec_server(struct server *server, char *keyname, int *firstp, int *lastp); |
|
#endif |
|
void mark_servers(int flag); |
|
void cleanup_servers(void); |
|
int add_update_server(int flags, |
|
union mysockaddr *addr, |
|
union mysockaddr *source_addr, |
|
const char *interface, |
|
const char *domain, |
|
union all_addr *local_addr); |