root/trunk/tool/renetcolRC.py @ 149

Revision 149, 20.5 KB (checked in by andreu, 12 years ago)

Correction of timer 360 -> 300 and new message at startup

Line 
1
2##  File: renetcolRC.py
3 
4##  Authors: ANDREU Francois-Xavier
5 
6##  Copyright (C) 2010 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
41########### DEFAULT VALUES, YOU MUST CHANGE IT ###############################
42IPversion = 4
43localAddr = ''
44localAddr6 = '0::'
45localPort = 2222
46collectorAddr = "127.0.0.1"
47collectorAddr6 = "0::"
48collectorPort = 52571  # if you change this port number, apply the
49                       # modification on the renetcolSender.h file
50                       # and you'll need a new compilation of the colllector
51##############################################################################
52
53myInputControlThread = None
54printValue =      [ 0,1,1,0,1,0,0,1,1,0, # 0 to 9
55                    0,1,1,0,0,0,1,1,0,0, # 10...
56                    1,0,0,0,0,0,0,1,1,0, #
57                    0,0,0,0,0,0,0,0,0,0, #
58                    0,0,0,0,0,0,1,1,0,0, #
59                    0,0,0,0,0,0,0,0,0,0, #
60                    0,0,0,0,0,0,0,0,0,1, #
61                    1,1,1,1,1,1,1,1,1,1, #
62                    0,0,0,0,0,0,0,0,0,0,  # 80 to 89
63                    0,0,0,0,0,0,0,0,0,0, #
64                    0,0,0,0,0,0,0,0,0,0, #
65                    0,0,0,0,0,0,0,0,0,0, #
66                    0,0,0,0,0,0,0,0,0,0, #
67                    0,0,0,0,0,0,0,0,0,0 # 130 to 139
68                    ]
69firstParseValue = [ 0,0,0,0,0,0,0,0,0,0,
70                    0,0,0,0,0,0,0,0,0,0,
71                    0,0,0,0,0,0,0,0,0,0,
72                    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 # 130 to 139
83                    ]
84checkUpValues =   [ 0,0,0,0,0,0,0,0,0,0,
85                    0,0,0,0,0,0,0,0,0,0,
86                    0,0,0,0,0,0,0,0,0,0,
87                    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 # 130 to 139
98                    ]
99fieldsName =  [ "","IN_BYT","IN_PKTS","","PROT","TOS","TCP_FL","S_PORT","IPv4@S","S_MASK",
100                "InSNMP","D_PORT","IPv4@D","D_MASK","OutSNMP","NextHop","S_AS","D_AS","","",
101                "TTL","TTL","","","","","","IPv6@S","IPv6@D","IPv6_S_MASK",
102                "IPv6_D_MASK","","","","","","","","","",
103                "","","","","","","M_T_L_T","M_T_L_@","","",
104                "","","","","","","","","","",
105                "","","","","","","","","","ROUTER",
106                "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",
107                "","","","","","","","","","", # 80 to 89
108                "","","","","","","","","","",
109                "","","","","","","","","","",
110                "","","","","","","","","","",
111                "","","","","","","","","","",
112                "","","","","","","","","","" # 130 to 139
113                ]
114flowCpt = 0
115mask = [ 0,0,0 ]
116spaceSep = " "
117tabSep = "\t"
118freeze = 0
119record = 0
120record_file_name = ""
121record_file = None
122is_already_see = 0
123collectorRule=""
124router=0
125tpl_def = {}
126os_type = 0
127oldTpl = 0
128fromRouter = ""
129myTimer = None
130myCPT = 1
131
132class InputControl(threading.Thread):
133    def kill(self, timeout):
134        self.imRunning = 0
135        time.sleep(1)
136        print "\n.\n..\n..."
137        time.sleep(1)
138        print "....\n.....\n......"       
139        time.sleep(1)
140        if self.myFlowInput:
141            self.myFlowInput.socket_close()
142        self.join(timeout)
143       
144    def __init__(self, address, port):
145        self.imRunning = 1
146        self.currentflow = None
147        threading.Thread.__init__(self)
148        self.myFlowInput = FlowInput(address, port)
149
150    def run(self):
151        global freeze, record
152        while self.imRunning:
153            if self.myFlowInput:
154                tmp = self.myFlowInput.get_flow()
155                if (tmp[0]!=None):
156                    self.currentflow = Flow(tmp)
157                    if (freeze==0) & self.currentflow.enable():
158                        self.currentflow.print_flow2()
159                    if (record==1) & self.currentflow.enable():
160                        self.currentflow.write_flow2()
161##                else:
162##                    self.myFlowInput = None
163   
164class Flow:
165    def __init__(self, data):
166        self.flow = [ data[0], data[1] ]
167
168# flow selection
169    def enable(self):
170        global firstParseValue, checkUpValues, tpl_def, fromRouter
171        res = 1
172        resS = 1
173        resD = 1
174        for i in range (0, len(tpl_def[self.flow[0]])):
175            f = tpl_def[self.flow[0]][i][0]
176            # or f==15 or f==18 or f==47
177            if ( f==8 ) and ( checkUpValues[f]==1 ):
178                resS = resS & ( ((struct.unpack('>L',(socket.inet_aton(self.flow[1][i])))[0] & mask[1-1]) == firstParseValue[f]) )
179            elif ( f==12 ) and ( checkUpValues[f]==1 ):
180                resD = resD & ( ((struct.unpack('>L',(socket.inet_aton(self.flow[1][i])))[0] & mask[1-1]) == firstParseValue[f]) )
181            elif ( i==27 or i==28 ):
182                pass
183            elif ( (f==1) and (checkUpValues[f]==1) ):
184                res = res & ( (self.flow[1][i] <= ((firstParseValue[f])+((firstParseValue[f])*5/100))) and ((self.flow[1][i] >= ((firstParseValue[f])-((firstParseValue[f])*5/100)))) )
185            elif (checkUpValues[f]==1):
186                res = res & (self.flow[1][i] == firstParseValue[f])
187        if ( checkUpValues[69]==1 ):
188            res = res & ( (fromRouter == firstParseValue[69]) )
189        res = res & (resS or resD)
190        return res
191
192# flow print
193    def print_flow2(self):
194        global printValue, tpl_def, flowCpt, fieldsName, oldTpl, os_type, fromRouter
195        myliste = []
196        myTpl = []
197        strFlow = ""
198        strField = ""
199        underscore_line = ""
200        flowCpt+=1
201        if (flowCpt%60 == 0 or oldTpl != self.flow[0]):
202##        if (flowCpt%100 == 0):
203            flowCpt = 0
204            for i in range (0, len(tpl_def[self.flow[0]])):
205                f = tpl_def[self.flow[0]][i][0]
206                if printValue[f]:
207                    if ( f==27 or f==28 or f==62 or f==63 ):
208                        strField += str(fieldsName[f])
209                        l = len(str(fieldsName[f]))
210                        if ((40-l)%8 == 0):
211                            tabNb = int((40-l)/8)
212                        else:
213                            tabNb = int((40-l)/8) + 1
214                        for j in range (0, tabNb):
215                            strField += "\t"
216                        for k in range (0, 40):
217                            underscore_line += "-"
218                    elif ( f==8 or f==15 or f==12 or f==18 or f==47 ):
219                        strField += str(fieldsName[f])
220                        l = len(str(fieldsName[f]))
221                        if ((16-l)%8 == 0):
222                            tabNb = int((16-l)/8)
223                        else:
224                            tabNb = int((16-l)/8) + 1
225                        for j in range (0, tabNb):
226                            strField += "\t"
227                        for k in range (0, 16):
228                            underscore_line += "-"
229                    else:
230                        strField += str(fieldsName[f])
231                        strField += "\t"
232                        for k in range (0, 8):
233                            underscore_line += "-"
234            if (oldTpl != self.flow[0]):
235                print " "
236            if (os_type == 0):
237                esc = '\x1b['
238                sep = ';'
239                end = 'm'
240                if (printValue[69]):
241                    rt = str(fieldsName[69])
242                    toprint = esc+"37"+sep+"44"+end+strField+rt+esc+"0"+end
243                else:
244                    toprint = esc+"37"+sep+"44"+end+strField+esc+"0"+end
245                print toprint
246            else:
247                if (printValue[69]):
248                    strField += str(fieldsName[69])
249                print strField
250                print underscore_line
251        for i in range (0, len(tpl_def[self.flow[0]])):
252            f = tpl_def[self.flow[0]][i][0]
253            if printValue[f]:
254                if ( f==27 or f==28 or f==62 or f==63 ):
255                    strFlow += str(self.flow[1][i])
256                    l = len(str(self.flow[1][i]))
257                    if ((40-l)%8 == 0):
258                        tabNb = int((40-l)/8)
259                    else:
260                        tabNb = int((40-l)/8) + 1
261                    for j in range (0, tabNb):
262                        strFlow += "\t"
263                elif ( f==8 or f==12 or f==15 or f==18 or f==47 ):
264                    strFlow += str(self.flow[1][i])
265                    l = len(str(self.flow[1][i]))
266                    if ((16-l)%8 == 0):
267                        tabNb = int((16-l)/8)
268                    else:
269                        tabNb = int((16-l)/8) + 1
270                    for j in range (0, tabNb):
271                        strFlow += "\t"
272                elif (f==21):
273                    myliste += [str(self.flow[1][i]-self.flow[1][i+1])]
274                    strFlow += str(self.flow[1][i]-self.flow[1][i+1])
275                    strFlow += "\t"
276                elif (f==22):
277                    pass
278                else:
279                    myliste += [str(self.flow[1][i])]
280                    strFlow += str(self.flow[1][i])
281                    for k in range (len(str(self.flow[1][i])), 7):
282                        strFlow += " "
283                    strFlow += "\t"
284        if (printValue[69]):
285            strFlow += fromRouter
286        print strFlow
287        oldTpl = self.flow[0]
288
289# flow record
290    def write_flow2(self):
291        global printValue, record_file, tpl_def
292        myliste = []
293        for i in range (0, len(tpl_def[self.flow[0]])):
294            f = tpl_def[self.flow[0]][i][0]
295            if printValue[f]:
296                if (f==21):
297                    myliste += [str(self.flow[1][i]-self.flow[1][i+1])]
298                elif (f==22):
299                    pass
300                else:
301                    myliste += [str(self.flow[1][i])]
302        theflow = string.join(myliste, "\t")+"\t"+fromRouter+"\n"
303        if (record_file!=None):
304            record_file.write(theflow)
305       
306class FlowInput:
307    def __init__(self, h, p):
308        self.HOST = h
309        self.PORT = p
310        if (IPversion == 4):
311            self.socketnumber = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
312        elif (IPversion == 6):
313            self.socketnumber = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
314        else:
315            print "IP protocol ", IPversion ," not supported"
316            exit(0)
317        self.socketnumber.bind((self.HOST, self.PORT))
318   
319    def get_flow(self):
320        global collectorRule, tpl_def, os_type, fromRouter
321        if (self.socketnumber!=None):
322            data = self.socketnumber.recvfrom(1024)
323            flow = data[0]
324            code = struct.unpack('<H', flow[0:2])
325            if (code[0] == 1): ## a def packet
326                routerSrc = struct.unpack('<L', flow[2:6])
327                sourceId = struct.unpack('<L', flow[6:10])
328                tplId = struct.unpack('<H', flow[10:12])
329                mykeylst = []
330                mykeylst += [str(routerSrc[0])]
331                mykeylst += [str(sourceId[0])]
332                mykeylst += [str(tplId[0])]
333                mykeystr = string.join(mykeylst,"");
334                fields = []
335                fieldNb = struct.unpack('<H', flow[12:14])
336                for i in range(0, fieldNb[0]):
337                    fd = struct.unpack('<H',flow[14+(i*4):16+(i*4)])
338                    tp = struct.unpack('<H',flow[14+(2+i*4):16+(2+i*4)])
339                    fields.insert(i,(fd[0],tp[0]))
340                tpl_def[mykeystr] = fields
341                return ( None, None)
342            if (code[0]==11): ## a data packet
343                routerSrc = struct.unpack('<L', flow[4:8])
344                tmp =  struct.unpack('<L', flow[4:8])
345                fromRouter = socket.inet_ntoa(struct.pack('>L', tmp[0]))
346                sourceId = struct.unpack('<L', flow[8:12])
347                tplId = struct.unpack('<H', flow[12:14])
348                mykeylst = []
349                mykeylst += [str(routerSrc[0])]
350                mykeylst += [str(sourceId[0])]
351                mykeylst += [str(tplId[0])]
352                mykeystr = string.join(mykeylst,"")
353                if (tpl_def.has_key(mykeystr)== True):
354                    field_list = []
355                    index = 0
356                    for i in range (0, len(tpl_def[mykeystr])):
357                        if (tpl_def[mykeystr][i][1]==1):
358                            value = struct.unpack('<B',flow[14+index:15+index])
359                            field_list.insert(i,value[0])
360                        if (tpl_def[mykeystr][i][1]==2):
361                            value = struct.unpack('>H',flow[14+index:16+index])
362                            field_list.insert(i,value[0])
363                        if (tpl_def[mykeystr][i][1]==3):
364                            value = struct.unpack('<BBB',flow[14+index:17+index])
365                            valueTmp = struct.pack('<BBBB',value[2],value[1],value[0],0)
366                            valueFinal = struct.unpack('<L', valueTmp)
367                            valueFinal2 = (valueFinal[0])>>4
368                            field_list.insert(i,valueFinal2)
369                        if (tpl_def[mykeystr][i][1]==4):
370                            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):
371                                value = socket.inet_ntoa(flow[14+index:18+index])
372                                field_list.insert(i,value)
373                            else:
374                                value = struct.unpack('<L', flow[14+index:18+index])
375                                value = struct.unpack('>L', flow[14+index:18+index])
376                                field_list.insert(i,value[0])
377                        if (tpl_def[mykeystr][i][1]==16):
378                            if (os_type==1):
379                                field_list.insert(i,nt_inet_ntop(flow[14+index:30+index]))
380                            else:
381                                tmp = socket.inet_ntop(socket.AF_INET6,flow[14+index:30+index])
382                                field_list.insert(i,tmp)
383                        index += tpl_def[mykeystr][i][1]
384                    return mykeystr, field_list
385##                else:
386##                  print "I'm waiting the tpl def for the key", mykeystr
387##                return (routerSrc[0], field_list)
388            return ( None, None)
389        return ( None, None)
390
391    def socket_close(self):
392        if self.socketnumber:
393           try :
394               self.socketnumber.shutdown(2)
395               self.socketnumber = None
396           except socket.error:
397              pass
398
399def print_hello(widget, event):
400    print "Hello, World!"
401
402def nt_inet_ntop(packed_ip):
403    cpt = 0
404    double = 0
405    string_ip = ""
406    tmp = binascii.hexlify(packed_ip[0:2])
407    if ( int(tmp,16)!=0 ):
408        string_ip += tmp
409        tmp = binascii.hexlify(packed_ip[2:4])
410        if ( int(tmp,16)==0 ):
411            cpt+=1
412            double = 1
413            if (cpt==1):
414                string_ip += ":"
415        else:
416            cpt=0
417            string_ip += ":"+tmp
418        tmp = binascii.hexlify(packed_ip[4:6])
419        if ( int(tmp,16)==0 ):
420            cpt+=1
421            double = 1
422            if (cpt==1):
423                string_ip += ":"
424        else:
425            cpt=0
426            string_ip += ":"+tmp
427        tmp = binascii.hexlify(packed_ip[6:8])
428        if ( int(tmp,16)==0 ):
429            if (double==1 and cpt==0):
430                string_ip += ":0"
431            else:
432                cpt+=1
433                double = 1
434                if (cpt==1):
435                    string_ip += ":"
436        else:
437            cpt=0
438            string_ip += ":"+tmp
439        tmp = binascii.hexlify(packed_ip[8:10])
440        if ( int(tmp,16)==0 ):
441            if (double==1 and cpt==0):
442                string_ip += ":0"
443            else:
444                cpt+=1
445                double = 1
446                if (cpt==1):
447                    string_ip += ":"
448        else:
449            cpt=0
450            string_ip += ":"+tmp
451        tmp = binascii.hexlify(packed_ip[10:12])
452        if ( int(tmp,16)==0 ):
453            if (double==1 and cpt==0):
454                string_ip += ":0"
455            else:
456                cpt+=1
457                double = 1
458                if (cpt==1):
459                    string_ip += ":"
460        else:
461            cpt=0
462            string_ip += ":"+tmp
463        tmp = binascii.hexlify(packed_ip[12:14])
464        if ( int(tmp,16)==0 ):
465            if (double==1 and cpt==0):
466                string_ip += ":0"
467            else:
468                cpt+=1
469                double = 1
470                if (cpt==1):
471                    string_ip += ":"
472        else:
473            cpt=0
474            string_ip += ":"+tmp
475        tmp = binascii.hexlify(packed_ip[14:16])
476        if ( int(tmp,16) != 0 ):
477            string_ip += ":"+tmp
478        else:
479            string_ip += ":"
480    else:
481        string_ip = "::"
482    return string_ip
483
484def timer_action():
485    global record_file, record_file_name, myTimer, myCPT
486    myCPT+=1
487    myTimer.cancel()
488    my_new_file_name = "%s_%s_%d" % (record_file_name,time.strftime("%Y%m%d", time.gmtime()),myCPT)
489    ##my_new_file_name = "%s_%d" % (record_file_name,myCPT)
490    print my_new_file_name
491    new_record_file = file(my_new_file_name, 'w')
492    old_record_file = record_file
493    record_file = new_record_file
494    old_record_file.close()
495    now2 = time.time()
496    reste = 300-(operator.mod(now2,300))
497    myTimer = threading.Timer(300.0,timer_action)
498    myTimer.start()
499
500def callback_RotRec(widget, data=None):
501    global record, myTimer
502    if ((record == 0) and (widget.get_active() == 1)):
503        info_dialog(widget, None, "You must before activated the record ! ")
504        widget.set_active(0)
505    else:
506        if widget.get_active() == 1:
507            print "STARTING RECORD ROTATION"
508            now2 = time.time()
509            reste = 300-(operator.mod(now2,300))
510            myTimer = threading.Timer(300,timer_action)
511            myTimer.start()
512        if widget.get_active() == 0:
513            myTimer.cancel()
514            print "STOPPING RECORD ROTATION"
515
516if __name__ == "__main__":
517    global comboRouter, os_type, printShit
518    global localAddr, localPort
519   
520    if (os.name =="nt"):
521        os_type = 1
522    elif (os.name =="posix"):
523        os_type = 0
524    else:
525        os_type = 3
526
527    myInputControlThread = InputControl(localAddr, localPort)
528    myInputControlThread.start()
529       
530    print "---------------------------------------------------------------"
531    print " renetcolRC is part of renetcol "
532    print " this module is a remote client which can recieved flow \ "
533    print " information from renetcol. "
534    print "----------------------------------------------------------------"
Note: See TracBrowser for help on using the browser.