Commit 4395076d7fa9d2aac8e71e13f679e50d2f8cb067
Committed by
Eduardo Santos
1 parent
be5b7045
Exists in
master
Várias correções nas coletas das impressoras, incluindo problema que só exportava o último contador.
Showing
5 changed files
with
373 additions
and
17 deletions
Show diff stats
README.md
1 | -cocar-agente | 1 | +Instalação |
2 | ============ | 2 | ============ |
3 | 3 | ||
4 | Módulo agente coletor para o software Cocar | 4 | Módulo agente coletor para o software Cocar |
@@ -11,3 +11,26 @@ Para funcionar é necessário primeiro instalar o pacote da distribuição e só | @@ -11,3 +11,26 @@ Para funcionar é necessário primeiro instalar o pacote da distribuição e só | ||
11 | virtualenv --system-site-packages -p /usr/bin/python2.7 cocar-agente | 11 | virtualenv --system-site-packages -p /usr/bin/python2.7 cocar-agente |
12 | </pre> | 12 | </pre> |
13 | 13 | ||
14 | + | ||
15 | +Operação | ||
16 | +================ | ||
17 | + | ||
18 | +Descrição dos principais comandos de operação | ||
19 | + | ||
20 | +* Varredura contínua de rede | ||
21 | + | ||
22 | +<pre> | ||
23 | +/srv/cocar-agente/bin/paster scan continous_scan | ||
24 | +</pre> | ||
25 | + | ||
26 | +* Leitura e export do contador das impressoras | ||
27 | + | ||
28 | +<pre> | ||
29 | +/srv/cocar-agente/bin/paster scan printer_scan -t 10000000 | ||
30 | +</pre> | ||
31 | + | ||
32 | +* Coleta de MAC address que não foi inicialmente identificado | ||
33 | + | ||
34 | +<pre> | ||
35 | +/srv/cocar-agente/bin/paster scan scan_mac_all -a eth0 -t 10 | ||
36 | +</pre> | ||
14 | \ No newline at end of file | 37 | \ No newline at end of file |
cocar/commands/scan_commands.py
@@ -16,10 +16,11 @@ from ..model.printer import Printer, PrinterCounter | @@ -16,10 +16,11 @@ from ..model.printer import Printer, PrinterCounter | ||
16 | from ..model.host import Host | 16 | from ..model.host import Host |
17 | from ..model.computer import Computer | 17 | from ..model.computer import Computer |
18 | from ..csv_utils import NetworkCSV | 18 | from ..csv_utils import NetworkCSV |
19 | -from ..session import NmapSession, SnmpSession | 19 | +from ..session import NmapSession, SnmpSession, ArpSession |
20 | from multiprocessing import Process, Queue | 20 | from multiprocessing import Process, Queue |
21 | from ..xml_utils import NmapXML | 21 | from ..xml_utils import NmapXML |
22 | from sqlalchemy.exc import IntegrityError | 22 | from sqlalchemy.exc import IntegrityError |
23 | +from sqlalchemy import and_ | ||
23 | 24 | ||
24 | log = logging.getLogger() | 25 | log = logging.getLogger() |
25 | 26 | ||
@@ -75,6 +76,12 @@ class ScanCommands(command.Command): | @@ -75,6 +76,12 @@ class ScanCommands(command.Command): | ||
75 | help='Arquivo individual de rede para ser carregado' | 76 | help='Arquivo individual de rede para ser carregado' |
76 | ) | 77 | ) |
77 | 78 | ||
79 | + parser.add_option('-a', '--iface', | ||
80 | + action='store', | ||
81 | + dest='iface', | ||
82 | + help='Interface de rede para utilizar no Arping' | ||
83 | + ) | ||
84 | + | ||
78 | def __init__(self, name): | 85 | def __init__(self, name): |
79 | """ | 86 | """ |
80 | Constructor method | 87 | Constructor method |
@@ -134,6 +141,15 @@ class ScanCommands(command.Command): | @@ -134,6 +141,15 @@ class ScanCommands(command.Command): | ||
134 | if cmd == 'import_printers': | 141 | if cmd == 'import_printers': |
135 | self.import_printers() | 142 | self.import_printers() |
136 | return | 143 | return |
144 | + if cmd == 'get_mac': | ||
145 | + self.get_mac() | ||
146 | + return | ||
147 | + if cmd == 'scan_mac': | ||
148 | + self.scan_mac() | ||
149 | + return | ||
150 | + if cmd == 'scan_mac_all': | ||
151 | + self.scan_mac() | ||
152 | + return | ||
137 | else: | 153 | else: |
138 | log.error('Command "%s" not recognized' % (cmd,)) | 154 | log.error('Command "%s" not recognized' % (cmd,)) |
139 | 155 | ||
@@ -286,6 +302,7 @@ class ScanCommands(command.Command): | @@ -286,6 +302,7 @@ class ScanCommands(command.Command): | ||
286 | while True: | 302 | while True: |
287 | log.info("Iniciando scan de redes...") | 303 | log.info("Iniciando scan de redes...") |
288 | self.scan_networks() | 304 | self.scan_networks() |
305 | + | ||
289 | log.info("Scan de redes finalizado. Iniciando procedimento de " | 306 | log.info("Scan de redes finalizado. Iniciando procedimento de " |
290 | "identificação de ativos de rede, computadores e impressoras") | 307 | "identificação de ativos de rede, computadores e impressoras") |
291 | self.load_network_files() | 308 | self.load_network_files() |
@@ -305,17 +322,31 @@ class ScanCommands(command.Command): | @@ -305,17 +322,31 @@ class ScanCommands(command.Command): | ||
305 | log.info("EXPORT DE IMPRESSORAS FINALIZADO!!! Reiniciando as coletas") | 322 | log.info("EXPORT DE IMPRESSORAS FINALIZADO!!! Reiniciando as coletas") |
306 | #time.sleep(600) | 323 | #time.sleep(600) |
307 | 324 | ||
325 | + def scan_mac_all(self): | ||
326 | + """ | ||
327 | + Fica varrendo a rede tentando arrumar os MAC's | ||
328 | + """ | ||
329 | + print("*** Aperente CTRL+C para encerrar a execução ***") | ||
330 | + | ||
331 | + while True: | ||
332 | + self.scan_mac() | ||
333 | + log.info("SCAN DE MAC FINALIZADO!!!") | ||
334 | + | ||
308 | def export_printers(self): | 335 | def export_printers(self): |
309 | """ | 336 | """ |
310 | Exporta todos os contadores para o Cocar | 337 | Exporta todos os contadores para o Cocar |
311 | """ | 338 | """ |
312 | session = self.cocar.Session | 339 | session = self.cocar.Session |
313 | - results = session.query(Printer).all() | 340 | + results = session.query(Printer).join( |
341 | + PrinterCounter.__table__, | ||
342 | + PrinterCounter.network_ip == Printer.network_ip | ||
343 | + ).all() | ||
314 | for printer in results: | 344 | for printer in results: |
315 | log.info("Exportando impressora %s", printer.network_ip) | 345 | log.info("Exportando impressora %s", printer.network_ip) |
316 | printer.export_printer(server_url=self.cocar.config.get('cocar', 'server_url'), session=session) | 346 | printer.export_printer(server_url=self.cocar.config.get('cocar', 'server_url'), session=session) |
317 | 347 | ||
318 | session.close() | 348 | session.close() |
349 | + log.info("EXPORT DAS IMPRESSORAS FINALIZADO!!! %s IMPRESSORAS EXPORTADAS!!!", len(results)) | ||
319 | 350 | ||
320 | def get_printer_attribute(self): | 351 | def get_printer_attribute(self): |
321 | """ | 352 | """ |
@@ -457,6 +488,30 @@ class ScanCommands(command.Command): | @@ -457,6 +488,30 @@ class ScanCommands(command.Command): | ||
457 | session = self.cocar.Session | 488 | session = self.cocar.Session |
458 | for hostname in nmap_xml.hosts.keys(): | 489 | for hostname in nmap_xml.hosts.keys(): |
459 | host = nmap_xml.identify_host(hostname, timeout=self.options.timeout) | 490 | host = nmap_xml.identify_host(hostname, timeout=self.options.timeout) |
491 | + # Antes de tudo verifica se ele já está na tabela de contadores | ||
492 | + counter = session.query( | ||
493 | + PrinterCounter.__table__ | ||
494 | + ).outerjoin( | ||
495 | + Printer.__table__, | ||
496 | + PrinterCounter.network_ip == Printer.network_ip | ||
497 | + ).filter( | ||
498 | + and_( | ||
499 | + PrinterCounter.network_ip == hostname, | ||
500 | + Printer.network_ip.is_(None) | ||
501 | + ) | ||
502 | + ).first() | ||
503 | + | ||
504 | + if counter is not None: | ||
505 | + # Agora insere a impressora | ||
506 | + log.info("Inserindo impressora com o IP %s", hostname) | ||
507 | + session.execute( | ||
508 | + Printer.__table__.insert().values( | ||
509 | + network_ip=host.network_ip | ||
510 | + ) | ||
511 | + ) | ||
512 | + session.flush() | ||
513 | + continue | ||
514 | + | ||
460 | if isinstance(host, Printer): | 515 | if isinstance(host, Printer): |
461 | # Vê se a impressora já está na base | 516 | # Vê se a impressora já está na base |
462 | results = session.query(Printer).filter(Printer.network_ip == hostname).first() | 517 | results = session.query(Printer).filter(Printer.network_ip == hostname).first() |
@@ -476,8 +531,21 @@ class ScanCommands(command.Command): | @@ -476,8 +531,21 @@ class ScanCommands(command.Command): | ||
476 | network_ip=hostname | 531 | network_ip=hostname |
477 | ) | 532 | ) |
478 | ) | 533 | ) |
479 | - session.flush() | ||
480 | log.info("Impressora %s adicionada novamente com sucesso", hostname) | 534 | log.info("Impressora %s adicionada novamente com sucesso", hostname) |
535 | + | ||
536 | + # Agora atualiza informações do host | ||
537 | + if host.mac_address is not None: | ||
538 | + session.execute( | ||
539 | + Host.__table__.update().values( | ||
540 | + mac_address=host.mac_address, | ||
541 | + name=host.name, | ||
542 | + ports=host.ports | ||
543 | + ).where( | ||
544 | + Host.network_ip == hostname | ||
545 | + ) | ||
546 | + ) | ||
547 | + session.flush() | ||
548 | + log.info("Informações do host %s atualizadas com sucesso", hostname) | ||
481 | else: | 549 | else: |
482 | log.error("ERRO!!! Host não encontrado com o IP!!! %s", hostname) | 550 | log.error("ERRO!!! Host não encontrado com o IP!!! %s", hostname) |
483 | else: | 551 | else: |
@@ -492,8 +560,34 @@ class ScanCommands(command.Command): | @@ -492,8 +560,34 @@ class ScanCommands(command.Command): | ||
492 | session.flush() | 560 | session.flush() |
493 | except IntegrityError, e: | 561 | except IntegrityError, e: |
494 | log.error("Erro adicionando computador com o IP %s. IP Repetido\n%s", hostname, e.message) | 562 | log.error("Erro adicionando computador com o IP %s. IP Repetido\n%s", hostname, e.message) |
563 | + # Agora atualiza informações do host | ||
564 | + if host.mac_address is not None: | ||
565 | + session.execute( | ||
566 | + Host.__table__.update().values( | ||
567 | + mac_address=host.mac_address, | ||
568 | + name=host.name, | ||
569 | + ports=host.ports | ||
570 | + ).where( | ||
571 | + Host.network_ip == hostname | ||
572 | + ) | ||
573 | + ) | ||
574 | + session.flush() | ||
575 | + log.info("Informações do host %s atualizadas com sucesso", hostname) | ||
495 | else: | 576 | else: |
496 | log.info("Computador com o IP %s já cadastrado", hostname) | 577 | log.info("Computador com o IP %s já cadastrado", hostname) |
578 | + # Agora atualiza informações do host | ||
579 | + if host.mac_address is not None: | ||
580 | + session.execute( | ||
581 | + Host.__table__.update().values( | ||
582 | + mac_address=host.mac_address, | ||
583 | + name=host.name, | ||
584 | + ports=host.ports | ||
585 | + ).where( | ||
586 | + Host.network_ip == hostname | ||
587 | + ) | ||
588 | + ) | ||
589 | + session.flush() | ||
590 | + log.info("Informações do host %s atualizadas com sucesso", hostname) | ||
497 | else: | 591 | else: |
498 | # Insere host genérico | 592 | # Insere host genérico |
499 | results = session.query(Host).filter(Host.network_ip == hostname).first() | 593 | results = session.query(Host).filter(Host.network_ip == hostname).first() |
@@ -504,12 +598,42 @@ class ScanCommands(command.Command): | @@ -504,12 +598,42 @@ class ScanCommands(command.Command): | ||
504 | session.flush() | 598 | session.flush() |
505 | except IntegrityError, e: | 599 | except IntegrityError, e: |
506 | log.error("Erro adicionando host genérico com o IP %s. IP Repetido\n%s", hostname, e.message) | 600 | log.error("Erro adicionando host genérico com o IP %s. IP Repetido\n%s", hostname, e.message) |
601 | + | ||
602 | + # Agora atualiza informações do host | ||
603 | + if host.mac_address is not None: | ||
604 | + session.execute( | ||
605 | + Host.__table__.update().values( | ||
606 | + mac_address=host.mac_address, | ||
607 | + name=host.name, | ||
608 | + ports=host.ports | ||
609 | + ).where( | ||
610 | + Host.network_ip == hostname | ||
611 | + ) | ||
612 | + ) | ||
613 | + session.flush() | ||
614 | + log.info("Informações do host %s atualizadas com sucesso", hostname) | ||
507 | else: | 615 | else: |
508 | log.info("Host genérico com o IP %s já cadastrado", hostname) | 616 | log.info("Host genérico com o IP %s já cadastrado", hostname) |
509 | 617 | ||
618 | + # Agora atualiza informações do host | ||
619 | + if host.mac_address is not None: | ||
620 | + session.execute( | ||
621 | + Host.__table__.update().values( | ||
622 | + mac_address=host.mac_address, | ||
623 | + name=host.name, | ||
624 | + ports=host.ports | ||
625 | + ).where( | ||
626 | + Host.network_ip == hostname | ||
627 | + ) | ||
628 | + ) | ||
629 | + session.flush() | ||
630 | + log.info("Informações do host %s atualizadas com sucesso", hostname) | ||
631 | + | ||
510 | #session.flush() | 632 | #session.flush() |
511 | session.close() | 633 | session.close() |
512 | 634 | ||
635 | + log.info("CARGA DO ARQUIVO DE REDE %s FINALIZADA!!!", network_file) | ||
636 | + | ||
513 | def import_printers(self): | 637 | def import_printers(self): |
514 | """ | 638 | """ |
515 | Importa impressoras já cadastradas e não presentes na base local | 639 | Importa impressoras já cadastradas e não presentes na base local |
@@ -535,6 +659,86 @@ class ScanCommands(command.Command): | @@ -535,6 +659,86 @@ class ScanCommands(command.Command): | ||
535 | 659 | ||
536 | session.close() | 660 | session.close() |
537 | 661 | ||
662 | + def get_mac(self): | ||
663 | + """ | ||
664 | + Atualiza MAC Address para o host selecionado | ||
665 | + :return: | ||
666 | + """ | ||
667 | + if type(self.options.hosts) != list: | ||
668 | + self.options.hosts = [self.options.hosts] | ||
669 | + | ||
670 | + session = self.cocar.Session | ||
671 | + for host in self.options.hosts: | ||
672 | + arp = ArpSession( | ||
673 | + host=host, | ||
674 | + iface=self.options.iface, | ||
675 | + timeout=self.options.timeout | ||
676 | + ) | ||
677 | + | ||
678 | + result = arp.scan() | ||
679 | + | ||
680 | + if result is not None: | ||
681 | + log.debug("Atualizando MAC = %s para host = %s", result, host) | ||
682 | + session.execute( | ||
683 | + Host.__table__.update().values( | ||
684 | + mac_address=result | ||
685 | + ).where( | ||
686 | + Host.network_ip == host | ||
687 | + ) | ||
688 | + ) | ||
689 | + session.flush() | ||
690 | + | ||
691 | + session.close() | ||
692 | + | ||
693 | + def scan_mac(self): | ||
694 | + """ | ||
695 | + Scan all hosts to update macs | ||
696 | + """ | ||
697 | + processes = int(self.cocar.config.get('cocar', 'processes')) | ||
698 | + # Create queues | ||
699 | + task_queue = Queue() | ||
700 | + done_queue = Queue() | ||
701 | + | ||
702 | + session = self.cocar.Session | ||
703 | + results = session.query(Host).all() | ||
704 | + for host in results: | ||
705 | + arp = ArpSession( | ||
706 | + host=host.network_ip, | ||
707 | + iface=self.options.iface, | ||
708 | + timeout=self.options.timeout | ||
709 | + ) | ||
710 | + task_queue.put(arp) | ||
711 | + | ||
712 | + #Start worker processes | ||
713 | + for i in range(processes): | ||
714 | + Process(target=worker_mac, args=(task_queue, done_queue)).start() | ||
715 | + | ||
716 | + # Get and print results | ||
717 | + print 'Unordered results:' | ||
718 | + for i in range(len(results)): | ||
719 | + host_list = done_queue.get() | ||
720 | + log.debug(host_list) | ||
721 | + if host_list[1] is None: | ||
722 | + log.error("Nao foi possivel encontrar o mac do host %s", host_list[0]) | ||
723 | + continue | ||
724 | + try: | ||
725 | + log.debug("Atualizando MAC = %s para host = %s", host_list[1], host_list[0]) | ||
726 | + session.execute( | ||
727 | + Host.__table__.update().values( | ||
728 | + mac_address=host_list[1] | ||
729 | + ).where( | ||
730 | + Host.network_ip == host_list[0] | ||
731 | + ) | ||
732 | + ) | ||
733 | + session.flush() | ||
734 | + except AttributeError, e: | ||
735 | + log.error("Erro na atualização do MAC para host %s\n%s", host_list[0], e.message) | ||
736 | + continue | ||
737 | + | ||
738 | + # Tell child processes to stop | ||
739 | + for i in range(processes): | ||
740 | + task_queue.put('STOP') | ||
741 | + | ||
538 | 742 | ||
539 | def make_query(host): | 743 | def make_query(host): |
540 | """This does the actual snmp query | 744 | """This does the actual snmp query |
@@ -558,6 +762,17 @@ def make_query_printer(host): | @@ -558,6 +762,17 @@ def make_query_printer(host): | ||
558 | return host.printer_dict() | 762 | return host.printer_dict() |
559 | 763 | ||
560 | 764 | ||
765 | +def make_query_mac(host): | ||
766 | + """This does the actual snmp query | ||
767 | + | ||
768 | + This is a bit fancy as it accepts both instances | ||
769 | + of SnmpSession and host/ip addresses. This | ||
770 | + allows a user to customize mass queries with | ||
771 | + subsets of different hostnames and community strings | ||
772 | + """ | ||
773 | + return host.scan_list() | ||
774 | + | ||
775 | + | ||
561 | # Function run by worker processes | 776 | # Function run by worker processes |
562 | def worker(inp, output): | 777 | def worker(inp, output): |
563 | for func in iter(inp.get, 'STOP'): | 778 | for func in iter(inp.get, 'STOP'): |
@@ -569,4 +784,11 @@ def worker(inp, output): | @@ -569,4 +784,11 @@ def worker(inp, output): | ||
569 | def worker_printer(inp, output): | 784 | def worker_printer(inp, output): |
570 | for func in iter(inp.get, 'STOP'): | 785 | for func in iter(inp.get, 'STOP'): |
571 | result = make_query_printer(func) | 786 | result = make_query_printer(func) |
787 | + output.put(result) | ||
788 | + | ||
789 | + | ||
790 | +# Function run by worker processes | ||
791 | +def worker_mac(inp, output): | ||
792 | + for func in iter(inp.get, 'STOP'): | ||
793 | + result = make_query_mac(func) | ||
572 | output.put(result) | 794 | output.put(result) |
573 | \ No newline at end of file | 795 | \ No newline at end of file |
cocar/model/printer.py
@@ -46,13 +46,30 @@ class Printer(Host): | @@ -46,13 +46,30 @@ class Printer(Host): | ||
46 | """ | 46 | """ |
47 | Exporta todos os contadores para a impressora | 47 | Exporta todos os contadores para a impressora |
48 | """ | 48 | """ |
49 | - counter_list = session.query( | ||
50 | - PrinterCounter | ||
51 | - ).filter( | ||
52 | - PrinterCounter.network_ip == self.network_ip | ||
53 | - ).all() | ||
54 | - | ||
55 | - for counter in counter_list: | 49 | + #query = session.query( |
50 | + # PrinterCounter | ||
51 | + #).filter( | ||
52 | + # PrinterCounter.__table__.c.network_ip == self.network_ip | ||
53 | + #) | ||
54 | + | ||
55 | + stm = """SELECT printer_counter.network_ip as ip_address, | ||
56 | + host.mac_address, | ||
57 | + host.inclusion_date, | ||
58 | + host.scantime, | ||
59 | + printer.model, | ||
60 | + printer.serial, | ||
61 | + printer.description, | ||
62 | + printer_counter.counter, | ||
63 | + printer_counter.counter_time | ||
64 | +FROM host | ||
65 | +JOIN printer ON host.network_ip = printer.network_ip | ||
66 | +JOIN printer_counter ON printer.network_ip = printer_counter.network_ip | ||
67 | +WHERE printer_counter.network_ip = '%s'""" % self.network_ip | ||
68 | + | ||
69 | + counter_list = session.execute(stm, mapper=PrinterCounter).fetchall() | ||
70 | + | ||
71 | + for elm in counter_list: | ||
72 | + counter = PrinterCounter(**elm) | ||
56 | print(counter) | 73 | print(counter) |
57 | result = counter.export_counter(server_url, session) | 74 | result = counter.export_counter(server_url, session) |
58 | if result: | 75 | if result: |
@@ -61,6 +78,7 @@ class Printer(Host): | @@ -61,6 +78,7 @@ class Printer(Host): | ||
61 | log.error("Erro na remocao do contador %s para a impressora %s", counter.counter, self.network_ip) | 78 | log.error("Erro na remocao do contador %s para a impressora %s", counter.counter, self.network_ip) |
62 | return False | 79 | return False |
63 | 80 | ||
81 | + log.info("EXPORT DA IMPRESSORA %s FINALIZADO!!! %s CONTADORES EXPORTADOS!!!", self.network_ip, len(counter_list)) | ||
64 | return True | 82 | return True |
65 | 83 | ||
66 | 84 | ||
@@ -157,7 +175,7 @@ class PrinterCounter(Printer): | @@ -157,7 +175,7 @@ class PrinterCounter(Printer): | ||
157 | return False | 175 | return False |
158 | 176 | ||
159 | if response.status_code == 200: | 177 | if response.status_code == 200: |
160 | - log.info("Contador para a impressora %s com contador %s" | 178 | + log.info("Contador para a impressora %s com contador %s " |
161 | "exportado com sucesso", self.network_ip, self.counter) | 179 | "exportado com sucesso", self.network_ip, self.counter) |
162 | # Remove o contador | 180 | # Remove o contador |
163 | session.execute( | 181 | session.execute( |
cocar/session.py
@@ -7,6 +7,7 @@ import netsnmp | @@ -7,6 +7,7 @@ import netsnmp | ||
7 | import subprocess | 7 | import subprocess |
8 | import logging | 8 | import logging |
9 | from . import Cocar | 9 | from . import Cocar |
10 | +import re | ||
10 | 11 | ||
11 | log = logging.getLogger() | 12 | log = logging.getLogger() |
12 | 13 | ||
@@ -247,4 +248,80 @@ class NmapSession(object): | @@ -247,4 +248,80 @@ class NmapSession(object): | ||
247 | log.error("Install nmap: sudo apt-get install nmap") | 248 | log.error("Install nmap: sudo apt-get install nmap") |
248 | return False | 249 | return False |
249 | 250 | ||
250 | - return True | ||
251 | \ No newline at end of file | 251 | \ No newline at end of file |
252 | + return True | ||
253 | + | ||
254 | + | ||
255 | +class ArpSession(object): | ||
256 | + """ | ||
257 | + Classe para buscar informações de MAC do ativo | ||
258 | + """ | ||
259 | + def __init__(self, | ||
260 | + host, | ||
261 | + iface='eth0', | ||
262 | + timeout='10'): | ||
263 | + """ | ||
264 | + :param host: Endereço IP do host a ser escaneado | ||
265 | + :param mac: MAC address do host | ||
266 | + :param timeout: Timeout esperando pelo reply da interface | ||
267 | + """ | ||
268 | + self.host = host | ||
269 | + self.iface = iface | ||
270 | + self.timeout = timeout | ||
271 | + | ||
272 | + def scan(self): | ||
273 | + """ | ||
274 | + | ||
275 | + :return: Somente MAc | ||
276 | + """ | ||
277 | + log.debug("Iniciando scan para o host %s", self.host) | ||
278 | + try: | ||
279 | + scanv = subprocess.Popen(["sudo", | ||
280 | + "arping", | ||
281 | + "-I", | ||
282 | + self.iface, | ||
283 | + "-c", | ||
284 | + '1', | ||
285 | + "-w", | ||
286 | + self.timeout, | ||
287 | + self.host], | ||
288 | + stdout=subprocess.PIPE, | ||
289 | + stderr=subprocess.PIPE).communicate()[0] | ||
290 | + | ||
291 | + match = re.search("(\[)(.*)(\])", scanv) | ||
292 | + | ||
293 | + if match: | ||
294 | + return match.group(2) | ||
295 | + | ||
296 | + return match | ||
297 | + except OSError: | ||
298 | + log.error("Install arping: sudo apt-get install arping") | ||
299 | + return None | ||
300 | + | ||
301 | + def scan_list(self): | ||
302 | + """ | ||
303 | + | ||
304 | + :return: List com host e MAC | ||
305 | + """ | ||
306 | + log.debug("Iniciando scan para o host %s", self.host) | ||
307 | + try: | ||
308 | + scanv = subprocess.Popen(["sudo", | ||
309 | + "arping", | ||
310 | + "-I", | ||
311 | + self.iface, | ||
312 | + "-c", | ||
313 | + '1', | ||
314 | + "-w", | ||
315 | + self.timeout, | ||
316 | + self.host], | ||
317 | + stdout=subprocess.PIPE, | ||
318 | + stderr=subprocess.PIPE).communicate()[0] | ||
319 | + | ||
320 | + match = re.search("(\[)(.*)(\])", scanv) | ||
321 | + | ||
322 | + if match: | ||
323 | + return [self.host, match.group(2)] | ||
324 | + | ||
325 | + return [self.host, match] | ||
326 | + except OSError: | ||
327 | + log.error("Install arping: sudo apt-get install arping") | ||
328 | + return None | ||
252 | \ No newline at end of file | 329 | \ No newline at end of file |
cocar/xml_utils.py
@@ -32,10 +32,7 @@ class NmapXML(object): | @@ -32,10 +32,7 @@ class NmapXML(object): | ||
32 | if addr.get('addrtype') == 'ipv4': | 32 | if addr.get('addrtype') == 'ipv4': |
33 | host = addr.get('addr') | 33 | host = addr.get('addr') |
34 | elif addr.get('addrtype') == 'mac': | 34 | elif addr.get('addrtype') == 'mac': |
35 | - mac = { | ||
36 | - 'address': addr.get('addr'), | ||
37 | - 'vendor': addr.get('vendor') | ||
38 | - } | 35 | + mac = addr.get('addr') |
39 | 36 | ||
40 | # A chave do dicionário é o IP | 37 | # A chave do dicionário é o IP |
41 | self.hosts[host] = dict() | 38 | self.hosts[host] = dict() |
@@ -129,6 +126,25 @@ class NmapXML(object): | @@ -129,6 +126,25 @@ class NmapXML(object): | ||
129 | open_ports=host['ports'], | 126 | open_ports=host['ports'], |
130 | ) | 127 | ) |
131 | return printer | 128 | return printer |
129 | + elif host.get('os'): | ||
130 | + # Nesse caso já sei que é computador. Precisa identificar o OS | ||
131 | + for os in host['os'].keys(): | ||
132 | + if int(host['os'][os]['accuracy']) > accuracy: | ||
133 | + accuracy = int(host['os'][os]['accuracy']) | ||
134 | + os_final = os | ||
135 | + | ||
136 | + scantime = int(host.get('endtime')) - int(host.get('starttime')) | ||
137 | + computer = model.computer.Computer( | ||
138 | + ip_address=hostname, | ||
139 | + mac_address=host.get('mac'), | ||
140 | + hostname=host.get('hostname'), | ||
141 | + inclusion_date=host.get('endtime'), | ||
142 | + scantime=scantime, | ||
143 | + open_ports=host.get('ports'), | ||
144 | + so=host['os'][os_final] | ||
145 | + ) | ||
146 | + | ||
147 | + return computer | ||
132 | else: | 148 | else: |
133 | # Desiste e retorna host genérico | 149 | # Desiste e retorna host genérico |
134 | host = model.host.Host( | 150 | host = model.host.Host( |