diff --git a/CHANGELOG b/CHANGELOG index 55e71c9..69762ae 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2638,11 +2638,11 @@ version 2.46 Tighten up data-checking code for DNS packet handling. Thanks to Steve Dodd who found certain illegal packets which could crash dnsmasq. No memory overwrite was - possible, so this is not a security issue beond the DoS + possible, so this is not a security issue beyond the DoS potential. Update example config dhcp option 47, the previous - suggestion generated and illegal, zero-length, + suggestion generated an illegal, zero-length, option. Thanks to Matthias Andree for finding this. Rewrite hosts-file reading code to remove the limit of @@ -2692,3 +2692,91 @@ version 2.46 Force re-reading of /etc/resolv.conf when an "interface up" event occurs. + +version 2.47 + Updated French translation. Thanks to Gildas Le Nadan. + + Fixed interface enumeration code to work on NetBSD + 5.0. Thanks to Roy Marples for the patch. + + Updated config.h to use the same location for the lease + file on NetBSD as the other *BSD variants. Also allow + LEASEFILE and CONFFILE symbols to be overriden in CFLAGS. + + Handle duplicate address detection on IPv6 more + intelligently. In IPv6, an interface can have an address + which is not usable, because it is still undergoing DAD + (such addresses are marked "tentative"). Attempting to + bind to an address in this state returns an error, + EADDRNOTAVAIL. Previously, on getting such an error, + dnsmasq would silently abandon the address, and never + listen on it. Now, it retries once per second for 20 + seconds before generating a fatal error. 20 seconds should + be long enough for any DAD process to complete, but can be + adjusted in src/config.h if necessary. Thanks to Martin + Krafft for the bug report. + + Add DBus introspection. Patch from Jeremy Laine. + + Update Dbus configuration file. Patch from Colin Walters. + Fix for this bug: + http://bugs.freedesktop.org/show_bug.cgi?id=18961 + + Support arbitrarily encapsulated DHCP options, suggestion + and initial patch from Samium Gromoff. This is useful for + (eg) gPXE, which expect all its private options to be + encapsulated inside a single option 175. So, eg, + + dhcp-option = encap:175, 190, "iscsi-client0" + dhcp-option = encap:175, 191, "iscsi-client0-secret" + + will provide iSCSI parameters to gPXE. + + Enhance --dhcp-match to allow testing of the contents of a + client-sent option, as well as its presence. This + application in mind for this is RFC 4578 + client-architecture specifiers, but it's generally useful. + Joey Korkames suggested the enhancement. + + Move from using the IP_XMIT_IF ioctl to IP_BOUND_IF on + OpenSolaris. Thanks to Bastian Machek for the heads-up. + + No longer complain about blank lines in + /etc/ethers. Thanks to Jon Nelson for the patch. + + Fix binding of servers to physical devices, eg + --server=/domain/1.2.3.4@eth0 which was broken from 2.43 + onwards unless --query-port=0 set. Thanks to Peter Naulls + for the bug report. + + Reply to DHCPINFORM requests even when the supplied ciaddr + doesn't fall in any dhcp-range. In this case it's not + possible to supply a complete configuration, but + individually-configured options (eg PAC) may be useful. + + Allow the source address of an alias to be a range: + --alias=192.168.0.0,10.0.0.0,255.255.255.0 maps the whole + subnet 192.168.0.0->192.168.0.255 to 10.0.0.0->10.0.0.255, + as before. + --alias=192.168.0.10-192.168.0.40,10.0.0.0,255.255.255.0 + maps only the 192.168.0.10->192.168.0.40 region. Thanks to + Ib Uhrskov for the suggestion. + + Don't dynamically allocate DHCP addresses which may break + Windows. Addresses which end in .255 or .0 are broken in + Windows even when using supernetting. + --dhcp-range=192.168.0.1,192.168.1.254,255,255,254.0 means + 192.168.0.255 is a valid IP address, but not for Windows. + See Microsoft KB281579. We therefore no longer allocate + these addresses to avoid hard-to-diagnose problems. + + Update Polish translation. Thanks to Jan Psota. + + Delete the PID-file when dnsmasq shuts down. Note that by + this time, dnsmasq is normally not running as root, so + this will fail if the PID-file is stored in a root-owned + directory; such failure is silently ignored. To take + advantage of this feature, the PID-file must be stored in a + directory owned and write-able by the user running + dnsmasq. + diff --git a/Makefile b/Makefile index 6490efb..66de5bd 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# dnsmasq is Copyright (c) 2000-2008 Simon Kelley +# dnsmasq is Copyright (c) 2000-2009 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 @@ -10,8 +10,8 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . PREFIX = /usr/local BINDIR = ${PREFIX}/sbin diff --git a/contrib/lease-access/README b/contrib/lease-access/README new file mode 100644 index 0000000..fc66bdf --- /dev/null +++ b/contrib/lease-access/README @@ -0,0 +1,20 @@ +Hello, + +For some specific application I needed to deny access to a MAC address +to a lease. For this reason I modified the dhcp-script behavior and is +called with an extra parameter "access" once a dhcp request or discover +is received. In that case if the exit code of the script is zero, +dnsmasq continues normally, and if non-zero the packet is ignored. + +This was not added as a security feature but as a mean to handle +differently some addresses. It is also quite intrusive since it requires +changes in several other subsystems. + +It attach the patch in case someone is interested. + +regards, +Nikos + +nmav@gennetsa.com + + diff --git a/contrib/lease-access/lease.access.patch b/contrib/lease-access/lease.access.patch new file mode 100644 index 0000000..ad76e25 --- /dev/null +++ b/contrib/lease-access/lease.access.patch @@ -0,0 +1,578 @@ +Index: src/dnsmasq.c +=================================================================== +--- src/dnsmasq.c (revision 696) ++++ src/dnsmasq.c (revision 821) +@@ -59,7 +59,6 @@ + static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp); + static void check_dns_listeners(fd_set *set, time_t now); + static void sig_handler(int sig); +-static void async_event(int pipe, time_t now); + static void fatal_event(struct event_desc *ev); + static void poll_resolv(void); + +@@ -275,7 +274,7 @@ + piperead = pipefd[0]; + pipewrite = pipefd[1]; + /* prime the pipe to load stuff first time. */ +- send_event(pipewrite, EVENT_RELOAD, 0); ++ send_event(pipewrite, EVENT_RELOAD, 0, 0); + + err_pipe[1] = -1; + +@@ -340,7 +339,7 @@ + } + else if (getuid() == 0) + { +- send_event(err_pipe[1], EVENT_PIDFILE, errno); ++ send_event(err_pipe[1], EVENT_PIDFILE, errno, 0); + _exit(0); + } + } +@@ -372,7 +371,7 @@ + (setgroups(0, &dummy) == -1 || + setgid(gp->gr_gid) == -1)) + { +- send_event(err_pipe[1], EVENT_GROUP_ERR, errno); ++ send_event(err_pipe[1], EVENT_GROUP_ERR, errno, 0); + _exit(0); + } + +@@ -415,14 +414,14 @@ + + if (bad_capabilities != 0) + { +- send_event(err_pipe[1], EVENT_CAP_ERR, bad_capabilities); ++ send_event(err_pipe[1], EVENT_CAP_ERR, bad_capabilities, 0); + _exit(0); + } + + /* finally drop root */ + if (setuid(ent_pw->pw_uid) == -1) + { +- send_event(err_pipe[1], EVENT_USER_ERR, errno); ++ send_event(err_pipe[1], EVENT_USER_ERR, errno, 0); + _exit(0); + } + +@@ -434,7 +433,7 @@ + /* lose the setuid and setgid capbilities */ + if (capset(hdr, data) == -1) + { +- send_event(err_pipe[1], EVENT_CAP_ERR, errno); ++ send_event(err_pipe[1], EVENT_CAP_ERR, errno, 0); + _exit(0); + } + #endif +@@ -647,7 +646,7 @@ + } + + if (FD_ISSET(piperead, &rset)) +- async_event(piperead, now); ++ async_event(piperead, now, NULL, 0); + + #ifdef HAVE_LINUX_NETWORK + if (FD_ISSET(daemon->netlinkfd, &rset)) +@@ -674,7 +673,7 @@ + #endif + + if (daemon->dhcp && FD_ISSET(daemon->dhcpfd, &rset)) +- dhcp_packet(now); ++ dhcp_packet(piperead, now); + + #ifndef NO_FORK + if (daemon->helperfd != -1 && FD_ISSET(daemon->helperfd, &wset)) +@@ -719,17 +718,18 @@ + else + return; + +- send_event(pipewrite, event, 0); ++ send_event(pipewrite, event, 0, 0); + errno = errsave; + } + } + +-void send_event(int fd, int event, int data) ++void send_event(int fd, int event, int data, int priv) + { + struct event_desc ev; + + ev.event = event; + ev.data = data; ++ ev.priv = priv; + + /* error pipe, debug mode. */ + if (fd == -1) +@@ -771,14 +771,17 @@ + die(_("cannot open %s: %s"), daemon->log_file ? daemon->log_file : "log", EC_FILE); + } + } +- +-static void async_event(int pipe, time_t now) ++ ++/* returns the private data of the event ++ */ ++int async_event(int pipe, time_t now, struct event_desc* event, unsigned int secs) + { + pid_t p; + struct event_desc ev; + int i; + +- if (read_write(pipe, (unsigned char *)&ev, sizeof(ev), 1)) ++ if (read_timeout(pipe, (unsigned char *)&ev, sizeof(ev), now, secs) > 0) ++ { + switch (ev.event) + { + case EVENT_RELOAD: +@@ -872,6 +875,14 @@ + flush_log(); + exit(EC_GOOD); + } ++ } ++ else ++ return -1; /* timeout */ ++ ++ if (event) ++ memcpy( event, &ev, sizeof(ev)); ++ ++ return 0; + } + + static void poll_resolv() +Index: src/config.h +=================================================================== +--- src/config.h (revision 696) ++++ src/config.h (revision 821) +@@ -51,6 +51,8 @@ + #define TFTP_MAX_CONNECTIONS 50 /* max simultaneous connections */ + #define LOG_MAX 5 /* log-queue length */ + #define RANDFILE "/dev/urandom" ++#define SCRIPT_TIMEOUT 6 ++#define LEASE_CHECK_TIMEOUT 10 + + /* DBUS interface specifics */ + #define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq" +Index: src/dnsmasq.h +=================================================================== +--- src/dnsmasq.h (revision 696) ++++ src/dnsmasq.h (revision 821) +@@ -116,6 +116,7 @@ + /* Async event queue */ + struct event_desc { + int event, data; ++ unsigned int priv; + }; + + #define EVENT_RELOAD 1 +@@ -390,6 +391,7 @@ + #define ACTION_OLD_HOSTNAME 2 + #define ACTION_OLD 3 + #define ACTION_ADD 4 ++#define ACTION_ACCESS 5 + + #define DHCP_CHADDR_MAX 16 + +@@ -709,6 +711,7 @@ + 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); ++int read_timeout(int fd, unsigned char *packet, int size, time_t now, int secs); + + /* log.c */ + void die(char *message, char *arg1, int exit_code); +@@ -748,7 +751,7 @@ + + /* dhcp.c */ + void dhcp_init(void); +-void dhcp_packet(time_t now); ++void dhcp_packet(int piperead, time_t now); + + struct dhcp_context *address_available(struct dhcp_context *context, + struct in_addr addr, +@@ -792,14 +795,16 @@ + void rerun_scripts(void); + + /* rfc2131.c */ +-size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, ++size_t dhcp_reply(int pipefd, struct dhcp_context *context, char *iface_name, int int_index, + size_t sz, time_t now, int unicast_dest, int *is_inform); + + /* dnsmasq.c */ + int make_icmp_sock(void); + int icmp_ping(struct in_addr addr); +-void send_event(int fd, int event, int data); ++void send_event(int fd, int event, int data, int priv); + void clear_cache_and_reload(time_t now); ++int wait_for_child(int pipe); ++int async_event(int pipe, time_t now, struct event_desc*, unsigned int timeout); + + /* isc.c */ + #ifdef HAVE_ISC_READER +@@ -832,9 +837,9 @@ + /* helper.c */ + #ifndef NO_FORK + int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd); +-void helper_write(void); ++int helper_write(void); + void queue_script(int action, struct dhcp_lease *lease, +- char *hostname, time_t now); ++ char *hostname, time_t now, unsigned int uid); + int helper_buf_empty(void); + #endif + +Index: src/util.c +=================================================================== +--- src/util.c (revision 696) ++++ src/util.c (revision 821) +@@ -444,3 +444,38 @@ + return 1; + } + ++int read_timeout(int fd, unsigned char *packet, int size, time_t now, int secs) ++{ ++ ssize_t n, done; ++ time_t expire; ++ ++ expire = now + secs; ++ ++ for (done = 0; done < size; done += n) ++ { ++ retry: ++ if (secs > 0) alarm(secs); ++ n = read(fd, &packet[done], (size_t)(size - done)); ++ ++ if (n == 0) ++ return 0; ++ else if (n == -1) ++ { ++ if (errno == EINTR) { ++ my_syslog(LOG_INFO, _("read timed out (errno %d)"), errno); ++ return 0; ++ } ++ ++ if (retry_send() || errno == ENOMEM || errno == ENOBUFS || errno == EAGAIN) ++ { ++ if (secs == 0 || (secs > 0 && dnsmasq_time() < expire)) ++ goto retry; ++ } ++ ++ my_syslog(LOG_INFO, _("error in read (timeout %d, errno %d)"), secs, errno); ++ return 0; ++ } ++ } ++ return 1; ++} ++ +Index: src/dhcp.c +=================================================================== +--- src/dhcp.c (revision 696) ++++ src/dhcp.c (revision 821) +@@ -103,7 +103,7 @@ + daemon->dhcp_packet.iov_base = safe_malloc(daemon->dhcp_packet.iov_len); + } + +-void dhcp_packet(time_t now) ++void dhcp_packet(int piperead, time_t now) + { + struct dhcp_packet *mess; + struct dhcp_context *context; +@@ -239,7 +239,8 @@ + if (!iface_enumerate(&parm, complete_context, NULL)) + return; + lease_prune(NULL, now); /* lose any expired leases */ +- iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz, ++ ++ iov.iov_len = dhcp_reply(piperead, parm.current, ifr.ifr_name, iface_index, (size_t)sz, + now, unicast_dest, &is_inform); + lease_update_file(now); + lease_update_dns(); +Index: src/helper.c +=================================================================== +--- src/helper.c (revision 696) ++++ src/helper.c (revision 821) +@@ -45,6 +45,7 @@ + #endif + unsigned char hwaddr[DHCP_CHADDR_MAX]; + char interface[IF_NAMESIZE]; ++ unsigned int uid; + }; + + static struct script_data *buf = NULL; +@@ -60,7 +61,7 @@ + then fork our process. */ + if (pipe(pipefd) == -1 || !fix_fd(pipefd[1]) || (pid = fork()) == -1) + { +- send_event(err_fd, EVENT_PIPE_ERR, errno); ++ send_event(err_fd, EVENT_PIPE_ERR, errno, 0); + _exit(0); + } + +@@ -87,13 +88,13 @@ + { + if (daemon->options & OPT_NO_FORK) + /* send error to daemon process if no-fork */ +- send_event(event_fd, EVENT_HUSER_ERR, errno); ++ send_event(event_fd, EVENT_HUSER_ERR, errno, 0); + else + { + /* kill daemon */ +- send_event(event_fd, EVENT_DIE, 0); ++ send_event(event_fd, EVENT_DIE, 0, 0); + /* return error */ +- send_event(err_fd, EVENT_HUSER_ERR, errno);; ++ send_event(err_fd, EVENT_HUSER_ERR, errno, 0); + } + _exit(0); + } +@@ -122,6 +123,8 @@ + action_str = "del"; + else if (data.action == ACTION_ADD) + action_str = "add"; ++ else if (data.action == ACTION_ACCESS) ++ action_str = "access"; + else if (data.action == ACTION_OLD || data.action == ACTION_OLD_HOSTNAME) + action_str = "old"; + else +@@ -178,9 +181,11 @@ + { + /* On error send event back to main process for logging */ + if (WIFSIGNALED(status)) +- send_event(event_fd, EVENT_KILLED, WTERMSIG(status)); +- else if (WIFEXITED(status) && WEXITSTATUS(status) != 0) +- send_event(event_fd, EVENT_EXITED, WEXITSTATUS(status)); ++ send_event(event_fd, EVENT_KILLED, WTERMSIG(status), data.uid); ++ else if (WIFEXITED(status)) ++ send_event(event_fd, EVENT_EXITED, WEXITSTATUS(status), data.uid); ++ else ++ send_event(event_fd, EVENT_EXITED, -1, data.uid); + break; + } + +@@ -263,7 +268,7 @@ + err = errno; + } + /* failed, send event so the main process logs the problem */ +- send_event(event_fd, EVENT_EXEC_ERR, err); ++ send_event(event_fd, EVENT_EXEC_ERR, err, data.uid); + _exit(0); + } + } +@@ -295,7 +300,7 @@ + } + + /* pack up lease data into a buffer */ +-void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t now) ++void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t now, unsigned int uid) + { + unsigned char *p; + size_t size; +@@ -332,6 +337,7 @@ + buf_size = size; + } + ++ buf->uid = uid; + buf->action = action; + buf->hwaddr_len = lease->hwaddr_len; + buf->hwaddr_type = lease->hwaddr_type; +@@ -393,12 +399,15 @@ + return bytes_in_buf == 0; + } + +-void helper_write(void) ++/* returns -1 if write failed for a reason, 1 if no data exist ++ * and 0 if everything was ok. ++ */ ++int helper_write(void) + { + ssize_t rc; + + if (bytes_in_buf == 0) +- return; ++ return 1; + + if ((rc = write(daemon->helperfd, buf, bytes_in_buf)) != -1) + { +@@ -409,9 +418,11 @@ + else + { + if (errno == EAGAIN || errno == EINTR) +- return; ++ return -1; + bytes_in_buf = 0; + } ++ ++ return 0; + } + + #endif +Index: src/rfc2131.c +=================================================================== +--- src/rfc2131.c (revision 696) ++++ src/rfc2131.c (revision 821) +@@ -100,8 +100,49 @@ + int clid_len, unsigned char *clid, int *len_out); + static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt); + ++static int check_access_script( int piperead, struct dhcp_lease *lease, struct dhcp_packet *mess, time_t now) ++{ ++#ifndef NO_FORK ++unsigned int uid; ++struct event_desc ev; ++int ret; ++struct dhcp_lease _lease; ++ ++ if (daemon->lease_change_command == NULL) return 0; /* ok */ ++ ++ if (!lease) { /* if host has not been seen before lease is NULL */ ++ memset(&_lease, 0, sizeof(_lease)); ++ lease = &_lease; ++ lease_set_hwaddr(lease, mess->chaddr, NULL, mess->hlen, mess->htype, 0); ++ } ++ ++ uid = rand16(); ++ queue_script(ACTION_ACCESS, lease, NULL, now, uid); ++ ++ /* send all data to helper process */ ++ do ++ { ++ helper_write(); ++ } while (helper_buf_empty() == 0); ++ ++ /* wait for our event */ ++ ret = 0; ++ do ++ { ++ ret = async_event( piperead, now, &ev, SCRIPT_TIMEOUT); ++ } ++ while(ev.priv != uid && ret >= 0); ++ ++ if (ret < 0 || ev.data != 0) /* timeout or error */ ++ { ++ return -1; ++ } ++ ++#endif ++ return 0; /* ok */ ++} + +-size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, ++size_t dhcp_reply(int piperead, struct dhcp_context *context, char *iface_name, int int_index, + size_t sz, time_t now, int unicast_dest, int *is_inform) + { + unsigned char *opt, *clid = NULL; +@@ -252,7 +293,7 @@ + mac->netid.next = netid; + netid = &mac->netid; + } +- ++ + /* Determine network for this packet. Our caller will have already linked all the + contexts which match the addresses of the receiving interface but if the + machine has an address already, or came via a relay, or we have a subnet selector, +@@ -329,7 +370,7 @@ + my_syslog(LOG_INFO, _("Available DHCP range: %s -- %s"), daemon->namebuff, inet_ntoa(context_tmp->end)); + } + } +- ++ + mess->op = BOOTREPLY; + + config = find_config(daemon->dhcp_conf, context, clid, clid_len, +@@ -418,7 +459,7 @@ + else + mess->yiaddr = lease->addr; + } +- ++ + if (!message && + !lease && + (!(lease = lease_allocate(mess->yiaddr)))) +@@ -641,7 +682,14 @@ + memcpy(req_options, option_ptr(opt, 0), option_len(opt)); + req_options[option_len(opt)] = OPTION_END; + } +- ++ ++ if (mess_type == DHCPREQUEST || mess_type == DHCPDISCOVER) ++ if (check_access_script(piperead, lease, mess, now) < 0) ++ { ++ my_syslog(LOG_INFO, _("Ignoring client due to access script")); ++ return 0; ++ } ++ + switch (mess_type) + { + case DHCPDECLINE: +Index: src/log.c +=================================================================== +--- src/log.c (revision 696) ++++ src/log.c (revision 821) +@@ -73,7 +73,7 @@ + + if (!log_reopen(daemon->log_file)) + { +- send_event(errfd, EVENT_LOG_ERR, errno); ++ send_event(errfd, EVENT_LOG_ERR, errno, 0); + _exit(0); + } + +Index: src/lease.c +=================================================================== +--- src/lease.c (revision 696) ++++ src/lease.c (revision 821) +@@ -511,7 +511,7 @@ + if (lease->old_hostname) + { + #ifndef NO_FORK +- queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now); ++ queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now, 0); + #endif + free(lease->old_hostname); + lease->old_hostname = NULL; +@@ -520,7 +520,7 @@ + else + { + #ifndef NO_FORK +- queue_script(ACTION_DEL, lease, lease->hostname, now); ++ queue_script(ACTION_DEL, lease, lease->hostname, now, 0); + #endif + old_leases = lease->next; + +@@ -540,7 +540,7 @@ + if (lease->old_hostname) + { + #ifndef NO_FORK +- queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now); ++ queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now, 0); + #endif + free(lease->old_hostname); + lease->old_hostname = NULL; +@@ -552,7 +552,7 @@ + (lease->aux_changed && (daemon->options & OPT_LEASE_RO))) + { + #ifndef NO_FORK +- queue_script(lease->new ? ACTION_ADD : ACTION_OLD, lease, lease->hostname, now); ++ queue_script(lease->new ? ACTION_ADD : ACTION_OLD, lease, lease->hostname, now, 0); + #endif + lease->new = lease->changed = lease->aux_changed = 0; + +Index: man/dnsmasq.8 +=================================================================== +--- man/dnsmasq.8 (revision 696) ++++ man/dnsmasq.8 (revision 821) +@@ -724,12 +724,15 @@ + .B \-6 --dhcp-script= + Whenever a new DHCP lease is created, or an old one destroyed, the + binary specified by this option is run. The arguments to the process +-are "add", "old" or "del", the MAC ++are "add", "old", "access" or "del", the MAC + address of the host (or ""), the IP address, and the hostname, + if known. "add" means a lease has been created, "del" means it has + been destroyed, "old" is a notification of an existing lease when + dnsmasq starts or a change to MAC address or hostname of an existing + lease (also, lease length or expiry and client-id, if leasefile-ro is set). ++The "access" keyword means that a request was just received and depending ++on the script exit status request for address will be granted, if exit status ++is zero or not if it is non-zero. + The process is run as root (assuming that dnsmasq was originally run as + root) even if dnsmasq is configured to change UID to an unprivileged user. + The environment is inherited from the invoker of dnsmasq, and if the diff --git a/dbus/dnsmasq.conf b/dbus/dnsmasq.conf index f048c00..82b1c76 100644 --- a/dbus/dnsmasq.conf +++ b/dbus/dnsmasq.conf @@ -5,12 +5,10 @@ - - diff --git a/dnsmasq.conf.example b/dnsmasq.conf.example index 1708742..b4e9d80 100644 --- a/dnsmasq.conf.example +++ b/dnsmasq.conf.example @@ -342,6 +342,22 @@ #dhcp-boot=net:#gpxe,undionly.kpxe #dhcp-boot=mybootimage +# Encapsulated options for Etherboot gPXE. All the options are +# encapsulated within option 175 +#dhcp-option=encap:175, 1, 5b # priority code +#dhcp-option=encap:175, 176, 1b # no-proxydhcp +#dhcp-option=encap:175, 177, string # bus-id +#dhcp-option=encap:175, 189, 1b # BIOS drive code +#dhcp-option=encap:175, 190, user # iSCSI username +#dhcp-option=encap:175, 191, pass # iSCSI password + +# Test for the architecture of a netboot client. PXE clients are +# supposed to send their architecture as option 93. (See RFC 4578) +#dhcp-match=peecees, option:client-arch, 0 #x86-32 +#dhcp-match=itanics, option:client-arch, 2 #IA64 +#dhcp-match=hammers, option:client-arch, 6 #x86-64 +#dhcp-match=mactels, option:client-arch, 7 #EFI x86-64 + # Enable dnsmasq's built-in TFTP server #enable-tftp @@ -409,7 +425,8 @@ #alias=1.2.3.4,5.6.7.8 # and this maps 1.2.3.x to 5.6.7.x #alias=1.2.3.0,5.6.7.0,255.255.255.0 - +# and this maps 192.168.0.10->192.168.0.40 to 10.0.0.10->10.0.0.40 +#alias=192.168.0.10-192.168.0.40,10.0.0.0,255.255.255.0 # Change these lines if you want dnsmasq to serve MX records. diff --git a/doc.html b/doc.html index d8b8fd9..7eefe34 100644 --- a/doc.html +++ b/doc.html @@ -89,11 +89,11 @@ Dnsmasq is part of the Debian distribution, it can be downloaded from here or installed using apt.

Links.

-There is an article in German on dnsmasq at http://www.linuxnetmag.com/de/issue7/m7dnsmasq1.html -and Damien Raude-Morvan has one in French at http://www.drazzib.com/docs-dnsmasq.html +Damien Raude-Morvan has an article in French at http://www.drazzib.com/docs-dnsmasq.html There is a good article about dnsmasq at http://www.enterprisenetworkingplanet.com/netos/article.php/3377351 +and another at http://www.linux.com/articles/149040 and Ilya Evseev has an article in Russian about dnsmasq to be found at http://ilya-evseev.narod.ru/articles/dnsmasq

License.

Dnsmasq is distributed under the GPL. See the file COPYING in the distribution diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 index a2f90a7..cd096e3 100644 --- a/man/dnsmasq.8 +++ b/man/dnsmasq.8 @@ -15,8 +15,8 @@ contents of /etc/hosts so that local hostnames which do not appear in the global DNS can be resolved and also answers DNS queries for DHCP configured hosts. .PP -The dnsmasq DHCP server supports static address assignments, multiple -networks, DHCP-relay and RFC3011 subnet specifiers. It automatically +The dnsmasq DHCP server supports static address assignments and multiple +networks. It automatically sends a sensible default set of DHCP options, and can be configured to send any desired set of DHCP options, including vendor-encapsulated options. It includes a secure, read-only, @@ -208,13 +208,17 @@ Bogus private reverse lookups. All reverse lookups for private IP ranges (ie 192 which are not found in /etc/hosts or the DHCP leases file are answered with "no such domain" rather than being forwarded upstream. .TP -.B \-V, --alias=,[,] +.B \-V, --alias=[]|[-],[,] Modify IPv4 addresses returned from upstream nameservers; old-ip is replaced by new-ip. If the optional mask is given then any address which matches the masked old-ip will be re-written. So, for instance .B --alias=1.2.3.0,6.7.8.0,255.255.255.0 will map 1.2.3.56 to 6.7.8.56 and 1.2.3.67 to 6.7.8.67. This is what -Cisco PIX routers call "DNS doctoring". +Cisco PIX routers call "DNS doctoring". If the old IP is given as +range, then only addresses in the range, rather than a whole subnet, +are re-written. So +.B --alias=192.168.0.10-192.168.0.40,10.0.0.0,255.255.255.0 +maps 192.168.0.10->192.168.0.40 to 10.0.0.10->10.0.0.40 .TP .B \-B, --bogus-nxdomain= Transform replies which contain the IP address given into "No such @@ -513,13 +517,15 @@ Token-Ring hardware address, since the ARP-address type for token ring is 6. As a special case, it is possible to include more than one -hardware address. This allows an IP address to be associated with +hardware address. eg: +.B --dhcp-host=11:22:33:44:55:66,12:34:56:78:90:12,192.168.0.2 +This allows an IP address to be associated with multiple hardware addresses, and gives dnsmasq permission to abandon a DHCP lease to one of the hardware addresses when another one asks for a lease. Beware that this is a dangerous thing to do, it will only work reliably if only one of the hardware addresses is active at any -time and there is no way for dnsmasq to enforce this. It is, however -useful, for instance to allocate a stable IP address to a laptop which +time and there is no way for dnsmasq to enforce this. It is, for instance, +useful to allocate a stable IP address to a laptop which has both wired and wireless interfaces. .TP .B --dhcp-hostsfile= @@ -543,7 +549,7 @@ have exactly the same effect as options containing the same information. /etc/ethers is re-read when dnsmasq receives SIGHUP. .TP -.B \-O, --dhcp-option=[,[,]][vendor:[],][|option:],[[,]] +.B \-O, --dhcp-option=[,[,]][encap:,][vendor:[],][|option:],[[,]] Specify different or extra options to DHCP clients. By default, dnsmasq sends some standard options to DHCP clients, the netmask and broadcast address are set to the same as the host running dnsmasq, and @@ -603,10 +609,18 @@ client. It is possible to omit the vendorclass completely; .B --dhcp-option=vendor:,1,0.0.0.0 in which case the encapsulated option is always sent. + +Options may be encapsulated within other options: for instance +.B --dhcp-option=encap:175, 190, "iscsi-client0" +will send option 175, within which is the option 190. If multiple +options are given which are encapsulated with the same option number +then they will be correctly combined into one encapsulated option. +encap: and vendor: are may not both be set in the same dhcp-option. + The address 0.0.0.0 is not treated specially in -encapsulated vendor class options. +encapsulated options. .TP -.B --dhcp-option-force=[,[,]][vendor:[],],[[,]] +.B --dhcp-option-force=[,[,]][encap:,][vendor:[],],[[,]] This works in exactly the same way as .B --dhcp-option except that the option will always be sent, even if the client does @@ -658,10 +672,22 @@ agent ID and one provided by a relay agent, the network-id tag is set. .B --dhcp-subscrid=, Map from RFC3993 subscriber-id relay agent options to network-id tags. .TP -.B --dhcp-match=,