# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	README
#	ChangeLog
#	Makefile
#	Makefile.notbsd
#	ether2dns.l
#
echo x - README
sed 's/^X//' >README << 'END-of-README'
XThis is a quickie used by me to create IPv6 DNS entries for our 
Xmachines assuming stateless address auto-configuration.
X
XUse, modify and redistribute at your own risk only.
X
XInput format is standard /etc/ethers format.
X
X% ether2dns
Xether2dns 1.6
Xusage: ether2dns [-I|-A|-R|-6] [-p prefix] [-d domain] [-e expire]
X prefix required for -A and -6
X domain required for -R
X%%%
X -A creates AAAA records
X -R creates reverse mappings
X -N creates reverse mappings below .INT (deprecated)
X -6 creates A6 records
X 
X -p is the prefix (assumed to be /64, i:j:k:l form for AAAA, domain name
X		of next level prefix for A6).
X
X -d is the domain (must have trailing dot).
X 
X -e is the expiration time (default is 86400).
X
XYou have to add your own SOA etc.
X$ORIGIN will be created for -A if domain is given, and for -R if prefix
Xis given.
X
XKnown bugs:
X
X* no documentation other than this file and the usage() output
X* not enough syntax checking 
X
X	Ignatios Souvatzis
X	ignatios@cs.uni-bonn.de
END-of-README
echo x - ChangeLog
sed 's/^X//' >ChangeLog << 'END-of-ChangeLog'
X2011-01-28	Fix typo in README
X
X2011-01-13	Use example domain and documentation prefix in other
X		Makefile.
X		Released 1.5.
X
X2011-01-13	Even work for first hex digit not decimal.
X		Use example domain and documentation prefix.
X		Released 1.4.
X
X2007-12-19	Mostly, implement and document .INT/.ARPA.
X		Release 1.3. 
X
X2001-01-16	Better error checking.
X		Released 1.2.
X
X2001-01-12	Added A6 support.
X		Released 1.1 to alt.sources.
X
X2001-01-04	Added more $ORIGIN creation
X		Added nonBSD Makefile and more Makefile magic
X		Released 1.0 to alt.sources
END-of-ChangeLog
echo x - Makefile
sed 's/^X//' >Makefile << 'END-of-Makefile'
XMKMAN=no
XPROG=ether2dns
XSRCS=${PROG}.l
XLDADD=-ll
XCLEANFILES+=ether2dns.shar
XSHAR=shar
X
X.include <bsd.prog.mk>
X
Xtest: ether2dns
X	echo 00:a0:24:88:af:0f testmachine | ./ether2dns -A -p 2001:db8:7:6
X	echo 00:a0:24:88:af:0f testmachine | ./ether2dns -6 -p example.net
X	echo 00:a0:24:88:af:0f testmachine | ./ether2dns -R -d example.net
X
Xether2dns.dist: ether2dns.shar
X	echo Archive-name: ether2dns-1.4/part01 > $@ && \
X	echo Submitted-by: ignatios@cs.uni-bonn.de >> $@ && \
X	echo Environment: flex,ansi-c >> $@ && \
X	echo "" >> $@ && \
X	pgp -sat < $< >> $@
X
Xether2dns.shar: README ChangeLog Makefile Makefile.notbsd $(SRCS)
X	$(SHAR) $> > $@
X
XREADME: ether2dns
X	sed -ne "1,/% ether2dns/p" README > README.new
X	./ether2dns 2>> README.new || true
X	sed -ne '/%%%/,$$p' README >> README.new
X	cmp -s README.new README || mv README.new README
END-of-Makefile
echo x - Makefile.notbsd
sed 's/^X//' >Makefile.notbsd << 'END-of-Makefile.notbsd'
XCC=gcc $(CDEBUG)
XCFLAGS=-O2 -Wall
XLEX=flex
XSHAR=gshar
X
Xether2dns: ether2dns.o
X	$(CC) -o ether2dns ether2dns.o -ll
X
Xclean: 
X	-rm ether2dns.o ether2dns.c lex.yy.c *.core *~
X
Xtest: ether2dns
X	echo 00:a0:24:88:af:0f cosinus | ./ether2dns -A -p 3ffe:400:450:1000
X	echo 00:a0:24:88:af:0f cosinus | ./ether2dns -6 -p neubau.ipv6.cs.uni-bonn.de.
X	echo 00:a0:24:88:af:0f cosinus | ./ether2dns -R -d ipv6.cs.uni-bonn.de
X
Xether2dns.dist: ether2dns.shar
X	echo Archive-name: ether2dns-1.1/part01 > $@ && \
X	echo Submitted-by: ignatios@cs.uni-bonn.de >> $@ && \
X	echo Environment: flex,ansi-c >> $@ && \
X	echo "" >> $@
X	pgp -sat < $< >> $@
X
Xether2dns.shar: README ChangeLog Makefile Makefile.notbsd $(SRCS)
X	$(SHAR) $> >> $@
X
XREADME::
X	sed -ne "1,/% ether2dns/p" README > README.new
X	./ether2dns 2>> README.new || true
X	sed -ne '/%%%/,$$p' README >> README.new
X	cmp -s README.new README || mv README.new README
END-of-Makefile.notbsd
echo x - ether2dns.l
sed 's/^X//' >ether2dns.l << 'END-of-ether2dns.l'
X/*
X *
X * Copyright 2001,2003,2007,2011 Ignatios Souvatzis. All rights reserved.
X *
X * Use, modify, and redistribute at your own risk.
X * Redistribute changed copies only when saying so.
X */
X
X%{
Xconst char rcsid[] = "$Id: ether2dns.l,v 1.21 2011/01/13 13:38:44 ignatios Exp $";
X
X#include <assert.h>
X#include <stdio.h>
X#include <strings.h>
X#include <unistd.h>
X
X#define eatspace(s) while((*s == ' ') || (*s == '\t')) ++s
X
Xvoid syntax(char *);
Xvoid usage(void);
Xvoid process_aaaa(char *);
Xvoid process_a6(char *);
Xvoid process_rev(char *);
X
Xint line = 1;
Xint pos;
Xint verbose;
Xunsigned expire = 86400;
X
Xunsigned short ifid[4];
Xunsigned buf[6];
X
Xchar *prefix, *domain;
X
Xvoid (*process)(char *);
X
X%}
XHEXDIGIT [0-9A-Fa-f]
X%%
X#.*$			; /* eat ents */
X^{HEXDIGIT}+		buf[0] = strtoul(yytext,0,16); pos = 1;
X:{HEXDIGIT}+		if (pos   > 5) syntax("too many octets"); buf[pos++]=strtoul(yytext+1,0,16);
X\n			++line; memset(buf, 0, sizeof(buf)); /* count lines */
X[ \t]+[A-Za-z][^ \t\n]+	if (pos++ > 6) syntax("too many names"); (*process)(yytext);
X%%
Xvoid
Xsyntax(char *what) {
X#ifdef EBUGSUPPORT
X	char *nirvana = 0;
X	volatile char c;
X#endif
X
X	fprintf(stderr, "syntax error at line %d pos %d: %s\n",
X		line, pos, what);
X
X	if (!verbose)
X		exit(1);
X
X	if (prefix)
X		fprintf(stderr, "prefix %s\n", prefix);
X	if (domain)
X		fprintf(stderr, "domain %s\n", domain);
X
X#ifdef EBUGSUPPORT
X	c = *nirvana;
X#endif
X	exit(1);
X}
X
Xvoid
Xusage() {
X	fputs("ether2dns 1.6\n"
X		"usage: ether2dns [-I|-A|-R|-6]"
X		" [-p prefix] [-d domain]"
X		" [-e expire]\n"
X		" prefix required for -A and -6\n"
X		" domain required for -R\n", stderr);
X	exit(1);
X}
X
Xvoid
Xmakeifid(void) {
X	int i;
X
X	if (pos < 7)
X		syntax("strange MAC address (not enough octets)");
X
X	if (pos > 7)
X		syntax("strange MAC address (too many octets)");
X
X	for (i=0; i<6; i++)
X		if (buf[i] >= 256)
X			syntax("strange MAC address (octet out of range)");
X
X
X	ifid[0] = (buf[0]^2)      *256 + buf[1];
X	ifid[1] = buf[2]          *256 + 0xff;
X	ifid[2] = 0xfe            *256 + buf[3];
X	ifid[3] = buf[4]          *256 + buf[5];
X}
X
Xvoid
Xprocess_aaaa(char *name) {
X
X	makeifid();
X	eatspace(name);
X
X	printf("%-20s %d IN AAAA\t%s:%x:%x:%x:%x\n", name, expire, prefix,
X		ifid[0], ifid[1], ifid[2], ifid[3]);
X}
X
Xvoid
Xprocess_a6(char *name) {
X
X	makeifid();
X	eatspace(name);
X
X	printf("%-20s %d IN A6 64\t::%x:%x:%x:%x %s\n", name, expire,
X		ifid[0], ifid[1], ifid[2], ifid[3], prefix);
X}
X
Xvoid
Xnot_implemented(char *what) {
X	fprintf(stderr, "%s not implemented\n", what);
X	exit(1);
X}
X
Xvoid
Xprocess_rev(char *name) {
X	if (!domain)
X		usage();
X
X	makeifid();
X	eatspace(name);
X
X	printf("%x.", (ifid[3] >>  0) & 0xf);
X	printf("%x.", (ifid[3] >>  4) & 0xf);
X	printf("%x.", (ifid[3] >>  8) & 0xf);
X	printf("%x.", (ifid[3] >> 12) & 0xf);
X
X	printf("%x.", (ifid[2] >>  0) & 0xf);
X	printf("%x.", (ifid[2] >>  4) & 0xf);
X	printf("%x.", (ifid[2] >>  8) & 0xf);
X	printf("%x.", (ifid[2] >> 12) & 0xf);
X
X	printf("%x.", (ifid[1] >>  0) & 0xf);
X	printf("%x.", (ifid[1] >>  4) & 0xf);
X	printf("%x.", (ifid[1] >>  8) & 0xf);
X	printf("%x.", (ifid[1] >> 12) & 0xf);
X
X	printf("%x.", (ifid[0] >>  0) & 0xf);
X	printf("%x.", (ifid[0] >>  4) & 0xf);
X	printf("%x.", (ifid[0] >>  8) & 0xf);
X	printf("%x", (ifid[0] >> 12) & 0xf);
X
X	printf(" %d IN PTR %s.%s\n", expire, name, domain);
X}
X
Xvoid
Xonly_one_type(void (*f)(char *)) {
X	if (process != NULL) {
X		fprintf(stderr, "Only one table type at a time!\n");
X		exit(1);
X	}
X	process = f;
X}
X
X
Xint main(int argc, char *argv[]) {
X	int rc;
X
X	char *rev_prefix = 0;
X
X	while ((rc = getopt(argc, argv, "6ANRd:e:p:v")) != -1) {
X		switch(rc) {
X		case '6':
X			only_one_type(process_a6);
X			break;
X		case 'A':
X			only_one_type(process_aaaa);
X			break;
X		case 'N':
X			only_one_type(process_rev);
X			rev_prefix="INT";
X			break;
X		case 'R':
X			only_one_type(process_rev);
X			rev_prefix="ARPA";
X			break;
X			
X		case 'd':
X			domain = optarg;
X			break;
X
X		case 'e':
X			expire = atoi(optarg);
X			break;
X
X		case 'p':
X			prefix = optarg;
X			break;
X
X		case 'v':
X			verbose = 1;
X			break;
X		default:
X			usage();
X		}
X	}
X	if (!process)
X		usage();
X
X	if ((process == process_a6 || process == process_aaaa) && !prefix)
X		usage();
X
X	if ((process == process_a6 || process == process_aaaa) && domain) {
X		printf("$ORIGIN %s\n\n", domain);
X	}
X
X	if ((process == process_rev) && prefix) {
X		unsigned numprefix[4];
X		int i;
X
X		if (4 != sscanf(prefix, "%x:%x:%x:%x", numprefix, numprefix+1,
X		    numprefix+2, numprefix+3)) 
X			usage();
X		
X		printf("$ORIGIN ");
X		for (i=3; i>=0; i--)
X			printf("%x.%x.%x.%x.", numprefix[i] & 0xf,
X			    (numprefix[i] >>  4) & 0xf,
X			    (numprefix[i] >>  8) & 0xf,
X			    (numprefix[i] >> 12) & 0xf);
X
X		assert(rev_prefix);
X		printf("IP6.%s.\n\n", rev_prefix);
X	}
X
X	yylex();
X
X	exit(0);
X}
END-of-ether2dns.l
exit

