added packet fuzzing
[goodfet] / client / goodfet.ccspi
index f8d10bd..59eee33 100755 (executable)
@@ -5,7 +5,7 @@
 # Additions 2011-2012 Ryan Speers ryan@rmspeers.com
 
 #N.B.,
-#Might be CC2420 Specific
+#Very CC2420 Specific
 
 import sys;
 import binascii;
@@ -13,10 +13,30 @@ import array, time;
 
 from GoodFETCCSPI import GoodFETCCSPI;
 
+
+#Some quick functions for yanking values out of a packet.
+def srcadr(packet):
+    """Returns the source address of a packet as an integer."""
+    return ord(packet[4])+(ord(packet[5])<<8);
+def isencrypted(packet):
+    """Returns true if the packet is encrypted.""";
+    try:
+        return ord(packet[1])&0x08;
+    except:
+        return False;
+def pktnonceseq(packet):
+    """Returns the nonce sequence of a packet."""
+    nonce=0;
+    for byte in [0xa,9,8,7]:
+        nonce=(nonce<<8)|ord(packet[byte]);
+    return nonce;
+
 if(len(sys.argv)==1):
     print "Usage: %s verb [objects]\n" % sys.argv[0];
     print "%s info" % sys.argv[0];
     print "%s regs" % sys.argv[0];
+    print "%s ram" % sys.argv[0];
+    print "%s ramtest" % sys.argv[0];
     print "%s test" % sys.argv[0];
     print "%s peek 0x$start [0x$stop]" % sys.argv[0];
     print "%s poke 0x$adr 0x$val" % sys.argv[0];
@@ -28,11 +48,18 @@ if(len(sys.argv)==1):
     
     print "\n%s surf" % sys.argv[0];
     print "%s sniff [chan]" % sys.argv[0];
+    print "%s fastsniff [chan]" % sys.argv[0];
+    print "%s sniffstrings [chan]" % sys.argv[0];
     print "%s bsniff [chan]" % sys.argv[0];
+    print "%s sniffcrypt 0x$key [chan]" % sys.argv[0];
     print "%s sniffdissect" % sys.argv[0];
+    print "%s sniffnonce" % sys.argv[0];
     
     print "\n%s txtoscount [-i|-r]   TinyOS BlinkToLED" % sys.argv[0];
     print "%s reflexjam [channel=11] [delay=0]" % sys.argv[0];
+    
+    print "\n%s txpiptest" % sys.argv[0];
+    print "%s txpipscapy" % sys.argv[0];
 
     sys.exit();
 
@@ -95,6 +122,32 @@ if(sys.argv[1]=="regs"):
     for adr in range(0x10,0x40): #*1024):
         val=client.peek(adr);
         print "%04x:=0x%04x" % (adr,val);
+if(sys.argv[1]=="ram"):
+    for adr in range(0x0,0x16D,16):
+        row=client.peekram(adr,32);
+        s="";
+        for foo in row:
+            s=s+(" %02x" % ord(foo))
+        print "%04x: %s" % (adr,s);
+if(sys.argv[1]=="ramtest"):
+    client.pokeram(0x00,[0xde,0xad,0xbe,0xef,
+                         0xde,0xad,0xbe,0xef,
+                         0xde,0xad,0xbe,0xef,
+                         0xde,0xad,0xbe,0xef,
+                         0xde,0xad,0xbe,0xef,
+                         0xde,0xad,0xbe,0xef,
+                         0xde,0xad,0xbe,0xef,
+                         0xde,0xad,0xbe,0xef,
+                         0xde,0xad,0xbe,0xef,
+                         0xde,0xad,0xbe,0xef,
+                         0xde,0xad,0xbe,0xef]);
+    
+    for adr in range(0x0,0x16D,16):
+        row=client.peekram(adr,32);
+        s="";
+        for foo in row:
+            s=s+(" %02x" % ord(foo))
+        print "%04x: %s" % (adr,s);
 if(sys.argv[1]=="test"):
     data=client.trans([0x20, 0xde, 0xad]);
     print "%02x %02x" % (ord(data[1]), ord(data[2]));
@@ -185,7 +238,8 @@ if sys.argv[1]=="surf":
         sys.stdout.flush();
         chan=chan+1;
 
-if(sys.argv[1]=="sniff" or sys.argv[1]=="sniffdissect"):
+if(sys.argv[1]=="sniff" or sys.argv[1]=="sniffdissect" or sys.argv[1]=="sniffstrings" or
+   sys.argv[1]=="sniffnonce" or sys.argv[1]=="fastsniff"):
     #Promiscuous mode.
     client.RF_promiscuity(1);
     client.RF_autocrc(1);
@@ -201,16 +255,30 @@ if(sys.argv[1]=="sniff" or sys.argv[1]=="sniffdissect"):
     client.CC_RFST_RX();
     print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
                                             client.RF_getfreq()/10**6);
+    #If fastsniffing, then send that command.
+    if sys.argv[1]=="fastsniff":
+        client.RF_rxpacketrepeat();
+    
     #Now we're ready to get packets.
     while 1:
-        client.setup(); #Really oughtn't be necessary, but can't hurt.
-        client.CC_RFST_RX();
+        #client.CC_RFST_RX(); # Cop-out that confuses reception!
         
         packet=None;
         while packet==None:
             packet=client.RF_rxpacket();
         if sys.argv[1]=="sniffdissect":
             client.printdissect(packet);
+        elif sys.argv[1]=="sniffstrings":
+            print packet;
+        elif sys.argv[1]=="sniffnonce":
+            if isencrypted(packet):
+                try:
+                    print "%04x: %08x -- %s" % (srcadr(packet),
+                                            pktnonceseq(packet),
+                                            client.packet2str(packet)
+                                            );
+                except:
+                    pass;
         else:
             client.printpacket(packet);
         sys.stdout.flush();
@@ -238,6 +306,43 @@ if(sys.argv[1]=="bsniff"):
         client.printpacket(packet);
         sys.stdout.flush();
 
+if(sys.argv[1]=="sniffcrypt"):
+    print "Zigbee crypto is pretty damned complicated, and this doesn't work yet.";
+    #Just broadcast.
+    client.RF_promiscuity(1);
+    client.RF_setsmac(0xFFFFFFFF);
+    client.RF_autocrc(1);
+    #client.poke(0x19, 0x03C7); #SECCTRL0, enabling CCM crypto w/ KEY0
+    client.poke(0x19, 0x03C6); #SECCTRL0, enabling CTRL crypto w/ KEY0
+    
+    #What follows is the nonce.
+    client.poke(0x20, 0x000a); #SECCTRL1, skipping 10 bytes of header
+    
+    if len(sys.argv)>2:
+        key=int(sys.argv[2],16);
+        nonce=int(sys.argv[3],16);
+        
+        print "Setting KEY0 to %x" % key;
+        print "Setting NONCE to %x" % nonce;
+        client.RF_setkey(key);
+        client.RF_setnonce(nonce);
+    if len(sys.argv)>3:
+        freq=eval(sys.argv[3]);
+        if freq>100:
+            client.RF_setfreq(freq);
+        else:
+            client.RF_setchan(freq);
+    client.CC_RFST_RX();
+    print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
+                                            client.RF_getfreq()/10**6);
+    #Now we're ready to get packets.
+    while 1:
+        packet=None;
+        while packet==None:
+            packet=client.RF_rxpacketdec();
+        client.printpacket(packet);
+        sys.stdout.flush();
+
 if(sys.argv[1]=="txtest"):
     if len(sys.argv)>2:
         freq=eval(sys.argv[2]);
@@ -304,7 +409,7 @@ if(sys.argv[1]=="txpiptest" or sys.argv[1]=="txpipscapy"):
             client.RF_setfreq(freq);
         else:
             client.RF_setchan(freq);
-    print "Transmitting on as %010x on %i MHz" % (
+    print "Transmitting on PIP injection as %010x on %i MHz" % (
         client.RF_getsmac(),
         client.RF_getfreq()/10**6);