Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 11/02/2018, à 17:03

diesel

[Script] Adresse ipv6 de type Unique Local unicast Address (rfc4193)

Ces adresses, uniquement utilisables sur un "réseau local" sont définies dans la RFC4193.

Au 3.2.2., la RFC4193 propose un "algorithme" pour construire ces adresses.

Ci-joint un script bash qui permet de mettre en œuvre cet "algorithme" :

[EDIT]

Pour le lecteur pressé, la dernière version du script suite aux discussions ci-dessous :

{ expr $(date +%s%N) - $(date -d '01/01/1900' +%s%N) | sed -e 's/^.\{10\}/& /' -e 's/ 0*/ /' | xargs printf '%08x%08x' ; ip a | grep -m 1 'link/ether' | sed -e 's/^[ \t]*//' | cut -f 2 -d ' ' | sed -e 's/://g' -e 's/^.\{6\}/&fffe/' ;} | xxd -r -p | sha1sum -b | cut -f 1 -d ' ' | tail -c 11 | sed -e 's/^/fd/' -e 's/^.\{4\}/&:/' -e 's/^.\{9\}/&:/' -e 's/^.\{14\}/&::\/64/'

[/EDIT]

echo -n "$(expr $(date +%s) + 2208988808 | sed -e 's/^0*//' | xargs printf '%08x')$(date +%N | sed -e 's/^0*//' | xargs printf '%08x')$(ip a | grep -m 1 'link/ether' | sed -e 's/^[ \t]*//' | cut -f 2 -d ' ' | sed -e 's/://g' | sed -e 's/^.\{6\}/&fffe/')" | xxd -r -p | sha1sum -b | cut -f 1 -d ' ' | tail -c 11 | sed -e 's/^/fd/' | sed -e 's/^.\{4\}/&:/' | sed -e 's/^.\{9\}/&:/' | sed -e 's/^.\{14\}/&::\/64/'

Le résultat va être, par exemple : fd4d:23b1:3412::/64, ce qui permettra de créer (en supposant que le numéro de sous-réseau est "0") les adresses fd4d:23b1:3412::1/64, fd4d:23b1:3412::2/64, etc...
Et avec un numéro de sous-réseau différent de "0" ("c5e" par exemple), de créer les adresses fd4d:23b1:3412:c5e::1/64, fd4d:23b1:3412:c5e::2/64, etc...

Le fonctionnement du script est le suivant :

- le premier "echo" va permettre de fusionner les sorties des commandes "date" et "ip" remises en forme, ce qui va donner au final une chaîne de caractères représentant en hexadécimal un mot de 128 bits,
- la commande "date" est, en deux temps, associée via un pipe à la commande "sed" qui enlève les éventuels zéros non significatifs, puis à la commande  "printf" qui va donner deux fois 32 bits en hexadécimal. Remarquer l'ajustement du nombre de secondes de la date POSIX pour se ramener au 1er janvier 1900 0h00 (selon le 6. de la rfc5904),
- la commande "ip" est associée via un pipe à la commande "grep", laquelle va isoler la ligne contenant l'adresse MAC de la première interface qui en est dotée (ethernet ou WIFI). Après un nettoyage des éventuels espaces en début de ligne avec "sed", la commande "cut" isole l'adresse MAC. Enfin deux commandes "sed" vont, d'une part enlever les ":" de l'adresse MAC, puis insérer "fffe" au milieu de celle-ci pour la transformer en identifiant EUI-64,
- le résultat de la première commande "echo" est passé à la commande "xxd" qui transforme la suite de caractères hexadécimaux en binaire. Ensuite, ce binaire est transféré à la commande "sha1sum" qui va créer un hash de 160 bits. Celui-ci est "nettoyé" avec la commande "cut" qui suit. La commande "tail" permet de ne conserver que les 40 bits de poids faible et enfin, les 4 "sed" vont finir la mise en forme de la sortie.

Amicalement.

Jean-Marie

Dernière modification par diesel (Le 05/03/2019, à 13:06)


Je déteste qu'on cherche à me faire passer pour un con, j'y arrive déjà très bien tout seul.
Le mort, il sait pas qu'il est mort ; c'est pour les autres que c'est dur.................... Pour les cons, c'est pareil.

Hors ligne

#2 Le 11/02/2018, à 18:28

Brunod

Re : [Script] Adresse ipv6 de type Unique Local unicast Address (rfc4193)

Merci ! Je ne sais pas quand j'en aurai besoin, mais c'est à garder sous le coude wink


Windows est un système d'exploitation de l'homme par l'ordinateur. Linux, c'est le contraire...
39 pc linux convertis

Hors ligne

#3 Le 13/02/2018, à 21:43

diesel

Re : [Script] Adresse ipv6 de type Unique Local unicast Address (rfc4193)

Une version plus concise du script qui se passe du "echo" initial :

( expr $(date +%s) + 2208988808 | sed 's/^0*//' | xargs printf '%08x' ; date +%N | sed 's/^0*//' | xargs printf '%08x' ; ip a | grep -m 1 'link/ether' | sed 's/^[ \t]*//' | cut -f 2 -d ' ' | sed -e 's/://g' -e 's/^.\{6\}/&fffe/' ) | xxd -r -p | sha1sum -b | cut -f 1 -d ' ' | tail -c 11 | sed -e 's/^/fd/' -e 's/^.\{4\}/&:/' -e 's/^.\{9\}/&:/' -e 's/^.\{14\}/&::\/64/'

Amicalement.

Jean-Marie

Dernière modification par diesel (Le 13/02/2018, à 21:54)


Je déteste qu'on cherche à me faire passer pour un con, j'y arrive déjà très bien tout seul.
Le mort, il sait pas qu'il est mort ; c'est pour les autres que c'est dur.................... Pour les cons, c'est pareil.

Hors ligne

#4 Le 13/02/2018, à 22:50

Watael

Re : [Script] Adresse ipv6 de type Unique Local unicast Address (rfc4193)

salut,

pourquoi ouvrir un sous-shell pour grouper des commandes ? utilise des accolades.
expr ? parce que tu utilises un shell non-POSIX ?
est-ce que le nombre de secondes depuis EPOCH additionné de 2208988808 peut donner un nombre commençant par zéro ?
xargs pour utiliser printf ?
ou

printf '%08x' $(($(date +%s)+2208988808))

simplement ?

on continue
date +%-N comme ça les nano-secondes ne commenceront jamais par zéro !

NON ! grep | sed | cut | sed c'est pas possible !
utilise awk

etc...


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#5 Le 14/02/2018, à 08:06

diesel

Re : [Script] Adresse ipv6 de type Unique Local unicast Address (rfc4193)

Bonjour Watael,

Tout d'abord, merci pour tes remarques.

Ensuite, je ne suis pas le spécialiste intergalactique de bash.

Enfin, pour répondre à tes remarques :

- pour le sous-shell, j'ai pas compris le coup des accolades (je viens de vérifier dans le man de "bash". Ok pour la remarque. Je viens encore d'apprendre quelque chose wink ). Quoi que, je viens d'essayer en remplaçant les parenthèses par des accolades ; et bien, ça marche pô (avec bash). Bon, ça y est, il faut un ";" avant l'accolade fermante. C'est malin, ça me fait un caractère en plus, wink
- "expr" ; oui, j'aurais pu utiliser la syntaxe que tu proposes "$(($(date +%s)+2208988808))". Cependant, je n'aime pas trop cette syntaxe qui est vraiment chatouilleuse sur les espaces, ce qui n'est pas le cas de "expr". Ben, finalement, non, avec ou sans espaces au niveau des parenthèses, ça marche pareil,
- "xargs" ; j'ai voulu écrire un script dans lequel les traitements se suivent "naturellement" dans l'ordre des pipes, quitte à ne pas être optimal dans la concision de l'écriture, ni même dans le temps d'exécution,
- nombre de secondes et "date +%-N" ; je ne connaissais pas la syntaxe "+%-N", c'est pourquoi j'ai utilisé "sed" pour virer les zéros non significatifs, et pour être exhaustif, j'ai mis le même traitement pour les secondes bien que sachant pertinemment que ce nombre ne commençait pas par zéro. Maintenant, si je peux garantir que les deux résultats n'ont pas de zéro non significatifs, je supprimerai les deux "sed" sans aucun remord.
- "awk" ; c'est certainement très bien (c'est ce que je lis partout), mais je ne sais pas l'utiliser alors que je maîtrise assez bien "grep", "cut" et "sed". De plus, sur le plan didactique (y compris pour moi), ça a l'avantage de bien décomposer les traitements : je trouve, je nettoie, j'isole la chaîne de caractères qui m'intéresse, je mets en forme.
- etc... ; j'ai pas trouvé. wink big_smile

Cela dit, mon script, il donne le bon résultat (dans ses deux versions). Et comme c'est du one shot, il n'a pas besoin d'être optimisé en termes de nombre de commandes chargées puis lancées.

Bon, je vais le retravailler.

[EDIT] Une version encore simplifiée :

{ expr $(date +%s) + 2208988808 | xargs printf '%08x' ; date +%-N | xargs printf '%08x' ; ip a | grep -m 1 'link/ether' | sed -e 's/^[ \t]*//' | cut -f 2 -d ' ' | sed -e 's/://g' -e 's/^.\{6\}/&fffe/' ;} | xxd -r -p | sha1sum -b | cut -f 1 -d ' ' | tail -c 11 | sed -e 's/^/fd/' -e 's/^.\{4\}/&:/' -e 's/^.\{9\}/&:/' -e 's/^.\{14\}/&::\/64/'

Et pour "faire plaisir" à Watael : wink

{ printf '%08x' $(( $(date +%s) + 2208988808 )) ; printf '%08x' $(date +%-N) ; ip a | grep -m 1 'link/ether' | sed -e 's/^[ \t]*//' | cut -f 2 -d ' ' | sed -e 's/://g' -e 's/^.\{6\}/&fffe/' ;} | xxd -r -p | sha1sum -b | cut -f 1 -d ' ' | tail -c 11 | sed -e 's/^/fd/' -e 's/^.\{4\}/&:/' -e 's/^.\{9\}/&:/' -e 's/^.\{14\}/&::\/64/'

[/EDIT]

Amicalement.

Jean-Marie

Dernière modification par diesel (Le 14/02/2018, à 10:42)


Je déteste qu'on cherche à me faire passer pour un con, j'y arrive déjà très bien tout seul.
Le mort, il sait pas qu'il est mort ; c'est pour les autres que c'est dur.................... Pour les cons, c'est pareil.

Hors ligne

#6 Le 14/02/2018, à 13:53

diesel

Re : [Script] Adresse ipv6 de type Unique Local unicast Address (rfc4193)

Allez, un petit dernier pour la route :

Dans les scripts précédents, la récupération de la date en deux étapes risque d'introduire une incohérence entre le nombre de secondes et le nombre de nanosecondes (on prélève une unité, puis le nombre de nanosecondes de l'unité suivante). Vous pourrez toujours objecter (à relativement juste titre) que ce n'est pas important puisque l'erreur sera inférieure à une seconde, mais sur le principe, ce n'est pas bon.

Alors, une petite évolution du script :

{ expr $(date +%s%N) + 2208988808000000000 | sed -e 's/^.\{10\}/& /' -e 's/ 0*/ /' | xargs printf '%08x%08x' ; ip a | grep -m 1 'link/ether' | sed -e 's/^[ \t]*//' | cut -f 2 -d ' ' | sed -e 's/://g' -e 's/^.\{6\}/&fffe/' ;} | xxd -r -p | sha1sum -b | cut -f 1 -d ' ' | tail -c 11 | sed -e 's/^/fd/' -e 's/^.\{4\}/&:/' -e 's/^.\{9\}/&:/' -e 's/^.\{14\}/&::\/64/'

Après avoir récupéré la date POSIX (secondes et nanosecondes), ajouté le nombre de secondes pour ramener au 1er janvier 1900 à 0h00, ajouté un espace entre les secondes et les nanosecondes, puis supprimé les zéros non significatifs au chiffre des nanosecondes, le tout est passé à la commande "printf" pour générer les 64 bits de l'heure en hexadécimal.

Amicalement.

Jean-Marie

Dernière modification par diesel (Le 14/02/2018, à 14:00)


Je déteste qu'on cherche à me faire passer pour un con, j'y arrive déjà très bien tout seul.
Le mort, il sait pas qu'il est mort ; c'est pour les autres que c'est dur.................... Pour les cons, c'est pareil.

Hors ligne

#7 Le 14/02/2018, à 15:12

Watael

Re : [Script] Adresse ipv6 de type Unique Local unicast Address (rfc4193)

echo $(($(date +%s%N)+($(date -d '01/01/1900 00:00' +%s%N) /-1)))

parce que le nombre de secondes depuis 01/01/1900 change à chaque instant.

mais si tu veux que le processus soit clairement détaillé, pourquoi ne pas passer par des variables intermédiaires ? ainsi chaque étape serait visiblement distinguée...

Dernière modification par Watael (Le 14/02/2018, à 15:14)


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#8 Le 14/02/2018, à 15:39

diesel

Re : [Script] Adresse ipv6 de type Unique Local unicast Address (rfc4193)

Certes,

Cependant, la représentation numérique de la date du 1er janvier 1900 à 0h00 a, elle, le mérite d'être fixe. Elle vaut : -2208989361000000000 (dixit la commande date).

Il est d'ailleurs amusant de constater qu'il y a 553 secondes d'écart (soit un peu plus de 9 minutes) avec ce que j'avais calculé à la main (-2208988808000000000).

Cependant, autant prendre la valeur renvoyée par le système. D'où le script :

{ expr $(date +%s%N) - $(date -d '01/01/1900' +%s%N) | sed -e 's/^.\{10\}/& /' -e 's/ 0*/ /' | xargs printf '%08x%08x' ; ip a | grep -m 1 'link/ether' | sed -e 's/^[ \t]*//' | cut -f 2 -d ' ' | sed -e 's/://g' -e 's/^.\{6\}/&fffe/' ;} | xxd -r -p | sha1sum -b | cut -f 1 -d ' ' | tail -c 11 | sed -e 's/^/fd/' -e 's/^.\{4\}/&:/' -e 's/^.\{9\}/&:/' -e 's/^.\{14\}/&::\/64/'

Quant à la syntaxe, je trouve beaucoup plus naturel d'utiliser la commande "expr" plutôt que la commande "echo" (que j'utilise souvent par ailleurs) pour juste obtenir le résultat d'un calcul (et ça fait moins de caractères à frapper wink ).

L'utilisation de variables intermédiaires est effectivement une bonne suggestion, mais mon idée de départ était de résoudre le problème en une ligne de commande unique et en essayant de s'en tenir à la philosophie KISS d'UNIX (keep it simple stupid) ; donc une suite de commandes les plus simples possibles et des pipes.

Amicalement.

Jean-Marie

Dernière modification par diesel (Le 23/02/2018, à 17:35)


Je déteste qu'on cherche à me faire passer pour un con, j'y arrive déjà très bien tout seul.
Le mort, il sait pas qu'il est mort ; c'est pour les autres que c'est dur.................... Pour les cons, c'est pareil.

Hors ligne

#9 Le 14/02/2018, à 18:18

Watael

Re : [Script] Adresse ipv6 de type Unique Local unicast Address (rfc4193)

expr est une commande externe (comme ls, date...).

j'ai laissé le echo parce que tu tiens à utiliser xargs

dixneufCent=$(($(date +%s%N)+($(date -d '01/01/1900 00:00' +%s%N) /-1)))
printf '%08x08x' ${dixneufCent::10} ${dixneufCent:10}

s'il est indispensable de couper la valeur en deux nombres de 10 chiffres...

il faut te mettre d'accord, soit tu veux "démontrer" l'algorithme, soit utiliser des pipes (ce qui, selon moi, ne simplifie pas la lecture ou l'exécution).
il est également recommandé qu'une ligne de commande ne dépasse pas (par souci de lisibilité) 80 caractères.


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#10 Le 14/02/2018, à 19:04

diesel

Re : [Script] Adresse ipv6 de type Unique Local unicast Address (rfc4193)

Ben..., il est indispensable de couper, d'une part la valeur entière pour la convertir en 8 digits hexadécimaux, et d'autre part le nombre de nanosecondes pour le convertir, lui aussi en 8 digits hexadécimaux.

Si on essaye de convertir d'un seul coup la date exprimée en nanosecondes, ça ne donne pas le même résultat.

Pour moi, une telle écriture avec une succession de pipes est le meilleur moyen de contrôler au fur et à mesure la progression du traitement. Si je veux aller voir ce qui se passe à la cinquième étape du traitement, il me suffit de supprimer tout ce qu'il y a derrière et de lancer l'exécution. Si ça fonctionne, deux coups de flèche vers le haut au clavier et je reviens à la commande complète et je peux aller à la sixième étape, etc...

Enfin, mon propos n'est pas de démontrer l'algorithme. J'ai écrit la première version de ce script parce que j'en avais besoin dans le cadre de la configuration d'un serveur (et que je n'ai rien trouvé sur le net qui me donnait le résultat dont j'avais besoin). Puis j'ai pensé que ça pourrait être utile à d'autres.

Pour en revenir à ta première remarque, effectivement, "expr" est une commande externe. Et alors ?, je ne vois pas ce qu'il y a de mal à ça. "date", "printf", "ip", et "awk" aussi. Dans une telle commande "one shot", on n'en est pas à optimiser la microseconde ou quelques kilo-octets de mémoire.

Et j'ai bien conscience que je n'ai qu'une maîtrise assez basique de bash. Dans chacune de tes interventions, je découvre des syntaxes que j’ignorais (${dixneufCent::10} ou ${dixneufCent:10} dans le cas présent). Il va falloir que je regarde ce que ça fait.

Amicalement.

Jean-Marie

Dernière modification par diesel (Le 14/02/2018, à 19:04)


Je déteste qu'on cherche à me faire passer pour un con, j'y arrive déjà très bien tout seul.
Le mort, il sait pas qu'il est mort ; c'est pour les autres que c'est dur.................... Pour les cons, c'est pareil.

Hors ligne

#11 Le 14/02/2018, à 19:45

Watael

Re : [Script] Adresse ipv6 de type Unique Local unicast Address (rfc4193)

on utilise une commande externe quand le shell ne sait pas le faire tout seul.
si printf savait afficher les nanosecondes, je n'aurais même pas utilisé date (peut-être dans la prochaine version de bash. ça a été demandé).
printf est une commande interne, c'est unebuiltin.

mon propos n'est pas de démontrer l'algorithme.

c'est ce que j'avais compris :

ça a l'avantage de bien décomposer les traitements


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne