Commit b0e7bbb7 authored by Dimitris Aragiorgis's avatar Dimitris Aragiorgis
Browse files

Merge branch 'develop'

parents 35bc4bd3 0f4a61eb
#!/usr/bin/env python
from scapy.all import *
import argparse
import sys
def parse_options():
parser = argparse.ArgumentParser()
parser.add_argument("-n", dest="num",
default=None, type=int,
help="Packet number to show. Show all if not given.")
parser.add_argument("pcapfile", type=str,
help="Pcap file generated with tcpdump -w")
return parser.parse_args()
def main():
opts = parse_options()
try:
paks = rdpcap(opts.pcapfile)
except IOError:
print "File does not exists"
return 1
except:
print "Not a pcap file"
return 1
if opts.num is not None:
try:
p = paks[opts.num]
p.show()
return 0
except IndexError:
print "Packet number exceeds total packets captured (%d)!" % len(paks)
return 1
paks.show()
return 0
if __name__ == "__main__":
sys.exit(main())
......@@ -53,6 +53,9 @@ from scapy.layers.inet6 import IPv6, ICMPv6ND_RA, ICMPv6ND_NA, \
ICMPv6NDOptPrefixInfo, \
ICMPv6NDOptRDNSS
from scapy.layers.dhcp import BOOTP, DHCP
from scapy.layers.dhcp6 import DHCP6_Reply, DHCP6OptDNSServers, \
DHCP6OptServerId, DHCP6OptClientId, \
DUID_LLT, DHCP6_InfoRequest
DEFAULT_CONFIG = "/etc/nfdhcpd/nfdhcpd.conf"
......@@ -91,6 +94,7 @@ enable_ipv6 = boolean(default=True)
ra_period = integer(min=1, max=4294967295)
rs_queue = integer(min=0, max=65535)
ns_queue = integer(min=0, max=65535)
dhcp_queue = integer(min=0, max=65535)
nameservers = ip_addr_list(family=6)
"""
......@@ -349,7 +353,7 @@ class Subnet(object):
class VMNetProxy(object): # pylint: disable=R0902
def __init__(self, data_path, dhcp_queue_num=None, # pylint: disable=R0913
rs_queue_num=None, ns_queue_num=None,
rs_queue_num=None, ns_queue_num=None, dhcpv6_queue_num=None,
dhcp_lease_lifetime=DEFAULT_LEASE_LIFETIME,
dhcp_lease_renewal=DEFAULT_LEASE_RENEWAL,
dhcp_domain='',
......@@ -405,6 +409,10 @@ class VMNetProxy(object): # pylint: disable=R0902
self._setup_nfqueue(ns_queue_num, AF_INET6, self.ns_response, 10)
self.ipv6_enabled = True
if dhcpv6_queue_num is not None:
self._setup_nfqueue(dhcpv6_queue_num, AF_INET6, self.dhcpv6_response, 10)
self.ipv6_enabled = True
def get_binding(self, ifindex, mac):
try:
if self.mac_indexed_clients:
......@@ -694,6 +702,68 @@ class VMNetProxy(object): # pylint: disable=R0902
logging.warn(" - Unkown error during DHCP response on %s (%s): %s",
binding.tap, binding.hostname, str(e))
def dhcpv6_response(self, arg1, arg2=None): # pylint: disable=W0613
logging.info(" * Processing pending DHCPv6 request")
# Workaround for supporting both squeezy's nfqueue-bindings-python
# and wheezy's python-nfqueue because for some reason the function's
# signature has changed and has broken compatibility
# See bug http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=718894
if arg2:
payload = arg2
else:
payload = arg1
pkt = IPv6(payload.get_data())
indev = get_indev(payload)
#TODO: figure out how to find the src mac
mac = None
binding = self.get_binding(indev, mac)
if binding is None:
# We don't know anything about this interface, so accept the packet
# and return
logging.debug(" - Ignoring dhcpv6 request for mac %s", mac)
# We don't know what to do with this packet, so let the kernel
# handle it
payload.set_verdict(nfqueue.NF_ACCEPT)
return
# Signal the kernel that it shouldn't further process the packet
payload.set_verdict(nfqueue.NF_DROP)
subnet = binding.net6
indevmac = self.get_iface_hw_addr(binding.indev)
ifll = subnet.make_ll64(indevmac)
if ifll is None:
return
ofll = subnet.make_ll64(binding.mac)
if ofll is None:
return
logging.info(" - Generating DHCPv6 response for host %s (mac %s) on tap %s",
binding.hostname, binding.mac, binding.tap)
resp = Ether(src=indevmac, dst=binding.mac)/\
IPv6(tc=192, src=str(ifll), dst=str(ofll))/\
UDP(sport=pkt.dport, dport=pkt.sport)/\
DHCP6_Reply(trid=pkt[DHCP6_InfoRequest].trid)/\
DHCP6OptClientId(duid=pkt[DHCP6OptClientId].duid)/\
DHCP6OptServerId(duid=DUID_LLT(lladdr=indevmac, timeval=time.time()))/\
DHCP6OptDNSServers(dnsservers=self.ipv6_nameservers,
optlen=16 * len(self.ipv6_nameservers))
try:
binding.sendp(resp)
except socket.error, e:
logging.warn(" - DHCPv6 on %s (%s) failed: %s",
binding.tap, binding.hostname, str(e))
except Exception, e:
logging.warn(" - Unkown error during DHCPv6 on %s (%s): %s",
binding.tap, binding.hostname, str(e))
def rs_response(self, arg1, arg2=None): # pylint: disable=W0613
""" Generate a reply to a BOOTP/DHCP request
......@@ -750,7 +820,7 @@ class VMNetProxy(object): # pylint: disable=R0902
binding.hostname, mac, binding.tap)
resp = Ether(src=indevmac)/\
IPv6(src=str(ifll))/ICMPv6ND_RA(routerlifetime=14400)/\
IPv6(src=str(ifll))/ICMPv6ND_RA(O=1, routerlifetime=14400)/\
ICMPv6NDOptPrefixInfo(prefix=str(subnet.prefix),
prefixlen=subnet.prefixlen)
......@@ -1111,6 +1181,7 @@ if __name__ == "__main__":
if config["ipv6"].as_bool("enable_ipv6"):
proxy_opts.update({
"dhcpv6_queue_num": config["ipv6"].as_int("dhcp_queue"),
"rs_queue_num": config["ipv6"].as_int("rs_queue"),
"ns_queue_num": config["ipv6"].as_int("ns_queue"),
"ra_period": config["ipv6"].as_int("ra_period"),
......
......@@ -24,5 +24,6 @@ enable_ipv6 = yes
ra_period = 300 # seconds
rs_queue = 43 # NFQUEUE number to listen on for router solicitations
ns_queue = 44 # NFQUEUE number to listen on for neighbor solicitations
dhcp_queue = 45 # NFQUEUE number to listen on for neighbor solicitations
# IPv6 nameservers to send using the ICMPv6 RA RDNSS option (RFC 5006)
nameservers = 2001:db8:100::1, 2001:db8:200::2
......@@ -3,6 +3,7 @@ domain ip {
chain PREROUTING {
interface tap+ proto udp dport 67 NFQUEUE queue-num 42;
interface prv+ proto udp dport 67 NFQUEUE queue-num 42;
interface br+ proto udp dport 67 NFQUEUE queue-num 42;
}
}
}
......@@ -12,6 +13,7 @@ domain ip6 {
chain PREROUTING {
interface tap+ proto icmpv6 icmpv6-type router-solicitation NFQUEUE queue-num 43;
interface tap+ proto icmpv6 icmpv6-type neighbour-solicitation NFQUEUE queue-num 44;
interface tap+ proto udp dport 547 NFQUEUE queue-num 45;
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment