diff options
author | Simon Kelley <simon@thekelleys.org.uk> | 2012-02-14 20:55:25 +0000 |
---|---|---|
committer | Simon Kelley <simon@thekelleys.org.uk> | 2012-02-14 20:55:25 +0000 |
commit | 0793380b4038e5cf4c0ebaac27c0dda8cd0e232c (patch) | |
tree | bd87013aa2c9bba67357afd38c36c39cb051cdad | |
parent | 1adadf585d993199678d8f29be7b9abafd816800 (diff) | |
download | dnsmasq-2.60test11.tar.gz |
Implement dhcp-ignore-names and DNSMASQ_RELAY_ADDRESS for IPv6v2.60test11
Build DHCPv6 by default.
-rw-r--r-- | man/dnsmasq.8 | 2 | ||||
-rw-r--r-- | src/config.h | 2 | ||||
-rw-r--r-- | src/dhcp6.c | 8 | ||||
-rw-r--r-- | src/dnsmasq.h | 1 | ||||
-rw-r--r-- | src/helper.c | 3 | ||||
-rw-r--r-- | src/lease.c | 26 | ||||
-rw-r--r-- | src/rfc3315.c | 24 |
7 files changed, 58 insertions, 8 deletions
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 index 00f9bd8..39b2251 100644 --- a/man/dnsmasq.8 +++ b/man/dnsmasq.8 @@ -820,7 +820,7 @@ agent ID and one provided by a relay agent, the tag is set. (IPv4 and IPv6) Map from RFC3993 subscriber-id relay agent options to tags. .TP .B --dhcp-proxy[=<ip addr>]...... -A normal DHCP relay agent is only used to forward the initial parts of +(IPv4 only) A normal DHCP relay agent is only used to forward the initial parts of a DHCP interaction to the DHCP server. Once a client is configured, it communicates directly with the server. This is undesirable if the relay agent is addding extra information to the DHCP packets, such as diff --git a/src/config.h b/src/config.h index ecf1c42..63e7488 100644 --- a/src/config.h +++ b/src/config.h @@ -116,7 +116,7 @@ RESOLVFILE has no library dependencies other than libc */ #define HAVE_DHCP -/* #define HAVE_DHCP6 */ +#define HAVE_DHCP6 #define HAVE_TFTP #define HAVE_SCRIPT /* #define HAVE_LUASCRIPT */ diff --git a/src/dhcp6.c b/src/dhcp6.c index c8fe2ef..5736f21 100644 --- a/src/dhcp6.c +++ b/src/dhcp6.c @@ -292,8 +292,12 @@ int address6_allocate(struct dhcp_context *context, unsigned char *clid, int cl else if (!match_netid(c->filter, netids, pass)) continue; else - { - start = addr6part(&c->start6) + ((j + c->addr_epoch + serial) % (1 + addr6part(&c->end6) - addr6part(&c->start6))); + { + if (option_bool(OPT_CONSEC_ADDR)) + /* seed is largest extant lease addr in this context */ + start = lease_find_max_addr6(c) + serial; + else + start = addr6part(&c->start6) + ((j + c->addr_epoch + serial) % (1 + addr6part(&c->end6) - addr6part(&c->start6))); /* iterate until we find a free address. */ addr = start; diff --git a/src/dnsmasq.h b/src/dnsmasq.h index 5ed0001..b175092 100644 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -928,6 +928,7 @@ 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); struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 addr); +u64 lease_find_max_addr6(struct dhcp_context *context); #endif void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr, unsigned char *clid, int hw_len, int hw_type, int clid_len); diff --git a/src/helper.c b/src/helper.c index 4e92d25..fd7d949 100644 --- a/src/helper.c +++ b/src/helper.c @@ -490,6 +490,9 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd) } buf = grab_extradata(buf, end, "DNSMASQ_TAGS", &err); + + if (is6) + buf = grab_extradata(buf, end, "DNSMASQ_RELAY_ADDRESS", &err); for (i = 0; buf; i++) { diff --git a/src/lease.c b/src/lease.c index 4fdf226..b2236c0 100644 --- a/src/lease.c +++ b/src/lease.c @@ -493,7 +493,31 @@ struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 add } return NULL; -} +} + +/* Find largest assigned address in context */ +u64 lease_find_max_addr6(struct dhcp_context *context) +{ + struct dhcp_lease *lease; + u64 addr = addr6part(&context->start6); + + if (!(context->flags & (CONTEXT_STATIC | CONTEXT_PROXY))) + for (lease = leases; lease; lease = lease->next) + { +#ifdef HAVE_DHCP6 + if (!(lease->flags & (LEASE_TA | LEASE_NA))) + continue; +#endif + if (is_same_net6((struct in6_addr *)lease->hwaddr, &context->start6, 64) && + addr6part((struct in6_addr *)lease->hwaddr) > addr6part(&context->start6) && + addr6part((struct in6_addr *)lease->hwaddr) <= addr6part(&context->end6) && + addr6part((struct in6_addr *)lease->hwaddr) > addr) + addr = addr6part((struct in6_addr *)lease->hwaddr); + } + + return addr; +} + #endif /* Find largest assigned address in context */ diff --git a/src/rfc3315.c b/src/rfc3315.c index 9cfcf84..22d5e45 100644 --- a/src/rfc3315.c +++ b/src/rfc3315.c @@ -32,7 +32,7 @@ static void put_opt6_string(char *s); static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **relay_tagsp, struct dhcp_context *context, int interface, char *iface_name, void *inbuff, size_t sz, int is_unicast, time_t now); -static int dhcp6_no_relay(int msg_type, struct dhcp_netid *tags, struct dhcp_context *context, +static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dhcp_netid *tags, struct dhcp_context *context, int interface, char *iface_name, void *inbuff, size_t sz, int is_unicast, time_t now); static void log6_packet(char *type, unsigned char *clid, int clid_len, struct in6_addr *addr, int xid, char *iface, char *string); @@ -114,7 +114,7 @@ static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid ** return 0; } - return dhcp6_no_relay(msg_type, *relay_tagsp, context, interface, iface_name, inbuff, sz, is_unicast, now); + return dhcp6_no_relay(msg_type, link_address, *relay_tagsp, context, interface, iface_name, inbuff, sz, is_unicast, now); } /* must have at least msg_type+hopcount+link_address+peer_address+minimal size option @@ -170,7 +170,7 @@ static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid ** return 1; } -static int dhcp6_no_relay(int msg_type, struct dhcp_netid *tags, struct dhcp_context *context, +static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dhcp_netid *tags, struct dhcp_context *context, int interface, char *iface_name, void *inbuff, size_t sz, int is_unicast, time_t now) { void *packet_options = inbuff + 4; @@ -670,6 +670,11 @@ static int dhcp6_no_relay(int msg_type, struct dhcp_netid *tags, struct dhcp_con lease_add_extradata(lease, (unsigned char *)n->net, strlen(n->net), n->next ? ' ' : 0); } } + + if (link_address) + inet_ntop(AF_INET6, link_address, daemon->addrbuff, ADDRSTRLEN); + + lease_add_extradata(lease, (unsigned char *)daemon->addrbuff, link_address ? strlen(daemon->addrbuff) : 0, 0); if ((class_opt = opt6_find(packet_options, end, OPTION6_USER_CLASS, 2))) { @@ -1206,6 +1211,19 @@ static int dhcp6_no_relay(int msg_type, struct dhcp_netid *tags, struct dhcp_con } } } + + + /* if all the netids in the ignore_name list are present, ignore client-supplied name */ + if (!hostname_auth) + { + struct dhcp_netid_list *id_list; + + for (id_list = daemon->dhcp_ignore_names; id_list; id_list = id_list->next) + if ((!id_list->list) || match_netid(id_list->list, tagif, 0)) + break; + if (id_list) + hostname = NULL; + } if (hostname) { |