Adding DHCP test cases
diff --git a/src/test/dhcp/dhcpTest.py b/src/test/dhcp/dhcpTest.py
new file mode 100644
index 0000000..52788fc
--- /dev/null
+++ b/src/test/dhcp/dhcpTest.py
@@ -0,0 +1,84 @@
+import unittest
+from nose.tools import *
+from nose.twistedtools import reactor, deferred
+from twisted.internet import defer
+from scapy.all import *
+import time
+import os, sys
+import copy
+import json
+CORD_TEST_UTILS = 'utils'
+test_root = os.getenv('CORD_TEST_ROOT') or './'
+sys.path.append(test_root + CORD_TEST_UTILS)
+from DHCP import DHCPTest
+
+log.setLevel('INFO')
+
+class dhcp_exchange(unittest.TestCase):
+
+    dhcp_server_config = {
+        "ip": "10.1.11.50",
+        "mac": "ca:fe:ca:fe:ca:fe",
+        "subnet": "255.255.252.0",
+        "broadcast": "10.1.11.255",
+        "router": "10.1.8.1",
+        "domain": "8.8.8.8",
+        "ttl": "63",
+        "lease": "300",
+        "renew": "150",
+        "rebind": "200",
+        "delay": "2",
+        "timeout": "150",
+        "startip": "10.1.11.51",
+        "endip": "10.1.11.100"
+    }
+    
+    def onos_load_config(self, config):
+          json_dict = json.JSONEncoder().encode(config)
+          with tempfile.NamedTemporaryFile(delete=False) as temp:
+                temp.write(json_dict)
+                temp.flush()
+                temp.close()
+          log.info('Loading DHCP config in file %s to ONOS.' %temp.name)
+          os.system('./dhcp_config_load.sh %s' %temp.name)
+          os.unlink(temp.name)
+          time.sleep(2)
+
+    def onos_dhcp_table_load(self, config = None):
+          dhcp_dict = {'apps' : { 'org.onosproject.dhcp' : { 'dhcp' : copy.copy(self.dhcp_server_config) } } }
+          dhcp_config = dhcp_dict['apps']['org.onosproject.dhcp']['dhcp']
+          if config:
+              for k in config.keys():
+                  if dhcp_config.has_key(k):
+                      dhcp_config[k] = config[k]
+          self.onos_load_config(dhcp_dict)
+
+    def send_recv(self, update_seed = False):
+        cip, sip = self.dhcp.send(update_seed = update_seed)
+        assert_not_equal(cip, None)
+        assert_not_equal(sip, None)
+        log.info('Got dhcp client IP %s from server %s for mac %s' %
+                 (cip, sip, self.dhcp.get_mac(cip)[0]))
+        return cip,sip
+
+    def test_dhcp_1request(self, iface = 'veth0'):
+        config = {'startip':'10.10.10.20', 'endip':'10.10.10.100', 
+                  'ip':'10.10.10.2', 'mac': "ca:fe:ca:fe:cb:fe",
+                  'subnet': '255.255.255.0', 'broadcast':'10.10.10.255', 'router':'10.10.10.1'}
+        self.onos_dhcp_table_load(config)
+        self.dhcp = DHCPTest(seed_ip = '10.10.10.1', iface = iface)
+        self.send_recv()
+
+    def test_dhcp_Nrequest(self, iface = 'veth0'):
+        config = {'startip':'192.168.1.20', 'endip':'192.168.1.100', 
+                  'ip':'192.168.1.2', 'mac': "ca:fe:ca:fe:cc:fe",
+                  'subnet': '255.255.255.0', 'broadcast':'192.168.1.255', 'router': '192.168.1.1'}
+        self.onos_dhcp_table_load(config)
+        self.dhcp = DHCPTest(seed_ip = '192.169.1.1', iface = iface)
+        ip_map = {}
+        for i in range(10):
+            cip, sip = self.send_recv(update_seed = True)
+            if ip_map.has_key(cip):
+                log.info('IP %s given out multiple times' %cip)
+                assert_equal(False, ip_map.has_key(cip))
+            ip_map[cip] = sip
diff --git a/src/test/dhcp/dhcp_config_load.sh b/src/test/dhcp/dhcp_config_load.sh
new file mode 100755
index 0000000..cbed6d8
--- /dev/null
+++ b/src/test/dhcp/dhcp_config_load.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+json="$1"
+controller="$2"
+if [ x"$json" = "x" ]; then
+  echo "No json file specified. Exiting"
+  exit 127
+fi
+if [ x"$controller" = "x" ]; then
+    controller=`ovs-vsctl show | egrep "Controller|tcp" | grep -v ptcp | sed 's,Controller,,g' | sed 's,\",,g' | tr -s ' '|awk -F":" '{print $2}'`
+    echo "Controller at $controller"
+fi
+echo "Loading dhcp config json file $json to controller at $controller"
+curl --fail -sSL --user karaf:karaf \
+    -X POST -H 'Content-Type:application/json' \
+    http://$controller:8181/onos/v1/network/configuration/ -d@$json
+
+
diff --git a/src/test/utils/DHCP.py b/src/test/utils/DHCP.py
new file mode 100644
index 0000000..cafa95e
--- /dev/null
+++ b/src/test/utils/DHCP.py
@@ -0,0 +1,110 @@
+from scapy.all import *
+
+conf.verb = 0 # Disable Scapy verbosity
+conf.checkIPaddr = 0 # Don't check response packets for matching destination IPs
+
+class DHCPTest:
+
+    def __init__(self, seed_ip = '192.168.1.1', iface = 'veth0'):
+        self.seed_ip = seed_ip
+        self.seed_mac = self.ipToMac(self.seed_ip)
+        self.iface = iface
+        self.mac_map = {}
+        self.mac_inverse_map = {}
+
+    def is_mcast(self, ip):
+        mcast_octet = (atol(ip) >> 24) & 0xff
+        return True if mcast_octet >= 224 and mcast_octet <= 239 else False
+
+    def send(self, mac = None, update_seed = False):
+        '''Send a DHCP discover/offer'''
+
+        if mac is None:
+            mac = self.seed_mac
+            if update_seed:
+                self.seed_ip = self.incIP(self.seed_ip)
+                self.seed_mac = self.ipToMac(self.seed_ip)
+                mac = self.seed_mac
+                
+        chmac = self.macToChaddr(mac)
+        L2 = Ether(dst="ff:ff:ff:ff:ff:ff", src=mac)
+        L3 = IP(src="0.0.0.0", dst="255.255.255.255")
+        L4 = UDP(sport=68, dport=67)
+        L5 = BOOTP(chaddr=chmac)
+        L6 = DHCP(options=[("message-type","discover"),"end"])
+        resp = srp1(L2/L3/L4/L5/L6, filter="udp and port 68", timeout=5, iface=self.iface)
+        try:
+            srcIP = resp.yiaddr
+            serverIP = resp.siaddr
+        except AttributeError:
+            print("Failed to acquire IP via DHCP for %s on interface %s" %(mac, self.iface))
+            return (None, None)
+
+        for x in resp.lastlayer().options:
+            if(x == 'end'):
+                break
+            op,val = x
+            if(op == "subnet_mask"):
+                subnet_mask = val
+            elif(op == 'server_id'):
+                server_id = val
+            
+        L5 = BOOTP(chaddr=chmac, yiaddr=srcIP)
+        L6 = DHCP(options=[("message-type","request"), ("server_id",server_id), 
+                           ("subnet_mask",subnet_mask), ("requested_addr",srcIP), "end"])
+        srp1(L2/L3/L4/L5/L6, filter="udp and port 68", timeout=5, iface=self.iface)
+        self.mac_map[mac] = (srcIP, serverIP)
+        self.mac_inverse_map[srcIP] = (mac, serverIP)
+        return (srcIP, serverIP)
+
+    def send_next(self):
+        '''Send next dhcp discover/request with updated mac'''
+
+        return self.send(update_seed = True)
+
+    def macToChaddr(self, mac):
+        rv = []
+        mac = mac.split(":")
+        for x in mac:
+            rv.append(chr(int(x, 16)))
+        return reduce(lambda x,y: x + y, rv)
+
+    def get_ip(self, mac):
+        if self.mac_map.has_key(mac):
+            return self.mac_map[mac]
+        return (None, None)
+
+    def get_mac(self, ip):
+        if self.mac_inverse_map.has_key(ip):
+            return self.mac_inverse_map[ip]
+        return (None, None)
+
+    def ipToMac(self, ip):
+        '''Generate a mac from a ip'''
+
+        mcast = self.is_mcast(ip)
+        mac = "01:00:5e" if mcast == True else "00:00:00"
+        octets = ip.split(".")
+        for x in range(1,4):
+            num = str(hex(int(octets[x])))
+            num =  num.split("x")[1]
+            if len(num) < 2:
+                num = "0" + str(num)
+            mac += ":" + num
+        return mac
+
+    def incIP(self, ip, n=1):
+        '''Increment an IP'''
+
+        if n < 1: 
+            return ip
+        o = ip.split(".")
+        for ii in range(3,-1,-1):
+            if int(o[ii]) < 255:
+                o[ii] = str(int(o[ii]) + 1)
+                break
+            else: 
+                o[ii] = str(0)
+
+        n -= 1
+        return self.incIP(".".join(o), n)
diff --git a/src/test/utils/EapPAP.py b/src/test/utils/EapPAP.py
index c936dc3..a40ae9d 100644
--- a/src/test/utils/EapPAP.py
+++ b/src/test/utils/EapPAP.py
@@ -65,20 +65,21 @@
         self.nextEvent = self.PAPEventTable.EVT_EAP_PAP_USER_REQ
 
     def _eapPAPUserReq(self):
-        print 'Inside Challenge'
+        print 'UserReq Inside Challenge'
         p = self.eapol_recv()
         code, pkt_id, eaplen = unpack("!BBH", p[0:4])
         print "Code %d, id %d, len %d" %(code, pkt_id, eaplen)
         assert_equal(code, EAP_REQUEST)
         reqtype = unpack("!B", p[4:5])[0]
         reqdata = p[5:4+eaplen]
-        assert_equal(reqtype, EAP_TYPE_MD5)
+        assert_equal(reqtype, EAP_TYPE_TLS)
         print "<====== Send EAP Response with Password = %s ================>" % PAP_PASSWD 
         self.eapol_id_req(pkt_id, PAP_PASSWD)
-        self.nextEvent = self.PAPEventTable.EVT_EAP_PAP_PASSWD_REQ
+        #self.nextEvent = self.PAPEventTable.EVT_EAP_PAP_PASSWD_REQ
+        self.nextEvent = self.PAPEventTable.EVT_EAP_PAP_DONE
  
     def _eapPAPPassReq(self):
-        print 'Inside Challenge'
+        print 'PassReq Inside Challenge'
         p = self.eapol_recv()
         code, pkt_id, eaplen = unpack("!BBH", p[0:4])
         print "Code %d, id %d, len %d" %(code, pkt_id, eaplen)