Revision 06e6d9bc nfdhcpd
b/nfdhcpd | ||
---|---|---|
53 | 53 |
ICMPv6NDOptPrefixInfo, \ |
54 | 54 |
ICMPv6NDOptRDNSS |
55 | 55 |
from scapy.layers.dhcp import BOOTP, DHCP |
56 |
from scapy.layers.dhcp6 import DHCP6_Reply, DHCP6OptDNSServers, \ |
|
57 |
DHCP6OptServerId, DHCP6OptClientId, \ |
|
58 |
DUID_LLT, DHCP6_InfoRequest |
|
56 | 59 |
|
57 | 60 |
|
58 | 61 |
DEFAULT_CONFIG = "/etc/nfdhcpd/nfdhcpd.conf" |
... | ... | |
91 | 94 |
ra_period = integer(min=1, max=4294967295) |
92 | 95 |
rs_queue = integer(min=0, max=65535) |
93 | 96 |
ns_queue = integer(min=0, max=65535) |
97 |
dhcp_queue = integer(min=0, max=65535) |
|
94 | 98 |
nameservers = ip_addr_list(family=6) |
95 | 99 |
""" |
96 | 100 |
|
... | ... | |
349 | 353 |
|
350 | 354 |
class VMNetProxy(object): # pylint: disable=R0902 |
351 | 355 |
def __init__(self, data_path, dhcp_queue_num=None, # pylint: disable=R0913 |
352 |
rs_queue_num=None, ns_queue_num=None, |
|
356 |
rs_queue_num=None, ns_queue_num=None, dhcpv6_queue_num=None,
|
|
353 | 357 |
dhcp_lease_lifetime=DEFAULT_LEASE_LIFETIME, |
354 | 358 |
dhcp_lease_renewal=DEFAULT_LEASE_RENEWAL, |
355 | 359 |
dhcp_domain='', |
... | ... | |
405 | 409 |
self._setup_nfqueue(ns_queue_num, AF_INET6, self.ns_response, 10) |
406 | 410 |
self.ipv6_enabled = True |
407 | 411 |
|
412 |
if dhcpv6_queue_num is not None: |
|
413 |
self._setup_nfqueue(dhcpv6_queue_num, AF_INET6, self.dhcpv6_response, 10) |
|
414 |
self.ipv6_enabled = True |
|
415 |
|
|
408 | 416 |
def get_binding(self, ifindex, mac): |
409 | 417 |
try: |
410 | 418 |
if self.mac_indexed_clients: |
... | ... | |
694 | 702 |
logging.warn(" - Unkown error during DHCP response on %s (%s): %s", |
695 | 703 |
binding.tap, binding.hostname, str(e)) |
696 | 704 |
|
705 |
def dhcpv6_response(self, arg1, arg2=None): # pylint: disable=W0613 |
|
706 |
|
|
707 |
logging.info(" * Processing pending DHCPv6 request") |
|
708 |
# Workaround for supporting both squeezy's nfqueue-bindings-python |
|
709 |
# and wheezy's python-nfqueue because for some reason the function's |
|
710 |
# signature has changed and has broken compatibility |
|
711 |
# See bug http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=718894 |
|
712 |
if arg2: |
|
713 |
payload = arg2 |
|
714 |
else: |
|
715 |
payload = arg1 |
|
716 |
pkt = IPv6(payload.get_data()) |
|
717 |
indev = get_indev(payload) |
|
718 |
|
|
719 |
#TODO: figure out how to find the src mac |
|
720 |
mac = None |
|
721 |
binding = self.get_binding(indev, mac) |
|
722 |
if binding is None: |
|
723 |
# We don't know anything about this interface, so accept the packet |
|
724 |
# and return |
|
725 |
logging.debug(" - Ignoring dhcpv6 request for mac %s", mac) |
|
726 |
# We don't know what to do with this packet, so let the kernel |
|
727 |
# handle it |
|
728 |
payload.set_verdict(nfqueue.NF_ACCEPT) |
|
729 |
return |
|
730 |
|
|
731 |
# Signal the kernel that it shouldn't further process the packet |
|
732 |
payload.set_verdict(nfqueue.NF_DROP) |
|
733 |
|
|
734 |
subnet = binding.net6 |
|
735 |
|
|
736 |
indevmac = self.get_iface_hw_addr(binding.indev) |
|
737 |
ifll = subnet.make_ll64(indevmac) |
|
738 |
if ifll is None: |
|
739 |
return |
|
740 |
|
|
741 |
ofll = subnet.make_ll64(binding.mac) |
|
742 |
if ofll is None: |
|
743 |
return |
|
744 |
|
|
745 |
logging.info(" - Generating DHCPv6 response for host %s (mac %s) on tap %s", |
|
746 |
binding.hostname, binding.mac, binding.tap) |
|
747 |
|
|
748 |
resp = Ether(src=indevmac, dst=binding.mac)/\ |
|
749 |
IPv6(tc=192, src=str(ifll), dst=str(ofll))/\ |
|
750 |
UDP(sport=pkt.dport, dport=pkt.sport)/\ |
|
751 |
DHCP6_Reply(trid=pkt[DHCP6_InfoRequest].trid)/\ |
|
752 |
DHCP6OptClientId(duid=pkt[DHCP6OptClientId].duid)/\ |
|
753 |
DHCP6OptServerId(duid=DUID_LLT(lladdr=indevmac, timeval=time.time()))/\ |
|
754 |
DHCP6OptDNSServers(dnsservers=self.ipv6_nameservers, |
|
755 |
optlen=16 * len(self.ipv6_nameservers)) |
|
756 |
|
|
757 |
try: |
|
758 |
binding.sendp(resp) |
|
759 |
except socket.error, e: |
|
760 |
logging.warn(" - DHCPv6 on %s (%s) failed: %s", |
|
761 |
binding.tap, binding.hostname, str(e)) |
|
762 |
except Exception, e: |
|
763 |
logging.warn(" - Unkown error during DHCPv6 on %s (%s): %s", |
|
764 |
binding.tap, binding.hostname, str(e)) |
|
765 |
|
|
766 |
|
|
697 | 767 |
def rs_response(self, arg1, arg2=None): # pylint: disable=W0613 |
698 | 768 |
""" Generate a reply to a BOOTP/DHCP request |
699 | 769 |
|
... | ... | |
750 | 820 |
binding.hostname, mac, binding.tap) |
751 | 821 |
|
752 | 822 |
resp = Ether(src=indevmac)/\ |
753 |
IPv6(src=str(ifll))/ICMPv6ND_RA(routerlifetime=14400)/\ |
|
823 |
IPv6(src=str(ifll))/ICMPv6ND_RA(O=1, routerlifetime=14400)/\
|
|
754 | 824 |
ICMPv6NDOptPrefixInfo(prefix=str(subnet.prefix), |
755 | 825 |
prefixlen=subnet.prefixlen) |
756 | 826 |
|
... | ... | |
1111 | 1181 |
|
1112 | 1182 |
if config["ipv6"].as_bool("enable_ipv6"): |
1113 | 1183 |
proxy_opts.update({ |
1184 |
"dhcpv6_queue_num": config["ipv6"].as_int("dhcp_queue"), |
|
1114 | 1185 |
"rs_queue_num": config["ipv6"].as_int("rs_queue"), |
1115 | 1186 |
"ns_queue_num": config["ipv6"].as_int("ns_queue"), |
1116 | 1187 |
"ra_period": config["ipv6"].as_int("ra_period"), |
Also available in: Unified diff