add arp cmd; always return lists from checkLog

The arp CLI command sends gratuitous ARPs from all hosts - this
makes it easier for ONOS to discover hosts.

Previously checkLog returned None, None if the log file didn't
exist; now we return an empty list, to avoid breaking when we
take the len() of errors or warnings (which was happening before)
and to avoid having to check for None, None, which didn't seem to
add a lot of value to justify its complexity.

Change-Id: I84847fcf70525c82ac037d8a84cf40d21ab2a106
diff --git a/tools/dev/mininet/onos.py b/tools/dev/mininet/onos.py
index 6c5b817..947a330 100755
--- a/tools/dev/mininet/onos.py
+++ b/tools/dev/mininet/onos.py
@@ -281,7 +281,7 @@
     def checkLog( self ):
         "Return log file errors and warnings"
         log = join( self.dir, 'log' )
-        errors, warnings = None, None
+        errors, warnings = [], []
         if isfile( log ):
             lines = open( log ).read().split( '\n' )
             errors = [ line for line in lines if 'ERROR' in line ]
@@ -547,6 +547,32 @@
                         status = status if status else 'OK'
                         info( node, '\t', running, '\t', status, '\n' )
 
+    def do_arp( self, line ):
+        "Send gratuitous arps from all data network hosts"
+        startTime = time.time()
+        try:
+            count = int( line )
+        except:
+            count = 1
+        # Technically this check should be on the host
+        if '-U' not in quietRun( 'arping -h' ):
+            warn( 'Please install iputils-arping' )
+            return
+        # This is much faster if we do it in parallel
+        for host in self.mn.net.hosts:
+            intf = host.defaultIntf()
+            # -b: keep using broadcasts; -f: quit after 1 reply
+            # -U: gratuitous ARP update
+            host.sendCmd( 'arping -bf -c', count, '-U -I',
+                           intf.name, intf.IP() )
+        for host in self.mn.net.hosts:
+            # We could check the output here if desired
+            host.waitOutput()
+            info( '.' )
+        info( '\n' )
+        elapsed = time.time() - startTime
+        debug( 'Completed in %.2f seconds\n' % elapsed )
+
 
 # For interactive use, exit on error
 exitOnError = dict( nodeOpts={ 'alertAction': 'exit' } )