pbiering / ipv6calc

ipv6calc
https://www.deepspace6.net/projects/ipv6calc.html
Other
46 stars 15 forks source link

Add support for IPv6 -> EUI64/MAC #7

Closed Malvineous closed 6 years ago

Malvineous commented 6 years ago

At present you cannot extract the EUI64 or MAC component from an IPv6 address:

ipv6calc --in ipv6 2001:db8::a8bb:ccff:fedd:eeff --out eui64
Specify proper action or input for output format: eui64
$ ipv6calc --in ipv6 2001:db8::a8bb:ccff:fedd:eeff --out mac  
No valid MAC address given!

However if you use --showinfo then both these values are extracted:

ipv6calc --in ipv6 2001:db8::a8bb:ccff:fedd:eeff --showinfo
Interface identifier: a8bb:ccff:fedd:eeff
EUI-48/MAC address: aa:bb:cc:dd:ee:ff

It would be very helpful if we could extract these values without scraping the --showinfo output.

My reason for requesting this feature is that I would like to take an internal IPv6 address from DNS for a number of hosts on my LAN, extract the EUI64 or MAC component of each, and then append that onto a routable IPv6 prefix from my ISP in order to construct a valid global IPv6 address for each host. I then plan to update DNS records with these newly constructed global IPv6 addresses, so that when my router's IPv4 address changes, all my hosts get their DNS entries updated with their new public IPv6 addresses.

Essentially, I have an IPv6 address and I want to replace the prefix on it with a different prefix. For example, I have the private IP fd00::1234 and I should remove the fd00::/64 prefix, then replace it with the 2001:db8:aaaa:bbbb::/64 prefix instead, to produce the public address 2001:db8:aaaa:bbbb::1234. The prefix is a 6rd one generated from my ISP's IPv6 prefix and my IPv4 address.

I can use ipv6calc to convert the IPv4 address into a valid 6rd prefix, however there doesn't seem to be a way to replace the prefix on a private IPv6 address with a public prefix, or to extract the EUI64/MAC so you can use string concatenation to replace the prefix either.

pbiering commented 6 years ago

extraction of EUI64 or even MAC can be implemented (started already) but during implementation I found that this is not helpful for you because EUI64 / MAC have XOR'ed bit inside (see your example "a8" turns into "aa") - what you need is simply extracting the IID (aka suffix), but this is already implemented since long time:

ipv6calc -q --in ipv6 2001:db8::a8bb:ccff:fedd:eeff --printsuffix --forceprefix 64
a8bb:ccff:fedd:eeff

This kind of "magic" options can be found using ipv6calc -O ipv6addr -h

Malvineous commented 6 years ago

Thanks for the quick response!

Could you XOR the bit again to turn a8 back into aa as you do with --showinfo?

--printsuffix works to extract the EUI64, however now I'm not sure sure how to prepend the new prefix onto the front of it. It works with --in prefix+mac --action prefixmac2ipv6 (when I extract the MAC from --showinfo) however I don't seem to be able to do the same with the EUI64:

$ IID=`ipv6calc -q --in ipv6 2001:db8::a8bb:ccff:fedd:eeff --printsuffix --forceprefix 64`
$ ipv6calc --in eui64 $IID --out ipv6  # Somehow set prefix to 2001:db8:aaaa:bbbb::/64 here too!
Error in given EUI-64 address, 'a8bb:ccff:fedd:eeff' is not valid (number of colons/dashes/spaces is not 5 or number of dashes is not 1)!

I'm not sure why it wants 5 colons when as far as I can tell an EUI64 address normally has only three! If I put 5 colons in it still tells me it needs 5 colons so I'm not sure what's wrong. Of course the command is incomplete but I don't think I can go further until I can work how what I am doing wrong here!

pbiering commented 6 years ago

EUI64 address format is xx:xx:xx:xx:xx:xx:xx:xx only, your string shows an IID.

But why so complicated? ´´´ IPV6_OLD="2001:db8::a8bb:ccff:fedd:eeff" IPV6_PREFIX_NEW="2001:db8:aaaa:bbbb" IID=$(ipv6calc -q --in ipv6 $IPV6_OLD --printsuffix --forceprefix 64) IPV6_NEW="$IPV6_PREFIX_NEW:$IID" echo $IPV6_NEW ´´´ the misleading error message is a bug, fixed now already locally, will be pushed next days latest

Malvineous commented 6 years ago

Oh I see, I have only ever seen EUI-64 as what you call IID format so I assumed they were the same.

Hmm, I think I can make that work with --printprefix:

IPV6_ISP_PREFIX="2001:db8::/32"
IP=`dig +short myip.opendns.com @resolver1.opendns.com`
    # => 170.170.187.187 (aaaa:bbbb)
IPV6_MY_PREFIX=`ipv6calc --action 6rd_local_prefix --6rd_prefix "$IPV6_ISP_PREFIX" --in ipv4 "$IP" --out ipv6 --printprefix`
    # => 2001:db8:aaaa:bbbb
IPV6_PRIVATE=`dig +short "$H.example.com" aaaa @localhost`
    # => fd00:db8::a8bb:ccff:fedd:eeff
IID=`ipv6calc -q --in ipv6 "$IPV6_PRIVATE" --printsuffix --forceprefix 64`
    # => a8bb:ccff:fedd:eeff
IPV6_PUBLIC="$IPV6_MY_PREFIX:$IID"
    # => 2001:db8:aaaa:bbbb:a8bb:ccff:fedd:eeff

Perfect! Many thanks for your help! Feel free to close this issue.

pbiering commented 6 years ago

minor bugs found during investigations fixed now in master