d9d85fadb5ada1d5e27e2c87b7e4f8e8d2a8d786
[goodfet] / client / experiments.py
1 import sys;
2 import binascii;
3 import array;
4 import csv, time, argparse;
5 import datetime
6 import os
7 from random import randrange
8 import random
9 from GoodFETMCPCAN import GoodFETMCPCAN;
10 from GoodFETMCPCANCommunication import GoodFETMCPCANCommunication
11 from intelhex import IntelHex;
12 import Queue
13 import math
14
15 tT = time
16
17
18 class experiments(GoodFETMCPCANCommunication):
19     """ 
20     This class provides methods for reverse-engineering the protocols on the CAN bus network
21     via the GOODTHOPTER10 board, U{http://goodfet.sourceforge.net/hardware/goodthopter10/}    
22     
23     """
24     
25     def __init__(self, data_location):
26         """ 
27         Constructor
28         @type datalocation: string
29         @param datalocation: path to the folder where data will be stored
30         """
31         GoodFETMCPCANCommunication.__init__(self, data_location)
32         #super(experiments,self).__init(self)
33         self.freq = 500;
34         
35     
36     def filterStdSweep(self, freq, low, high, time = 5):
37         """
38         This method will sweep through the range of standard ids given from low to high.
39         This will actively filter for 6 ids at a time and sniff for the given amount of
40         time in seconds. If at least one message is read in then it will go individually
41         through the 6 ids and sniff only for that id for the given amount of time. All the
42         data gathered will be saved.  This does not save any sniffed packets.
43         
44         @type  freq: number
45         @param freq: The frequency at which the bus is communicating
46         @type   low: integer
47         @param  low: The low end of the id sweep
48         @type  high: integer 
49         @param high: The high end of the id sweep
50         @type  time: number
51         @param time: Sniff time for each trial. Default is 5 seconds
52         
53         @rtype: list of numbers
54         @return: A list of all IDs found during the sweep.
55         """
56         msgIDs = []
57         self.client.serInit()
58         self.client.MCPsetup()
59         for i in range(low, high+1, 6):
60             print "sniffing id: %d, %d, %d, %d, %d, %d" % (i,i+1,i+2,i+3,i+4,i+5)
61             comment= "sweepFilter: "
62             #comment = "sweepFilter_%d_%d_%d_%d_%d_%d" % (i,i+1,i+2,i+3,i+4,i+5)
63             description = "Running a sweep filer for all the possible standard IDs. This run filters for: %d, %d, %d, %d, %d, %d" % (i,i+1,i+2,i+3,i+4,i+5)
64             count = self.sniff(freq=freq, duration = time, description = description,comment = comment, standardid = [i, i+1, i+2, i+3, i+4, i+5])
65             if( count != 0):
66                 for j in range(i,i+5):
67                     comment = "sweepFilter: "
68                     #comment = "sweepFilter: %d" % (j)
69                     description = "Running a sweep filer for all the possible standard IDs. This run filters for: %d " % j
70                     count = self.sniff(freq=freq, duration = time, description = description,comment = comment, standardid = [j, j, j, j])
71                     if( count != 0):
72                         msgIDs.append(j)
73         return msgIDs
74     
75     
76     def sweepRandom(self, freq, number = 5, time = 5):
77         """
78         This method will choose random values to listen out of all the possible standard ids up to
79         the given number. It will sniff for the given amount of time on each set of ids on the given 
80         frequency. Sniffs in groups of 6 but when at least one message is read in it will go through all
81         six individually before continuing. This does not save any sniffed packets.
82         
83         @type  freq: number
84         @param freq: The frequency at which the bus is communicating
85         @type  number: integer
86         @param number: High end of the possible ids. This will define a range from 0 to number that the ids will be chosen from
87         @type  time: number
88         @param time: Sniff time for each trial. Default is 5 seconds
89         
90         @rtype: list of numbers, list of numbers 
91         @return: A list of all IDs found during the sweep and a list of all the IDs that were listened for throughout the test
92         """
93         msgIDs = [] #standard IDs that we have observed during run
94         ids = [] #standard IDs that have been tried
95         self.client.serInit()
96         self.client.MCPsetup()
97         for i in range(0,number+1,6):
98             idsTemp = []
99             comment = "sweepFilter: "
100             for j in range(0,6,1):
101                 id = randrange(2047)
102                 #comment += "_%d" % id
103                 idsTemp.append(id)
104                 ids.append(id)
105             #print comment
106             description = "Running a sweep filer for all the possible standard IDs. This runs the following : " + comment
107             count = self.sniff(freq=freq, duration=time, description=description, comment = comment, standardid = idsTemp)
108             if( count != 0):
109                 for element in idsTemp:
110                     #comment = "sweepFilter: %d" % (element)
111                     comment="sweepFilter: "
112                     description = "Running a sweep filer for all the possible standard IDs. This run filters for: %d " % element
113                     count = self.sniff(freq=freq, duration = time, description = description,comment = comment, standardid = [element, element, element])
114                     if( count != 0):
115                         msgIDs.append(j)
116         return msgIDs, ids
117     
118     
119     def rtrSweep(self,freq,lowID,highID, attempts = 1,duration = 1, verbose = True):
120         """
121         This method will sweep through the range of ids given by lowID to highID and
122         send a remote transmissions request (RTR) to each id and then listen for a response. 
123         The RTR will be repeated in the given number of attempts and will sniff for the given duration
124         continuing to the next id.
125         
126         Any messages that are sniffed will be saved to a csv file. The filename will be stored in the DATA_LOCATION folder
127         with a filename that is the date (YYYYMMDD)_rtr.csv. If the file already exists it will append to the end of the file
128         The format will follow that of L{GoodFETMCPCANCommunication.sniff} in that the columns will be as follows:
129             1. timestamp:     as floating point number
130             2. error boolean: 1 if there was an error detected of packet formatting (not exhaustive check). 0 otherwise
131             3. comment tag:   comment about experiments as String
132             4. duration:      Length of overall sniff
133             5. filtering:     1 if there was filtering. 0 otherwise
134             6. db0:           Integer
135             
136                 ---
137             7. db7:           Integer
138         
139         @type  freq: number
140         @param freq: The frequency at which the bus is communicating
141         @type   lowID: integer
142         @param  lowID: The low end of the id sweep
143         @type  highID: integer 
144         @param highID: The high end of the id sweep
145         @type attempts: integer
146         @param attempts: The number of times a RTR will be repeated for a given standard id
147         @type  duration: integer
148         @param duration: The length of time that it will listen to the bus after sending an RTR
149         @type verbose:  boolean
150         @param verbose: When true, messages will be printed out to the terminal
151         
152         @rtype: None
153         @return: Does not return anything
154         """
155         #set up file for writing
156         now = datetime.datetime.now()
157         datestr = now.strftime("%Y%m%d")
158         path = self.DATA_LOCATION+datestr+"_rtr.csv"
159         filename = path
160         outfile = open(filename,'a');
161         dataWriter = csv.writer(outfile,delimiter=',');
162         dataWriter.writerow(['# Time     Error        Bytes 1-13']);
163         dataWriter.writerow(['#' + "rtr sweep from %d to %d"%(lowID,highID)])
164         if( verbose):
165             print "started"
166         #self.client.serInit()
167         #self.spitSetup(freq)
168         
169         #for each id
170         for i in range(lowID,highID+1, 1):
171             self.client.serInit()
172             self.spitSetup(freq) #reset the chip to try and avoid serial timeouts
173             #set filters
174             standardid = [i, i, i, i]
175             self.addFilter(standardid, verbose = True)
176             
177             #### split SID into different areas
178             SIDlow = (standardid[0] & 0x07) << 5;  # get SID bits 2:0, rotate them to bits 7:5
179             SIDhigh = (standardid[0] >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
180             #create RTR packet
181             packet = [SIDhigh, SIDlow, 0x00,0x00,0x40]
182             dataWriter.writerow(["#requested id %d"%i])
183             #self.client.poke8(0x2C,0x00);  #clear the CANINTF register; we care about bits 0 and 1 (RXnIF flags) which indicate a message is being held 
184             #clear buffer
185             packet1 = self.client.rxpacket();
186             packet2 = self.client.rxpacket();
187             #send in rtr request
188             self.client.txpacket(packet)
189             ## listen for 2 packets. one should be the rtr we requested the other should be
190             ## a new packet response
191             starttime = tT.time()
192             while ((time.time() - starttime) < duration): #listen for the given duration time period
193                 packet = self.client.rxpacket()
194                 if( packet == None):
195                     continue
196                 # we have sniffed a packet, save it
197                 row = []
198                 row.append("%f"%time.time()) #timestamp
199                 row.append(0) #error flag (not checkign)
200                 row.append("rtrRequest_%d"%i) #comment
201                 row.append(duration) #sniff time
202                 row.append(1) # filtering boolean
203                 for byte in packet:
204                     row.append("%02x"%ord(byte));
205                 dataWriter.writerow(row)
206                 print self.client.packet2parsedstr(packet)
207             trial= 2;
208             # for each trial repeat
209             while( trial <= attempts):
210                 print "trial: ", trial
211                 self.client.MCPrts(TXB0=True);
212                 starttime = time.time()
213                 # this time we will sniff for the given amount of time to see if there is a
214                 # time till the packets come in
215                 while( (time.time()-starttime) < duration):
216                     packet=self.client.rxpacket();
217                     if( packet == None):
218                         continue
219                     row = []
220                     row.append("%f"%time.time()) #timestamp
221                     row.append(0) #error flag (not checking)
222                     row.append("rtrRequest_%d"%i) #comment
223                     row.append(duration) #sniff time
224                     row.append(1) # filtering boolean
225                     for byte in packet:
226                         row.append("%02x"%ord(byte));
227                     dataWriter.writerow(row)
228                     print self.client.packet2parsedstr(packet)
229                 trial += 1
230         print "sweep complete"
231         outfile.close()
232         
233     # This method will do generation based fuzzing on the id given in standard id
234     # dbLimits is a dictionary of the databytes
235     # dbLimits['db0'] = [low, High]
236     # ..
237     # dbLimits['db7'] = [low, High]
238     # where low is the low end of values for the fuzz, high is the high end value
239     # period is the time between sending packets in milliseconds, writesPerFuzz is the times the 
240     # same fuzzed packet will be injecetez. Fuzzes is the number of different packets to be injected
241     def generationFuzzer(self,freq, standardIDs, dbLimits, period, writesPerFuzz, Fuzzes):
242         """
243         This method will perform generation based fuzzing on the bus. The method will inject
244         properly formatted, randomly generated messages at a given period for a I{writesPerFuzz} 
245         number of times. The packets that are injected into the bus will all be saved in the following path
246         DATALOCATION/InjectedData/(today's date (YYYYMMDD))_GenerationFuzzedPackets.csv. An example filename would be 20130222_GenerationFuzzedPackets.csv
247         Where DATALOCATION is provided when the class is initiated. The data will be saved as integers.
248         Each row will be formatted in the following form::
249                      row = [time of injection, standardID, 8, db0, db1, db2, db3, db4, db5, db6, db7]
250         
251         @type  freq: number
252         @param freq: The frequency at which the bus is communicating
253         @type standardIDs: list of integers
254         @param standardIDs: List of standard IDs the user wishes to fuzz on. An ID will randomly be chosen
255                             with every new random packet generated. If only 1 ID is input in the list then it will
256                             only fuzz on that one ID.
257         @type  dbLimits: dictionary
258         @param dbLimits: This is a dictionary that holds the limits of each bytes values. Each value in the dictionary will be a list 
259                          containing the lowest possible value for the byte and the highest possible value. The form is shown below::
260                             
261                             dbLimits['db0'] = [low, high]
262                             dbLimits['db1'] = [low, high]
263                             ...
264                             dbLimits['db7'] = [low, high] 
265         
266         @type period: number
267         @param period: The time gap between packet inejctions given in milliseconds
268         @type writesPerFuzz: integer
269         @param writesPerFuzz: This will be the number of times that each randomly generated packet will be injected onto the bus
270                               before a new packet is generated
271         @type Fuzzes: integer
272         @param Fuzzes: The number of packets to be generated and injected onto bus
273         
274         @rtype: None
275         @return: This method does not return anything
276                          
277         """
278         #print "Fuzzing on standard ID: %d" %standardId
279         self.client.serInit()
280         self.spitSetup(freq)
281         packet = [0,0,0x00,0x00,0x08,0,0,0,0,0,0,0,0] #empty template
282         #form a basic packet
283         
284 #        #### split SID into different regs
285 #        SIDlow = (standardIds[0] & 0x07) << 5;  # get SID bits 2:0, rotate them to bits 7:5
286 #        SIDhigh = (standardIds[0] >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
287 #        
288 #        packet = [SIDhigh, SIDlow, 0x00,0x00, # pad out EID regs
289 #                  0x08, # bit 6 must be set to 0 for data frame (1 for RTR) 
290 #                  # lower nibble is DLC                   
291 #                 packetTemp[0],packetTemp[1],packetTemp[2],packetTemp[3],packetTemp[4],packetTemp[5],packetTemp[6],packetTemp[7]]
292 #        
293         
294         #get folder information (based on today's date)
295         now = datetime.datetime.now()
296         datestr = now.strftime("%Y%m%d")
297         path = self.DATA_LOCATION+"InjectedData/"+datestr+"_GenerationFuzzedPackets.csv"
298         filename = path
299         outfile = open(filename,'a');
300         dataWriter = csv.writer(outfile,delimiter=',');
301         #dataWriter.writerow(['# Time     Error        Bytes 1-13']);
302         #dataWriter.writerow(['#' + description])
303             
304         numIds = len(standardIDs)
305         fuzzNumber = 0; #: counts the number of packets we have generated
306         while( fuzzNumber < Fuzzes):
307             id_new = standardIDs[random.randint(0,numIds-1)]
308             print id_new
309             #### split SID into different regs
310             SIDhigh = (id_new >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
311             SIDlow = (id_new & 0x07) << 5;  # get SID bits 2:0, rotate them to bits 7:5
312             packet[0] = SIDhigh
313             packet[1] = SIDlow
314             
315             #generate a fuzzed packet
316             for i in range(0,8): # for each data byte, fuzz it
317                 idx = "db%d"%i
318                 limits = dbLimits[idx]
319                 value = random.randint(limits[0],limits[1]) #generate pseudo-random integer value
320                 packet[i+5] = value
321             print packet
322             #put a rough time stamp on the data and get all the data bytes    
323             row = [time.tT(), id_new,8] # could make this 8 a variable 
324             msg = "Injecting: "
325             for i in range(5,13):
326                 row.append(packet[i])
327                 msg += " %d"%packet[i]
328             #print msg
329             dataWriter.writerow(row)
330             self.client.txpacket(packet)
331             tT.sleep(period/1000)
332             
333             #inject the packet the given number of times. 
334             for i in range(1,writesPerFuzz):
335                 self.client.MCPrts(TXB0=True)
336                 tT.sleep(period/1000)
337             fuzzNumber += 1
338         print "Fuzzing Complete"   
339         outfile.close()
340             
341     def generalFuzz(self,freq, Fuzzes, period, writesPerFuzz):
342         """
343         The method will inject properly formatted, randomly generated messages at a given period for a I{writesPerFuzz} 
344         number of times. A new random standard id will be chosen with each newly generated packet. IDs will be chosen from the full
345         range of potential ids ranging from 0 to 4095. The packets that are injected into the bus will all be saved in the following path
346         DATALOCATION/InjectedData/(today's date (YYYYMMDD))_GenerationFuzzedPackets.csv. An example filename would be 20130222_GenerationFuzzedPackets.csv
347         Where DATALOCATION is provided when the class is initiated. The data will be saved as integers.
348         Each row will be formatted in the following form::
349                      row = [time of injection, standardID, 8, db0, db1, db2, db3, db4, db5, db6, db7]
350         
351         @type  freq: number
352         @param freq: The frequency at which the bus is communicating
353         @type period: number
354         @param period: The time gap between packet inejctions given in milliseconds
355         @type writesPerFuzz: integer
356         @param writesPerFuzz: This will be the number of times that each randomly generated packet will be injected onto the bus
357                               before a new packet is generated
358         @type Fuzzes: integer
359         @param Fuzzes: The number of packets to be generated and injected onto bus
360         
361         @rtype: None
362         @return: This method does not return anything
363                          
364         """
365         #print "Fuzzing on standard ID: %d" %standardId
366         self.client.serInit()
367         self.spitSetup(freq)
368         packet = [0,0,0x00,0x00,0x08,0,0,0,0,0,0,0,0] #empty template
369         
370         #get folder information (based on today's date)
371         now = datetime.datetime.now()
372         datestr = now.strftime("%Y%m%d")
373         path = self.DATA_LOCATION+"InjectedData/"+datestr+"_GenerationFuzzedPackets.csv"
374         filename = path
375         outfile = open(filename,'a');
376         dataWriter = csv.writer(outfile,delimiter=',');
377         #dataWriter.writerow(['# Time     Error        Bytes 1-13']);
378         #dataWriter.writerow(['#' + description])
379             
380         fuzzNumber = 0; #: counts the number of packets we have generated
381         while( fuzzNumber < Fuzzes):
382             #generate new random standard id in the full range of possible values
383             id_new = random.randint(0,4095) 
384             #print id_new
385             #### split SID into different regs
386             SIDhigh = (id_new >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
387             SIDlow = (id_new & 0x07) << 5;  # get SID bits 2:0, rotate them to bits 7:5
388             packet[0] = SIDhigh
389             packet[1] = SIDlow
390             
391             #generate a fuzzed packet
392             for i in range(0,8): # for each data byte, fuzz it
393                 idx = "db%d"%i
394                 
395                 value = random.randint(0, 255) #generate pseudo-random integer value
396                 packet[i+5] = value
397             print packet
398             #put a rough time stamp on the data and get all the data bytes    
399             row = [time.time(), id_new,8] 
400             """@todo: allow for varied packet lengths"""
401             msg = "Injecting: "
402             for i in range(5,13):
403                 row.append(packet[i])
404                 msg += " %d"%packet[i]
405             #print msg
406             dataWriter.writerow(row)
407             self.client.txpacket(packet)
408             time.sleep(period/1000)
409             
410             #inject the packet the given number of times. 
411             for i in range(1,writesPerFuzz):
412                 self.client.MCPrts(TXB0=True)
413                 time.sleep(period/1000)
414             fuzzNumber += 1
415         print "Fuzzing Complete"   
416         outfile.close()
417     
418     # assumes 8 byte packets
419     def packetRespond(self,freq, time, repeats, period,  responseID, respondPacket,listenID, listenPacket = None):
420         """
421         This method will allow the user to listen for a specific packet and then respond with a given message.
422         If no listening packet is included then the method will only listen for the id and respond with the specified
423         packet when it receives a message from that id. This process will continue for the given amount of time (in seconds). 
424         and with each message received that matches the listenPacket and ID the transmit message will be sent the I{repeats} number
425         of times at the specified I{period}. This message assumes a packet length of 8 for both messages, although the listenPacket can be None
426         
427         @type freq: number
428         @param freq: Frequency of the CAN bus
429         @type time: number
430         @param time: Length of time to perform the packet listen/response in seconds.
431         @type repeats: Integer
432         @param repeats: The number of times the response packet will be injected onto the bus after the listening 
433                         criteria has been met.
434         @type period: number
435         @param period: The time interval between messages being injected onto the CAN bus. This will be specified in milliseconds
436         @type responseID: Integer
437         @param responseID: The standard ID of the message that we want to inject
438         @type respondPacket: List of integers
439         @param respondPacket: The data we wish to inject into the bus. In the format where respondPacket[0] = databyte 0 ... respondPacket[7] = databyte 7
440                               This assumes a packet length of 8.
441         @type listenID: Integer
442         @param listenID: The standard ID of the messages that we are listening for. When we read the correct message from this ID off of the bus, the method will
443                          begin re-injecting the responsePacket on the responseID
444         @type listenPacket: List of Integers
445         @param listenPacket: The data we wish to listen for before we inject packets. This will be a list of the databytes, stored as integers such that
446                              listenPacket[0] = data byte 0, ..., listenPacket[7] = databyte 7. This assumes a packet length of 8. This input can be None and this
447                              will lead to the program only listening for the standardID and injecting the response as soon as any message from that ID is given
448         """
449         
450         
451         self.client.serInit()
452         self.spitSetup(freq)
453         
454         #formulate response packet
455         SIDhigh = (responseID >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
456         SIDlow = (responseID & 0x07) << 5;  # get SID bits 2:0, rotate them to bits 7:5
457         #resPacket[0] = SIDhigh
458         #resPacket[1] = SIDlow
459         resPacket = [SIDhigh, SIDlow, 0x00,0x00, # pad out EID regs
460                   0x08, # bit 6 must be set to 0 for data frame (1 for RTR) 
461                   # lower nibble is DLC                   
462                  respondPacket[0],respondPacket[1],respondPacket[2],respondPacket[3],respondPacket[4],respondPacket[5],respondPacket[6],respondPacket[7]]
463         #load packet/send once
464         """@todo: make this only load the data onto the chip and not send """
465         self.client.txpacket(resPacket) 
466         self.addFilter([listenID,listenID,listenID,listenID, listenID, listenID]) #listen only for this packet
467         startTime = tT.time()
468         packet = None
469         while( (tT.time() - startTime) < time):
470             packet = self.client.rxpacket()
471             if( packet != None):
472                 print "packet read in, responding now"
473                 # assume the ids already match since we are filtering for the id
474                 
475                 #compare packet received to desired packet
476                 if( listenPacket == None): # no packets given, just want the id
477                     for i in range(0,repeats):
478                         self.client.MCPrts(TXB0=True)
479                         tT.sleep(period/1000)
480                 else: #compare packets
481                     sid =  ord(packet[0])<<3 | ord(packet[1])>>5
482                     print "standard id of packet recieved: ", sid #standard ID
483                     msg = ""
484                     for i in range(0,8):
485                         idx = 5 + i
486                         byteIn = ord(packet[idx])
487                         msg += " %d" %byteIn
488                         compareIn = listenPacket[i]
489                         print byteIn, compareIn
490                         if( byteIn != compareIn):
491                             packet == None
492                             print "packet did not match"
493                             break
494                     print msg
495                     if( packet != None ):
496                         self.client.MCPrts(TXB0=True)
497                         tT.sleep(period/1000)
498         print "Response Listening Terminated."
499                 
500         
501 #    def generationFuzzRandomID(self, freq, standardIDs, dbLimits, period, writesPerFuzz, Fuzzes):
502 #        print "Fuzzing on standard ID: %d" %standardId
503 #        self.client.serInit()
504 #        self.spitSetup(freq)
505 #        packetTemp = [0,0,0,0,0,0,0,0]
506 #        #form a basic packet
507 #        
508 #        #### split SID into different regs
509 #        SIDlow = (standardId & 0x07) << 5;  # get SID bits 2:0, rotate them to bits 7:5
510 #        SIDhigh = (standardId >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
511 #        
512 #        packet = [SIDhigh, SIDlow, 0x00,0x00, # pad out EID regs
513 #                  0x08, # bit 6 must be set to 0 for data frame (1 for RTR) 
514 #                  # lower nibble is DLC                   
515 #                 packetTemp[0],packetTemp[1],packetTemp[2],packetTemp[3],packetTemp[4],packetTemp[5],packetTemp[6],packetTemp[7]]
516 #        
517 #        
518 #        #get folder information (based on today's date)
519 #        now = datetime.datetime.now()
520 #        datestr = now.strftime("%Y%m%d")
521 #        path = self.DATA_LOCATION+"InjectedData/"+datestr+"_GenerationFuzzedPackets.csv"
522 #        filename = path
523 #        outfile = open(filename,'a');
524 #        dataWriter = csv.writer(outfile,delimiter=',');
525 #        #dataWriter.writerow(['# Time     Error        Bytes 1-13']);
526 #        #dataWriter.writerow(['#' + description])
527 #            
528 #        numIds = len(standardIDs)
529 #        fuzzNumber = 0;
530 #        while( fuzzNumber < Fuzzes):
531 #            id_new = standsardIDs[random.randint(0,numIds-1)]
532 #            #### split SID into different regs
533 #            SIDlow = (id_new & 0x07) << 5;  # get SID bits 2:0, rotate them to bits 7:5
534 #            SIDhigh = (id_new >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
535 #            packet[0] = SIDhigh
536 #            packet[1] = SIDlow
537 #            
538 #            #generate a fuzzed packet
539 #            for i in range(0,8): # for each databyte, fuzz it
540 #                idx = "db%d"%i
541 #                limits = dbLimits[idx]
542 #                value = random.randint(limits[0],limits[1]) #generate pseudo-random integer value
543 #                packet[i+5] = value
544 #            
545 #            #put a rough time stamp on the data and get all the data bytes    
546 #            row = [time.time(), standardId,8]
547 #            msg = "Injecting: "
548 #            for i in range(5,13):
549 #                row.append(packet[i])
550 #                msg += " %d"%packet[i]
551 #            #print msg
552 #            dataWriter.writerow(row)
553 #            self.client.txpacket(packet)
554 #            #inject the packet repeatily 
555 #            for i in range(1,writesPerFuzz):
556 #                self.client.MCPrts(TXB0=True)
557 #                time.sleep(period/1000)
558 #            fuzzNumber += 1
559 #        print "Fuzzing Complete"   
560 #        outfile.close()