diff options
Diffstat (limited to 'contrib/dns-loc/dnsmasq2-loc-rfc1876.patch')
-rwxr-xr-x | contrib/dns-loc/dnsmasq2-loc-rfc1876.patch | 522 |
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); ++} |