640 | | button = gtk.CheckButton(" router ") |
641 | | button.connect("toggled", callback_check_rule, None) |
642 | | coll_hbox.pack_start(button, False, False, 0) |
643 | | mainTT.set_tip(button, "Check it to capture all flows from one router and enter the IPv4 address of this router. IN TEST") |
644 | | button.show() |
| 640 | ## button = gtk.CheckButton(" router ") |
| 641 | ## button.connect("toggled", callback_check_rule, None) |
| 642 | ## coll_hbox.pack_start(button, False, False, 0) |
| 643 | ## mainTT.set_tip(button, "Check it to capture all flows from one router and enter the IPv4 address of this router. IN TEST") |
| 644 | ## button.show() |
647 | | prefix_entry(45, "Required Format : \n <field> <operation> <address>\nlike 8 = 10.0.0.1 \nor 8 = 10.0.1.0/24 \nor 27 = 2001::1 \nor 27 = 2001::/64 (IPv6 address only on Linux system)\nonly '=' operator for the moment\n------------------------------\nIn this version 0.0.7, you can compare the following fields:\nROUTER_SRC_ADDR: 0\nIN_BYTES: 1\nL4_PROT: 4\nL4_SRC_PORT: 7\nIPV4_SRC_ADDR: 8\nINPUT_SNMP: 10\nL4_DST_PORT: 11\nIPV4_DST_ADDR: 12\nOUTPUT_SNMP: 14\nIPV4_NEXT_HOP: 15\nSRC_AS: 16\nDST_AS: 17\nBGP_IPV4_NEXT_HOP: 18\nIPV6_SRC_ADDR: 27\nIPV6_DST_ADDR: 28\nIPV6_NEXT_HOP: 62\nBPG_IPV6_NEXT_HOP: 63\nIP_PROTOCOL_VERSION: 60\n---------------------------", coll_pbbox, "", 0) |
| 647 | prefix_entry(249, "Required Format : \n<field> = <value>[ & <field> = <value>]\ |
| 648 | \nlike \ |
| 649 | \n8 = 10.0.0.4 \ |
| 650 | \n\t(all flows from IP Source 10.0.0.4)\ |
| 651 | \nor 8 = 10.0.1.0/24 \ |
| 652 | \n\t(all flows with IP Source in subnet 10.0.1.0/24)\ |
| 653 | \nor 27 = 2001::1 (IPv6 address only on Linux system)\ |
| 654 | \n\t(all flows from IP Source 2001::1)\ |
| 655 | \nor 27 = 2001::/64 \ |
| 656 | \n\t(all flows with IP Source in subnet 2001::/64)\ |
| 657 | \nor 0 = 10.0.0.1 & 4 = 1\ |
| 658 | \n\t(all ICMP flows from router 10.0.0.1)\ |
| 659 | \nonly equal operator in this release\ |
| 660 | \nmaximum 4 logical '&' for one filter (limit 249 chars)\ |
| 661 | \n----------------------------------\ |
| 662 | \n---- NetFlow Fields list ------\ |
| 663 | \nROUTER_SRC_ADDR:\t 0\ |
| 664 | \nIN_BYTES:\t\t\t 1\ |
| 665 | \nL4_PROT:\t\t\t 4\ |
| 666 | \nL4_SRC_PORT:\t\t 7\ |
| 667 | \nIPV4_SRC_ADDR:\t\t 8\ |
| 668 | \nINPUT_SNMP:\t\t\t10\ |
| 669 | \nL4_DST_PORT:\t\t11\ |
| 670 | \nIPV4_DST_ADDR:\t\t12\ |
| 671 | \nOUTPUT_SNMP:\t\t14\ |
| 672 | \nIPV4_NEXT_HOP:\t\t15\ |
| 673 | \nSRC_AS:\t\t\t\t16\ |
| 674 | \nDST_AS:\t\t\t\t17\ |
| 675 | \nBGP_IPV4_NEXT_HOP:\t18\ |
| 676 | \nIPV6_SRC_ADDR:\t\t27\ |
| 677 | \nIPV6_DST_ADDR:\t\t28\ |
| 678 | \nIPV6_NEXT_HOP:\t\t62\ |
| 679 | \nBPG_IPV6_NEXT_HOP:\t63\ |
| 680 | \nIP_PROT_VERSION:\t60\ |
| 681 | \n---------------------------", coll_pbbox, "", 0) |
| 797 | def sent_rule_from_cli(msg): |
| 798 | global collectorAddr, collectorPort, collectorAddr6, IPversion |
| 799 | s = None |
| 800 | if (IPversion==4): |
| 801 | tmpaf = socket.AF_INET |
| 802 | addr = collectorAddr |
| 803 | port = collectorPort |
| 804 | elif (IPversion == 6): |
| 805 | tmpaf = socket.AF_INET6 |
| 806 | addr = collectorAddr6 |
| 807 | port = collectorPort |
| 808 | else: |
| 809 | print "Wrong IP version : ", IPversion |
| 810 | exit(0) |
| 811 | for res in socket.getaddrinfo(addr, port, tmpaf, socket.SOCK_STREAM): |
| 812 | af, socktype, proto, canonname, sa = res |
| 813 | try: |
| 814 | s = socket.socket(af, socktype, proto) |
| 815 | except socket.error, msg: |
| 816 | s = None |
| 817 | continue |
| 818 | try: |
| 819 | s.connect(sa) |
| 820 | except socket.error, msg: |
| 821 | s.close() |
| 822 | s = None |
| 823 | continue |
| 824 | break |
| 825 | if s is None: |
| 826 | check_dialog( None, None, "could not open socket") |
| 827 | else: |
| 828 | s.send(msg) |
| 829 | check_dialog( None, None, "Action was sent") |
| 830 | s.close() |
| 831 | |
772 | | rule = entry_text.split(' ') |
773 | | field = rule[0] |
774 | | operator = rule[1] |
775 | | value = rule[2] |
776 | | if (field=='0' or field=='8' or field=='12' or field=='15' or field=='18' or field=='47'): |
777 | | if (re.match('^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(/\d{1,2})?$',value)): |
778 | | splitter = value.split('/') |
779 | | adip = struct.unpack('>L',socket.inet_aton(splitter[0]))[0] |
780 | | if len(splitter)>1: |
781 | | bits = int(splitter[1]) |
782 | | if bits <= 32 and bits > 0: |
783 | | mask[1] = 0xffffffffL << (32 - bits) |
| 842 | ## here we parse the filter, possibility of many filter concatened with '&' operator |
| 843 | filters = entry_text.split('&') |
| 844 | if len(filters)>5: |
| 845 | check_dialog( widget, None, "No more 4 '&' !") |
| 846 | is_ok = 0 |
| 847 | else: |
| 848 | is_ok = 1 |
| 849 | for f in filters: |
| 850 | rule = f.split(' ') |
| 851 | if len(mymsg)==0: |
| 852 | field = rule[0] |
| 853 | operator = rule[1] |
| 854 | value = rule[2] |
| 855 | mymsg = "C" + "_" + field + "_" + operator + "_" + value |
| 856 | else: |
| 857 | field = rule[1] |
| 858 | operator = rule[2] |
| 859 | value = rule[3] |
| 860 | mymsg += "_C" + "_" + field + "_" + operator + "_" + value |
| 861 | print f |
| 862 | print mymsg |
| 863 | if (field=='0' or field=='8' or field=='12' or field=='15' or field=='18' or field=='47'): |
| 864 | if (re.match('^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(/\d{1,2})?$',value)): |
| 865 | splitter = value.split('/') |
| 866 | adip = struct.unpack('>L',socket.inet_aton(splitter[0]))[0] |
| 867 | if len(splitter)>1: |
| 868 | bits = int(splitter[1]) |
| 869 | if bits <= 32 and bits > 0: |
| 870 | mask[1] = 0xffffffffL << (32 - bits) |
| 871 | is_good = 1 |
| 872 | else: |
| 873 | check_dialog( widget, None, "Wrong value in mask!") |
| 874 | is_good = 0 |
| 875 | else: |
| 876 | value = value+"/32" |
| 877 | mask[1] = 0xffffffffL |
| 878 | is_good = 1 |
| 879 | else: |
| 880 | check_dialog( widget, None, "Wrong value !") |
| 881 | if (field=='27' or field=='28' or field=='62'): |
| 882 | ipv6ad_mask = value.split('/') |
| 883 | if len(ipv6ad_mask)==1: |
| 884 | try: |
| 885 | socket.gethostbyaddr(value) |
| 886 | is_good = 1 |
| 887 | except socket.gaierror: |
| 888 | check_dialog( widget, None, "Wrong value !") |
| 889 | except socket.herror: ## can't resolv |
| 890 | check_dialog( widget, None, "I can't resolv !") |
| 891 | except socket.error: |
| 892 | check_dialog( widget, None, "Error in gethostbyaddr()!") |
| 893 | else: |
| 894 | is_good = 1 |
| 895 | ##here, check the prefix value? |
| 896 | if (field=='60' or field=='46'): |
| 897 | if (int(value) < 256): |
788 | | else: |
789 | | value = value+"/32" |
790 | | mask[1] = 0xffffffffL |
791 | | is_good = 1 |
792 | | else: |
793 | | check_dialog( widget, None, "Wrong value !") |
794 | | if (field=='27' or field=='28' or field=='62'): |
795 | | ipv6ad_mask = value.split('/') |
796 | | if len(ipv6ad_mask)==1: |
797 | | try: |
798 | | socket.gethostbyaddr(value) |
799 | | is_good = 1 |
800 | | except socket.gaierror: |
801 | | check_dialog( widget, None, "Wrong value !") |
802 | | except socket.herror: ## can't resolv |
803 | | check_dialog( widget, None, "I can't resolv !") |
804 | | except socket.error: |
805 | | check_dialog( widget, None, "Error in gethostbyaddr()!") |
806 | | else: |
807 | | is_good = 1 |
808 | | ##here, check the prefix value? |
809 | | if (field=='60' or field=='46'): |
810 | | if (int(value) < 256): |
811 | | is_good = 1 |
812 | | else: |
813 | | check_dialog( widget, None, "Wrong value, must be < 256 !") |
814 | | is_good = 0 |
815 | | if (field=='1'): |
816 | | if (int(value) < 4294967295): |
817 | | is_good = 1 |
818 | | else: |
819 | | check_dialog( widget, None, "Wrong value, must be < 4294967295 !") |
820 | | is_good = 0 |
821 | | if (field=='7' or field=='11' or field=='4'): |
822 | | if (int(value) < 65536): |
823 | | is_good = 1 |
824 | | else: |
825 | | check_dialog( widget, None, "Wrong value, must be < 65536 !") |
826 | | is_good = 0 |
827 | | if (field=='10' or field=='14' or field=='16' or field=='17'): |
828 | | if (int(value) < 65536): |
829 | | is_good = 1 |
830 | | else: |
831 | | check_dialog( widget, None, "Wrong value, must be < 65536 !") |
832 | | is_good = 0 |
833 | | if (is_good==1): |
| 902 | if (field=='1'): |
| 903 | if (int(value) < 4294967295): |
| 904 | is_good = 1 |
| 905 | else: |
| 906 | check_dialog( widget, None, "Wrong value, must be < 4294967295 !") |
| 907 | is_good = 0 |
| 908 | if (field=='7' or field=='11' or field=='4'): |
| 909 | if (int(value) < 65536): |
| 910 | is_good = 1 |
| 911 | else: |
| 912 | check_dialog( widget, None, "Wrong value, must be < 65536 !") |
| 913 | is_good = 0 |
| 914 | if (field=='10' or field=='14' or field=='16' or field=='17'): |
| 915 | if (int(value) < 65536): |
| 916 | is_good = 1 |
| 917 | else: |
| 918 | check_dialog( widget, None, "Wrong value, must be < 65536 !") |
| 919 | is_good = 0 |
| 920 | if (is_good==1 and is_ok==1): |
| 1168 | parser = OptionParser() |
| 1169 | parser.add_option("-r", "--router", dest="rtr", help ="router address used for NetFlow data export") |
| 1170 | parser.add_option("-i", "--index", dest="ind", help ="Interface index get with snmpwalk") |
| 1171 | (options, args) = parser.parse_args() |
| 1172 | rtr = options.rtr |
| 1173 | ind = options.ind |
| 1174 | |
| 1175 | if len(sys.argv)==5: |
| 1176 | myInputControlThread = InputControl(localAddr, localPort) |
| 1177 | myInputControlThread.start() |
| 1178 | msg = str(localPort) + " C_0_=_" + rtr + "_C_10_=_" + ind |
| 1179 | print msg |
| 1180 | sent_rule_from_cli(msg) |
| 1181 | |