103 lines · 2.1 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ /* * linklocal - print ipv6 link-local or 6to4 address of a mac address. * eui is ieee's extended unique identifier, per rfc2373. */ #include <u.h>#include <libc.h>#include <ip.h> enum {	Mac0mcast	= 1<<0,		/* multicast address */	Mac0localadm	= 1<<1,		/* locally-administered address, */	V60globaladm	= 1<<1,		/* but ipv6 reverses the meaning */}; static char *v4_6to4; static voidusage(void){	fprint(2, "usage: %s [-t ipv4] ether...\n", argv0);	exits("usage");} voidea2eui64(uchar *lla, uchar *ea){	*lla++ = *ea++ | V60globaladm;	/* oui (company id) */	*lla++ = *ea++;			/* " */	*lla++ = *ea++;			/* " */	*lla++ = 0xFF;			/* mac-48 in eui-64 (sic) */	*lla++ = 0xFE;			/* " */	*lla++ = *ea++;			/* manufacturer-assigned */	*lla++ = *ea++;			/* " */	*lla = *ea;			/* " */} voideaip26to4(uchar *lla, uchar *ea, uchar *ipv4){	*lla++ = 0x20;			/* 6to4 address */	*lla++ = 0x02;			/* " */	memmove(lla, ipv4, IPv4addrlen);	lla += IPv4addrlen;	memset(lla, 0, 2);	ea2eui64(lla + 2, ea);} voidea2lla(uchar *lla, uchar *ea){	*lla++ = 0xFE;			/* link-local v6 */	*lla++ = 0x80;			/* " */	memset(lla, 0, 6);	ea2eui64(lla + 6, ea);} static voidprocess(char *ether){	uchar ethaddr[6], ipaddr[IPaddrlen], ipv4[IPv4addrlen]; 	if (parseether(ethaddr, ether) < 0)		sysfatal("%s: not an ether address", ether);	if (v4_6to4) {		v4parseip(ipv4, v4_6to4);		eaip26to4(ipaddr, ethaddr, ipv4);	} else		ea2lla(ipaddr, ethaddr);	print("%I\n", ipaddr);} voidmain(int argc, char *argv[]){	int i; 	ARGBEGIN {	case 't':		v4_6to4 = EARGF(usage());		break;	default:		usage();		break;	} ARGEND 	fmtinstall('I', eipfmt);	if (argc <= 0)		usage(); 	for (i = 0; i < argc; i++)		process(argv[i]);	exits(0);}