root/trunk/tool/renetcolRC.py @ 151

Revision 151, 24.3 KB (checked in by andreu, 12 years ago)

Warning at beginning fixed

Line 
1
2##  File: renetcolRC.py
3 
4##  Authors: ANDREU Francois-Xavier
5 
6##  Copyright (C) 2010-2011 GIP RENATER
7 
8
9##   This file is part of renetcol.
10 
11##   renetcol is free software; you can redistribute it and/or modify
12##   it under the terms of the GNU General Public License as published by
13##   the Free Software Foundation; either version 2 of the License, or
14##   (at your option) any later version.
15 
16##   renetcol is distributed in the hope that it will be useful,
17##   but WITHOUT ANY WARRANTY; without even the implied warranty of
18##   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19##   GNU General Public License for more details.
20 
21##   You should have received a copy of the GNU General Public License
22##   along with renetcol; if not, write to the Free Software
23##   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24 
25
26import os
27import binascii
28import struct
29import time
30
31import operator
32import threading
33import string
34import re
35import socket
36import sys
37import traceback
38import commands
39from optparse import OptionParser
40
41global localAddr, localPort
42global rrt, record, record_file_name
43
44########### DEFAULT VALUES, YOU MUST CHANGE IT ###############################
45IPversion = 4
46localAddr = ''
47localAddr6 = '0::'
48localPort = 2222
49collectorAddr = "127.0.0.1"
50collectorAddr6 = "0::"
51collectorPort = 52571  # if you change this port number, apply the
52                       # modification on the renetcolSender.h file
53                       # and you'll need a new compilation of the collector
54##############################################################################
55
56myInputControlThread = None
57printValue =      [ 0,1,1,0,1,0,0,1,1,0, # 0 to 9
58                    0,1,1,0,0,0,1,1,0,0, # 10...
59                    0,1,0,0,0,0,0,1,1,0, #
60                    0,0,0,0,0,0,0,0,0,0, #
61                    0,0,0,0,0,0,1,1,0,0, #
62                    0,0,0,0,0,0,0,0,0,0, #
63                    0,0,0,0,0,0,0,0,0,1, #
64                    1,1,1,1,1,1,1,1,1,1, #
65                    0,0,0,0,0,0,0,0,0,0,  # 80 to 89
66                    0,0,0,0,0,0,0,0,0,0, #
67                    0,0,0,0,0,0,0,0,0,0, #
68                    0,0,0,0,0,0,0,0,0,0, #
69                    0,0,0,0,0,0,0,0,0,0, #
70                    0,0,0,0,0,0,0,0,0,0 # 130 to 139
71                    ]
72firstParseValue = [ 0,0,0,0,0,0,0,0,0,0,
73                    0,0,0,0,0,0,0,0,0,0,
74                    0,0,0,0,0,0,0,0,0,0,
75                    0,0,0,0,0,0,0,0,0,0,
76                    0,0,0,0,0,0,0,0,0,0,
77                    0,0,0,0,0,0,0,0,0,0,
78                    0,0,0,0,0,0,0,0,0,0,
79                    0,0,0,0,0,0,0,0,0,0,
80                    0,0,0,0,0,0,0,0,0,0,
81                    0,0,0,0,0,0,0,0,0,0, #
82                    0,0,0,0,0,0,0,0,0,0, #
83                    0,0,0,0,0,0,0,0,0,0, #
84                    0,0,0,0,0,0,0,0,0,0, #
85                    0,0,0,0,0,0,0,0,0,0 # 130 to 139
86                    ]
87checkUpValues =   [ 0,0,0,0,0,0,0,0,0,0,
88                    0,0,0,0,0,0,0,0,0,0,
89                    0,0,0,0,0,0,0,0,0,0,
90                    0,0,0,0,0,0,0,0,0,0,
91                    0,0,0,0,0,0,0,0,0,0,
92                    0,0,0,0,0,0,0,0,0,0,
93                    0,0,0,0,0,0,0,0,0,0,
94                    0,0,0,0,0,0,0,0,0,0,
95                    0,0,0,0,0,0,0,0,0,0,
96                    0,0,0,0,0,0,0,0,0,0, #
97                    0,0,0,0,0,0,0,0,0,0, #
98                    0,0,0,0,0,0,0,0,0,0, #
99                    0,0,0,0,0,0,0,0,0,0, #
100                    0,0,0,0,0,0,0,0,0,0 # 130 to 139
101                    ]
102fieldsName =  [ "","IN_BYTES","IN_PKTS","","PROT","TOS","TCP_FL","S_PORT","IPv4@S","S_MASK",
103                "InSNMP","D_PORT","IPv4@D","D_MASK","OutSNMP","NextHop","S_AS","D_AS","","",
104                "LT","AGE","","","","","","IPv6@S","IPv6@D","IPv6_S_MASK",
105                "IPv6_D_MASK","","","","","","","","","",
106                "","","","","","","M_T_L_T","M_T_L_@","","",
107                "","","","","","","","","","",
108                "","","","","","","","","","ROUTER;TIMESTAMP",
109                "M_L_1","M_L_2","M_L_3","M_L_4","M_L_5","M_L_6","M_L_7","M_L_8","M_L_9","M_L_10",
110                "","","","","","","","","","", # 80 to 89
111                "","","","","","","","","","",
112                "","","","","","","","","","",
113                "","","","","","","","","","",
114                "","","","","","","","","","",
115                "","","","","","","","","","" # 130 to 139
116                ]
117flowCpt = 0
118flowCptW = 0
119mask = [ 0,0,0 ]
120spaceSep = " "
121tabSep = "\t"
122freeze = 0
123record = 0
124record_file_name = ""
125record_file = None
126is_already_see = 0
127collectorRule=""
128router=0
129tpl_def = {}
130oldTpl = 0
131oldTplW = 0
132fromRouter = ""
133myTimer = None
134myCPT = 1
135rrt = 3600
136
137class InputControl(threading.Thread):
138    def kill(self, timeout):
139        self.imRunning = 0
140        time.sleep(1)
141        print "\n.\n..\n..."
142        time.sleep(1)
143        print "....\n.....\n......"       
144        time.sleep(1)
145        if self.myFlowInput:
146            self.myFlowInput.socket_close()
147        self.join(timeout)
148       
149    def __init__(self, address, port):
150        self.imRunning = 1
151        self.currentflow = None
152        threading.Thread.__init__(self)
153        self.myFlowInput = FlowInput(address, port)
154
155    def run(self):
156        global freeze, record
157        while self.imRunning:
158            if self.myFlowInput:
159                tmp = self.myFlowInput.get_flow()
160                if (tmp[0]!=None):
161                    self.currentflow = Flow(tmp)
162                    if (freeze==0) & self.currentflow.enable():
163                        self.currentflow.print_flow2()
164                    if (record==1) & self.currentflow.enable():
165                        self.currentflow.write_flow2()
166##                else:
167##                    self.myFlowInput = None
168   
169class Flow:
170    def __init__(self, data):
171        self.flow = [ data[0], data[1] ]
172
173# flow selection
174    def enable(self):
175        global firstParseValue, checkUpValues, tpl_def, fromRouter
176        res = 1
177        resS = 1
178        resD = 1
179        for i in range (0, len(tpl_def[self.flow[0]])):
180            f = tpl_def[self.flow[0]][i][0]
181            # or f==15 or f==18 or f==47
182            if ( f==8 ) and ( checkUpValues[f]==1 ):
183                resS = resS & ( ((struct.unpack('>L',(socket.inet_aton(self.flow[1][i])))[0] & mask[1-1]) == firstParseValue[f]) )
184            elif ( f==12 ) and ( checkUpValues[f]==1 ):
185                resD = resD & ( ((struct.unpack('>L',(socket.inet_aton(self.flow[1][i])))[0] & mask[1-1]) == firstParseValue[f]) )
186            elif ( i==27 or i==28 ):
187                pass
188            elif ( (f==1) and (checkUpValues[f]==1) ):
189                res = res & ( (self.flow[1][i] <= ((firstParseValue[f])+((firstParseValue[f])*5/100))) and ((self.flow[1][i] >= ((firstParseValue[f])-((firstParseValue[f])*5/100)))) )
190            elif (checkUpValues[f]==1):
191                res = res & (self.flow[1][i] == firstParseValue[f])
192        if ( checkUpValues[69]==1 ):
193            res = res & ( (fromRouter == firstParseValue[69]) )
194        res = res & (resS or resD)
195        return res
196
197# flow print
198    def print_flow2(self):
199        global printValue, tpl_def, flowCpt, fieldsName, oldTpl, os_type, fromRouter
200        myliste = []
201        myTpl = []
202        strFlow = ""
203        strField = ""
204        underscore_line = ""
205        flowCpt+=1
206        if (flowCpt%60 == 0 or oldTpl != self.flow[0]):
207##        if (flowCpt%100 == 0):
208            flowCpt = 0
209            for i in range (0, len(tpl_def[self.flow[0]])):
210                f = tpl_def[self.flow[0]][i][0]
211                if printValue[f]:
212                    if ( f==27 or f==28 or f==62 or f==63 ):
213                        strField += str(fieldsName[f])
214                        l = len(str(fieldsName[f]))
215                        if ((40-l)%8 == 0):
216                            tabNb = int((40-l)/8)
217                        else:
218                            tabNb = int((40-l)/8) + 1
219                        for j in range (0, tabNb):
220                            strField += "\t"
221                        for k in range (0, 40):
222                            underscore_line += "-"
223                    elif ( f==8 or f==15 or f==12 or f==18 or f==47 ):
224                        strField += str(fieldsName[f])
225                        l = len(str(fieldsName[f]))
226                        if ((16-l)%8 == 0):
227                            tabNb = int((16-l)/8)
228                        else:
229                            tabNb = int((16-l)/8) + 1
230                        for j in range (0, tabNb):
231                            strField += "\t"
232                        for k in range (0, 16):
233                            underscore_line += "-"
234                    else:
235                        strField += str(fieldsName[f])
236                        strField += "\t"
237                        for k in range (0, 8):
238                            underscore_line += "-"
239            if (oldTpl != self.flow[0]):
240                print " "
241            if (os_type == 0):
242                esc = '\x1b['
243                sep = ';'
244                end = 'm'
245                if (printValue[69]):
246                    rt = str(fieldsName[69])
247                    toprint = esc+"37"+sep+"44"+end+strField+rt+esc+"0"+end
248                else:
249                    toprint = esc+"37"+sep+"44"+end+strField+esc+"0"+end
250                print toprint
251            else:
252                if (printValue[69]):
253                    strField += str(fieldsName[69])
254                print strField
255                print underscore_line
256        for i in range (0, len(tpl_def[self.flow[0]])):
257            f = tpl_def[self.flow[0]][i][0]
258            if printValue[f]:
259                if ( f==27 or f==28 or f==62 or f==63 ):
260                    strFlow += str(self.flow[1][i])
261                    l = len(str(self.flow[1][i]))
262                    if ((40-l)%8 == 0):
263                        tabNb = int((40-l)/8)
264                    else:
265                        tabNb = int((40-l)/8) + 1
266                    for j in range (0, tabNb):
267                        strFlow += "\t"
268                elif ( f==8 or f==12 or f==15 or f==18 or f==47 ):
269                    strFlow += str(self.flow[1][i])
270                    l = len(str(self.flow[1][i]))
271                    if ((16-l)%8 == 0):
272                        tabNb = int((16-l)/8)
273                    else:
274                        tabNb = int((16-l)/8) + 1
275                    for j in range (0, tabNb):
276                        strFlow += "\t"
277                elif (f==21):
278                    myliste += [str(self.flow[1][i]-self.flow[1][i+1])]
279                    strFlow += str(self.flow[1][i]-self.flow[1][i+1])
280                    strFlow += "\t"
281                elif (f==22):
282                    pass
283                else:
284                    myliste += [str(self.flow[1][i])]
285                    strFlow += str(self.flow[1][i])
286                    for k in range (len(str(self.flow[1][i])), 7):
287                        strFlow += " "
288                    strFlow += "\t"
289        if (printValue[69]):
290            strFlow += fromRouter+"\t"+time.strftime("%Y/%m/%d %H:%M", time.gmtime())
291        print strFlow
292        oldTpl = self.flow[0]
293
294# flow record
295    def write_flow2(self):
296        global printValue, record_file, tpl_def, flowCptW, fieldsName, oldTplW, os_type, fromRouter
297        myliste = []
298        myTpl = []
299        strFlow = ""
300        strField = ""
301        underscore_line = "#"
302        flowCptW+=1
303        if (flowCptW%6 == 0 or oldTplW != self.flow[0]):
304##        if (flowCpt%100 == 0):
305            strField = "#"
306            flowCptW = 0
307            for i in range (0, len(tpl_def[self.flow[0]])):
308                f = tpl_def[self.flow[0]][i][0]
309                if printValue[f]:
310                    if ( f==27 or f==28 or f==62 or f==63 ):
311                        strField += str(fieldsName[f])
312                        l = len(str(fieldsName[f]))
313                        if ((40-l)%8 == 0):
314                            tabNb = int((40-l)/8)
315                        else:
316                            tabNb = int((40-l)/8) + 1
317                        for j in range (0, tabNb):
318                            strField += ";"
319                        for k in range (0, 40):
320                            underscore_line += "-"
321                    elif ( f==8 or f==15 or f==12 or f==18 or f==47 ):
322                        strField += str(fieldsName[f])
323                        l = len(str(fieldsName[f]))
324                        if ((16-l)%8 == 0):
325                            tabNb = int((16-l)/8)
326                        else:
327                            tabNb = int((16-l)/8) + 1
328                        #for j in range (0, tabNb):
329                        strField += ";"
330                        for k in range (0, 16):
331                            underscore_line += "-"
332                    else:
333                        strField += str(fieldsName[f])
334                        strField += ";"
335                        for k in range (0, 8):
336                            underscore_line += "-"
337            if (oldTplW != self.flow[0]):
338                record_file.write("")
339            if (os_type == 0):
340                esc = '\x1b['
341                sep = ';'
342                end = 'm'
343                if (printValue[69]):
344                    rt = str(fieldsName[69])
345                    toprint = esc+"37"+sep+"44"+end+strField+rt+esc+"0"+end+"\n"
346                else:
347                    toprint = esc+"37"+sep+"44"+end+strField+esc+"0"+end+"\n"
348                record_file.write(toprint)
349            else:
350                if (printValue[69]):
351                    strField += str(fieldsName[69])
352                if (record_file!=None):
353                    record_file.write(strField)
354                    record_file.write("\n")
355#                    record_file.write(underscore_line)
356#                    record_file.write("\n")
357        for i in range (0, len(tpl_def[self.flow[0]])):
358            f = tpl_def[self.flow[0]][i][0]
359            if printValue[f]:
360                if (f==21):
361                    myliste += [str(self.flow[1][i]-self.flow[1][i+1])]
362                elif (f==22):
363                    pass
364                else:
365                    myliste += [str(self.flow[1][i])]
366        theflow = string.join(myliste, ";")+";"+fromRouter+";"+time.strftime("%Y%m%d%H%M", time.gmtime())+"\n"
367        if (record_file!=None):
368            record_file.write(theflow)
369            oldTplW = self.flow[0]
370       
371class FlowInput:
372    def __init__(self, h, p):
373        self.HOST = h
374        self.PORT = p
375        if (IPversion == 4):
376            self.socketnumber = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
377        elif (IPversion == 6):
378            self.socketnumber = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
379        else:
380            print "IP protocol ", IPversion ," not supported"
381            exit(0)
382        self.socketnumber.bind((self.HOST, self.PORT))
383   
384    def get_flow(self):
385        global collectorRule, tpl_def, os_type, fromRouter
386        if (self.socketnumber!=None):
387            data = self.socketnumber.recvfrom(1024)
388            flow = data[0]
389            code = struct.unpack('<H', flow[0:2])
390            if (code[0] == 1): ## a def packet
391                routerSrc = struct.unpack('<L', flow[2:6])
392                sourceId = struct.unpack('<L', flow[6:10])
393                tplId = struct.unpack('<H', flow[10:12])
394                mykeylst = []
395                mykeylst += [str(routerSrc[0])]
396                mykeylst += [str(sourceId[0])]
397                mykeylst += [str(tplId[0])]
398                mykeystr = string.join(mykeylst,"");
399                fields = []
400                fieldNb = struct.unpack('<H', flow[12:14])
401                for i in range(0, fieldNb[0]):
402                    fd = struct.unpack('<H',flow[14+(i*4):16+(i*4)])
403                    tp = struct.unpack('<H',flow[14+(2+i*4):16+(2+i*4)])
404                    fields.insert(i,(fd[0],tp[0]))
405                tpl_def[mykeystr] = fields
406                return ( None, None)
407            if (code[0]==11): ## a data packet
408                routerSrc = struct.unpack('<L', flow[4:8])
409                tmp =  struct.unpack('<L', flow[4:8])
410                fromRouter = socket.inet_ntoa(struct.pack('>L', tmp[0]))
411                sourceId = struct.unpack('<L', flow[8:12])
412                tplId = struct.unpack('<H', flow[12:14])
413                mykeylst = []
414                mykeylst += [str(routerSrc[0])]
415                mykeylst += [str(sourceId[0])]
416                mykeylst += [str(tplId[0])]
417                mykeystr = string.join(mykeylst,"")
418                if (tpl_def.has_key(mykeystr)== True):
419                    field_list = []
420                    index = 0
421                    for i in range (0, len(tpl_def[mykeystr])):
422                        if (tpl_def[mykeystr][i][1]==1):
423                            value = struct.unpack('<B',flow[14+index:15+index])
424                            field_list.insert(i,value[0])
425                        if (tpl_def[mykeystr][i][1]==2):
426                            value = struct.unpack('>H',flow[14+index:16+index])
427                            field_list.insert(i,value[0])
428                        if (tpl_def[mykeystr][i][1]==3):
429                            value = struct.unpack('<BBB',flow[14+index:17+index])
430                            valueTmp = struct.pack('<BBBB',value[2],value[1],value[0],0)
431                            valueFinal = struct.unpack('<L', valueTmp)
432                            valueFinal2 = (valueFinal[0])>>4
433                            field_list.insert(i,valueFinal2)
434                        if (tpl_def[mykeystr][i][1]==4):
435                            if (tpl_def[mykeystr][i][0]==8 or tpl_def[mykeystr][i][0]==12 or tpl_def[mykeystr][i][0]==15 or tpl_def[mykeystr][i][0]==18 or tpl_def[mykeystr][i][0]==47):
436                                value = socket.inet_ntoa(flow[14+index:18+index])
437                                field_list.insert(i,value)
438                            else:
439                                value = struct.unpack('<L', flow[14+index:18+index])
440                                value = struct.unpack('>L', flow[14+index:18+index])
441                                field_list.insert(i,value[0])
442                        if (tpl_def[mykeystr][i][1]==16):
443                            if (os_type==1):
444                                field_list.insert(i,nt_inet_ntop(flow[14+index:30+index]))
445                            else:
446                                tmp = socket.inet_ntop(socket.AF_INET6,flow[14+index:30+index])
447                                field_list.insert(i,tmp)
448                        index += tpl_def[mykeystr][i][1]
449                    return mykeystr, field_list
450##                else:
451##                  print "I'm waiting the tpl def for the key", mykeystr
452##                return (routerSrc[0], field_list)
453            return ( None, None)
454        return ( None, None)
455
456    def socket_close(self):
457        if self.socketnumber:
458           try :
459               self.socketnumber.shutdown(2)
460               self.socketnumber = None
461           except socket.error:
462              pass
463
464def print_hello(widget, event):
465    print "Hello, World!"
466
467def nt_inet_ntop(packed_ip):
468    cpt = 0
469    double = 0
470    string_ip = ""
471    tmp = binascii.hexlify(packed_ip[0:2])
472    if ( int(tmp,16)!=0 ):
473        string_ip += tmp
474        tmp = binascii.hexlify(packed_ip[2:4])
475        if ( int(tmp,16)==0 ):
476            cpt+=1
477            double = 1
478            if (cpt==1):
479                string_ip += ":"
480        else:
481            cpt=0
482            string_ip += ":"+tmp
483        tmp = binascii.hexlify(packed_ip[4:6])
484        if ( int(tmp,16)==0 ):
485            cpt+=1
486            double = 1
487            if (cpt==1):
488                string_ip += ":"
489        else:
490            cpt=0
491            string_ip += ":"+tmp
492        tmp = binascii.hexlify(packed_ip[6:8])
493        if ( int(tmp,16)==0 ):
494            if (double==1 and cpt==0):
495                string_ip += ":0"
496            else:
497                cpt+=1
498                double = 1
499                if (cpt==1):
500                    string_ip += ":"
501        else:
502            cpt=0
503            string_ip += ":"+tmp
504        tmp = binascii.hexlify(packed_ip[8:10])
505        if ( int(tmp,16)==0 ):
506            if (double==1 and cpt==0):
507                string_ip += ":0"
508            else:
509                cpt+=1
510                double = 1
511                if (cpt==1):
512                    string_ip += ":"
513        else:
514            cpt=0
515            string_ip += ":"+tmp
516        tmp = binascii.hexlify(packed_ip[10:12])
517        if ( int(tmp,16)==0 ):
518            if (double==1 and cpt==0):
519                string_ip += ":0"
520            else:
521                cpt+=1
522                double = 1
523                if (cpt==1):
524                    string_ip += ":"
525        else:
526            cpt=0
527            string_ip += ":"+tmp
528        tmp = binascii.hexlify(packed_ip[12:14])
529        if ( int(tmp,16)==0 ):
530            if (double==1 and cpt==0):
531                string_ip += ":0"
532            else:
533                cpt+=1
534                double = 1
535                if (cpt==1):
536                    string_ip += ":"
537        else:
538            cpt=0
539            string_ip += ":"+tmp
540        tmp = binascii.hexlify(packed_ip[14:16])
541        if ( int(tmp,16) != 0 ):
542            string_ip += ":"+tmp
543        else:
544            string_ip += ":"
545    else:
546        string_ip = "::"
547    return string_ip
548
549def timer_action():
550    global record_file, record_file_name, myTimer, myCPT, rrt
551    myCPT+=1
552    myTimer.cancel()
553    my_new_file_name = "%s_%s.txt" % (record_file_name,time.strftime("%Y%m%d%H%M", time.gmtime()))
554    ##my_new_file_name = "%s_%d" % (record_file_name,myCPT)
555    print my_new_file_name
556    new_record_file = file(my_new_file_name, 'a+')
557    old_record_file = record_file
558    record_file = new_record_file
559    old_record_file.close()
560    now2 = time.time()
561    reste = rrt-(operator.mod(now2,rrt))
562    myTimer = threading.Timer(rrt,timer_action)
563    myTimer.start()
564
565def RotRec():
566    global record, myTimer, rrt
567
568if __name__ == "__main__":
569    global comboRouter, os_type, printShit
570
571    os_type = 0
572    print ""
573    print ""
574    print ""
575 
576    print "----------------------------------------------------------------------------"
577    print " renetcolRC is part of renetcol "
578    print " This module writed in python is a remote client which can received flows "
579    print " information from renetcol. It was built from renetcolGUI source without "
580    print " the gtk interface and without the interaction with renetcol."
581    print " To receive flows from renetcol the filter with the field number 69 MUST be"
582    print " actived on renetcol (in your file rules.txt)"
583    print "----------------------------------------------------------------------------"
584   
585    if (os.name =="nt"):
586        os_type = 1
587    elif (os.name =="posix"):
588        os_type = 0
589    else:
590        os_type = 3
591
592    parser = OptionParser()
593    parser.add_option("-o", "--output", dest="out", help ="Output filename prefix, ex: \"/tmp/myrecord\", timestamp will be added to the filename")
594    parser.add_option("-t", "--time", dest="tim", help ="Round robin interval (in seconde), default is \"3600\" for 1h")
595    (options, args) = parser.parse_args()
596    outputFileName = options.out
597    rrt = int(options.tim)
598
599    if (outputFileName!=None):
600        record = 1
601        record_file_name = outputFileName
602        record_file = file(record_file_name, 'a+')
603        RotRec()
604    else:
605        record = 0
606
607    print ""
608    print ""
609    print ""
610    print "---------------------------------------"
611    print " STARTING RECORD ROTATION"
612    print " with following parameters:"
613    print " output filename prefix :",outputFileName
614    print " interval: ",rrt, " seconds"
615    print "---------------------------------------"
616    now2 = time.time()
617    reste = rrt-(operator.mod(now2,rrt))
618    myTimer = threading.Timer(rrt,timer_action)
619    myTimer.start()
620    ##myTimer.cancel()
621    ##print "STOPPING RECORD ROTATION"
622
623    myInputControlThread = InputControl(localAddr, localPort)
624    myInputControlThread.start()
625       
Note: See TracBrowser for help on using the browser.