Skip to content

Commit 58ccfbd

Browse files
committed
ipv6-gen-slaac: Utility to generate SLAAC address
Given an IPv6 network & MAC address generate the corresponding SLAAC address. e.g $ ./ipv6-gen-slaac 2001:db8:a:b:: 00:24:1d:ba:80:00 SLAAC : 2001:db8:a:b:224:1dff:feba:8000 Signed-off-by: Andrew Clayton <andrew@digital-domain.net>
1 parent 7803d7f commit 58ccfbd

File tree

4 files changed

+73
-2
lines changed

4 files changed

+73
-2
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ gen-ula
44
ipv6-arpa
55
ipv6-extract-mac
66
ipv6-fmt
7+
ipv6-gen-slaac
78
ipv6-isin
89
ipv6-range
910
mac-to-eui64

Makefile

+5-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ ifneq "$(GLIBC_VER_OK)" "1"
1818
endif
1919

2020
all: ipv6-range ipv6-arpa ipv6-isin gen-ula mac-to-eui64 mac-type \
21-
ipv6-extract-mac prefix-to-mask mask-to-prefix ipv6-fmt
21+
ipv6-extract-mac prefix-to-mask mask-to-prefix ipv6-fmt ipv6-gen-slaac
2222

2323
ipv6-range: ipv6-range.c
2424
$(CC) $(CFLAGS) -o $@ $<
@@ -50,6 +50,9 @@ mask-to-prefix: mask-to-prefix.c
5050
ipv6-fmt: ipv6-fmt.c
5151
$(CC) $(CFLAGS) -o $@ $<
5252

53+
ipv6-gen-slaac: ipv6-gen-slaac.c
54+
$(CC) $(CFLAGS) -o $@ $<
55+
5356
clean:
5457
rm -f ipv6-range ipv6-arpa ipv6-isin gen-ula mac-to-eui64 mac-type \
55-
ipv6-extract-mac prefix-to-mask mask-to-prefix ipv6-fmt
58+
ipv6-extract-mac prefix-to-mask mask-to-prefix ipv6-fmt ipv6-gen-slaac

README

+6
Original file line numberDiff line numberDiff line change
@@ -98,5 +98,11 @@ ipv6-fmt - Given an IPv6 address format it in compressed,
9898
Expanded : 2001:0db8:0000:0000:0000:dead:0000:beef
9999
URI Literal : [2001:db8::dead:0:beef]
100100

101+
ipv6-gen-slaac - Given an IPv6 network & MAC address, generate the
102+
corresponding SLAAC address.
103+
104+
$ ./ipv6-gen-slaac 2001:db8:a:b:: 00:24:1d:ba:80:00
105+
SLAAC : 2001:db8:a:b:224:1dff:feba:8000
106+
101107
These tools are licensed under the GNU General Public License Version 2 or
102108
the GNU Lesser General Public License Version 2.1

ipv6-gen-slaac.c

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* ipv6-gen-slaac.c - Given an IPv6 network & MAC address create the
3+
* corresponding SLAAC address.
4+
*
5+
* Copyright (C) 2017 Andrew Clayton <andrew@digital-domain.net>
6+
*
7+
* Licensed under the GNU General Public License Version 2 or
8+
* the GNU Lesser General Public License Version 2.1
9+
*
10+
* See GPLv2 & LGPLv2.1 in the source tree.
11+
*/
12+
13+
#include <stdio.h>
14+
#include <stdlib.h>
15+
#include <string.h>
16+
#include <arpa/inet.h>
17+
18+
#include "short_types.h"
19+
20+
int main(int argc, char *argv[])
21+
{
22+
int i;
23+
int len;
24+
u8 mac[8];
25+
u8 slaacn[sizeof(struct in6_addr)];
26+
char slaac[INET6_ADDRSTRLEN];
27+
28+
if (argc < 2) {
29+
fprintf(stderr, "Usage: ipv6-gen-slaac <IPv6 network> <MAC address>\n");
30+
exit(EXIT_FAILURE);
31+
}
32+
33+
len = snprintf(slaac, sizeof(slaac), "%s", argv[1]);
34+
if (slaac[len-1] == ':' && slaac[len-2] == ':')
35+
slaac[len-1] = '\0';
36+
else if (slaac[len-1] != ':')
37+
snprintf(slaac + len, sizeof(slaac), ":");
38+
39+
mac[0] = strtoul(argv[2], NULL, 16);
40+
mac[1] = strtoul(argv[2]+3, NULL, 16);
41+
mac[2] = strtoul(argv[2]+6, NULL, 16);
42+
mac[3] = 0xff;
43+
mac[4] = 0xfe;
44+
mac[5] = strtoul(argv[2]+9, NULL, 16);
45+
mac[6] = strtoul(argv[2]+12, NULL, 16);
46+
mac[7] = strtoul(argv[2]+15, NULL, 16);
47+
48+
/* Toggle the (U/L) bit 0000 00*0 */
49+
mac[0] ^= 1 << 1;
50+
51+
for (i = 0; i < 8; i += 2)
52+
snprintf(slaac + strlen(slaac), sizeof(slaac), "%02x%02x%s",
53+
mac[i], mac[i+1], i+1 < 7 ? ":" : "");
54+
55+
/* Display in compressed form */
56+
inet_pton(AF_INET6, slaac, slaacn);
57+
inet_ntop(AF_INET6, slaacn, slaac, INET6_ADDRSTRLEN);
58+
printf("SLAAC : %s\n", slaac);
59+
60+
exit(EXIT_SUCCESS);
61+
}

0 commit comments

Comments
 (0)