Auteur Sujet: Script pour récupérer l'IP et indiquer si c'est une IPv4 ou une IPv6  (Lu 74686 fois)

0 Membres et 1 Invité sur ce sujet

vivien

  • Administrateur
  • *
  • Messages: 47 183
    • Twitter LaFibre.info
Script perl pour récupérer l'IP publique et indiquer si c'est une IPv4 ou une IPv6

Script Perl :
#!/usr/bin/perl -w
use strict;
use 
LWP::Simple;

my $ipget("https://ip.lafibre.info/ip.php");
printf("Adresse IP publique : $ip\n");
printf("Protocole IP : IPv%d\n",(index($ip,":")==-1)?4:6);


Le script est dispo sur : https://ip.lafibre.info/scripts/ip.pl



Script Python :
#!/usr/bin/python3
from urllib.request import urlopen
ip 
urlopen('https://ip.lafibre.info/ip.php').read()
print(
"Adresse IP publique :"ip.decode('ascii'))
print(
"Protocole IP : IPv%d" % (if b':' in ip else 4))


Le script est dispo sur : https://ip.lafibre.info/scripts/ip.py



Le scipt shell (bash) :
#!/bin/sh
ip=$(wget wget --https://ip.lafibre.info/ip.php)
echo Adresse IP publique $ip
case "$ipin
*:* ) echo Protocole IP IPv6;;
* ) echo 
Protocole IP IPv4;;
esac


Le script est dispo sur : https://ip.lafibre.info/scripts/ip.sh



Script original (sur lequel se base la discussion ci-dessous) :
#!/usr/bin/perl -w
use strict;
### Dépendance à installer :
# sudo apt install w3m

### FONCTION Détection IPv4 vs IPv6
sub detection_ip {
	
my $str shift;
	
$str =~ s/^\s*//;
	
$str =~ s/\s*$//;
 
	
if (
$str =~ s/^((?:\d+\.)+\d+)(?::(\d+))?$//) {
	
	
return 
'IPv4';
	
}
	
return 
'IPv6';
}

### DÉBUT DU PROGRAMME

# Récupération IP publique
my $IP_client = `/usr/bin/w3m -dump https://ip.lafibre.info/ip.php`;
chomp($IP_client);
print (
"Adresse IP publique : $IP_client\n");

# Détection du protocole IP
my ($IP_version) = detection_ip($IP_client);
print 
"Protocole IP : $IP_version\n";


installation :
wget https://ip.lafibre.info/ip.pl
chmod +x ip.pl
sudo apt install w3m
./ip.pl


Exemple si IPv6 n'est pas disponible :
$ ./ip.pl
Adresse IP publique : 46.227.16.8
Protocole IP : IPv4

Exemple si IPv6 est disponible :
$ ./ip.pl
Adresse IP publique : 2a01:6e00:10:410::2
Protocole IP : IPv6

Marin

  • Client Bbox vdsl
  • Modérateur
  • *
  • Messages: 2 804
  • 73
Script perl pour récupérer l'IP et indiquer si c'est une IPv4 ou une IPv6
« Réponse #1 le: 24 décembre 2015 à 12:19:44 »
Exemple d'implèmentation en Python 3, sans dépendance externe :

from urllib.request import urlopen
ip = urlopen('https://ip.lafibre.info/ip.php').read()
print("Adresse IP publique :", ip.decode('ascii'))
print("Protocole IP : IPv%d" % (6 if b':' in ip else 4))

vivien

  • Administrateur
  • *
  • Messages: 47 183
    • Twitter LaFibre.info
Script perl pour récupérer l'IP et indiquer si c'est une IPv4 ou une IPv6
« Réponse #2 le: 24 décembre 2015 à 12:50:15 »
Impressionnant la compacité du code et l'absence de dépendances externes.

Je l'ai rajouté sur la page : http://ip.lafibre.info/scripts/ip.py

Il faut que je me plonge dans le Python...

kgersen

  • Modérateur
  • Abonné Bbox fibre
  • *
  • Messages: 9 091
  • Paris (75)
Script perl pour récupérer l'IP et indiquer si c'est une IPv4 ou une IPv6
« Réponse #3 le: 24 décembre 2015 à 13:34:24 »
c'est ton code perl qui est pas top top plutot ?

un truc comme ca devrait marcher en Perl (pas testé:):
use LWP::Simple;
$ip= get("https://ip.lafibre.info/ip.php");
printf("Adresse IP publique : $ip\n");
printf("Protocole IP : IPv%d\n",(index(":",$ip)==-1)?4:6);

ps: on me signale que LWP n'est pas forcement installé. Dans ce cas:
sudo apt install libwww-perlou via CPAN

kgersen

  • Modérateur
  • Abonné Bbox fibre
  • *
  • Messages: 9 091
  • Paris (75)
Script perl pour récupérer l'IP et indiquer si c'est une IPv4 ou une IPv6
« Réponse #4 le: 24 décembre 2015 à 14:10:13 »
ou en Shell directement, pas besoin d'installer quoique ce soit sauf curl:

ip=$(curl -s https://ip.lafibre.info/ip.php)
echo Adresse IP publique : $ip
case "$ip" in
*:* ) echo Protocole IP : IPv6;;
* ) echo Protocole IP : IPv4;;
esac

alain_p

  • Abonné Free fibre
  • *
  • Messages: 16 245
  • Delta S 10G-EPON sur Les Ulis (91)
Script perl pour récupérer l'IP et indiquer si c'est une IPv4 ou une IPv6
« Réponse #5 le: 24 décembre 2015 à 16:39:05 »
Et c'est un peu moins obscur que les expressions régulières Perl.

corrector

  • Invité
Script perl pour récupérer l'IP et indiquer si c'est une IPv4 ou une IPv6
« Réponse #6 le: 24 décembre 2015 à 16:44:47 »
Code: (C++) [Sélectionner]
#include <iostream>
using namespace std;

enum IP_family {
addr_IPv4,
addr_IPv6,
addr_unknown
};

const char *to_string (IP_family f) {
switch (f) {
case addr_IPv6:
return "IPv6";
case addr_IPv4:
return "IPv4";
default:
return "unknown";
}
}

IP_family addr_type (const string &addr) {
if (addr.find_first_of (':') != string::npos)
return addr_IPv6;
if (addr.find_first_of ('.') != string::npos)
return addr_IPv4;
return addr_unknown;
}

ostream &operator<< (ostream &os, IP_family f) {
return os << to_string (f);
}

void test (const string &str) {
cout << ""\" << str << "\" is " << addr_type(str) << endl;
}

int main() {
test ("46.227.16.8");
test ("2a01:6e00:10:410::2");
test ("42");
return 0;
}
https://ideone.com/jG8yYv

"46.227.16.8" is IPv4
"2a01:6e00:10:410::2" is IPv6
"42" is unknown

corrector

  • Invité
Script perl pour récupérer l'IP et indiquer si c'est une IPv4 ou une IPv6
« Réponse #7 le: 24 décembre 2015 à 16:57:48 »
Et c'est un peu moins obscur que les expressions régulières Perl.
Les regexp, en français expression rationnelles, correspondent à un automate (déterministe ou non).

Les perlre ne sont pas des regexp, elles ne sont pas rationnelles!

corrector

  • Invité
Script perl pour récupérer l'IP et indiquer si c'est une IPv4 ou une IPv6
« Réponse #8 le: 24 décembre 2015 à 17:25:44 »
Et c'est un peu moins obscur que les expressions régulières Perl.
Petite explication :
   $str =~ s/^\s*//;
   $str =~ s/\s*$//;

Citer
    ^        Match the beginning of the line

    $        Match the end of the string (or before newline at the end

    \d        [3]  Match a decimal digit character

    \s        [3]  Match a whitespace character

En résumé :

^\s* tous les espaces en début de chaîne
\s*$ tous les espaces en fin de chaîne
s/toto// remplace toto par rien (= supprimer)
s/^\s*// remplace tous les espaces en début de chaîne par rien (= supprimer)

   if ($str =~ s/^((?:\d+\.)+\d+)(?::(\d+))?$//) {
Citer
n
Prevent the grouping metacharacters () from capturing. This modifier, new in 5.22, will stop $1 , $2 , etc... from being filled in.
  "hello" =~ /(hi|hello)/;   # $1 is "hello"
  "hello" =~ /(hi|hello)/n;  # $1 is undef
This is equivalent to putting ?: at the beginning of every capturing group:
  "hello" =~ /(?:hi|hello)/; # $1 is undef

http://perldoc.perl.org/perlre.html#Regular-Expressions

\d+ suite de chiffres (non vide) = nombre en décimal "1" "23" "111" "000000"
\d+\. nombre en décimal suivi d'un point
((?:\d+\.) idem
((?:\d+\.) au moins une fois : nombre en décimal suivi d'un point "1." "12." "1.3." "12.345." "12.000.56452."
(?:\d+\.)+\d+ série de nombres en décimal séparés par un point  "1.0" "12.01" "1.3.5" "12.345.000" "12.3.56452.5111" "12.3.56452.5111.0"

On voit donc qu'à aucun moment on ne vérifie que c'est syntaxiquement une adresse IPv4 bien formée (4 mots de 8 bits écrit en décimal). On va désigner ça par dotted-decimal.

((?:\d+\.)+\d+) idem, rend disponible l'expression matchée plus tard

: deux points
:(\d+) deux points suivi d'un nombre, rend disponible le nombre; appelons ça decimal-port
(?::(\d+)) idem
(?::(\d+))? optionnellement deux points suivi d'un nombre, rend disponible le nombre


^((?:\d+\.)+\d+)(?::(\d+))?$

chaîne complète constituée de dotted-decimal suivi éventuellement de decimal-port, rend disponible les deux composantes sous forme de $1 et $2

exemples :

"1.0" "12.01:124" "1.3.5" "12.345.0:00" "12.3.56452:5111" "12.3.56452.5111.0.12:123422"

corrector

  • Invité
Script perl pour récupérer l'IP et indiquer si c'est une IPv4 ou une IPv6
« Réponse #9 le: 24 décembre 2015 à 17:31:47 »
c'est ton code perl qui est pas top top plutot ?

un truc comme ca devrait marcher en Perl (pas testé:):
index(":",$ip)
Oui mais ça n'a rien à voir avec ce que teste vivien en Perl.

corrector

  • Invité
Script perl pour récupérer l'IP et indiquer si c'est une IPv4 ou une IPv6
« Réponse #10 le: 24 décembre 2015 à 17:51:06 »
Les regexp, en français expression rationnelles, correspondent à un automate (déterministe ou non).

Les perlre ne sont pas des regexp, elles ne sont pas rationnelles!
Mais en l'occurrence l'expression de vivien est bien rationnelle, enfin, ce sont deux expressions qui définissent des variables.

Une expression est rationnelle si on peut l'écrire avec uniquement les opérateurs suivants

| alternative
* répétition (étoile de Kleene)

ce qui est le cas pour le programme de vivien :

\d = 0|1|2|3...
\d+ = \d*\d
(\d+.)+ = (\d*\d.)*\d*\d.
(\d+.)+\d+ = (\d*\d.)*\d*\d.\d*\d
(:\d+)? = (:\d*\d)|
(l'alternative de droite est vide)

(\d+.)+\d+(:\d+)? = (\d*\d.)*\d*\d.\d*\d((:\d*\d)|)

(La question du stockage des correspondances est laissé de coté.)

corrector

  • Invité
Script perl pour récupérer l'IP et indiquer si c'est une IPv4 ou une IPv6
« Réponse #11 le: 24 décembre 2015 à 18:17:55 »
On peut écrire cela sous forme d'un automate avec
état initial S0
état final END
goto A,B signifie passer à l'état A ou bien l'état B

S0 : if (isdigit) goto S0,S1
S1 : if (isdigit) goto S2
S2 : if (".") goto S0,S10
S10 : if (isdigit) goto S10,S11
S11 : if (isdigit) goto END,S20
S20 : if (":") goto S30
S30 : if (isdigit) goto S30,S31
S31 : if (isdigit) goto END


isdigit est lui même un automate :

S0 : if ("0") goto END
S0 : if ("1") goto END
S0 : if ("2") goto END
...
S0 : if ("9") goto END