This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository mum. See http://git.chorem.org/mum.git commit cc27df362b252e1425f353fad7de86c37ead1e24 Author: Alexis Guilbaud <guilbaud@codelutin.com> Date: Tue Jan 27 15:34:53 2015 +0100 reorganisation des modules python + index fonctionne partiellement avec angularJS --- .gitignore | 3 +- .../Nagios_detection.py => __init__.py} | 0 app/app.py | 85 ++----------- .../{SNMP_detection.py => __init__.py} | 0 .../{Nagios_detection.py => nagios_detection.py} | 0 app/detection_modules/nmap_detection.py | 136 +++++++++++++++++++++ .../{Nagios_detection.py => snmp_detection.py} | 0 .../{SSH_detection.py => ssh_detection.py} | 0 .../__init__.py} | 0 res.xml | 32 +++-- static/js/controllers/script.js | 52 ++++++++ views/index.html | 25 ++-- 12 files changed, 234 insertions(+), 99 deletions(-) diff --git a/.gitignore b/.gitignore index a662fbf..6ba581a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ bower_components venv node_modules -*~ \ No newline at end of file +*~ +.idea diff --git a/app/detection_modules/Nagios_detection.py b/app/__init__.py similarity index 100% copy from app/detection_modules/Nagios_detection.py copy to app/__init__.py diff --git a/app/app.py b/app/app.py index 40910b6..8ee89da 100755 --- a/app/app.py +++ b/app/app.py @@ -1,10 +1,9 @@ __author__ = 'aguilbaud' from bottle import * -from xml.dom import minidom -import pexpect -import json +from detection_modules.nmap_detection import check_ip_range, get_current_ip +state = "" @route('/') def index(section='home'): @@ -14,77 +13,19 @@ def index(section='home'): def angular(): return template('angular') -@post('/detect') -def detection(): - ip_range = request.forms.get('ip_range') - #Verification de la syntaxe de la plage d'entree - #TODO Il faudrait egalement verifier que la plage n'est pas trop grande, et que les valeurs soient <=255 - #=> p-e faire un appel pour chaque plage de 10 (voire 1 appel pour 1 IP) - if re.search('\d{1,3}(-\d{1,3})?:\d{1,3}(-\d{1,3})?:\d{1,3}(-\d{1,3})?:\d{1,3}(-\d{1,3})?', ip_range) \ - or ip_range == 'localhost': - # option -v3 permet d'avoir une preview du scan avec services up ou down, mais "desorganise" le xml... - child = pexpect.spawn('nmap', ['-A', ip_range, '-oX', 'res.xml']) - res = '' - try: - while child.isalive(): - child.expect('Completed', timeout=None) - res += child.before + '<br/>' - except pexpect.EOF: - res += ' A FINI' - parse_res() - except pexpect.TIMEOUT: - res += ' TIMEOUT' - return res +@post('/detect/<ip_range>') +def start_first_detection(ip_range): + #ip_range = request.forms.get('ip_range') + print ip_range + ''' + if re.search('^\d{1,3}(-\d{1,3})?[.]\d{1,3}(-\d{1,3})?[.]\d{1,3}(-\d{1,3})?[.]\d{1,3}(-\d{1,3})?$', ip_range): + state = "Scanning" + check_ip_range(ip_range) else: return '<p>La plage d\'IP est mal formatee</p>' + ''' -def parse_res(): - # Ouverture du fichier xml avec le parseur minidom - root = minidom.parse("res.xml") - collection = root.documentElement - - # Recuperer tous les <host> de la collection - hosts = collection.getElementsByTagName("host") - - # Recuperation des noeuds de chaque <host> et affichage de leur attributss - # JSON = liste de dictionnaires - for host in hosts: - status = host.getElementsByTagName('status')[0] - address = host.getElementsByTagName('address')[0] - - dict_host = {} - dict_host['addr'] = address.getAttribute('addr') - dict_host['date'] = host.getAttribute('endtime') - dict_host['state'] = status.getAttribute('state') - dict_host['os'] = 'unknown' # par defaut - - hostnames_elem = host.getElementsByTagName('hostnames')[0] - hostnames = hostnames_elem.getElementsByTagName('hostname') - dict_hostname = {} - for hostname in hostnames: - dict_host['hostname'] = hostname.getAttribute("name") - - ports_elem = host.getElementsByTagName('ports')[0] - ports = ports_elem.getElementsByTagName('port') - list_dict_port = [] - for port in ports: - dict_port = {} - state = port.getElementsByTagName('state')[0] - service = port.getElementsByTagName('service')[0] - if service.hasAttribute("ostype"): - dict_host['os'] = service.getAttribute("ostype") - if state.getAttribute('state') == 'open': - dict_port['portid'] = port.getAttribute('portid') - dict_port['portname'] = service.getAttribute('name') - # Ajouter d'autres infos ? - list_dict_port.append(dict_port) - dict_host['openports'] = list_dict_port - # sauvegarde de l'host dans la base elasticsearch avec pour ID son IP - print dict_host['addr'] - pexpect.run('curl -XPUT \'localhost:9200/host/external/' + dict_host['addr'] + '?pretty\' -d \'' + - json.dumps(dict_host, sort_keys=True,indent=4, separators=(',', ': ')) + '\'') - @error(404) def error404(error): return '<h1>Cette page n\'existe pas</h1>' @@ -99,8 +40,8 @@ def bower_files(filepath): return static_file(filepath, root='bower_components') @get('/getval') -def getVal(): - return "toto" +def getval(): + return get_current_ip() if __name__ == '__main__': diff --git a/app/detection_modules/SNMP_detection.py b/app/detection_modules/__init__.py similarity index 100% rename from app/detection_modules/SNMP_detection.py rename to app/detection_modules/__init__.py diff --git a/app/detection_modules/Nagios_detection.py b/app/detection_modules/nagios_detection.py similarity index 100% copy from app/detection_modules/Nagios_detection.py copy to app/detection_modules/nagios_detection.py diff --git a/app/detection_modules/nmap_detection.py b/app/detection_modules/nmap_detection.py new file mode 100644 index 0000000..0722001 --- /dev/null +++ b/app/detection_modules/nmap_detection.py @@ -0,0 +1,136 @@ +from xml.dom import minidom +import pexpect +import json + +current_ip = "" +# fonction qui permet de decomposer les differentes plages d'ip +# lance la detection nmap pour chacune des ip comprises dans cette plage +def check_ip_range(ip_range): + # separation des 4 octets + byte1 = ip_range.split('.')[0] + byte2 = ip_range.split('.')[1] + byte3 = ip_range.split('.')[2] + byte4 = ip_range.split('.')[3] + + # separation des plages eventuelles + split_byte1 = byte1.split('-') + split_byte2 = byte2.split('-') + split_byte3 = byte3.split('-') + split_byte4 = byte4.split('-') + + # si aucune plage n'est indiquee, on cree une plage de meme valeur + if len(split_byte1) == 1: + split_byte1.append(split_byte1[0]) + # verification que les nombres sont ordonnes correctement + # et que les valeurs entrees sont inferieures a 255 + split_byte1 = check_order_and_under_255(split_byte1) + + # idem pour le deuxieme octet + if len(split_byte2) == 1: + split_byte2.append(split_byte2[0]) + split_byte2 = check_order_and_under_255(split_byte2) + + # idem pour le troisieme octet + if len(split_byte3) == 1: + split_byte3.append(split_byte3[0]) + split_byte3 = check_order_and_under_255(split_byte3) + + # idem pour le quatrieme octet + if len(split_byte4) == 1: + split_byte4.append(split_byte4[0]) + split_byte4 = check_order_and_under_255(split_byte4) + + # il est possible d'ajouter ici une condition pour verifier que l'utilisateur + # n'ait pas entre une plage d'IP trop grande + + # pour toutes les plages dans l'ordre croissant, en partant du dernier octet + for i in range(int(split_byte1[0]), int(split_byte1[1]) + 1): + for j in range(int(split_byte2[0]), int(split_byte2[1]) + 1): + for k in range(int(split_byte3[0]), int(split_byte3[1]) + 1): + for l in range(int(split_byte4[0]), int(split_byte4[1]) + 1): + launch_detection(i, j, k, l) + + +# verifie que la plage de donnee entree est dans l'ordre croissant +# et que ses valeurs sont inferieures a 255 +# si ce n'est pas le cas, retourne le tableau trie et/ou avec les valeurs capees a 255 +def check_order_and_under_255(tab_val): + if int(tab_val[0]) > 255 : + tab_val[0] = '255' + if int(tab_val[1]) > 255 : + tab_val[1] = '255' + if int(tab_val[0]) > int(tab_val[1]): + tmp = tab_val[1] + tab_val[1] = tab_val[0] + tab_val[0] = tmp + return tab_val + + +# lance la detection a l'aide de nmap sur l'ip representee par les 4 octets passes en parametres +def launch_detection(b1, b2, b3, b4): + ip = str(b1) + '.' + str(b2) + '.' + str(b3) + '.' + str(b4) + current_ip = ip + child = pexpect.spawn('nmap', ['-A', ip, '-oX', 'res.xml']) + res = '' + # ici : possibilite de verifier l'avancement du scan, si option verbose (-v3) activee dans la commande nmap + try: + while child.isalive(): + child.expect('Completed', timeout=None) + res += child.before + '<br/>' + except pexpect.EOF: + res += ' A FINI' + parse_res() + except pexpect.TIMEOUT: + res += ' TIMEOUT' + return res + + +def get_current_ip(): + return current_ip + +# parse le resultat xml de nmap pour ne conserver que les valeurs interssantes +# envoie directement le resultat sur le service ElasticSearch +def parse_res(): + # Ouverture du fichier xml avec le parseur minidom + root = minidom.parse("res.xml") + collection = root.documentElement + + # Recuperer tous les <host> de la collection + hosts = collection.getElementsByTagName("host") + + # Recuperation des noeuds de chaque <host> et affichage de leur attributss + # JSON = liste de dictionnaires + for host in hosts: + status = host.getElementsByTagName('status')[0] + address = host.getElementsByTagName('address')[0] + + dict_host = {} + dict_host['addr'] = address.getAttribute('addr') + dict_host['date'] = host.getAttribute('endtime') + dict_host['state'] = status.getAttribute('state') + dict_host['os'] = 'unknown' # par defaut + + hostnames_elem = host.getElementsByTagName('hostnames')[0] + hostnames = hostnames_elem.getElementsByTagName('hostname') + for hostname in hostnames: + dict_host['hostname'] = hostname.getAttribute("name") + + ports_elem = host.getElementsByTagName('ports')[0] + ports = ports_elem.getElementsByTagName('port') + list_dict_port = [] + for port in ports: + dict_port = {} + state = port.getElementsByTagName('state')[0] + service = port.getElementsByTagName('service')[0] + if service.hasAttribute("ostype"): + dict_host['os'] = service.getAttribute("ostype") + if state.getAttribute('state') == 'open': + dict_port['portid'] = port.getAttribute('portid') + dict_port['portname'] = service.getAttribute('name') + # Ajouter d'autres infos ? + list_dict_port.append(dict_port) + dict_host['openports'] = list_dict_port + # sauvegarde de l'host dans la base elasticsearch avec pour ID son IP + print dict_host['addr'] + pexpect.run('curl -XPUT \'localhost:9200/host/external/' + dict_host['addr'] + '?pretty\' -d \'' + + json.dumps(dict_host) + '\'') \ No newline at end of file diff --git a/app/detection_modules/Nagios_detection.py b/app/detection_modules/snmp_detection.py similarity index 100% copy from app/detection_modules/Nagios_detection.py copy to app/detection_modules/snmp_detection.py diff --git a/app/detection_modules/SSH_detection.py b/app/detection_modules/ssh_detection.py similarity index 100% rename from app/detection_modules/SSH_detection.py rename to app/detection_modules/ssh_detection.py diff --git a/app/detection_modules/Nagios_detection.py b/app/monitoring_modules/__init__.py similarity index 100% rename from app/detection_modules/Nagios_detection.py rename to app/monitoring_modules/__init__.py diff --git a/res.xml b/res.xml index 1a97e6b..cbbe419 100644 --- a/res.xml +++ b/res.xml @@ -1,69 +1,68 @@ <?xml version="1.0"?> <?xml-stylesheet href="file:///usr/bin/../share/nmap/nmap.xsl" type="text/xsl"?> -<!-- Nmap 6.40 scan initiated Wed Jan 21 17:17:28 2015 as: /usr/bin/nmap -A -oX res.xml localhost --> -<nmaprun scanner="nmap" args="/usr/bin/nmap -A -oX res.xml localhost" start="1421857048" startstr="Wed Jan 21 17:17:28 2015" version="6.40" xmloutputversion="1.04"> +<!-- Nmap 6.40 scan initiated Mon Jan 26 14:06:22 2015 as: /usr/bin/nmap -A -oX res.xml 127.0.0.1 --> +<nmaprun scanner="nmap" args="/usr/bin/nmap -A -oX res.xml 127.0.0.1" start="1422277582" startstr="Mon Jan 26 14:06:22 2015" version="6.40" xmloutputversion="1.04"> <scaninfo type="connect" protocol="tcp" numservices="1000" services="1,3-4,6-7,9,13,17,19-26,30,32-33,37,42-43,49,53,70,79-85,88-90,99-100,106,109-111,113,119,125,135,139,143-144,146,161,163,179,199,211-212,222,254-256,259,264,280,301,306,311,340,366,389,406-407,416-417,425,427,443-445,458,464-465,481,497,500,512-515,524,541,543-545,548,554-555,563,587,593,616-617,625,631,636,646,648,666-668,683,687,691,700,705,711,714,720,722,726,749,765,777,783,787,800-801,808,843,873,880,888,898,900-9 [...] <verbose level="0"/> <debugging level="0"/> -<host starttime="1421857048" endtime="1421857172"><status state="up" reason="conn-refused" reason_ttl="0"/> +<host starttime="1422277583" endtime="1422277589"><status state="up" reason="conn-refused" reason_ttl="0"/> <address addr="127.0.0.1" addrtype="ipv4"/> <hostnames> -<hostname name="localhost" type="user"/> <hostname name="localhost" type="PTR"/> </hostnames> -<ports><extraports state="closed" count="994"> -<extrareasons reason="conn-refused" count="994"/> +<ports><extraports state="closed" count="995"> +<extrareasons reason="conn-refused" count="995"/> </extraports> <port protocol="tcp" portid="22"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="ssh" product="OpenSSH" version="6.6.1p1 Debian 4~bpo70+1" extrainfo="protocol 2.0" ostype="Linux" method="probed" conf="10"><cpe>cpe:/a:openbsd:openssh:6.6.1p1</cpe><cpe>cpe:/o:linux:linux_kernel</cpe></service><script id="ssh-hostkey" output="1024 91:dc:b9:10:b4:5c:21:bd:9d:53:53:03:58:96:18:1f (DSA) 2048 11:aa:0d:50:8d:a4:f2:43:7e:86:b2:02:e9:29:ca:e2 (RSA) 256 cf:22:d5:4b:e4:48 [...] +<elem key="fingerprint">91dcb910b45c21bd9d5353035896181f</elem> <elem key="type">ssh-dss</elem> <elem key="key">AAAAB3NzaC1kc3MAAACBANd0aGmv9wNOWbaMqW5VbHc5ybC7FSyg+8feAPUAkwOyLs1lw2X/VUbstHVjCDbSLfChtrh5apIq+z+zbBZS90qJSmjkS0ENKRV5pTG5op4iMDHEdKtxvoEo+6cUo4LiTgdD/TG7ckuVbu98oJDG0Ug+2Y6UNcJ2JdFnhiOxHOJhAAAAFQDE8Uvj6YjrnI+hT/fwHR9m1GW2pQAAAIAa6juP1IrZJYy1dzumFlGh3IL2FhPtR+jalO9Nd5Fbl5vFL/Qvn7AH87jTLUEUFEXyxwEDXD09rDhgXRpqOWPY68EOax4ElCvP3VcMEomrTwgTyxqTfkYiPfuEsrRYAlA+nTgK0ydXx4mgLfk0igHkNR0Ec8Njq7TVpV6ahgT19wAAAIA0FxIqx9VTOLQ1bmBDGlcdcAwLfDhWYqJJBrVtClf2s1kqcv7K4u6atbeOo/lCHHBMYS0h [...] <elem key="bits">1024</elem> -<elem key="fingerprint">91dcb910b45c21bd9d5353035896181f</elem> </table> <table> +<elem key="fingerprint">11aa0d508da4f2437e86b202e929cae2</elem> <elem key="type">ssh-rsa</elem> <elem key="key">AAAAB3NzaC1yc2EAAAADAQABAAABAQDcc3P+5Izgre8YSBrDtgkZyqxrH3CkyELs/xyjIVvGEhPD4VPd5Gx7rOTeAHnyDzJ0ca+YGnJjUISh+FDWxrzk5QmO1nVNEG+bRaZcdok/kzgJnj58IfEIeVB/NCPQJkOPW7asD5/SowBVRynnViPd42OhQVeyfMkhI1PMf8QZRSteGOyX7XrMgCEkFbmlF3jZTruYrAp+TjItQv0p+v16fL69uBHCSh/j+aVm00l5S29sNmMex+NGgfFGDWBouz3y5SE3KyKz9ECKw0MH2M8tCv/Tj6PlS8kuAulsJLQQ3wO0u9o/UaLbKuLBwz7dBHPNrD1XY8zyIco8u4QdubqJ</elem> <elem key="bits">2048</elem> -<elem key="fingerprint">11aa0d508da4f2437e86b202e929cae2</elem> </table> <table> +<elem key="fingerprint">cf22d54be448cae1585dffebc266ff18</elem> <elem key="type">ecdsa-sha2-nistp256</elem> <elem key="key">AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBI0QKwQluKYrYw2Heu9AYeeSLXi9fBZZvk/acMftAaFwEoUZhgqEPQNyQODw1K+WsbtY4c4ZAS9l34hqqrX0ZTg=</elem> <elem key="bits">256</elem> -<elem key="fingerprint">cf22d54be448cae1585dffebc266ff18</elem> </table> </script></port> <port protocol="tcp" portid="25"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="smtp" product="Exim smtpd" version="4.80" hostname="bou.codelutin.home" method="probed" conf="10"><cpe>cpe:/a:exim:exim:4.80</cpe></service><script id="smtp-commands" output="bou.codelutin.home Hello localhost [127.0.0.1], SIZE 52428800, 8BITMIME, PIPELINING, HELP, Commands supported: AUTH HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP "/></port> -<port protocol="tcp" portid="111"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="rpcbind" version="2-4" extrainfo="RPC #100000" method="probed" conf="10"/><script id="rpcinfo" output=" program version port/proto service 100000 2,3,4 111/tcp rpcbind 100000 2,3,4 111/udp rpcbind 100024 1 35529/udp status 100024 1 41686/tcp status "><table key="100000"> +<port protocol="tcp" portid="111"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="rpcbind" version="2-4" extrainfo="RPC #100000" method="probed" conf="10"/><script id="rpcinfo" output=" program version port/proto service 100000 2,3,4 111/tcp rpcbind 100000 2,3,4 111/udp rpcbind 100024 1 43928/tcp status 100024 1 60874/udp status "><table key="100000"> <table key="udp"> +<elem key="port">111</elem> <table key="version"> <elem>2</elem> <elem>3</elem> <elem>4</elem> </table> -<elem key="port">111</elem> </table> <table key="tcp"> +<elem key="port">111</elem> <table key="version"> <elem>2</elem> <elem>3</elem> <elem>4</elem> </table> -<elem key="port">111</elem> </table> </table> <table key="100024"> <table key="tcp"> +<elem key="port">43928</elem> <table key="version"> <elem>1</elem> </table> -<elem key="port">41686</elem> </table> <table key="udp"> +<elem key="port">60874</elem> <table key="version"> <elem>1</elem> </table> -<elem key="port">35529</elem> </table> </table> </script></port> @@ -71,10 +70,9 @@ </script></port> <port protocol="tcp" portid="8080"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="http" product="Apache Tomcat/Coyote JSP engine" version="1.1" method="probed" conf="10"/><script id="http-methods" output="Potentially risky methods: PUT DELETE See http://nmap.org/nsedoc/scripts/http-methods.html"/><script id="http-open-proxy" output="Proxy might be redirecting requests"/><script id="http-title" output="Apache Tomcat"><elem key="title">Apache Tomcat</elem> </script></port> -<port protocol="tcp" portid="9200"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="wap-wsp" servicefp="SF-Port9200-TCP:V=6.40%I=7%D=1/21%Time=54BFD123%P=x86_64-unknown-linux-gnu%r(GetRequest,1AA,"HTTP/1\.0\x20200\x20OK\r\nContent-Type:\x20application/json;\x20charset=UTF-8\r\nContent-Length:\x20339\r\n\r\n{\n\x20\x20\"status\"\x20:\x20200,\n\x20\x20\"name\"\x20:\x20\"Steven\x20Lang\",\n\x20\x20\"cluster_name\"\x20:\x20\&quo [...] </ports> -<times srtt="294" rttvar="76" to="100000"/> +<times srtt="211" rttvar="59" to="100000"/> </host> -<runstats><finished time="1421857172" timestr="Wed Jan 21 17:19:32 2015" elapsed="123.96" summary="Nmap done at Wed Jan 21 17:19:32 2015; 1 IP address (1 host up) scanned in 123.96 seconds" exit="success"/><hosts up="1" down="0" total="1"/> +<runstats><finished time="1422277589" timestr="Mon Jan 26 14:06:29 2015" elapsed="6.50" summary="Nmap done at Mon Jan 26 14:06:29 2015; 1 IP address (1 host up) scanned in 6.50 seconds" exit="success"/><hosts up="1" down="0" total="1"/> </runstats> </nmaprun> diff --git a/static/js/controllers/script.js b/static/js/controllers/script.js new file mode 100644 index 0000000..95ff8cd --- /dev/null +++ b/static/js/controllers/script.js @@ -0,0 +1,52 @@ +var formExample = angular.module('formExample', []); + +formExample.controller('ExampleController', ['$scope', '$http', function($scope, $http) { + $scope.master = {}; + $scope.ip_range = "198.116.0.1-10" + $scope.ip = "v"; + $scope.validated = false; + $scope.post_val = function(){ + $http.post('/detect/' + $scope.ip_range). + success(function(data, status, headers, config) { + // this callback will be called asynchronously + // when the response is available + }). + error(function(data, status, headers, config) { + // called asynchronously if an error occurs + // or server returns response with an error status. + }); + } + }]); + + +/*formExample.service("ipService", ["stateService", "$interval", + function(stateService, $timeout) { + //Variable privée + var current_ip = { + current_ip: "a", + }; + + //Getter pour la variable current_ip + this.get_current_ip = function() { + //Cette méthode fait appel à un autre service + $http.get('/getval'). + success(function(data, status, headers, config) { + current_ip = data + }). + error(function(data, status, headers, config) { + // called asynchronously if an error occurs + // or server returns response with an error status. + }); + return current_ip; + }; + + //5 secondes après le chargement de la page, la valeur d'une propriété change dans le service. + //La view est mise à jour automatiquement + $interval(function() { + formExample.service.get_current_ip() + }, 5000); + + + } +]); +*/ \ No newline at end of file diff --git a/views/index.html b/views/index.html index 7d285b9..223c04b 100644 --- a/views/index.html +++ b/views/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html lang="en" ng-app="" ng-controller="stateController"> +<html lang="fr"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> @@ -9,19 +9,26 @@ <title>Mum (Machines under monitoring)</title> - <script src="bower_components/jquery/dist/jquery.js"></script> <script src="bower_components/bootstrap/dist/js/bootstrap.js"></script> + <script src="bower_components/angular/angular.js"></script> + <script src="static/js/controllers/script.js"></script> <link href="bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" media="screen"> <link href="static/css/main.css" rel="stylesheet" media="screen"> </head> -<body> - - <form action="/detect" method="post"> - Plage d'IP à scanner (exemple : 198.116.0.1-10) : <input name="ip_range" type="text" /> - <input value="Valider" type="submit" /> - </form> - +<body ng-app="formExample"> +<div ng-controller="ExampleController"> + <form ng_submit="post_val()"> + <div ng-show="validated == false" class="ng-hide"> + Plage d'IP à scanner (exemple : 198.116.0.1-10) : <input name="ip_range" ng-model="ip_range" /> + <input value="Valider" type="submit" ng-click="validated = true"/> + </div> + <div ng-show="validated == true"> + <p>Lancé</p> + </div> + </form> +{{validated}} +</div> </body> </html> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.