1
0

update-mac-vendors.pl 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #!/usr/bin/perl
  2. #
  3. # Copyright (C) Roman Dmitriev, rnd@rajven.ru
  4. #
  5. use utf8;
  6. use warnings;
  7. use Encode;
  8. use open qw(:std :encoding(UTF-8));
  9. no warnings 'utf8';
  10. use English;
  11. use FindBin '$Bin';
  12. use lib "/opt/Eye/scripts";
  13. use Data::Dumper;
  14. use eyelib::config;
  15. use eyelib::main;
  16. use eyelib::database;
  17. use eyelib::common;
  18. use eyelib::net_utils;
  19. use strict;
  20. use warnings;
  21. binmode(STDOUT, ':encoding(utf8)');
  22. binmode(STDERR, ':encoding(utf8)');
  23. my $clean_run = $ARGV[0] || '';
  24. my $batch_size = 1000;
  25. # Очищаем таблицу если нужно
  26. if ($clean_run eq 'clean') {
  27. do_sql($dbh, "TRUNCATE TABLE mac_vendors");
  28. print "Таблица очищена\n";
  29. }
  30. # Получаем существующие OUI из базы
  31. my %existing_oui;
  32. if ($clean_run ne 'clean') {
  33. print "Получаем существующие OUI из базы...\n";
  34. my $sth = $dbh->prepare("SELECT oui FROM mac_vendors");
  35. $sth->execute;
  36. while (my ($oui) = $sth->fetchrow_array) {
  37. $existing_oui{$oui} = 1;
  38. }
  39. $sth->finish;
  40. print "Найдено существующих записей: " . scalar(keys %existing_oui) . "\n";
  41. }
  42. my $filename = "/opt/Eye/scripts/utils/mac-oids/manuf.csv";
  43. open(my $fh, '<:encoding(utf8)', $filename)
  44. or die "Не удалось открыть файл $filename: $!";
  45. print "Обработка файла...\n";
  46. my @batch_data;
  47. my $total_processed = 0;
  48. my $total_inserted = 0;
  49. my $line_num = 0;
  50. while (my $line = <$fh>) {
  51. $line_num++;
  52. chomp $line;
  53. # Пропускаем пустые строки
  54. next if $line =~ /^\s*$/;
  55. # Пропускаем заголовок
  56. next if $line_num == 1 && $line =~ /^MAC Prefix/;
  57. # Разбиваем на поля
  58. my @fields = split(/;/, $line, 3);
  59. my $oui = $fields[0] || '';
  60. my $company = $fields[1] || '';
  61. my $address = $fields[2] || '';
  62. # Убираем кавычки если есть
  63. $oui =~ s/^\"|\"$//g;
  64. $company =~ s/^\"|\"$//g;
  65. $address =~ s/^\"|\"$//g;
  66. # Очищаем данные
  67. $oui = trim($oui);
  68. $company = trim($company);
  69. $address = trim($address);
  70. # Пропускаем если нет OUI
  71. next unless $oui && $oui =~ /\S/;
  72. # Убираем маску подсети
  73. $oui =~ s{/[0-9]+}{};
  74. # Нормализуем MAC
  75. $oui = mac_splitted($oui);
  76. # Проверяем минимальную длину
  77. next unless length($oui) >= 8;
  78. # Пропускаем если уже есть в базе
  79. next if $existing_oui{$oui};
  80. # Добавляем в пакет
  81. push @batch_data, [$oui, $company, $address];
  82. $total_processed++;
  83. # Вставляем пакет при достижении размера
  84. if (@batch_data >= $batch_size) {
  85. $total_inserted += insert_batch_simple(\@batch_data);
  86. @batch_data = ();
  87. }
  88. # Прогресс
  89. print "Обработано строк: $line_num\r" if ($line_num % 1000 == 0);
  90. }
  91. close $fh;
  92. # Вставляем остатки
  93. if (@batch_data) {
  94. $total_inserted += insert_batch_simple(\@batch_data);
  95. }
  96. print "\n\nИтоги:\n";
  97. print "Обработано строк: $total_processed\n";
  98. print "Добавлено записей: $total_inserted\n";
  99. print "Done!\n";
  100. exit;
  101. # Простая пакетная вставка
  102. sub insert_batch_simple {
  103. my ($batch_ref) = @_;
  104. my @data = @$batch_ref;
  105. return 0 unless @data;
  106. my $sth = $dbh->prepare("
  107. INSERT INTO mac_vendors (oui, companyname, companyaddress)
  108. VALUES (?, ?, ?)
  109. ");
  110. $dbh->begin_work;
  111. my $inserted = 0;
  112. foreach my $row (@data) {
  113. my ($oui, $company, $address) = @$row;
  114. eval {
  115. $sth->execute($oui, $company, $address);
  116. $inserted++;
  117. };
  118. if ($@) {
  119. warn "Ошибка при вставке $oui: $@\n";
  120. }
  121. }
  122. $dbh->commit;
  123. $sth->finish;
  124. return $inserted;
  125. }