0

I have a list of possible to ip6 addresses converted MAC-addresses, that could be found in the output of

ping6 ff02::1%wlan0

possible mac addresses are for example:

66:70:02:75:80:fe, 64:70:02:74:80:fe, 66:70:02:74:80:ff

each of them would lead to a Link-local ip6 address beginning with fe80:: and inserted FF:FE in the middle

so 66:70:02:75:80:fe would lead to fe80::6670:2ff:fe75:80fe

I would like to create a script that gives out the matching LinkLocal address for a list of MAC adddresses like:

$ find-in-macs 66:70:02:75:80:fe 64:70:02:74:80:fe 66:70:02:74:80:ff

and the output:

matching IP6: fe80::6670:2ff:fe75:80fe

that script find-in-macs could look like this:

#!/bin/bash
mac_to_ipv6 () {
  IFS=':'; set $1; unset IFS
  ipv6_address="fe80::$(printf %02x $((0x$1 ^ 2)))$2:${3}ff:fe$4:$5$6"
  echo $ipv6_address
}


for i do
    echo checking $i
    ping6 ff02::1%wlan0|grep mac_to_ipv6 $i
done
3

Firstly, you not only have to split the MAC and insert ff:fe, you also need to flip the 7th bit to correctly represent a universal/local address.

This script will correctly format a link-local IPv6 address based on an ether address, including reducing leading zeros.

#!/bin/bash

IFS=':'; set $1; unset IFS
printf "fe80::%x:%x:%x:%x\n" $(( 0x${1}${2} ^ 0x200 )) 0x${3}ff 0xfe${4} 0x${5}${6}

Example of bit-flipping and zero reduction:

$ ether_to_ipv6 00:00:00:00:00:00
fe80::200:ff:fe00:0
$ ether_to_ipv6 11:11:11:11:11:11
fe80::1311:11ff:fe11:1111

Also keep in mind that it's technically not guaranteed that a link will have an address matching this algorithm. If there's a collision (malicious or otherwise) a new address must be chosen by one or both. Implementations may behave differently as to how this is actually handled, so YMMV.

However, if all you're really only trying to do is get a list of your actual neighbors (similar to arp in IPv4) then there's an easier way. Use Neighbor Discovery Protocol (ndp).

Linux:

ip -6 neigh show

Solaris:

netstat -pf inet6

Mac OS X, AIX, *BSD:

ndp -a

JunOS, IOS, Vyatta:

show ipv6 neighbors

Each of these commands will show a list of all live IPv6 neighbors using native ndp.

  • To be slightly more explicit: those commands don't send new NDP packets. They show the table of neighbours which have been recently contacted (which the kernel resolved with NDP previously). So you still need to contact them first... I'm not sure if the broadcast ping command shown in the question works for that, because you'll only be receiving IP packets from the neighbours, not sending them? Unless the neighbour's NDP then triggers a mutual discovery process? (It also assumes your neighbours respond to pings on the broadcast address). – sourcejedi Jun 14 '13 at 7:17
  • Yes, they actually query the kernel's in memory cache. However, neighbor discovery is automatic, so all hosts are aware of all other hosts on the same link automatically via ndp. There's no need to "broadcast" ping them (and there's no broadcast in IPv6 anyway). – bahamat Jun 15 '13 at 1:05
  • I tried it and I don't know what you're talking about. "ip neigh show" -> no ipv6 addresses. "ping6 ff02::1%wlan0" followed by "ip neigh show" -> my neighbour's ipv6 shows up. Perhaps you could link the RFC section that explains how you think hosts broadcast^Wmulticast to local ipv6 hosts their existence using NDP. My understanding of NDP is basically ARP ported up from ethernet to IPv6 local link, it doesn't add any amazing feature from whole cloth... – sourcejedi Jun 15 '13 at 7:04
  • You need to use ip -6 neigh show. The -6 is kind of important. NDP is much more than ARP. The RFC you're asking for is 4862. – bahamat Jun 15 '13 at 19:37
  • The default shows both IP6 and IP4, so using -6 doesn't affect my test (makes it easier to read though :-). There's nothing in the RFC section that adds a requirement to send to all-nodes (think how "chatty" that would get!). If you want to find out your neighbors you need to send more packets, like that ping6 command does. It's easy to be misled by the grandiose name Neighbor Advertisement, but that's only really used as a unicast reply to a Solicitation. (Outside of scenarios like IP4 gratuitous ARPs). – sourcejedi Jun 16 '13 at 9:34
0

With your tips, I could finish the script:

#!/bin/bash

mac_to_ipv6 () {
  IFS=':'; set $1; unset IFS
  ipv6_address="fe80::$(printf %02x $((0x$1 ^ 2)))$2:${3}ff:fe$4:$5$6"
  echo $ipv6_address
}
echo "Next MAC with ^C"
for i do
  echo
  echo checking for  $i = $(mac_to_ipv6 $i)
  echo 
  ping6 ff02::1%wlan0 | head -n 1000 | grep $(mac_to_ipv6 $i)
done

see: http://freifunk.in-kiel.de/wiki/Firmware#IPv6_Adresse_des_Routers

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.