--- embedaddon/dnsmasq/src/dnsmasq.h 2013/07/29 19:37:40 1.1.1.1
+++ embedaddon/dnsmasq/src/dnsmasq.h 2021/03/17 00:56:46 1.1.1.4
@@ -1,4 +1,4 @@
-/* dnsmasq is Copyright (c) 2000-2013 Simon Kelley
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
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
@@ -14,8 +14,14 @@
along with this program. If not, see .
*/
-#define COPYRIGHT "Copyright (c) 2000-2013 Simon Kelley"
+#define COPYRIGHT "Copyright (c) 2000-2021 Simon Kelley"
+/* We do defines that influence behavior of stdio.h, so complain
+ if included too early. */
+#ifdef _STDIO_H
+# error "Header file stdio.h included too early!"
+#endif
+
#ifndef NO_LARGEFILE
/* Ensure we can use files >2GB (log files may grow this big) */
# define _LARGEFILE_SOURCE 1
@@ -36,6 +42,12 @@
# define __EXTENSIONS__
#endif
+#if (defined(__GNUC__) && __GNUC__ >= 3) || defined(__clang__)
+#define ATTRIBUTE_NORETURN __attribute__ ((noreturn))
+#else
+#define ATTRIBUTE_NORETURN
+#endif
+
/* get these before config.h for IPv6 stuff... */
#include
#include
@@ -50,12 +62,17 @@
#include
#include "config.h"
+#include "ip6addr.h"
+#include "metrics.h"
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
+#define countof(x) (long)(sizeof(x) / sizeof(x[0]))
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
#include "dns-protocol.h"
#include "dhcp-protocol.h"
#ifdef HAVE_DHCP6
@@ -78,7 +95,11 @@ typedef unsigned long long u64;
#if defined(HAVE_SOLARIS_NETWORK)
# include
#endif
-#include
+#if defined(HAVE_POLL_H)
+# include
+#else
+# include
+#endif
#include
#include
#include
@@ -109,7 +130,9 @@ typedef unsigned long long u64;
#include
#include
#include
+#include
#include
+#include
#include
#include
#include
@@ -118,9 +141,11 @@ typedef unsigned long long u64;
#endif
#if defined(HAVE_LINUX_NETWORK)
+#include
+#include
#include
/* There doesn't seem to be a universally-available
- userpace header for these. */
+ userspace header for these. */
extern int capset(cap_user_header_t header, cap_user_data_t data);
extern int capget(cap_user_header_t header, cap_user_data_t data);
#define LINUX_CAPABILITY_VERSION_1 0x19980330
@@ -132,34 +157,50 @@ extern int capget(cap_user_header_t header, cap_user_d
#include
#endif
+/* Backwards compat with 2.83 */
+#if defined(HAVE_NETTLEHASH)
+# define HAVE_CRYPTOHASH
+#endif
+#if defined(HAVE_DNSSEC) || defined(HAVE_CRYPTOHASH)
+# include
+#endif
+
/* daemon is function in the C library.... */
#define daemon dnsmasq_daemon
+#define ADDRSTRLEN INET6_ADDRSTRLEN
+
/* Async event queue */
struct event_desc {
int event, data, msg_sz;
};
-#define EVENT_RELOAD 1
-#define EVENT_DUMP 2
-#define EVENT_ALARM 3
-#define EVENT_TERM 4
-#define EVENT_CHILD 5
-#define EVENT_REOPEN 6
-#define EVENT_EXITED 7
-#define EVENT_KILLED 8
-#define EVENT_EXEC_ERR 9
-#define EVENT_PIPE_ERR 10
-#define EVENT_USER_ERR 11
-#define EVENT_CAP_ERR 12
-#define EVENT_PIDFILE 13
-#define EVENT_HUSER_ERR 14
-#define EVENT_GROUP_ERR 15
-#define EVENT_DIE 16
-#define EVENT_LOG_ERR 17
-#define EVENT_FORK_ERR 18
-#define EVENT_LUA_ERR 19
-#define EVENT_TFTP_ERR 20
+#define EVENT_RELOAD 1
+#define EVENT_DUMP 2
+#define EVENT_ALARM 3
+#define EVENT_TERM 4
+#define EVENT_CHILD 5
+#define EVENT_REOPEN 6
+#define EVENT_EXITED 7
+#define EVENT_KILLED 8
+#define EVENT_EXEC_ERR 9
+#define EVENT_PIPE_ERR 10
+#define EVENT_USER_ERR 11
+#define EVENT_CAP_ERR 12
+#define EVENT_PIDFILE 13
+#define EVENT_HUSER_ERR 14
+#define EVENT_GROUP_ERR 15
+#define EVENT_DIE 16
+#define EVENT_LOG_ERR 17
+#define EVENT_FORK_ERR 18
+#define EVENT_LUA_ERR 19
+#define EVENT_TFTP_ERR 20
+#define EVENT_INIT 21
+#define EVENT_NEWADDR 22
+#define EVENT_NEWROUTE 23
+#define EVENT_TIME_ERR 24
+#define EVENT_SCRIPT_LOG 25
+#define EVENT_TIME 26
/* Exit codes. */
#define EC_GOOD 0
@@ -170,16 +211,6 @@ struct event_desc {
#define EC_MISC 5
#define EC_INIT_OFFSET 10
-/* Min buffer size: we check after adding each record, so there must be
- memory for the largest packet, and the largest record so the
- min for DNS is PACKETSZ+MAXDNAME+RRFIXEDSZ which is < 1000.
- This might be increased is EDNS packet size if greater than the minimum.
-*/
-#define DNSMASQ_PACKETSZ PACKETSZ+MAXDNAME+RRFIXEDSZ
-
-/* Trust the compiler dead-code eliminator.... */
-#define option_bool(x) (((x) < 32) ? daemon->options & (1u << (x)) : daemon->options2 & (1u << ((x) - 32)))
-
#define OPT_BOGUSPRIV 0
#define OPT_FILTER 1
#define OPT_LOG 2
@@ -209,11 +240,11 @@ struct event_desc {
#define OPT_TFTP_SECURE 26
#define OPT_TFTP_NOBLOCK 27
#define OPT_LOG_OPTS 28
-#define OPT_TFTP_APREF 29
+#define OPT_TFTP_APREF_IP 29
#define OPT_NO_OVERRIDE 30
#define OPT_NO_REBIND 31
#define OPT_ADD_MAC 32
-#define OPT_DNSSEC 33
+#define OPT_DNSSEC_PROXY 33
#define OPT_CONSEC_ADDR 34
#define OPT_CONNTRACK 35
#define OPT_FQDN_UPDATE 36
@@ -221,22 +252,79 @@ struct event_desc {
#define OPT_TFTP_LC 38
#define OPT_CLEVERBIND 39
#define OPT_TFTP 40
-#define OPT_LAST 41
+#define OPT_CLIENT_SUBNET 41
+#define OPT_QUIET_DHCP 42
+#define OPT_QUIET_DHCP6 43
+#define OPT_QUIET_RA 44
+#define OPT_DNSSEC_VALID 45
+#define OPT_DNSSEC_TIME 46
+#define OPT_DNSSEC_DEBUG 47
+#define OPT_DNSSEC_IGN_NS 48
+#define OPT_LOCAL_SERVICE 49
+#define OPT_LOOP_DETECT 50
+#define OPT_EXTRALOG 51
+#define OPT_TFTP_NO_FAIL 52
+#define OPT_SCRIPT_ARP 53
+#define OPT_MAC_B64 54
+#define OPT_MAC_HEX 55
+#define OPT_TFTP_APREF_MAC 56
+#define OPT_RAPID_COMMIT 57
+#define OPT_UBUS 58
+#define OPT_IGNORE_CLID 59
+#define OPT_SINGLE_PORT 60
+#define OPT_LEASE_RENEW 61
+#define OPT_LAST 62
+#define OPTION_BITS (sizeof(unsigned int)*8)
+#define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) )
+#define option_var(x) (daemon->options[(x) / OPTION_BITS])
+#define option_val(x) ((1u) << ((x) % OPTION_BITS))
+#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
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
-#define MS_TFTP LOG_USER
-#define MS_DHCP LOG_DAEMON
+#define MS_TFTP LOG_USER
+#define MS_DHCP LOG_DAEMON
+#define MS_SCRIPT LOG_MAIL
-struct all_addr {
- union {
- struct in_addr addr4;
-#ifdef HAVE_IPV6
- struct in6_addr addr6;
-#endif
- } addr;
+/* 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
+ cache entry, the other variants should not be larger than
+ sizeof(struct in6_addr) - 16 bytes.
+*/
+union all_addr {
+ struct in_addr addr4;
+ struct in6_addr addr6;
+ struct {
+ union {
+ struct crec *cache;
+ char *name;
+ } target;
+ unsigned int uid;
+ int is_name_ptr; /* disciminates target union */
+ } cname;
+ struct {
+ struct blockdata *keydata;
+ unsigned short keylen, flags, keytag;
+ unsigned char algo;
+ } key;
+ struct {
+ struct blockdata *keydata;
+ unsigned short keylen, keytag;
+ unsigned char algo;
+ unsigned char digest;
+ } ds;
+ struct {
+ struct blockdata *target;
+ unsigned short targetlen, srvport, priority, weight;
+ } srv;
+ /* for log_query */
+ struct {
+ unsigned short keytag, algo, digest, rcode;
+ } log;
};
+
struct bogus_addr {
struct in_addr addr;
struct bogus_addr *next;
@@ -261,10 +349,21 @@ struct naptr {
struct naptr *next;
};
+#ifndef NO_ID
+#define TXT_STAT_CACHESIZE 1
+#define TXT_STAT_INSERTS 2
+#define TXT_STAT_EVICTIONS 3
+#define TXT_STAT_MISSES 4
+#define TXT_STAT_HITS 5
+#define TXT_STAT_AUTH 6
+#define TXT_STAT_SERVERS 7
+#endif
+
struct txt_record {
char *name;
unsigned char *txt;
unsigned short class, len;
+ int stat;
struct txt_record *next;
};
@@ -274,39 +373,65 @@ struct ptr_record {
};
struct cname {
+ int ttl, flag;
char *alias, *target;
- struct cname *next;
+ struct cname *next, *targetp;
+};
+
+struct ds_config {
+ char *name, *digest;
+ int digestlen, class, algo, keytag, digest_type;
+ struct ds_config *next;
};
+#define ADDRLIST_LITERAL 1
+#define ADDRLIST_IPV6 2
+#define ADDRLIST_REVONLY 4
+#define ADDRLIST_PREFIX 8
+#define ADDRLIST_WILDCARD 16
+#define ADDRLIST_DECLINED 32
+
+struct addrlist {
+ union all_addr addr;
+ int flags, prefixlen;
+ time_t decline_time;
+ struct addrlist *next;
+};
+
+#define AUTH6 1
+#define AUTH4 2
+
struct auth_zone {
char *domain;
- struct subnet {
- int is6, prefixlen;
- struct in_addr addr4;
-#ifdef HAVE_IPV6
- struct in6_addr addr6;
-#endif
- struct subnet *next;
- } *subnet;
+ struct auth_name_list {
+ char *name;
+ int flags;
+ struct auth_name_list *next;
+ } *interface_names;
+ struct addrlist *subnet;
+ struct addrlist *exclude;
struct auth_zone *next;
};
+#define HR_6 1
+#define HR_4 2
struct host_record {
+ int ttl, flags;
struct name_list {
char *name;
struct name_list *next;
} *names;
struct in_addr addr;
-#ifdef HAVE_IPV6
struct in6_addr addr6;
-#endif
struct host_record *next;
};
struct interface_name {
char *name; /* domain name */
char *intr; /* interface name */
+ int family; /* AF_INET, AF_INET6 or zero for both */
+ struct addrlist *addr;
struct interface_name *next;
};
@@ -315,31 +440,18 @@ union bigname {
union bigname *next; /* freelist */
};
-struct keydata {
- struct keydata *next;
+struct blockdata {
+ struct blockdata *next;
unsigned char key[KEYBLOCK_LEN];
};
struct crec {
struct crec *next, *prev, *hash_next;
- /* union is 16 bytes when doing IPv6, 8 bytes on 32 bit machines without IPv6 */
- union {
- struct all_addr addr;
- struct {
- struct crec *cache;
- int uid;
- } cname;
- struct {
- struct keydata *keydata;
- unsigned char algo;
- unsigned char digest; /* DS only */
- unsigned short flags_or_keyid; /* flags for DNSKEY, keyid for DS */
- } key;
- } addr;
+ union all_addr addr;
time_t ttd; /* time to die */
- /* used as keylen if F_DS or F_DNSKEY, index to source for F_HOSTS */
- int uid;
- unsigned short flags;
+ /* used as class if DNSKEY/DS, index to source for F_HOSTS */
+ unsigned int uid;
+ unsigned int flags;
union {
char sname[SMALLDNAME];
union bigname *bname;
@@ -347,6 +459,9 @@ struct crec {
} name;
};
+#define SIZEOF_BARE_CREC (sizeof(struct crec) - SMALLDNAME)
+#define SIZEOF_POINTER_CREC (sizeof(struct crec) + sizeof(char *) - SMALLDNAME)
+
#define F_IMMORTAL (1u<<0)
#define F_NAMEP (1u<<1)
#define F_REVERSE (1u<<2)
@@ -363,35 +478,42 @@ struct crec {
#define F_CONFIG (1u<<13)
#define F_DS (1u<<14)
#define F_DNSSECOK (1u<<15)
-
-/* below here are only valid as args to log_query: cache
- entries are limited to 16 bits */
#define F_UPSTREAM (1u<<16)
#define F_RRNAME (1u<<17)
#define F_SERVER (1u<<18)
#define F_QUERY (1u<<19)
#define F_NOERR (1u<<20)
#define F_AUTH (1u<<21)
+#define F_DNSSEC (1u<<22)
+#define F_KEYTAG (1u<<23)
+#define F_SECSTAT (1u<<24)
+#define F_NO_RR (1u<<25)
+#define F_IPSET (1u<<26)
+#define F_NOEXTRA (1u<<27)
+#define F_SERVFAIL (1u<<28) /* currently unused. */
+#define F_RCODE (1u<<29)
+#define F_SRV (1u<<30)
-/* composites */
-#define F_TYPE (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS) /* Only one may be set */
+#define UID_NONE 0
+/* Values of uid in crecs with F_CONFIG bit set. */
+#define SRC_CONFIG 1
+#define SRC_HOSTS 2
+#define SRC_AH 3
-
/* struct sockaddr is not large enough to hold any address,
and specifically not big enough to hold an IPv6 address.
Blech. Roll our own. */
union mysockaddr {
struct sockaddr sa;
struct sockaddr_in in;
-#if defined(HAVE_IPV6)
struct sockaddr_in6 in6;
-#endif
};
/* bits in flag param to IPv6 callbacks from iface_enumerate() */
#define IFACE_TENTATIVE 1
#define IFACE_DEPRECATED 2
+#define IFACE_PERMANENT 4
#define SERV_FROM_RESOLV 1 /* 1 for servers from resolv, 0 for command line. */
@@ -407,11 +529,16 @@ union mysockaddr {
#define SERV_COUNTED 512 /* workspace for log code */
#define SERV_USE_RESOLV 1024 /* forward this domain in the normal way */
#define SERV_NO_REBIND 2048 /* inhibit dns-rebind protection */
+#define SERV_FROM_FILE 4096 /* read from --servers-file */
+#define SERV_LOOP 8192 /* server causes forwarding loop */
+#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 {
int fd;
union mysockaddr source_addr;
char interface[IF_NAMESIZE+1];
+ unsigned int ifindex, used, preallocated;
struct serverfd *next;
};
@@ -425,8 +552,12 @@ struct server {
char interface[IF_NAMESIZE+1];
struct serverfd *sfd;
char *domain; /* set if this server only handles a domain. */
- int flags, tcpfd;
+ int flags, tcpfd, edns_pktsz;
+ time_t pktsz_reduced;
unsigned int queries, failed_queries;
+#ifdef HAVE_LOOP
+ u32 uid;
+#endif
struct server *next;
};
@@ -439,13 +570,14 @@ struct ipsets {
struct irec {
union mysockaddr addr;
struct in_addr netmask; /* only valid for IPv4 */
- int tftp_ok, dhcp_ok, mtu, done, dad, dns_auth, index, multicast_done;
+ int tftp_ok, dhcp_ok, mtu, done, warned, dad, dns_auth, index, multicast_done, found, label;
char *name;
struct irec *next;
};
struct listener {
- int fd, tcpfd, tftpfd, family;
+ int fd, tcpfd, tftpfd, used;
+ union mysockaddr addr;
struct irec *iface; /* only sometimes valid for non-wildcard */
struct listener *next;
};
@@ -458,40 +590,102 @@ struct iname {
struct iname *next;
};
+/* subnet parameters from command line */
+struct mysubnet {
+ union mysockaddr addr;
+ int addr_used;
+ int mask;
+};
+
/* resolv-file parms from command-line */
struct resolvc {
struct resolvc *next;
int is_default, logged;
time_t mtime;
char *name;
+#ifdef HAVE_INOTIFY
+ int wd; /* inotify watch descriptor */
+ char *file; /* pointer to file part if path */
+#endif
};
-/* adn-hosts parms from command-line (also dhcp-hostsfile and dhcp-optsfile */
+/* adn-hosts parms from command-line (also dhcp-hostsfile and dhcp-optsfile and dhcp-hostsdir*/
#define AH_DIR 1
#define AH_INACTIVE 2
+#define AH_WD_DONE 4
+#define AH_HOSTS 8
+#define AH_DHCP_HST 16
+#define AH_DHCP_OPT 32
struct hostsfile {
struct hostsfile *next;
int flags;
char *fname;
- int index; /* matches to cache entries for logging */
+#ifdef HAVE_INOTIFY
+ int wd; /* inotify watch descriptor */
+#endif
+ unsigned int index; /* matches to cache entries for logging */
};
+/* packet-dump flags */
+#define DUMP_QUERY 0x0001
+#define DUMP_REPLY 0x0002
+#define DUMP_UP_QUERY 0x0004
+#define DUMP_UP_REPLY 0x0008
+#define DUMP_SEC_QUERY 0x0010
+#define DUMP_SEC_REPLY 0x0020
+#define DUMP_BOGUS 0x0040
+#define DUMP_SEC_BOGUS 0x0080
+
+
+/* DNSSEC status values. */
+#define STAT_SECURE 1
+#define STAT_INSECURE 2
+#define STAT_BOGUS 3
+#define STAT_NEED_DS 4
+#define STAT_NEED_KEY 5
+#define STAT_TRUNCATED 6
+#define STAT_SECURE_WILDCARD 7
+#define STAT_OK 8
+#define STAT_ABANDONED 9
+
#define FREC_NOREBIND 1
#define FREC_CHECKING_DISABLED 2
+#define FREC_HAS_SUBNET 4
+#define FREC_DNSKEY_QUERY 8
+#define FREC_DS_QUERY 16
+#define FREC_AD_QUESTION 32
+#define FREC_DO_QUESTION 64
+#define FREC_ADDED_PHEADER 128
+#define FREC_TEST_PKTSZ 256
+#define FREC_HAS_EXTRADATA 512
+#define FREC_HAS_PHEADER 1024
+#define FREC_NO_CACHE 2048
+#define HASH_SIZE 32 /* SHA-256 digest size */
+
struct frec {
- union mysockaddr source;
- struct all_addr dest;
+ struct frec_src {
+ union mysockaddr source;
+ union all_addr dest;
+ unsigned int iface, log_id;
+ int fd;
+ unsigned short orig_id;
+ struct frec_src *next;
+ } frec_src;
struct server *sentto; /* NULL means free */
struct randfd *rfd4;
-#ifdef HAVE_IPV6
struct randfd *rfd6;
-#endif
- unsigned int iface;
- unsigned short orig_id, new_id;
- int fd, forwardall, flags;
- unsigned int crc;
+ unsigned short new_id;
+ int forwardall, flags;
time_t time;
+ unsigned char *hash[HASH_SIZE];
+#ifdef HAVE_DNSSEC
+ int class, work_counter;
+ struct blockdata *stash; /* Saved reply, whilst we validate */
+ size_t stash_len;
+ struct frec *dependent; /* Query awaiting internally-generated DNSKEY or DS query */
+ struct frec *blocking_query; /* Query which is blocking us. */
+#endif
struct frec *next;
};
@@ -510,6 +704,8 @@ struct frec {
#define ACTION_OLD 3
#define ACTION_ADD 4
#define ACTION_TFTP 5
+#define ACTION_ARP 6
+#define ACTION_ARP_DEL 7
#define LEASE_NEW 1 /* newly created */
#define LEASE_CHANGED 2 /* modified */
@@ -519,6 +715,7 @@ struct frec {
#define LEASE_NA 32 /* IPv6 no-temporary lease */
#define LEASE_TA 64 /* IPv6 temporary lease */
#define LEASE_HAVE_HWADDR 128 /* Have set hwaddress */
+#define LEASE_EXP_CHANGED 256 /* Lease expiry time changed */
struct dhcp_lease {
int clid_len; /* length of client identifier */
@@ -530,15 +727,19 @@ struct dhcp_lease {
#ifdef HAVE_BROKEN_RTC
unsigned int length;
#endif
- int hwaddr_len, hwaddr_type; /* hw_type used for iaid in v6 */
- unsigned char hwaddr[DHCP_CHADDR_MAX]; /* also IPv6 address */
+ int hwaddr_len, hwaddr_type;
+ unsigned char hwaddr[DHCP_CHADDR_MAX];
struct in_addr addr, override, giaddr;
unsigned char *extradata;
unsigned int extradata_len, extradata_size;
int last_interface;
+ int new_interface; /* save possible originated interface */
+ int new_prefixlen; /* and its prefix length */
#ifdef HAVE_DHCP6
+ struct in6_addr addr6;
+ unsigned int iaid;
struct slaac_address {
- struct in6_addr addr, local;
+ struct in6_addr addr;
time_t ping_time;
int backoff; /* zero -> confirmed */
struct slaac_address *next;
@@ -564,6 +765,12 @@ struct tag_if {
struct tag_if *next;
};
+struct delay_config {
+ int delay;
+ struct dhcp_netid *netid;
+ struct delay_config *next;
+};
+
struct hwaddr_config {
int hwaddr_len, hwaddr_type;
unsigned char hwaddr[DHCP_CHADDR_MAX];
@@ -577,8 +784,9 @@ struct dhcp_config {
unsigned char *clid; /* clientid */
char *hostname, *domain;
struct dhcp_netid_list *netid;
+ struct dhcp_netid *filter;
#ifdef HAVE_DHCP6
- struct in6_addr addr6;
+ struct addrlist *addr6;
#endif
struct in_addr addr;
time_t decline_time;
@@ -600,7 +808,7 @@ struct dhcp_config {
#define CONFIG_DECLINED 1024 /* address declined by client */
#define CONFIG_BANK 2048 /* from dhcp hosts file */
#define CONFIG_ADDR6 4096
-#define CONFIG_WILDCARD 8192
+#define CONFIG_ADDR6_HOSTS 16384 /* address added by from /etc/hosts */
struct dhcp_opt {
int opt, len, flags;
@@ -628,6 +836,7 @@ struct dhcp_opt {
#define DHOPT_RFC3925 2048
#define DHOPT_TAGOK 4096
#define DHOPT_ADDR6 8192
+#define DHOPT_VENDOR_PXE 16384
struct dhcp_boot {
char *file, *sname, *tftp_sname;
@@ -636,6 +845,13 @@ struct dhcp_boot {
struct dhcp_boot *next;
};
+struct dhcp_match_name {
+ char *name;
+ int wildcard;
+ struct dhcp_netid *netid;
+ struct dhcp_match_name *next;
+};
+
struct pxe_service {
unsigned short CSA, type;
char *menu, *basename, *sname;
@@ -644,13 +860,15 @@ struct pxe_service {
struct pxe_service *next;
};
+#define DHCP_PXE_DEF_VENDOR "PXEClient"
+
#define MATCH_VENDOR 1
#define MATCH_USER 2
#define MATCH_CIRCUIT 3
#define MATCH_REMOTE 4
#define MATCH_SUBSCRIBER 5
-/* vendorclass, userclass, remote-id or cicuit-id */
+/* vendorclass, userclass, remote-id or circuit-id */
struct dhcp_vendor {
int len, match_type;
unsigned int enterprise;
@@ -659,6 +877,11 @@ struct dhcp_vendor {
struct dhcp_vendor *next;
};
+struct dhcp_pxe_vendor {
+ char *data;
+ struct dhcp_pxe_vendor *next;
+};
+
struct dhcp_mac {
unsigned int mask;
int hwaddr_len, hwaddr_type;
@@ -673,22 +896,19 @@ struct dhcp_bridge {
};
struct cond_domain {
- char *domain;
+ char *domain, *prefix;
struct in_addr start, end;
-#ifdef HAVE_IPV6
struct in6_addr start6, end6;
-#endif
- int is6;
+ int is6, indexed;
struct cond_domain *next;
};
-#ifdef OPTION6_PREFIX_CLASS
-struct prefix_class {
- int class;
- struct dhcp_netid tag;
- struct prefix_class *next;
+struct ra_interface {
+ char *name;
+ char *mtu_name;
+ int interval, lifetime, prio, mtu;
+ struct ra_interface *next;
};
-#endif
struct dhcp_context {
unsigned int lease_time, addr_epoch;
@@ -699,8 +919,8 @@ struct dhcp_context {
struct in6_addr start6, end6; /* range of available addresses */
struct in6_addr local6;
int prefix, if_index;
- unsigned int valid, preferred;
- time_t ra_time, ra_short_period_start;
+ unsigned int valid, preferred, saved_valid;
+ time_t ra_time, ra_short_period_start, address_lost_time;
char *template_interface;
#endif
int flags;
@@ -708,23 +928,37 @@ struct dhcp_context {
struct dhcp_context *next, *current;
};
-#define CONTEXT_STATIC 1
-#define CONTEXT_NETMASK 2
-#define CONTEXT_BRDCAST 4
-#define CONTEXT_PROXY 8
-#define CONTEXT_RA_ONLY 16
-#define CONTEXT_RA_DONE 32
-#define CONTEXT_RA_NAME 64
-#define CONTEXT_RA_STATELESS 128
-#define CONTEXT_DHCP 256
-#define CONTEXT_DEPRECATE 512
-#define CONTEXT_TEMPLATE 1024 /* create contexts using addresses */
-#define CONTEXT_CONSTRUCTED 2048
-#define CONTEXT_GC 4096
-#define CONTEXT_RA 8192
-#define CONTEXT_CONF_USED 16384
-#define CONTEXT_USED 32768
+struct shared_network {
+ int if_index;
+ struct in_addr match_addr, shared_addr;
+#ifdef HAVE_DHCP6
+ /* shared_addr == 0 for IP6 entries. */
+ struct in6_addr match_addr6, shared_addr6;
+#endif
+ struct shared_network *next;
+};
+#define CONTEXT_STATIC (1u<<0)
+#define CONTEXT_NETMASK (1u<<1)
+#define CONTEXT_BRDCAST (1u<<2)
+#define CONTEXT_PROXY (1u<<3)
+#define CONTEXT_RA_ROUTER (1u<<4)
+#define CONTEXT_RA_DONE (1u<<5)
+#define CONTEXT_RA_NAME (1u<<6)
+#define CONTEXT_RA_STATELESS (1u<<7)
+#define CONTEXT_DHCP (1u<<8)
+#define CONTEXT_DEPRECATE (1u<<9)
+#define CONTEXT_TEMPLATE (1u<<10) /* create contexts using addresses */
+#define CONTEXT_CONSTRUCTED (1u<<11)
+#define CONTEXT_GC (1u<<12)
+#define CONTEXT_RA (1u<<13)
+#define CONTEXT_CONF_USED (1u<<14)
+#define CONTEXT_USED (1u<<15)
+#define CONTEXT_OLD (1u<<16)
+#define CONTEXT_V6 (1u<<17)
+#define CONTEXT_RA_OFF_LINK (1u<<18)
+#define CONTEXT_SETLEASE (1u<<19)
+
struct ping_result {
struct in_addr addr;
time_t time;
@@ -747,6 +981,8 @@ struct tftp_transfer {
unsigned int block, blocksize, expansion;
off_t offset;
union mysockaddr peer;
+ union all_addr source;
+ int if_index;
char opt_blocksize, opt_transize, netascii, carrylf;
struct tftp_file *file;
struct tftp_transfer *next;
@@ -760,18 +996,26 @@ struct addr_list {
struct tftp_prefix {
char *interface;
char *prefix;
+ int missing;
struct tftp_prefix *next;
};
+struct dhcp_relay {
+ union all_addr local, server;
+ char *interface; /* Allowable interface for replies from server, and dest for IPv6 multicast */
+ int iface_index; /* working - interface in which requests arrived, for return */
+ struct dhcp_relay *current, *next;
+};
extern struct daemon {
/* datastuctures representing the command-line and
config file arguments. All set (including defaults)
in option.c */
- unsigned int options, options2;
+ unsigned int options[OPTION_SIZE];
struct resolvc default_resolv, *resolv_files;
time_t last_resolv;
+ char *servers_file;
struct mx_srv_record *mxnames;
struct naptr *naptr;
struct txt_record *txt, *rr;
@@ -781,7 +1025,9 @@ extern struct daemon {
struct auth_zone *auth_zones;
struct interface_name *int_names;
char *mxtarget;
- char *lease_file;
+ struct mysubnet *add_subnet4;
+ struct mysubnet *add_subnet6;
+ char *lease_file;
char *username, *groupname, *scriptuser;
char *luascript;
char *authserver, *hostmaster;
@@ -789,36 +1035,42 @@ extern struct daemon {
struct name_list *secondary_forward_server;
int group_set, osport;
char *domain_suffix;
- struct cond_domain *cond_domain;
+ struct cond_domain *cond_domain, *synth_domains;
char *runfile;
char *lease_change_command;
- struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers;
- struct bogus_addr *bogus_addr;
+ struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces;
+ struct bogus_addr *bogus_addr, *ignore_addr;
struct server *servers;
struct ipsets *ipsets;
int log_fac; /* log facility */
char *log_file; /* optional log file */
int max_logs; /* queue limit */
int cachesize, ftabsize;
- int port, query_port, min_port;
- unsigned long local_ttl, neg_ttl, max_ttl, max_cache_ttl, auth_ttl;
+ 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;
+ char *dns_client_id;
struct hostsfile *addn_hosts;
struct dhcp_context *dhcp, *dhcp6;
+ struct ra_interface *ra_interfaces;
struct dhcp_config *dhcp_conf;
struct dhcp_opt *dhcp_opts, *dhcp_match, *dhcp_opts6, *dhcp_match6;
+ struct dhcp_match_name *dhcp_name_match;
+ struct dhcp_pxe_vendor *dhcp_pxe_vendors;
struct dhcp_vendor *dhcp_vendors;
struct dhcp_mac *dhcp_macs;
struct dhcp_boot *boot_config;
struct pxe_service *pxe_services;
struct tag_if *tag_if;
struct addr_list *override_relays;
+ struct dhcp_relay *relay4, *relay6;
+ struct delay_config *delay_conf;
int override;
int enable_pxe;
int doing_ra, doing_dhcp6;
struct dhcp_netid_list *dhcp_ignore, *dhcp_ignore_names, *dhcp_gen_names;
struct dhcp_netid_list *force_broadcast, *bootp_dynamic;
- struct hostsfile *dhcp_hosts_file, *dhcp_opts_file;
- int dhcp_max, tftp_max;
+ struct hostsfile *dhcp_hosts_file, *dhcp_opts_file, *dynamic_dirs;
+ int dhcp_max, tftp_max, tftp_mtu;
int dhcp_server_port, dhcp_client_port;
int start_tftp_port, end_tftp_port;
unsigned int min_leasetime;
@@ -829,17 +1081,31 @@ extern struct daemon {
unsigned int duid_enterprise, duid_config_len;
unsigned char *duid_config;
char *dbus_name;
+ char *ubus_name;
+ char *dump_file;
+ int dump_mask;
unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry;
-#ifdef OPTION6_PREFIX_CLASS
- struct prefix_class *prefix_classes;
+ u32 metrics[__METRIC_MAX];
+#ifdef HAVE_DNSSEC
+ struct ds_config *ds;
+ char *timestamp_file;
#endif
/* globally used stuff for DNS */
char *packet; /* packet buffer */
int packet_buff_sz; /* size of above */
char *namebuff; /* MAXDNAME size buffer */
- unsigned int local_answer, queries_forwarded;
+#ifdef HAVE_DNSSEC
+ char *keyname; /* MAXDNAME size buffer */
+ char *workspacename; /* ditto */
+ unsigned long *rr_status; /* ceiling in TTL from DNSSEC or zero for insecure */
+ int rr_status_sz;
+ int dnssec_no_time_check;
+ int back_to_the_future;
+#endif
struct frec *frec_list;
+ struct frec_src *free_frec_src;
+ int frec_src_count;
struct serverfd *sfds;
struct irec *interfaces;
struct listener *listeners;
@@ -850,21 +1116,30 @@ extern struct daemon {
size_t packet_len; /* " " */
struct randfd *rfd_save; /* " " */
pid_t tcp_pids[MAX_PROCS];
+ int tcp_pipes[MAX_PROCS];
+ int pipe_to_parent;
struct randfd randomsocks[RANDOM_SOCKS];
int v6pktinfo;
+ 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 */
+ union mysockaddr *log_source_addr;
/* DHCP state */
int dhcpfd, helperfd, pxefd;
+#ifdef HAVE_INOTIFY
+ int inotifyfd;
+#endif
#if defined(HAVE_LINUX_NETWORK)
- int netlinkfd;
+ int netlinkfd, kernel_version;
#elif defined(HAVE_BSD_NETWORK)
- int dhcp_raw_fd, dhcp_icmp_fd;
+ int dhcp_raw_fd, dhcp_icmp_fd, routefd;
#endif
struct iovec dhcp_packet;
char *dhcp_buff, *dhcp_buff2, *dhcp_buff3;
struct ping_result *ping_results;
FILE *lease_stream;
struct dhcp_bridge *bridges;
+ struct shared_network *shared_networks;
#ifdef HAVE_DHCP6
int duid_len;
unsigned char *duid;
@@ -877,98 +1152,154 @@ extern struct daemon {
#ifdef HAVE_DBUS
struct watch *watches;
#endif
+ /* UBus stuff */
+#ifdef HAVE_UBUS
+ /* void * here to avoid depending on ubus headers outside ubus.c */
+ void *ubus;
+#endif
/* TFTP stuff */
struct tftp_transfer *tftp_trans, *tftp_done_trans;
/* utility string buffer, hold max sized IP address as string */
char *addrbuff;
+ char *addrbuff2; /* only allocated when OPT_EXTRALOG */
+#ifdef HAVE_DUMPFILE
+ /* file for packet dumps. */
+ int dumpfd;
+#endif
} *daemon;
/* cache.c */
void cache_init(void);
-void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg);
-char *record_source(int index);
-void querystr(char *desc, char *str, unsigned short type);
+void next_uid(struct crec *crecp);
+void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg);
+char *record_source(unsigned int index);
+char *querystr(char *desc, unsigned short type);
+int cache_find_non_terminal(char *name, time_t now);
struct crec *cache_find_by_addr(struct crec *crecp,
- struct all_addr *addr, time_t now,
- unsigned short prot);
+ union all_addr *addr, time_t now,
+ unsigned int prot);
struct crec *cache_find_by_name(struct crec *crecp,
- char *name, time_t now, unsigned short prot);
+ char *name, time_t now, unsigned int prot);
void cache_end_insert(void);
void cache_start_insert(void);
-struct crec *cache_insert(char *name, struct all_addr *addr,
- time_t now, unsigned long ttl, unsigned short flags);
+int cache_recv_insert(time_t now, int fd);
+struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class,
+ time_t now, unsigned long ttl, unsigned int flags);
void cache_reload(void);
-void cache_add_dhcp_entry(char *host_name, int prot, struct all_addr *host_address, time_t ttd);
+void cache_add_dhcp_entry(char *host_name, int prot, union all_addr *host_address, time_t ttd);
struct in_addr a_record_from_hosts(char *name, time_t now);
void cache_unhash_dhcp(void);
void dump_cache(time_t now);
+#ifndef NO_ID
+int cache_make_stat(struct txt_record *t);
+#endif
char *cache_get_name(struct crec *crecp);
+char *cache_get_cname_target(struct crec *crecp);
struct crec *cache_enumerate(int init);
+int read_hostsfile(char *filename, unsigned int index, int cache_size,
+ struct crec **rhash, int hashsz);
+
+/* blockdata.c */
+void blockdata_init(void);
+void blockdata_report(void);
+struct blockdata *blockdata_alloc(char *data, size_t len);
+void *blockdata_retrieve(struct blockdata *block, size_t len, void *data);
+struct blockdata *blockdata_read(int fd, size_t len);
+void blockdata_write(struct blockdata *block, size_t len, int fd);
+void blockdata_free(struct blockdata *blocks);
+
+/* domain.c */
char *get_domain(struct in_addr addr);
-#ifdef HAVE_IPV6
char *get_domain6(struct in6_addr *addr);
-#endif
-#ifdef HAVE_DNSSEC
-struct keydata *keydata_alloc(char *data, size_t len);
-void keydata_free(struct keydata *blocks);
-#endif
+int is_name_synthetic(int flags, char *name, union all_addr *addr);
+int is_rev_synth(int flag, union all_addr *addr, char *name);
/* rfc1035.c */
+int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
+ char *name, int isExtract, int extrabytes);
+unsigned char *skip_name(unsigned char *ansp, struct dns_header *header, size_t plen, int extrabytes);
+unsigned char *skip_questions(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,
char *name, unsigned short *typep);
size_t setup_reply(struct dns_header *header, size_t qlen,
- struct all_addr *addrp, unsigned int flags,
- unsigned long local_ttl);
-int extract_addresses(struct dns_header *header, size_t qlen, char *namebuff,
- time_t now, char **ipsets, int is_sign, int checkrebind,
- int checking_disabled);
+ union all_addr *addrp, unsigned int flags,
+ unsigned long ttl);
+int extract_addresses(struct dns_header *header, size_t qlen, char *name,
+ time_t now, char **ipsets, int is_sign, int check_rebind,
+ int no_cache_dnssec, int secure, int *doctored);
size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
- struct in_addr local_addr, struct in_addr local_netmask, time_t now);
+ struct in_addr local_addr, struct in_addr local_netmask,
+ time_t now, int ad_reqd, int do_bit, int have_pseudoheader);
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
- struct bogus_addr *addr, time_t now);
-unsigned char *find_pseudoheader(struct dns_header *header, size_t plen,
- size_t *len, unsigned char **p, int *is_sign);
+ struct bogus_addr *baddr, time_t now);
+int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr);
int check_for_local_domain(char *name, time_t now);
-unsigned int questions_crc(struct dns_header *header, size_t plen, char *buff);
size_t resize_packet(struct dns_header *header, size_t plen,
unsigned char *pheader, size_t hlen);
-size_t add_mac(struct dns_header *header, size_t plen, char *limit, union mysockaddr *l3);
int add_resource_record(struct dns_header *header, char *limit, int *truncp,
int nameoffset, unsigned char **pp, unsigned long ttl,
int *offset, unsigned short type, unsigned short class, char *format, ...);
-unsigned char *skip_questions(struct dns_header *header, size_t plen);
-int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
- char *name, int isExtract, int extrabytes);
-int in_arpa_name_2_addr(char *namein, struct all_addr *addrp);
+int in_arpa_name_2_addr(char *namein, union all_addr *addrp);
+int private_net(struct in_addr addr, int ban_localhost);
/* auth.c */
#ifdef HAVE_AUTH
-size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now, union mysockaddr *peer_addr);
+size_t answer_auth(struct dns_header *header, char *limit, size_t qlen,
+ time_t now, union mysockaddr *peer_addr, int local_query,
+ int do_bit, int have_pseudoheader);
+int in_zone(struct auth_zone *zone, char *name, char **cut);
#endif
+/* dnssec.c */
+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_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class);
+int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int *class,
+ int check_unsigned, int *neganswer, int *nons, int *nsec_ttl);
+int dnskey_keytag(int alg, int flags, unsigned char *key, int keylen);
+size_t filter_rrsigs(struct dns_header *header, size_t plen);
+int setup_timestamp(void);
+
+/* hash_questions.c */
+void hash_questions_init(void);
+unsigned char *hash_questions(struct dns_header *header, size_t plen, char *name);
+
+/* crypto.c */
+const struct nettle_hash *hash_find(char *name);
+int hash_init(const struct nettle_hash *hash, void **ctxp, unsigned char **digestp);
+int verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
+ unsigned char *digest, size_t digest_len, int algo);
+char *ds_digest_name(int digest);
+char *algo_digest_name(int algo);
+char *nsec3_digest_name(int digest);
+
/* util.c */
void rand_init(void);
unsigned short rand16(void);
-int legal_hostname(char *c);
-char *canonicalise(char *s, int *nomem);
-unsigned char *do_rfc1035_name(unsigned char *p, char *sval);
+u32 rand32(void);
+u64 rand64(void);
+int legal_hostname(char *name);
+char *canonicalise(char *in, int *nomem);
+unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit);
void *safe_malloc(size_t size);
+void safe_strncpy(char *dest, const char *src, size_t size);
void safe_pipe(int *fd, int read_noblock);
void *whine_malloc(size_t size);
int sa_len(union mysockaddr *addr);
int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2);
int hostname_isequal(const char *a, const char *b);
+int hostname_issubdomain(char *a, char *b);
time_t dnsmasq_time(void);
+int netmask_length(struct in_addr mask);
int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask);
-#ifdef HAVE_IPV6
int is_same_net6(struct in6_addr *a, struct in6_addr *b, int prefixlen);
u64 addr6part(struct in6_addr *addr);
void setaddr6part(struct in6_addr *addr, u64 host);
-#endif
-int retry_send(void);
+int retry_send(ssize_t rc);
void prettyprint_time(char *buf, unsigned int t);
int prettyprint_addr(union mysockaddr *addr, char *buf);
int parse_hex(char *in, unsigned char *out, int maxlen,
@@ -977,18 +1308,23 @@ int memcmp_masked(unsigned char *a, unsigned char *b,
unsigned int mask);
int expand_buf(struct iovec *iov, size_t size);
char *print_mac(char *buff, unsigned char *mac, int len);
-void bump_maxfd(int fd, int *max);
int read_write(int fd, unsigned char *packet, int size, int rw);
-
+void close_fds(long max_fd, int spare1, int spare2, int spare3);
int wildcard_match(const char* wildcard, const char* match);
+int wildcard_matchn(const char* wildcard, const char* match, int num);
+#ifdef HAVE_LINUX_NETWORK
+int kernel_version(void);
+#endif
/* log.c */
-void die(char *message, char *arg1, int exit_code);
+void die(char *message, char *arg1, int exit_code) ATTRIBUTE_NORETURN;
int log_start(struct passwd *ent_pw, int errfd);
int log_reopen(char *log_file);
+
void my_syslog(int priority, const char *format, ...);
-void set_log_writer(fd_set *set, int *maxfdp);
-void check_log_writer(fd_set *set);
+
+void set_log_writer(void);
+void check_log_writer(int force);
void flush_log(void);
/* option.c */
@@ -996,11 +1332,13 @@ void read_opts (int argc, char **argv, char *compile_o
char *option_string(int prot, unsigned int opt, unsigned char *val,
int opt_len, char *buf, int buf_len);
void reread_dhcp(void);
+void read_servers_file(void);
void set_option_bool(unsigned int opt);
void reset_option_bool(unsigned int opt);
struct hostsfile *expand_filelist(struct hostsfile *list);
char *parse_server(char *arg, union mysockaddr *addr,
union mysockaddr *source_addr, char *interface, int *flags);
+int option_read_dynfile(char *file, int flags);
/* forward.c */
void reply_query(int fd, int family, time_t now);
@@ -1008,53 +1346,64 @@ void receive_query(struct listener *listen, time_t now
unsigned char *tcp_request(int confd, time_t now,
union mysockaddr *local_addr, struct in_addr netmask, int auth_dns);
void server_gone(struct server *server);
-struct frec *get_new_frec(time_t now, int *wait);
+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,
- union mysockaddr *to, struct all_addr *source,
+ union mysockaddr *to, union all_addr *source,
unsigned int iface);
+void resend_query(void);
+struct randfd *allocate_rfd(int family);
+void free_rfd(struct randfd *rfd);
/* network.c */
int indextoname(int fd, int index, char *name);
-int local_bind(int fd, union mysockaddr *addr, char *intname, 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);
int reload_servers(char *fname);
+void mark_servers(int flag);
+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 enumerate_interfaces(int reset);
void create_wildcard_listeners(void);
-void create_bound_listeners(int die);
+void create_bound_listeners(int dienow);
+void warn_bound_listeners(void);
+void warn_wild_labels(void);
+void warn_int_names(void);
int is_dad_listeners(void);
-int iface_check(int family, struct all_addr *addr, char *name, int *auth_dns);
-int loopback_exception(int fd, int family, struct all_addr *addr, char *name);
+int iface_check(int family, union all_addr *addr, char *name, int *auth);
+int loopback_exception(int fd, int family, union all_addr *addr, char *name);
+int label_exception(int index, int family, union all_addr *addr);
int fix_fd(int fd);
int tcp_interface(int fd, int af);
-struct in_addr get_ifaddr(char *intr);
-#ifdef HAVE_IPV6
int set_ipv6pktinfo(int fd);
-#endif
#ifdef HAVE_DHCP6
void join_multicast(int dienow);
#endif
+#if defined(HAVE_LINUX_NETWORK) || defined(HAVE_BSD_NETWORK)
+void newaddress(time_t now);
+#endif
+
/* dhcp.c */
#ifdef HAVE_DHCP
void dhcp_init(void);
void dhcp_packet(time_t now, int pxe_fd);
struct dhcp_context *address_available(struct dhcp_context *context,
- struct in_addr addr,
+ struct in_addr taddr,
struct dhcp_netid *netids);
struct dhcp_context *narrow_context(struct dhcp_context *context,
struct in_addr taddr,
struct dhcp_netid *netids);
+struct ping_result *do_icmp_ping(time_t now, struct in_addr addr,
+ unsigned int hash, int loopback);
int address_allocate(struct dhcp_context *context,
struct in_addr *addrp, unsigned char *hwaddr, int hw_len,
- struct dhcp_netid *netids, time_t now);
-int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type);
-struct dhcp_config *find_config(struct dhcp_config *configs,
- struct dhcp_context *context,
- unsigned char *clid, int clid_len,
- unsigned char *hwaddr, int hw_len,
- int hw_type, char *hostname);
+ struct dhcp_netid *netids, time_t now, int loopback);
void dhcp_read_ethers(void);
struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr);
char *host_from_dns(struct in_addr addr);
@@ -1069,17 +1418,21 @@ struct dhcp_lease *lease4_allocate(struct in_addr addr
#ifdef HAVE_DHCP6
struct dhcp_lease *lease6_allocate(struct in6_addr *addrp, int lease_type);
struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
- int lease_type, int iaid, struct in6_addr *addr);
+ int lease_type, unsigned int iaid, struct in6_addr *addr);
void lease6_reset(void);
-struct dhcp_lease *lease6_find_by_client(struct dhcp_lease *first, int lease_type, unsigned char *clid, int clid_len, int iaid);
+struct dhcp_lease *lease6_find_by_client(struct dhcp_lease *first, int lease_type,
+ unsigned char *clid, int clid_len, unsigned int iaid);
struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 addr);
u64 lease_find_max_addr6(struct dhcp_context *context);
void lease_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface);
void lease_update_slaac(time_t now);
+void lease_set_iaid(struct dhcp_lease *lease, unsigned int iaid);
+void lease_make_duid(time_t now);
#endif
-void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
- unsigned char *clid, int hw_len, int hw_type, int clid_len, time_t now, int force);
-void lease_set_hostname(struct dhcp_lease *lease, char *name, int auth, char *domain, char *config_domain);
+void lease_set_hwaddr(struct dhcp_lease *lease, const unsigned char *hwaddr,
+ const unsigned char *clid, int hw_len, int hw_type,
+ int clid_len, time_t now, int force);
+void lease_set_hostname(struct dhcp_lease *lease, const char *name, int auth, char *domain, char *config_domain);
void lease_set_expires(struct dhcp_lease *lease, unsigned int len, time_t now);
void lease_set_interface(struct dhcp_lease *lease, int interface, time_t now);
struct dhcp_lease *lease_find_by_client(unsigned char *hwaddr, int hw_len, int hw_type,
@@ -1100,7 +1453,8 @@ void lease_add_extradata(struct dhcp_lease *lease, uns
/* rfc2131.c */
#ifdef HAVE_DHCP
size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
- size_t sz, time_t now, int unicast_dest, int *is_inform, int pxe_fd, struct in_addr fallback);
+ size_t sz, time_t now, int unicast_dest, int loopback,
+ int *is_inform, int pxe, struct in_addr fallback, time_t recvtime);
unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr,
int clid_len, unsigned char *clid, int *len_out);
#endif
@@ -1109,16 +1463,17 @@ unsigned char *extended_hwaddr(int hwtype, int hwlen,
#ifdef HAVE_DHCP
int make_icmp_sock(void);
int icmp_ping(struct in_addr addr);
+int delay_dhcp(time_t start, int sec, int fd, uint32_t addr, unsigned short id);
#endif
+void queue_event(int event);
void send_alarm(time_t event, time_t now);
void send_event(int fd, int event, int data, char *msg);
void clear_cache_and_reload(time_t now);
-void poll_resolv(int force, int do_reload, time_t now);
/* netlink.c */
#ifdef HAVE_LINUX_NETWORK
-void netlink_init(void);
-void netlink_multicast(time_t now);
+char *netlink_init(void);
+void netlink_multicast(void);
#endif
/* bpf.c */
@@ -1126,6 +1481,8 @@ void netlink_multicast(time_t now);
void init_bpf(void);
void send_via_bpf(struct dhcp_packet *mess, size_t len,
struct in_addr iface_addr, struct ifreq *ifr);
+void route_init(void);
+void route_sock(void);
#endif
/* bpf.c or netlink.c */
@@ -1134,17 +1491,25 @@ int iface_enumerate(int family, void *parm, int (callb
/* dbus.c */
#ifdef HAVE_DBUS
char *dbus_init(void);
-void check_dbus_listeners(fd_set *rset, fd_set *wset, fd_set *eset);
-void set_dbus_listeners(int *maxfdp, fd_set *rset, fd_set *wset, fd_set *eset);
+void check_dbus_listeners(void);
+void set_dbus_listeners(void);
# ifdef HAVE_DHCP
void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname);
# endif
#endif
+/* ubus.c */
+#ifdef HAVE_UBUS
+void ubus_init(void);
+void set_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);
+#endif
+
/* ipset.c */
#ifdef HAVE_IPSET
void ipset_init(void);
-int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags, int remove);
+int add_to_ipset(const char *setname, const union all_addr *ipaddr, int flags, int remove);
#endif
/* helper.c */
@@ -1156,19 +1521,21 @@ void queue_script(int action, struct dhcp_lease *lease
#ifdef HAVE_TFTP
void queue_tftp(off_t file_len, char *filename, union mysockaddr *peer);
#endif
+void queue_arp(int action, unsigned char *mac, int maclen,
+ int family, union all_addr *addr);
int helper_buf_empty(void);
#endif
/* tftp.c */
#ifdef HAVE_TFTP
void tftp_request(struct listener *listen, time_t now);
-void check_tftp_listeners(fd_set *rset, time_t now);
+void check_tftp_listeners(time_t now);
int do_tftp_script_run(void);
#endif
/* conntrack.c */
#ifdef HAVE_CONNTRACK
-int get_incoming_mark(union mysockaddr *peer_addr, struct all_addr *local_addr,
+int get_incoming_mark(union mysockaddr *peer_addr, union all_addr *local_addr,
int istcp, unsigned int *markp);
#endif
@@ -1176,9 +1543,8 @@ int get_incoming_mark(union mysockaddr *peer_addr, str
#ifdef HAVE_DHCP6
void dhcp6_init(void);
void dhcp6_packet(time_t now);
-struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len,
- int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans);
-int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr);
+struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len, int temp_addr,
+ unsigned int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans);
struct dhcp_context *address6_available(struct dhcp_context *context,
struct in6_addr *taddr,
struct dhcp_netid *netids,
@@ -1187,51 +1553,62 @@ struct dhcp_context *address6_valid(struct dhcp_contex
struct in6_addr *taddr,
struct dhcp_netid *netids,
int plain_range);
-struct dhcp_config *find_config6(struct dhcp_config *configs,
- struct dhcp_context *context,
- unsigned char *duid, int duid_len,
- char *hostname);
struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net,
- int prefix, u64 addr);
+ int prefix, struct in6_addr *addr);
void make_duid(time_t now);
void dhcp_construct_contexts(time_t now);
+void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac,
+ unsigned int *maclenp, unsigned int *mactypep, time_t now);
#endif
-
+
/* rfc3315.c */
#ifdef HAVE_DHCP6
unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name,
- struct in6_addr *fallback, size_t sz, int is_multicast, time_t now);
+ 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);
+void relay_upstream6(struct dhcp_relay *relay, ssize_t sz, struct in6_addr *peer_address,
+ u32 scope_id, time_t now);
+
+unsigned short relay_reply6( struct sockaddr_in6 *peer, ssize_t sz, char *arrival_interface);
#endif
/* dhcp-common.c */
#ifdef HAVE_DHCP
void dhcp_common_init(void);
ssize_t recv_dhcp_packet(int fd, struct msghdr *msg);
-struct dhcp_netid *run_tag_if(struct dhcp_netid *input);
+struct dhcp_netid *run_tag_if(struct dhcp_netid *tags);
struct dhcp_netid *option_filter(struct dhcp_netid *tags, struct dhcp_netid *context_tags,
struct dhcp_opt *opts);
-int match_netid(struct dhcp_netid *check, struct dhcp_netid *pool, int negonly);
+int match_netid(struct dhcp_netid *check, struct dhcp_netid *pool, int tagnotneeded);
char *strip_hostname(char *hostname);
void log_tags(struct dhcp_netid *netid, u32 xid);
int match_bytes(struct dhcp_opt *o, unsigned char *p, int len);
void dhcp_update_configs(struct dhcp_config *configs);
void display_opts(void);
-u16 lookup_dhcp_opt(int prot, char *name);
-u16 lookup_dhcp_len(int prot, u16 val);
-char *option_string(int prot, unsigned int opt, unsigned char *val,
- int opt_len, char *buf, int buf_len);
+int lookup_dhcp_opt(int prot, char *name);
+int lookup_dhcp_len(int prot, int val);
+struct dhcp_config *find_config(struct dhcp_config *configs,
+ struct dhcp_context *context,
+ unsigned char *clid, int clid_len,
+ unsigned char *hwaddr, int hw_len,
+ int hw_type, char *hostname,
+ struct dhcp_netid *filter);
+int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type);
#ifdef HAVE_LINUX_NETWORK
-void bindtodevice(int fd);
+char *whichdevice(void);
+void bindtodevice(char *device, int fd);
#endif
# ifdef HAVE_DHCP6
void display_opts6(void);
# endif
void log_context(int family, struct dhcp_context *context);
+void log_relay(int family, struct dhcp_relay *relay);
#endif
/* outpacket.c */
#ifdef HAVE_DHCP6
void end_opt6(int container);
+void reset_counter(void);
int save_counter(int newval);
void *expand(size_t headroom);
int new_opt6(int opt);
@@ -1247,7 +1624,7 @@ void put_opt6_string(char *s);
void ra_init(time_t now);
void icmp6_packet(time_t now);
time_t periodic_ra(time_t now);
-void ra_start_unsolicted(time_t now, struct dhcp_context *context);
+void ra_start_unsolicited(time_t now, struct dhcp_context *context);
#endif
/* slaac.c */
@@ -1255,4 +1632,48 @@ void ra_start_unsolicted(time_t now, struct dhcp_conte
void slaac_add_addrs(struct dhcp_lease *lease, time_t now, int force);
time_t periodic_slaac(time_t now, struct dhcp_lease *leases);
void slaac_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface, struct dhcp_lease *leases);
+#endif
+
+/* loop.c */
+#ifdef HAVE_LOOP
+void loop_send_probes(void);
+int detect_loop(char *query, int type);
+#endif
+
+/* inotify.c */
+#ifdef HAVE_INOTIFY
+void inotify_dnsmasq_init(void);
+int inotify_check(time_t now);
+void set_dynamic_inotify(int flag, int total_size, struct crec **rhash, int revhashsz);
+#endif
+
+/* poll.c */
+void poll_reset(void);
+int poll_check(int fd, short event);
+void poll_listen(int fd, short event);
+int do_poll(int timeout);
+
+/* rrfilter.c */
+size_t rrfilter(struct dns_header *header, size_t plen, int mode);
+u16 *rrfilter_desc(int type);
+int expand_workspace(unsigned char ***wkspc, int *szp, int new);
+
+/* edns0.c */
+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 add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *limit,
+ 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_edns0_config(struct dns_header *header, size_t plen, unsigned char *limit,
+ union mysockaddr *source, time_t now, int *check_subnet, int *cacheable);
+int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer);
+
+/* arp.c */
+int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now);
+int do_arp_script_run(void);
+
+/* dump.c */
+#ifdef HAVE_DUMPFILE
+void dump_init(void);
+void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src, union mysockaddr *dst);
#endif