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"),
|