Added more test cases for IGMP and DHCP
diff --git a/src/test/dhcp/dhcpTest.py b/src/test/dhcp/dhcpTest.py
index b33a585..76416de 100644
--- a/src/test/dhcp/dhcpTest.py
+++ b/src/test/dhcp/dhcpTest.py
@@ -162,3 +162,93 @@
         cip, sip = self.send_recv(update_seed = True, validate = False)
         assert_equal(cip, None)
         assert_equal(sip, None)
+
+
+    def test_dhcp_same_client_multiple_discover(self, iface = 'veth0'):
+	''' DHCP Client sending multiple discover . '''
+	config = {'startip':'10.10.10.20', 'endip':'10.10.10.69', 
+                 'ip':'10.10.10.2', 'mac': "ca:fe:ca:fe:ca: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)
+	cip, sip, mac = self.dhcp.only_discover()
+	log.info('Got dhcp client IP %s from server %s for mac %s . Not going to send DHCPREQUEST.' %  
+		  (cip, sip, mac) )
+	log.info('Triggering DHCP discover again.')
+	new_cip, new_sip, new_mac = self.dhcp.only_discover()
+	if cip == new_cip:
+		log.info('Got same ip for 2nd DHCP discover for client IP %s from server %s for mac %s. Triggering DHCP Request. '
+			  % (new_cip, new_sip, new_mac) )
+	elif cip != new_cip:
+		log.info('Ip after 1st discover %s' %cip)
+                log.info('Map after 2nd discover %s' %new_cip)
+		assert_equal(cip, new_cip)
+
+
+    def test_dhcp_same_client_multiple_request(self, iface = 'veth0'):
+	''' DHCP Client sending multiple repeat DHCP requests. '''
+	config = {'startip':'10.10.10.20', 'endip':'10.10.10.69', 
+                 'ip':'10.10.10.2', 'mac': "ca:fe:ca:fe:ca: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)
+	log.info('Sending DHCP discover and DHCP request.')
+	cip, sip = self.send_recv()
+	mac = self.dhcp.get_mac(cip)[0]
+	log.info("Sending DHCP request again.")
+	new_cip, new_sip = self.dhcp.only_request(cip, mac)
+	if (new_cip,new_sip) == (cip,sip):
+		
+		log.info('Got same ip for 2nd DHCP Request for client IP %s from server %s for mac %s.'
+			  % (new_cip, new_sip, mac) )
+	elif (new_cip,new_sip):
+		
+		log.info('No DHCP ACK')
+		assert_equal(new_cip, None)
+		assert_equal(new_sip, None)
+	else:
+		print "Something went wrong."	
+    
+    def test_dhcp_client_desired_address(self, iface = 'veth0'):
+	'''DHCP Client asking for desired IP address.'''
+	config = {'startip':'20.20.20.30', 'endip':'20.20.20.69', 
+                 'ip':'20.20.20.2', 'mac': "ca:fe:ca:fe:ca:fe",
+                 'subnet': '255.255.255.0', 'broadcast':'20.20.20.255', 'router':'20.20.20.1'}
+        self.onos_dhcp_table_load(config)
+        self.dhcp = DHCPTest(seed_ip = '20.20.20.31', iface = iface)
+	cip, sip, mac = self.dhcp.only_discover(desired = True)
+	log.info('Got dhcp client IP %s from server %s for mac %s .' %  
+		  (cip, sip, mac) )
+	if cip == self.dhcp.seed_ip:
+		log.info('Got dhcp client IP %s from server %s for mac %s as desired .' %  
+		  (cip, sip, mac) )
+	elif cip != self.dhcp.seed_ip:
+		log.info('Got dhcp client IP %s from server %s for mac %s .' %  
+		  (cip, sip, mac) )
+		log.info('The desired ip was: %s .' % self.dhcp.seed_ip)
+		assert_equal(cip, self.dhcp.seed_ip)
+		
+		
+    def test_dhcp_client_desired_address_out_of_pool(self, iface = 'veth0'):
+	'''DHCP Client asking for desired IP address from out of pool.'''
+	config = {'startip':'20.20.20.30', 'endip':'20.20.20.69', 
+                 'ip':'20.20.20.2', 'mac': "ca:fe:ca:fe:ca:fe",
+                 'subnet': '255.255.255.0', 'broadcast':'20.20.20.255', 'router':'20.20.20.1'}
+        self.onos_dhcp_table_load(config)
+        self.dhcp = DHCPTest(seed_ip = '20.20.20.35', iface = iface)
+	cip, sip, mac = self.dhcp.only_discover(desired = True)
+	log.info('Got dhcp client IP %s from server %s for mac %s .' %  
+		  (cip, sip, mac) )
+	if cip == self.dhcp.seed_ip:
+		log.info('Got dhcp client IP %s from server %s for mac %s as desired .' %  
+		  (cip, sip, mac) )
+	elif cip != self.dhcp.seed_ip:
+		log.info('Got dhcp client IP %s from server %s for mac %s .' %  
+		  (cip, sip, mac) )
+		log.info('The desired ip was: %s .' % self.dhcp.seed_ip)
+		assert_equal(cip, self.dhcp.seed_ip)
+	elif cip == None:
+		log.info('Got DHCP NAK')
+	
+			
+
diff --git a/src/test/igmp/igmpTest.py b/src/test/igmp/igmpTest.py
index 441e845..1670c62 100644
--- a/src/test/igmp/igmpTest.py
+++ b/src/test/igmp/igmpTest.py
@@ -45,6 +45,7 @@
     MMACGROUP1 = "01:00:5e:01:02:03"
     MMACGROUP2 = "01:00:5e:02:02:03"
     MINVALIDGROUP1 = "255.255.255.255"
+    MINVALIDGROUP2 = "255.255.255.255"
     IGMP_DST_MAC = "01:00:5e:00:01:01"
     IGMP_SRC_MAC = "5a:e1:ac:ec:4d:a1"
     IP_SRC = '1.2.3.4'
@@ -779,7 +780,7 @@
         join_state1 = IGMPTestState(groups = groups2)
         target1 = self.igmp_not_recv_task(self.V_INF1, groups2, join_state1)
         assert target1==1, 'EXPECTED FAILURE'
-        log.info('Interface is not receiving from multicast groups %s when we sent invalid join packet ' %groups2)
+        log.info('Interface is not receiving data from multicast groups %s when we sent invalid join packet ' %groups2)
         mcastTraffic1.stop()
         self.onos_ctrl.deactivate()
 
@@ -835,7 +836,7 @@
 
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+20)
     def test_igmp_join_data_receiving_during_subscriber_link_down_up_functionality(self):
-        '''This test is sending join with source list A,B,C and exclude D,F,G with valid multicast group during receiving data shutdown the data receiving port  '''
+        '''This test is sending join with source list A,B,C and exclude D,F,G with valid multicast group during receiving data, shutdown the data receiving port  '''
         df = defer.Deferred()
         def igmp_join_data_receiving_during_subscriber_link_down_up_functionality():
             self.igmp_join_data_receiving_during_subscriber_link_down_up_functionality(df = df)
@@ -865,7 +866,7 @@
         join_state1 = IGMPTestState(groups = groups2)
         target1 = self.igmp_not_recv_task(self.V_INF1, groups2, join_state1)
         assert target1==1, 'EXPECTED FAILURE'
-        log.info('Interface is not receiving from multicast groups %s when we sent invalid join packet ' %groups2)
+        log.info('Interface is not receiving data from multicast groups %s when we send invalid join packet ' %groups2)
         mcastTraffic1.stop()
         self.onos_ctrl.deactivate()
 
@@ -900,7 +901,7 @@
         join_state1 = IGMPTestState(groups = groups2)
         target1 = self.igmp_not_recv_task(self.V_INF1, groups2, join_state1)
         assert target1==1, 'EXPECTED FAILURE'
-        log.info('Interface is not receiving from multicast groups %s when we sent invalid join packet ' %groups2)
+        log.info('Interface is not receiving data from multicast groups %s when we send invalid join packet ' %groups2)
         mcastTraffic1.stop()
         self.onos_ctrl.deactivate()
 
@@ -913,3 +914,21 @@
             df.callback(0)
         reactor.callLater(0, igmp_invalidClassDIP_as_srclistIP_join_packet_functionality)
         return df 
+
+    def send_igmp_join_listeningQuery(self, groups, src_list = ['1.2.3.4'], ip_pkt = None, iface = 'veth0', delay = 2):
+         self.onos_ssm_table_load(groups, src_list)
+         igmp = IGMPv3(type = IGMP_TYPE_V3_MEMBERSHIP_REPORT, 
+                       max_resp_code=30,
+                       gaddr=self.IP_DST)
+         for g in groups:
+               gr = IGMPv3gr(rtype=IGMP_V3_GR_TYPE_EXCLUDE, mcaddr=g)
+               gr.sources = src_list
+               igmp.grps.append(gr)
+         if ip_pkt is None:
+               ip_pkt = self.igmp_eth/self.igmp_ip
+         pkt = ip_pkt/igmp
+         IGMPv3.fixup(pkt)
+         resp = srp1(pkt, iface=iface)
+         resp[0].summary()
+         if delay != 0:
+             time.sleep(delay)
diff --git a/src/test/utils/DHCP.py b/src/test/utils/DHCP.py
index 61c27a3..6c151ca 100644
--- a/src/test/utils/DHCP.py
+++ b/src/test/utils/DHCP.py
@@ -11,6 +11,8 @@
         self.iface = iface
         self.mac_map = {}
         self.mac_inverse_map = {}
+	self.bootpmac = None
+	self.dhcpresp = None
 
     def is_mcast(self, ip):
         mcast_octet = (atol(ip) >> 24) & 0xff
@@ -27,12 +29,14 @@
                 mac = self.seed_mac
                 
         chmac = self.macToChaddr(mac)
+	self.bootpmac = chmac
         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=10, iface=self.iface)
+	self.dhcpresp = resp
         try:
             srcIP = resp.yiaddr
             serverIP = resp.siaddr
@@ -58,6 +62,73 @@
         self.mac_inverse_map[srcIP] = (mac, serverIP)
         return (srcIP, serverIP)
 
+    def only_discover(self, mac = None, desired = False):  
+        '''Send a DHCP discover'''
+
+        if mac is None:
+            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(ciaddr=self.seed_ip, chaddr=chmac)
+	if desired:
+		L6 = DHCP(options=[("message-type","discover"),("requested_addr",self.seed_ip),"end"])
+	else:
+        	L6 = DHCP(options=[("message-type","discover"),"end"])
+
+        resp = srp1(L2/L3/L4/L5/L6, filter="udp and port 68", timeout=10, iface=self.iface)
+	
+	if(resp.lastlayer().options [0][1] == 2):
+        	try:
+            		srcIP = resp.yiaddr
+            		serverIP = resp.siaddr
+        	except AttributeError:
+           		 print "In Attribute error."
+            		 print("Failed to acquire IP via DHCP for %s on interface %s" %(mac, self.iface))
+            		 return (None, None, None)
+		return (srcIP, serverIP, mac)
+	
+	elif(resp.lastlayer().options [0][1] == 5):
+		
+		return (None, None, None)
+
+	
+    def only_request(self, cip, mac):
+        '''Send a DHCP offer'''
+        
+	
+	subnet_mask = "0.0.0.0"
+        for x in self.dhcpresp.lastlayer().options:
+            if(x == 'end'):
+                break
+            op,val = x
+            if(op == "subnet_mask"):
+                subnet_mask = val
+            elif(op == 'server_id'):
+                server_id = val
+
+        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=self.bootpmac, yiaddr=cip)
+        L6 = DHCP(options=[("message-type","request"), ("server_id",server_id),
+                           ("subnet_mask",subnet_mask), ("requested_addr",cip), "end"])
+	resp=srp1(L2/L3/L4/L5/L6, filter="udp and port 68", timeout=10, iface=self.iface)
+	if(resp.lastlayer().options [0][1] == 5):
+        	try:
+            		srcIP = resp.yiaddr
+            		serverIP = resp.siaddr
+        	except AttributeError:
+           		 print "In Attribute error."
+            		 print("Failed to acquire IP via DHCP for %s on interface %s" %(mac, self.iface))
+            		 return (None, None)
+		return (srcIP, serverIP)
+	else:
+		return (None, None)
+
+
     def discover_next(self):
         '''Send next dhcp discover/request with updated mac'''
         return self.discover(update_seed = True)