summaryrefslogtreecommitdiffstats
path: root/contrib/dns-loc/dnsmasq2-loc-rfc1876.patch
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/dns-loc/dnsmasq2-loc-rfc1876.patch')
-rwxr-xr-xcontrib/dns-loc/dnsmasq2-loc-rfc1876.patch522
1 files changed, 522 insertions, 0 deletions
diff --git a/contrib/dns-loc/dnsmasq2-loc-rfc1876.patch b/contrib/dns-loc/dnsmasq2-loc-rfc1876.patch
new file mode 100755
index 0000000..d950321
--- /dev/null
+++ b/contrib/dns-loc/dnsmasq2-loc-rfc1876.patch
@@ -0,0 +1,522 @@
+diff -Nur dnsmasq-2.39-orig/bld/Makefile dnsmasq-2.39/bld/Makefile
+--- dnsmasq-2.39-orig/bld/Makefile 2007-02-17 14:37:06.000000000 +0100
++++ dnsmasq-2.39/bld/Makefile 2007-05-20 18:23:44.000000000 +0200
+@@ -2,7 +2,7 @@
+ PKG_CONFIG ?= pkg-config
+
+
+-OBJS = cache.o rfc1035.o util.o option.o forward.o isc.o network.o \
++OBJS = cache.o rfc1035.o rfc1876.o util.o option.o forward.o isc.o network.o \
+ dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \
+ helper.o tftp.o log.o
+
+diff -Nur dnsmasq-2.39-orig/src/dnsmasq.h dnsmasq-2.39/src/dnsmasq.h
+--- dnsmasq-2.39-orig/src/dnsmasq.h 2007-04-20 12:53:38.000000000 +0200
++++ dnsmasq-2.39/src/dnsmasq.h 2007-05-20 19:50:37.000000000 +0200
+@@ -162,6 +162,12 @@
+ struct interface_name *next;
+ };
+
++struct loc_record {
++ char *name, loc[16];
++ unsigned short class;
++ struct loc_record *next;
++};
++
+ union bigname {
+ char name[MAXDNAME];
+ union bigname *next; /* freelist */
+@@ -476,6 +482,7 @@
+ struct mx_srv_record *mxnames;
+ struct txt_record *txt;
+ struct ptr_record *ptr;
++ struct loc_record *loc;
+ struct interface_name *int_names;
+ char *mxtarget;
+ char *lease_file;
+@@ -725,3 +732,6 @@
+ void tftp_request(struct listener *listen, struct daemon *daemon, time_t now);
+ void check_tftp_listeners(struct daemon *daemon, fd_set *rset, time_t now);
+ #endif
++
++/* rfc1876 */
++u_int32_t loc_aton(const char *ascii, u_char *binary);
+diff -Nur dnsmasq-2.39-orig/src/option.c dnsmasq-2.39/src/option.c
+--- dnsmasq-2.39-orig/src/option.c 2007-04-19 23:34:49.000000000 +0200
++++ dnsmasq-2.39/src/option.c 2007-05-20 20:15:15.000000000 +0200
+@@ -43,6 +43,7 @@
+ #define LOPT_REMOTE 269
+ #define LOPT_SUBSCR 270
+ #define LOPT_INTNAME 271
++#define LOPT_LOC 272
+
+ #ifdef HAVE_GETOPT_LONG
+ static const struct option opts[] =
+@@ -122,6 +123,7 @@
+ {"tftp-root", 1, 0, LOPT_PREFIX },
+ {"tftp-max", 1, 0, LOPT_TFTP_MAX },
+ {"ptr-record", 1, 0, LOPT_PTR },
++ {"loc-record", 1, 0, LOPT_LOC },
+ #if defined(__FreeBSD__) || defined(__DragonFly__)
+ {"bridge-interface", 1, 0 , LOPT_BRIDGE },
+ #endif
+@@ -235,6 +237,7 @@
+ { "-y, --localise-queries", gettext_noop("Answer DNS queries based on the interface a query was sent to."), NULL },
+ { "-Y --txt-record=name,txt....", gettext_noop("Specify TXT DNS record."), NULL },
+ { " --ptr-record=name,target", gettext_noop("Specify PTR DNS record."), NULL },
++ { " --loc-record=name,lat lon alt", gettext_noop("Specify LOC DNS record."), NULL },
+ { " --interface-name=name,interface", gettext_noop("Give DNS name to IPv4 address of interface."), NULL },
+ { "-z, --bind-interfaces", gettext_noop("Bind only to interfaces in use."), NULL },
+ { "-Z, --read-ethers", gettext_noop("Read DHCP static host information from %s."), ETHERSFILE },
+@@ -1835,6 +1838,37 @@
+ new->intr = safe_string_alloc(comma);
+ break;
+ }
++
++ case LOPT_LOC:
++ {
++ struct loc_record *new;
++ unsigned char *p, *q;
++
++ comma = split(arg);
++
++ if (!canonicalise_opt(arg))
++ {
++ option = '?';
++ problem = _("bad LOC record");
++ break;
++ }
++
++ new = safe_malloc(sizeof(struct loc_record));
++ new->next = daemon->loc;
++ daemon->loc = new;
++ new->class = C_IN;
++ if (!comma || loc_aton(comma,new->loc)!=16)
++ {
++ option = '?';
++ problem = _("bad LOC record");
++ break;
++ }
++
++ if (comma)
++ *comma = 0;
++ new->name = safe_string_alloc(arg);
++ break;
++ }
+
+ case LOPT_PTR: /* --ptr-record */
+ {
+diff -Nur dnsmasq-2.39-orig/src/rfc1035.c dnsmasq-2.39/src/rfc1035.c
+--- dnsmasq-2.39-orig/src/rfc1035.c 2007-04-20 12:54:26.000000000 +0200
++++ dnsmasq-2.39/src/rfc1035.c 2007-05-20 18:22:46.000000000 +0200
+@@ -1112,6 +1112,27 @@
+ }
+ }
+
++ if (qtype == T_LOC || qtype == T_ANY)
++ {
++ struct loc_record *t;
++ for(t = daemon->loc; t ; t = t->next)
++ {
++ if (t->class == qclass && hostname_isequal(name, t->name))
++ {
++ ans = 1;
++ if (!dryrun)
++ {
++ log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, 0, NULL, 0);
++ if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
++ daemon->local_ttl, NULL,
++ T_LOC, t->class, "t", 16, t->loc))
++ anscount++;
++
++ }
++ }
++ }
++ }
++
+ if (qclass == C_IN)
+ {
+ if (qtype == T_PTR || qtype == T_ANY)
+diff -Nur dnsmasq-2.39-orig/src/rfc1876.c dnsmasq-2.39/src/rfc1876.c
+--- dnsmasq-2.39-orig/src/rfc1876.c 1970-01-01 01:00:00.000000000 +0100
++++ dnsmasq-2.39/src/rfc1876.c 2007-05-20 19:50:10.000000000 +0200
+@@ -0,0 +1,379 @@
++/*
++ * routines to convert between on-the-wire RR format and zone file
++ * format. Does not contain conversion to/from decimal degrees;
++ * divide or multiply by 60*60*1000 for that.
++ */
++
++#include "dnsmasq.h"
++
++static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
++ 1000000,10000000,100000000,1000000000};
++
++/* takes an XeY precision/size value, returns a string representation.*/
++static const char *
++precsize_ntoa(u_int8_t prec)
++{
++ static char retbuf[sizeof("90000000.00")];
++ unsigned long val;
++ int mantissa, exponent;
++
++ mantissa = (int)((prec >> 4) & 0x0f) % 10;
++ exponent = (int)((prec >> 0) & 0x0f) % 10;
++
++ val = mantissa * poweroften[exponent];
++
++ (void) sprintf(retbuf,"%d.%.2d", val/100, val%100);
++ return (retbuf);
++}
++
++/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer.*/
++static u_int8_t
++precsize_aton(char **strptr)
++{
++ unsigned int mval = 0, cmval = 0;
++ u_int8_t retval = 0;
++ register char *cp;
++ register int exponent;
++ register int mantissa;
++
++ cp = *strptr;
++
++ while (isdigit(*cp))
++ mval = mval * 10 + (*cp++ - '0');
++
++ if (*cp == '.') { /* centimeters */
++ cp++;
++ if (isdigit(*cp)) {
++ cmval = (*cp++ - '0') * 10;
++ if (isdigit(*cp)) {
++ cmval += (*cp++ - '0');
++ }
++ }
++ }
++ cmval = (mval * 100) + cmval;
++
++ for (exponent = 0; exponent < 9; exponent++)
++ if (cmval < poweroften[exponent+1])
++ break;
++
++ mantissa = cmval / poweroften[exponent];
++ if (mantissa > 9)
++ mantissa = 9;
++
++ retval = (mantissa << 4) | exponent;
++
++ *strptr = cp;
++
++ return (retval);
++}
++
++/* converts ascii lat/lon to unsigned encoded 32-bit number.
++ * moves pointer. */
++static u_int32_t
++latlon2ul(char **latlonstrptr,int *which)
++{
++ register char *cp;
++ u_int32_t retval;
++ int deg = 0, min = 0, secs = 0, secsfrac = 0;
++
++ cp = *latlonstrptr;
++
++ while (isdigit(*cp))
++ deg = deg * 10 + (*cp++ - '0');
++
++ while (isspace(*cp))
++ cp++;
++
++ if (!(isdigit(*cp)))
++ goto fndhemi;
++
++ while (isdigit(*cp))
++ min = min * 10 + (*cp++ - '0');
++ while (isspace(*cp))
++ cp++;
++
++ if (!(isdigit(*cp)))
++ goto fndhemi;
++
++ while (isdigit(*cp))
++ secs = secs * 10 + (*cp++ - '0');
++
++ if (*cp == '.') { /* decimal seconds */
++ cp++;
++ if (isdigit(*cp)) {
++ secsfrac = (*cp++ - '0') * 100;
++ if (isdigit(*cp)) {
++ secsfrac += (*cp++ - '0') * 10;
++ if (isdigit(*cp)) {
++ secsfrac += (*cp++ - '0');
++ }
++ }
++ }
++ }
++
++ while (!isspace(*cp)) /* if any trailing garbage */
++ cp++;
++
++ while (isspace(*cp))
++ cp++;
++
++ fndhemi:
++ switch (*cp) {
++ case 'N': case 'n':
++ case 'E': case 'e':
++ retval = ((unsigned)1<<31)
++ + (((((deg * 60) + min) * 60) + secs) * 1000)
++ + secsfrac;
++ break;
++ case 'S': case 's':
++ case 'W': case 'w':
++ retval = ((unsigned)1<<31)
++ - (((((deg * 60) + min) * 60) + secs) * 1000)
++ - secsfrac;
++ break;
++ default:
++ retval = 0; /* invalid value -- indicates error */
++ break;
++ }
++
++ switch (*cp) {
++ case 'N': case 'n':
++ case 'S': case 's':
++ *which = 1; /* latitude */
++ break;
++ case 'E': case 'e':
++ case 'W': case 'w':
++ *which = 2; /* longitude */
++ break;
++ default:
++ *which = 0; /* error */
++ break;
++ }
++
++ cp++; /* skip the hemisphere */
++
++ while (!isspace(*cp)) /* if any trailing garbage */
++ cp++;
++
++ while (isspace(*cp)) /* move to next field */
++ cp++;
++
++ *latlonstrptr = cp;
++
++ return (retval);
++}
++
++/* converts a zone file representation in a string to an RDATA
++ * on-the-wire representation. */
++u_int32_t
++loc_aton(const char *ascii, u_char *binary)
++{
++ const char *cp, *maxcp;
++ u_char *bcp;
++
++ u_int32_t latit = 0, longit = 0, alt = 0;
++ u_int32_t lltemp1 = 0, lltemp2 = 0;
++ int altmeters = 0, altfrac = 0, altsign = 1;
++ u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */
++ u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */
++ u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */
++ int which1 = 0, which2 = 0;
++
++ cp = ascii;
++ maxcp = cp + strlen(ascii);
++
++ lltemp1 = latlon2ul(&cp, &which1);
++ lltemp2 = latlon2ul(&cp, &which2);
++
++ switch (which1 + which2) {
++ case 3: /* 1 + 2, the only valid combination */
++ if ((which1 == 1) && (which2 == 2)) { /* normal case */
++ latit = lltemp1;
++ longit = lltemp2;
++ } else if ((which1 == 2) && (which2 == 1)) {/*reversed*/
++ longit = lltemp1;
++ latit = lltemp2;
++ } else { /* some kind of brokenness */
++ return 0;
++ }
++ break;
++ default: /* we didn't get one of each */
++ return 0;
++ }
++
++ /* altitude */
++ if (*cp == '-') {
++ altsign = -1;
++ cp++;
++ }
++
++ if (*cp == '+')
++ cp++;
++
++ while (isdigit(*cp))
++ altmeters = altmeters * 10 + (*cp++ - '0');
++
++ if (*cp == '.') { /* decimal meters */
++ cp++;
++ if (isdigit(*cp)) {
++ altfrac = (*cp++ - '0') * 10;
++ if (isdigit(*cp)) {
++ altfrac += (*cp++ - '0');
++ }
++ }
++ }
++
++ alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
++
++ while (!isspace(*cp) && (cp < maxcp))
++ /* if trailing garbage or m */
++ cp++;
++
++ while (isspace(*cp) && (cp < maxcp))
++ cp++;
++ if (cp >= maxcp)
++ goto defaults;
++
++ siz = precsize_aton(&cp);
++
++ while (!isspace(*cp) && (cp < maxcp))/*if trailing garbage or m*/
++ cp++;
++
++ while (isspace(*cp) && (cp < maxcp))
++ cp++;
++
++ if (cp >= maxcp)
++ goto defaults;
++
++ hp = precsize_aton(&cp);
++
++ while (!isspace(*cp) && (cp < maxcp))/*if trailing garbage or m*/
++ cp++;
++
++ while (isspace(*cp) && (cp < maxcp))
++ cp++;
++
++ if (cp >= maxcp)
++ goto defaults;
++
++ vp = precsize_aton(&cp);
++
++ defaults:
++
++ bcp = binary;
++ *bcp++ = (u_int8_t) 0; /* version byte */
++ *bcp++ = siz;
++ *bcp++ = hp;
++ *bcp++ = vp;
++ PUTLONG(latit,bcp);
++ PUTLONG(longit,bcp);
++ PUTLONG(alt,bcp);
++
++ return (16); /* size of RR in octets */
++}
++
++/* takes an on-the-wire LOC RR and prints it in zone file
++ * (human readable) format. */
++char *
++loc_ntoa(const u_char *binary,char *ascii)
++{
++ static char tmpbuf[255*3];
++
++ register char *cp;
++ register const u_char *rcp;
++
++ int latdeg, latmin, latsec, latsecfrac;
++ int longdeg, longmin, longsec, longsecfrac;
++ char northsouth, eastwest;
++ int altmeters, altfrac, altsign;
++
++ const int referencealt = 100000 * 100;
++
++ int32_t latval, longval, altval;
++ u_int32_t templ;
++ u_int8_t sizeval, hpval, vpval, versionval;
++
++ char *sizestr, *hpstr, *vpstr;
++
++ rcp = binary;
++ if (ascii)
++ cp = ascii;
++ else {
++ cp = tmpbuf;
++ }
++
++ versionval = *rcp++;
++
++ if (versionval) {
++ sprintf(cp,"; error: unknown LOC RR version");
++ return (cp);
++ }
++
++ sizeval = *rcp++;
++
++ hpval = *rcp++;
++ vpval = *rcp++;
++
++ GETLONG(templ,rcp);
++ latval = (templ - ((unsigned)1<<31));
++
++ GETLONG(templ,rcp);
++ longval = (templ - ((unsigned)1<<31));
++
++ GETLONG(templ,rcp);
++ if (templ < referencealt) { /* below WGS 84 spheroid */
++ altval = referencealt - templ;
++ altsign = -1;
++ } else {
++ altval = templ - referencealt;
++ altsign = 1;
++ }
++
++ if (latval < 0) {
++ northsouth = 'S';
++ latval = -latval;
++ }
++ else
++ northsouth = 'N';
++
++ latsecfrac = latval % 1000;
++ latval = latval / 1000;
++ latsec = latval % 60;
++ latval = latval / 60;
++ latmin = latval % 60;
++ latval = latval / 60;
++ latdeg = latval;
++
++ if (longval < 0) {
++ eastwest = 'W';
++ longval = -longval;
++ }
++ else
++ eastwest = 'E';
++
++ longsecfrac = longval % 1000;
++ longval = longval / 1000;
++ longsec = longval % 60;
++ longval = longval / 60;
++ longmin = longval % 60;
++ longval = longval / 60;
++ longdeg = longval;
++
++ altfrac = altval % 100;
++ altmeters = (altval / 100) * altsign;
++
++ sizestr = strdup(precsize_ntoa(sizeval));
++ hpstr = strdup(precsize_ntoa(hpval));
++ vpstr = strdup(precsize_ntoa(vpval));
++
++ sprintf(cp,
++ "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
++ latdeg, latmin, latsec, latsecfrac, northsouth,
++ longdeg, longmin, longsec, longsecfrac, eastwest,
++ altmeters, altfrac, sizestr, hpstr, vpstr);
++ free(sizestr);
++ free(hpstr);
++ free(vpstr);
++
++ return (cp);
++}