|
| 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