Changeset 300 for trunk/klask
- Timestamp:
- Oct 4, 2017, 7:37:31 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/klask
r299 r300 882 882 } 883 883 884 #--------------------------------------------------------------- 885 sub update_switchdb { 886 my %args = ( 887 verbose => 0, 888 @_); 889 890 init_switch_names('yes'); #nomme les switchs 891 print "\n"; 892 893 my %where = (); 894 my %db_switch_output_port = (); 895 my %db_switch_ip_hostnamefq = (); 896 897 DETECT_ALL_ROUTER: 898 for my $one_router ( get_list_main_router(get_list_network()) ) { 899 print "Info: router loop $one_router\n" if $args{'verbose'}; 900 my %resol_arp = resolve_ip_arp_host($one_router, q{*}, q{low}); # resolution arp 901 902 next DETECT_ALL_ROUTER if $resol_arp{'mac_address'} eq 'unknow'; 903 print "VERBOSE_1: Router detected $resol_arp{'ipv4_address'} - $resol_arp{'mac_address'}\n" if $args{'verbose'}; 904 905 my $vlan_name = get_current_vlan_name_for_interface($resol_arp{'interface'}); 906 my $vlan_id = get_current_vlan_id($vlan_name); 907 $where{$resol_arp{'ipv4_address'}} = find_all_switch_port($resol_arp{'mac_address'}, $vlan_id); # retrouve les emplacements des routeurs 908 } 909 910 ALL_ROUTER_IP_ADDRESS: 911 for my $ip_router (Net::Netmask::sort_by_ip_address(keys %where)) { # '194.254.66.254')) { 912 913 next ALL_ROUTER_IP_ADDRESS if not exists $where{$ip_router}; # /a priori/ idiot car ne sers à rien... 914 915 ALL_SWITCH_CONNECTED: 916 for my $switch_detected ( keys %{$where{$ip_router}} ) { 917 918 my $switch = $where{$ip_router}->{$switch_detected}; 919 920 next ALL_SWITCH_CONNECTED if $switch->{'port_id'} eq '0'; 921 922 $db_switch_output_port{$switch->{'hostname'}} = $switch->{'port_hr'}; 923 print "VERBOSE_2: output port $switch->{'hostname'} : $switch->{'port_hr'}\n" if $args{'verbose'}; 924 } 925 } 926 927 my %db_switch_link_with = (); 928 929 my @list_all_switch = (); 930 my @list_switch_ipv4 = (); 931 for my $sw (@SWITCH_LIST) { 932 push @list_all_switch, $sw->{'hostname'}; 933 } 934 935 my $timestamp = time; 936 937 ALL_SWITCH: 938 for my $one_switch (@list_all_switch) { 939 my %resol_arp = resolve_ip_arp_host($one_switch, q{*}, q{low}); # arp resolution 940 if (exists $SWITCH_DB{$one_switch}{'fake-ip'}) { 941 my $fake_ip = $SWITCH_DB{$one_switch}{'fake-ip'}; 942 fast_ping($fake_ip); 943 print "WARNING: fake ip on switch $one_switch -> $fake_ip / $resol_arp{'ipv4_address'}\n" if $args{'verbose'}; 944 my %resol_arp_alt = resolve_ip_arp_host($fake_ip, q{*}, q{low}); # arp resolution 945 if ($resol_arp_alt{'mac_address'} ne 'unknow') { 946 $resol_arp{'mac_address'} = $resol_arp_alt{'mac_address'}; 947 $resol_arp{'interface'} = $resol_arp_alt{'interface'}; 948 $resol_arp{'ipv4_address'} .= '*'; 949 # Force a MAC trace on switch 950 system "arping -c 1 -w 1 -rR -i $resol_arp_alt{'interface'} $fake_ip > /dev/null 2>&1"; 951 } 952 } 953 print "Info: switch loop $one_switch\n" if $args{'verbose'}; 954 next ALL_SWITCH if $resol_arp{'mac_address'} eq 'unknow'; 955 956 push @list_switch_ipv4, $resol_arp{'ipv4_address'}; 957 958 my $vlan_name = get_current_vlan_name_for_interface($resol_arp{'interface'}); 959 my $vlan_id = get_current_vlan_id($vlan_name); 960 $where{$resol_arp{'ipv4_address'}} = find_all_switch_port($resol_arp{'mac_address'}, $vlan_id); # find port on all switch 961 962 if ($args{'verbose'}) { 963 print "VERBOSE_3: $one_switch $resol_arp{'ipv4_address'} $resol_arp{'mac_address'}\n"; 964 print "VERBOSE_3: $one_switch --- ", 965 join(' + ', keys %{$where{$resol_arp{'ipv4_address'}}}), 966 "\n"; 967 } 968 969 $db_switch_ip_hostnamefq{$resol_arp{'ipv4_address'}} = $resol_arp{'hostname_fq'}; 970 print "VERBOSE_4: db_switch_ip_hostnamefq $resol_arp{'ipv4_address'} -> $resol_arp{'hostname_fq'}\n" if $args{'verbose'}; 971 972 $SWITCH_DB{$one_switch}->{'ipv4_address'} = $resol_arp{'ipv4_address'}; 973 $SWITCH_DB{$one_switch}->{'mac_address'} = $resol_arp{'mac_address'}; 974 $SWITCH_DB{$one_switch}->{'timestamp'} = $timestamp; 975 $SWITCH_DB{$one_switch}->{'network'} = $vlan_name; 976 } 977 978 ALL_SWITCH_IP_ADDRESS: 979 for my $ip (@list_switch_ipv4) { 980 # for my $ip (Net::Netmask::sort_by_ip_address(@list_switch_ipv4)) { 981 982 print "VERBOSE_5: loop on $db_switch_ip_hostnamefq{$ip}\n" if $args{'verbose'}; 983 984 next ALL_SWITCH_IP_ADDRESS if not exists $where{$ip}; 985 # next ALL_SWITCH_IP_ADDRESS if not exists $SWITCH_PORT_COUNT{ $db_switch_ip_hostnamefq{$ip} }; 986 987 DETECTED_SWITCH: 988 for my $switch_detected ( keys %{$where{$ip}} ) { 989 990 my $switch = $where{$ip}->{$switch_detected}; 991 print "VERBOSE_6: $db_switch_ip_hostnamefq{$ip} -> $switch->{'hostname'} : $switch->{'port_hr'}\n" if $args{'verbose'}; 992 993 next if $switch->{'port_id'} eq '0'; 994 next if $switch->{'port_hr'} eq $db_switch_output_port{$switch->{'hostname'}}; 995 next if $switch->{'hostname'} eq $db_switch_ip_hostnamefq{$ip}; # $computerdb->{$ip}{'hostname'}; 996 997 $db_switch_link_with{ $db_switch_ip_hostnamefq{$ip} } ||= {}; 998 $db_switch_link_with{ $db_switch_ip_hostnamefq{$ip} }->{ $switch->{'hostname'} } = $switch->{'port_hr'}; 999 print "VERBOSE_7: +++++\n" if $args{'verbose'}; 1000 } 1001 1002 } 1003 1004 my %db_switch_connected_on_port = (); 1005 my $maybe_more_than_one_switch_connected = 'yes'; 1006 my $cloop = 0; 1007 1008 while ($maybe_more_than_one_switch_connected eq 'yes' and $cloop < 100) { 1009 $cloop++; 1010 print "VERBOSE_9: cloop reduction step: $cloop\n" if $args{'verbose'}; 1011 for my $sw (keys %db_switch_link_with) { 1012 for my $connect (keys %{$db_switch_link_with{$sw}}) { 1013 1014 my $port_hr = $db_switch_link_with{$sw}->{$connect}; 1015 1016 $db_switch_connected_on_port{"$connect$SEP_SWITCH_PORT$port_hr"} ||= {}; 1017 $db_switch_connected_on_port{"$connect$SEP_SWITCH_PORT$port_hr"}->{$sw}++; # Just to define the key 1018 } 1019 } 1020 1021 $maybe_more_than_one_switch_connected = 'no'; 1022 1023 SWITCH_AND_PORT: 1024 for my $swport (keys %db_switch_connected_on_port) { 1025 1026 next if keys %{$db_switch_connected_on_port{$swport}} == 1; 1027 1028 $maybe_more_than_one_switch_connected = 'yes'; 1029 1030 my ($sw_connect, $port_connect) = split m/ $SEP_SWITCH_PORT /xms, $swport, 2; 1031 my @sw_on_same_port = keys %{$db_switch_connected_on_port{$swport}}; 1032 print "VERBOSE_10: $swport -- ".$#sw_on_same_port." -- @sw_on_same_port\n" if $args{'verbose'}; 1033 1034 CONNECTED: 1035 for my $sw_connected (@sw_on_same_port) { 1036 1037 next CONNECTED if not keys %{$db_switch_link_with{$sw_connected}} == 1; 1038 1039 $db_switch_connected_on_port{$swport} = {$sw_connected => 1}; 1040 1041 for my $other_sw (@sw_on_same_port) { 1042 next if $other_sw eq $sw_connected; 1043 1044 delete $db_switch_link_with{$other_sw}->{$sw_connect}; 1045 } 1046 1047 # We can not do better for this switch for this loop 1048 next SWITCH_AND_PORT; 1049 } 1050 } 1051 } 1052 1053 my %db_switch_parent =(); 1054 1055 for my $sw (keys %db_switch_link_with) { 1056 for my $connect (keys %{$db_switch_link_with{$sw}}) { 1057 1058 my $port_hr = $db_switch_link_with{$sw}->{$connect}; 1059 1060 $db_switch_connected_on_port{"$connect$SEP_SWITCH_PORT$port_hr"} ||= {}; 1061 $db_switch_connected_on_port{"$connect$SEP_SWITCH_PORT$port_hr"}->{$sw} = $port_hr; 1062 1063 $db_switch_parent{$sw} = {switch => $connect, port_hr => $port_hr}; 1064 } 1065 } 1066 1067 print "Switch output port and parent port connection\n"; 1068 print "---------------------------------------------\n"; 1069 for my $sw (sort keys %db_switch_output_port) { 1070 if (exists $db_switch_parent{$sw}) { 1071 printf "%-28s %2s +--> %2s %-25s\n", $sw, $db_switch_output_port{$sw}, $db_switch_parent{$sw}->{'port_hr'}, $db_switch_parent{$sw}->{'switch'}; 1072 } 1073 else { 1074 printf "%-28s %2s +--> router\n", $sw, $db_switch_output_port{$sw}; 1075 } 1076 } 1077 print "\n"; 1078 1079 print "Switch parent and children port inter-connection\n"; 1080 print "------------------------------------------------\n"; 1081 for my $swport (sort keys %db_switch_connected_on_port) { 1082 my ($sw_connect, $port_connect) = split m/ $SEP_SWITCH_PORT /xms, $swport, 2; 1083 for my $sw (keys %{$db_switch_connected_on_port{$swport}}) { 1084 if (exists $db_switch_output_port{$sw}) { 1085 printf "%-28s %2s <--+ %2s %-25s\n", $sw_connect, $port_connect, $db_switch_output_port{$sw}, $sw; 1086 } 1087 else { 1088 printf "%-28s %2s <--+ %-25s\n", $sw_connect, $port_connect, $sw; 1089 } 1090 } 1091 } 1092 1093 my $switch_connection = { 1094 output_port => \%db_switch_output_port, 1095 parent => \%db_switch_parent, 1096 connected_on_port => \%db_switch_connected_on_port, 1097 link_with => \%db_switch_link_with, 1098 switch_db => \%SWITCH_DB, 1099 timestamp => $timestamp, 1100 checksum => get_switchdb_checksum(%SWITCH_DB), 1101 }; 1102 1103 YAML::Syck::DumpFile("$KLASK_SW_FILE", $switch_connection); 1104 return; 1105 } 1106 884 1107 ################################################################ 885 1108 # command … … 1084 1307 my $switch_connection = YAML::Syck::LoadFile("$KLASK_SW_FILE"); 1085 1308 if ($switch_checksum ne $switch_connection->{'checksum'}) { # Verify checksum 1086 print "ERROR: switch database must be rebuild\n"; 1309 print "WARNING: switch database is going to be rebuilt\n"; 1310 update_switchdb(verbose => $verbose); 1087 1311 } 1088 1312 … … 2522 2746 2523 2747 #--------------------------------------------------------------- 2524 sub update_switchdb {2525 my %args = (2526 verbose => 0,2527 @_);2528 2529 init_switch_names('yes'); #nomme les switchs2530 print "\n";2531 2532 my %where = ();2533 my %db_switch_output_port = ();2534 my %db_switch_ip_hostnamefq = ();2535 2536 DETECT_ALL_ROUTER:2537 for my $one_router ( get_list_main_router(get_list_network()) ) {2538 print "Info: router loop $one_router\n" if $args{'verbose'};2539 my %resol_arp = resolve_ip_arp_host($one_router, q{*}, q{low}); # resolution arp2540 2541 next DETECT_ALL_ROUTER if $resol_arp{'mac_address'} eq 'unknow';2542 print "VERBOSE_1: Router detected $resol_arp{'ipv4_address'} - $resol_arp{'mac_address'}\n" if $args{'verbose'};2543 2544 my $vlan_name = get_current_vlan_name_for_interface($resol_arp{'interface'});2545 my $vlan_id = get_current_vlan_id($vlan_name);2546 $where{$resol_arp{'ipv4_address'}} = find_all_switch_port($resol_arp{'mac_address'}, $vlan_id); # retrouve les emplacements des routeurs2547 }2548 2549 ALL_ROUTER_IP_ADDRESS:2550 for my $ip_router (Net::Netmask::sort_by_ip_address(keys %where)) { # '194.254.66.254')) {2551 2552 next ALL_ROUTER_IP_ADDRESS if not exists $where{$ip_router}; # /a priori/ idiot car ne sers à rien...2553 2554 ALL_SWITCH_CONNECTED:2555 for my $switch_detected ( keys %{$where{$ip_router}} ) {2556 2557 my $switch = $where{$ip_router}->{$switch_detected};2558 2559 next ALL_SWITCH_CONNECTED if $switch->{'port_id'} eq '0';2560 2561 $db_switch_output_port{$switch->{'hostname'}} = $switch->{'port_hr'};2562 print "VERBOSE_2: output port $switch->{'hostname'} : $switch->{'port_hr'}\n" if $args{'verbose'};2563 }2564 }2565 2566 my %db_switch_link_with = ();2567 2568 my @list_all_switch = ();2569 my @list_switch_ipv4 = ();2570 for my $sw (@SWITCH_LIST) {2571 push @list_all_switch, $sw->{'hostname'};2572 }2573 2574 my $timestamp = time;2575 2576 ALL_SWITCH:2577 for my $one_switch (@list_all_switch) {2578 my %resol_arp = resolve_ip_arp_host($one_switch, q{*}, q{low}); # arp resolution2579 if (exists $SWITCH_DB{$one_switch}{'fake-ip'}) {2580 my $fake_ip = $SWITCH_DB{$one_switch}{'fake-ip'};2581 fast_ping($fake_ip);2582 print "WARNING: fake ip on switch $one_switch -> $fake_ip / $resol_arp{'ipv4_address'}\n" if $args{'verbose'};2583 my %resol_arp_alt = resolve_ip_arp_host($fake_ip, q{*}, q{low}); # arp resolution2584 if ($resol_arp_alt{'mac_address'} ne 'unknow') {2585 $resol_arp{'mac_address'} = $resol_arp_alt{'mac_address'};2586 $resol_arp{'interface'} = $resol_arp_alt{'interface'};2587 $resol_arp{'ipv4_address'} .= '*';2588 # Force a MAC trace on switch2589 system "arping -c 1 -w 1 -rR -i $resol_arp_alt{'interface'} $fake_ip > /dev/null 2>&1";2590 }2591 }2592 print "Info: switch loop $one_switch\n" if $args{'verbose'};2593 next ALL_SWITCH if $resol_arp{'mac_address'} eq 'unknow';2594 2595 push @list_switch_ipv4, $resol_arp{'ipv4_address'};2596 2597 my $vlan_name = get_current_vlan_name_for_interface($resol_arp{'interface'});2598 my $vlan_id = get_current_vlan_id($vlan_name);2599 $where{$resol_arp{'ipv4_address'}} = find_all_switch_port($resol_arp{'mac_address'}, $vlan_id); # find port on all switch2600 2601 if ($args{'verbose'}) {2602 print "VERBOSE_3: $one_switch $resol_arp{'ipv4_address'} $resol_arp{'mac_address'}\n";2603 print "VERBOSE_3: $one_switch --- ",2604 join(' + ', keys %{$where{$resol_arp{'ipv4_address'}}}),2605 "\n";2606 }2607 2608 $db_switch_ip_hostnamefq{$resol_arp{'ipv4_address'}} = $resol_arp{'hostname_fq'};2609 print "VERBOSE_4: db_switch_ip_hostnamefq $resol_arp{'ipv4_address'} -> $resol_arp{'hostname_fq'}\n" if $args{'verbose'};2610 2611 $SWITCH_DB{$one_switch}->{'ipv4_address'} = $resol_arp{'ipv4_address'};2612 $SWITCH_DB{$one_switch}->{'mac_address'} = $resol_arp{'mac_address'};2613 $SWITCH_DB{$one_switch}->{'timestamp'} = $timestamp;2614 $SWITCH_DB{$one_switch}->{'network'} = $vlan_name;2615 }2616 2617 ALL_SWITCH_IP_ADDRESS:2618 for my $ip (@list_switch_ipv4) {2619 # for my $ip (Net::Netmask::sort_by_ip_address(@list_switch_ipv4)) {2620 2621 print "VERBOSE_5: loop on $db_switch_ip_hostnamefq{$ip}\n" if $args{'verbose'};2622 2623 next ALL_SWITCH_IP_ADDRESS if not exists $where{$ip};2624 # next ALL_SWITCH_IP_ADDRESS if not exists $SWITCH_PORT_COUNT{ $db_switch_ip_hostnamefq{$ip} };2625 2626 DETECTED_SWITCH:2627 for my $switch_detected ( keys %{$where{$ip}} ) {2628 2629 my $switch = $where{$ip}->{$switch_detected};2630 print "VERBOSE_6: $db_switch_ip_hostnamefq{$ip} -> $switch->{'hostname'} : $switch->{'port_hr'}\n" if $args{'verbose'};2631 2632 next if $switch->{'port_id'} eq '0';2633 next if $switch->{'port_hr'} eq $db_switch_output_port{$switch->{'hostname'}};2634 next if $switch->{'hostname'} eq $db_switch_ip_hostnamefq{$ip}; # $computerdb->{$ip}{'hostname'};2635 2636 $db_switch_link_with{ $db_switch_ip_hostnamefq{$ip} } ||= {};2637 $db_switch_link_with{ $db_switch_ip_hostnamefq{$ip} }->{ $switch->{'hostname'} } = $switch->{'port_hr'};2638 print "VERBOSE_7: +++++\n" if $args{'verbose'};2639 }2640 2641 }2642 2643 my %db_switch_connected_on_port = ();2644 my $maybe_more_than_one_switch_connected = 'yes';2645 my $cloop = 0;2646 2647 while ($maybe_more_than_one_switch_connected eq 'yes' and $cloop < 100) {2648 $cloop++;2649 print "VERBOSE_9: cloop reduction step: $cloop\n" if $args{'verbose'};2650 for my $sw (keys %db_switch_link_with) {2651 for my $connect (keys %{$db_switch_link_with{$sw}}) {2652 2653 my $port_hr = $db_switch_link_with{$sw}->{$connect};2654 2655 $db_switch_connected_on_port{"$connect$SEP_SWITCH_PORT$port_hr"} ||= {};2656 $db_switch_connected_on_port{"$connect$SEP_SWITCH_PORT$port_hr"}->{$sw}++; # Just to define the key2657 }2658 }2659 2660 $maybe_more_than_one_switch_connected = 'no';2661 2662 SWITCH_AND_PORT:2663 for my $swport (keys %db_switch_connected_on_port) {2664 2665 next if keys %{$db_switch_connected_on_port{$swport}} == 1;2666 2667 $maybe_more_than_one_switch_connected = 'yes';2668 2669 my ($sw_connect, $port_connect) = split m/ $SEP_SWITCH_PORT /xms, $swport, 2;2670 my @sw_on_same_port = keys %{$db_switch_connected_on_port{$swport}};2671 print "VERBOSE_10: $swport -- ".$#sw_on_same_port." -- @sw_on_same_port\n" if $args{'verbose'};2672 2673 CONNECTED:2674 for my $sw_connected (@sw_on_same_port) {2675 2676 next CONNECTED if not keys %{$db_switch_link_with{$sw_connected}} == 1;2677 2678 $db_switch_connected_on_port{$swport} = {$sw_connected => 1};2679 2680 for my $other_sw (@sw_on_same_port) {2681 next if $other_sw eq $sw_connected;2682 2683 delete $db_switch_link_with{$other_sw}->{$sw_connect};2684 }2685 2686 # We can not do better for this switch for this loop2687 next SWITCH_AND_PORT;2688 }2689 }2690 }2691 2692 my %db_switch_parent =();2693 2694 for my $sw (keys %db_switch_link_with) {2695 for my $connect (keys %{$db_switch_link_with{$sw}}) {2696 2697 my $port_hr = $db_switch_link_with{$sw}->{$connect};2698 2699 $db_switch_connected_on_port{"$connect$SEP_SWITCH_PORT$port_hr"} ||= {};2700 $db_switch_connected_on_port{"$connect$SEP_SWITCH_PORT$port_hr"}->{$sw} = $port_hr;2701 2702 $db_switch_parent{$sw} = {switch => $connect, port_hr => $port_hr};2703 }2704 }2705 2706 print "Switch output port and parent port connection\n";2707 print "---------------------------------------------\n";2708 for my $sw (sort keys %db_switch_output_port) {2709 if (exists $db_switch_parent{$sw}) {2710 printf "%-28s %2s +--> %2s %-25s\n", $sw, $db_switch_output_port{$sw}, $db_switch_parent{$sw}->{'port_hr'}, $db_switch_parent{$sw}->{'switch'};2711 }2712 else {2713 printf "%-28s %2s +--> router\n", $sw, $db_switch_output_port{$sw};2714 }2715 }2716 print "\n";2717 2718 print "Switch parent and children port inter-connection\n";2719 print "------------------------------------------------\n";2720 for my $swport (sort keys %db_switch_connected_on_port) {2721 my ($sw_connect, $port_connect) = split m/ $SEP_SWITCH_PORT /xms, $swport, 2;2722 for my $sw (keys %{$db_switch_connected_on_port{$swport}}) {2723 if (exists $db_switch_output_port{$sw}) {2724 printf "%-28s %2s <--+ %2s %-25s\n", $sw_connect, $port_connect, $db_switch_output_port{$sw}, $sw;2725 }2726 else {2727 printf "%-28s %2s <--+ %-25s\n", $sw_connect, $port_connect, $sw;2728 }2729 }2730 }2731 2732 my $switch_connection = {2733 output_port => \%db_switch_output_port,2734 parent => \%db_switch_parent,2735 connected_on_port => \%db_switch_connected_on_port,2736 link_with => \%db_switch_link_with,2737 switch_db => \%SWITCH_DB,2738 timestamp => $timestamp,2739 checksum => get_switchdb_checksum(%SWITCH_DB),2740 };2741 2742 YAML::Syck::DumpFile("$KLASK_SW_FILE", $switch_connection);2743 return;2744 }2745 2746 #---------------------------------------------------------------2747 2748 sub cmd_updatesw { 2748 2749 @ARGV = @_;
Note: See TracChangeset
for help on using the changeset viewer.