Behandlung des IPv6 Formats

satriani

satriani

SysLion
Hallo,

ich quälle mich hier mit einem Befehl zur Validierung einer IPv6, der sieht wie folgt aus:

Code:
# echo "3a07:8f9:321:8942:4f59:0000:0000:0000" | awk -F: '{for(i=1;i<=NF;i++)x=x""sprintf ("%4s", $i);gsub(/ /,"0",x);print x}' | sed 's/..../&:/g' | cut -d: -f1 -f2 -f3 -f4 -f5 -f6 -f7 -f8
# 3a07:08f9:0321:8942:4f59:0000:0000:0000
Beim Output werden 8f9 und 321 jeweils um eine vorstehenden Null ergänzt, soweit so gut. Doch man kann die IPv6 auch wie folgt kürzen 2001:db8:0:0:8d3::
Code:
# echo "2001:db8:0:0:8d3::" | awk -F: '{for(i=1;i<=NF;i++)x=x""sprintf ("%4s", $i);gsub(/ /,"0",x);print x}' | sed 's/..../&:/g' | cut -d: -f1 -f2 -f3 -f4 -f5 -f6 -f7 -f8
# 2001:0db8:0000:0000:08d3:0000:0000:
oder so 2001:db8::8d3:0:0:0
Code:
# echo "2001:db8::8d3:0:0:0" | awk -F: '{for(i=1;i<=NF;i++)x=x""sprintf ("%4s", $i);gsub(/ /,"0",x);print x}' | sed 's/..../&:/g' | cut -d: -f1 -f2 -f3 -f4 -f5 -f6 -f7 -f8
# 2001:0db8:0000:08d3:0000:0000:0000:
In beiden Fällen ist das Ergebnis wie man sieht, leider nicht wie erwünscht.
Bitte die Shellexperten um Einblick

Danke im Voraus, Gruß.
 
Zuletzt bearbeitet:
Na, nicht so schnell Bruderherz :D
Ich glaube ich muss darauf hinweisen welches Betriebssystem und Shell ich verwende. Ab jetzt steht es in meiner Signatur :)
Leider kann FreeBSD mit regex ohne weiteres nichts anfangen.
Danke trotzdem. Du bist wie immer eine Rakete was die Hilfsbereitschaft angeht :respekt:
 
Na, nicht so schnell Bruderherz :D
Ich bin nicht dein Bruder(-herz).:oldman
Ich glaube ich muss darauf hinweisen welches Betriebssystem und Shell ich verwende. Ab jetzt steht es in meiner Signatur :)
Eine gute Idee.
Leider kann FreeBSD mit regex ohne weiteres nichts anfangen.
Das ist richtig. Free BSD ist ein Betriebssystem.
Was du für die von mir rausgesuchten Lösungen benötigst ist die Bash:
http://www.cyberciti.biz/faq/freebsd-bash-installation/
Danke trotzdem. Du bist wie immer eine Rakete was die Hilfsbereitschaft angeht :respekt:
Ich tue was ich kann. :)
 
Das ist richtig. Free BSD ist ein Betriebssystem.
Was du für die von mir rausgesuchten Lösungen benötigst ist die Bash:
http://www.cyberciti.biz/faq/freebsd-bash-installation/

So gerne ich das hätte, doch leider ist das keine Option in diesem Fall.
Es dürfen keine Ports geholt werden und nur zwei nicht betriebssystemeigene Anwendungen installiert werden. Bash gehört leider nicht dazu.
Daher muss ich den Berg zum Propheten bringen, sprich nur mit nacktem FreeBSD auskommen :(
 
Da frage ich mich zwar, was das soll, aber nun gut.
Der zweite Link, den man zu meiner verlinkten Suchanfrage bei google findet liefert einen regulären Ausdruck für IPv6 Adressen.
Sofern du eine Version von grep hast, die --extended-regexp akzeptiert, solltest du diesen damit in angepasster Form benutzen können.
In jedem Fall kannst du den gennanten regulären Ausdruck in ein äquivalentes Shellskript umformen.

MfG

Schard

PS: Wenn du ein derart eingeschränktes System verwendest, ist es sicherlich sinnvoll, eingangs zu erwähnen, welche Programme überhaupt eingesetzt werden können.
 
Sofern du eine Version von grep hast, die --extended-regexp akzeptiert, solltest du diesen damit in angepasster Form benutzen können.

Laut "man grep" scheint grep tatsächlich extended-regexp zu unterstützen.
-E, --extended-regexp
Interpret PATTERN as an extended regular expression (see below).
Das Ergebnis ist leider nicht wie erhofft
Code:
# echo "2a01:488:66::0:1" | grep -E 's*((([0-9A-Fa-f]{1,4}:){7}(([0-9A-Fa-f]{1,4})|:))|(([0-9A-Fa-f]{1,4}:){6}(:|((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})|(:[0-9A-Fa-f]{1,4})))|(([0-9A-Fa-f]{1,4}:){5}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){4}(:[0-9A-Fa-f]{1,4}){0,1}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){3}(:[0-9A-Fa-f]{1,4}){0,2}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)(:[0-9A-Fa-f]{1,4}){0,4}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(:(:[0-9A-Fa-f]{1,4}){0,5}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})))(%.+)?\s*'
# 2a01:488:66::0:1

Ich habe ein nettes Skript gefunden das, zumindest auf Ubuntu mit Bash hervorragend funktioniert und muss an csh angepasst werden

Code:
INPUT="$@"

O=""

while [ "$O" != "$INPUT" ]; do
O="$INPUT"

# fill all words with zeroes

INPUT="$( sed  's|:\([0-9a-f]\{3\}\):|:0\1:|g' <<< "$INPUT" )"
INPUT="$( sed  's|:\([0-9a-f]\{3\}\)$|:0\1|g'  <<< "$INPUT")"
INPUT="$( sed  's|^\([0-9a-f]\{3\}\):|0\1:|g'  <<< "$INPUT" )"

INPUT="$( sed  's|:\([0-9a-f]\{2\}\):|:00\1:|g' <<< "$INPUT")"
INPUT="$( sed  's|:\([0-9a-f]\{2\}\)$|:00\1|g'  <<< "$INPUT")"
INPUT="$( sed  's|^\([0-9a-f]\{2\}\):|00\1:|g'  <<< "$INPUT")"

INPUT="$( sed  's|:\([0-9a-f]\):|:000\1:|g'  <<< "$INPUT")"
INPUT="$( sed  's|:\([0-9a-f]\)$|:000\1|g'   <<< "$INPUT")"
INPUT="$( sed  's|^\([0-9a-f]\):|000\1:|g'   <<< "$INPUT")"

done

# now expand the ::

grep -qs "::" <<< "$INPUT"
if [ "$?" -eq 0 ]; then
  GRPS="$(sed  's|[0-9a-f]||g' <<< "$INPUT" | wc -m)"
  ((GRPS--)) # carriage return
  ((MISSING=8-GRPS))
  for ((i=0;i<$MISSING;i++)); do
	  ZEROES="$ZEROES:0000"
	  done

# be careful where to place the :
 INPUT="$( sed  's|\(.\)::\(.\)|\1'$ZEROES':\2|g'   <<< "$INPUT")"
 INPUT="$( sed  's|\(.\)::$|\1'$ZEROES':0000|g'   <<< "$INPUT")"
 INPUT="$( sed  's|^::\(.\)|'$ZEROES':0000:\1|g;s|^:||g'   <<< "$INPUT")"

fi

# an expanded address has 39 chars + CR
if [ $(echo $INPUT | wc -m) != 40 ]; then
 echo "invalid IPv6 Address"
fi

# echo the fully expanded version of the address
echo $INPUT

Ich mache mich morgen an die Arbeit, mal sehen was daraus wird.

:gn8:
 
Geht es nicht einfach nur darum, die einzelnen Felder mit vier Stellen auszugeben und ggf. mit einer '0' links aufzufuellen? Dann wuerde dort "%04s" als Anweisung an sprintf ausreichen.
 
Nein, da du prüfen musst, ob in den Feldern etwas anderes als 0-9 und a-f steht. Außerdem kannst du an einer Stelle in der Adresse Felder die nur mit "0" gefüllt sind als "::" zusammenfassen, die neue Lokalhostadresse ist da ein schönes Beispiel: "::1" ist kürzter als "0000:0000:0000:0000:0000:0000:0000:0001"

Code:
dig +noall +answer AAAA facebook.com
facebook.com.           824     IN      AAAA    2a03:2880:2110:df01:face:b00c:0:8
Ausgeschreiben: 2a03:2880:2110:df01:face:b00c:0000:0008
Code:
dig +noall +answer AAAA google.com
google.com.             97      IN      AAAA    2a00:1450:4016:802[B][COLOR="#FF0000"]::[/COLOR][/B]1007
Ausgeschreiben: 2a00:1450:4016:0802:0000:0000:0000:1007

mfg
HeadCrash

PS: Danke für das finden des Skripts.

PPS: schon wieder zu langsam :)
 
wie würde das
Code:
grep -qs "::" <<< "$INPUT"
if [ "$?" -eq 0 ]; then
  GRPS="$(sed  's|[0-9a-f]||g' <<< "$INPUT" | wc -m)"
  ((GRPS--)) # carriage return
  ((MISSING=8-GRPS))
  for ((i=0;i<$MISSING;i++)); do
	  ZEROES="$ZEROES:0000"
	  done
für /bin/cs aussehen?
 
Im Netz konnte mich kein Script wirklich überzeugen, deshalb habe ich kurzerhand meins gebastelt und gut ist :D

Code:
#!/bin/sh
INPUT="$@"

for i in $INPUT
do
  i="$(echo $i | tr [A-Z] [a-z])"
  SEC="$(echo $i | sed 's/:/ /g' | wc -w | xargs)"
  COM="$(echo "8-$SEC" | bc)"
  ERG="$(yes 0000 | head -n$COM | xargs | sed 's/ /:/g')"
  if [ "$(echo $i | grep -o '::' | wc -l | xargs)" -gt 1 ] ||
     [ "$(echo $i | grep -o ':' | wc -l | xargs)" -lt 2 ] ||
     [ "$(echo $i | grep -o ':::')" ] ||
     [ "$(echo $i | sed 's/[a-f0-9:]//g')" ] ||
     [ "$(echo $i | grep '[a-f0-9]\{5\}')" ] ||
     [ "$(echo $i | grep '^:[a-f0-9]\|[a-f0-9]:$')" ] ||
     [ "$SEC" -gt 8 ]
  then
    echo "invalid IPv6 Address: $i"
  else
    if [ "echo $i | grep '::'" ]; then
      i="$(echo $i | sed 's/::/:'$ERG':/g; s/^://; s/:$//' | awk -F: '{for(i=1;i<=NF;i++)x=x""sprintf ("%4s", $i);gsub(/ /,"0",x);print x}' | sed 's/..../&:/g; s/^://; s/:$//')"
    else
      i="$(echo $i | awk -F: '{for(i=1;i<=NF;i++)x=x""sprintf ("%4s", $i);gsub(/ /,"0",x);print x}' | sed 's/..../&:/g; s/^://; s/:$//')"
    fi
    if [ "$(echo $i | wc -m | xargs)" -eq 40 ]; then
       echo $i
    else  
       echo "invalid IPv6 Address: $i"
    fi
  fi
done

Bitte, falls jemand einen Fehler findet oder Vorschlag hat, nur zu :search:

Danke.
 
Zuletzt bearbeitet:

Ähnliche Themen

Verschlüsseltes Backup-Script mit rsync

Problem mit HSPA+ Modem Huawei E353 - Installation unmöglich?

Ubuntu X / dbus problem

Last mit etc/passwd anzeigen lassen

Textkonsole mit KMS zu klein

Zurück
Oben