Annotation of embedaddon/dnsmasq/contrib/dns-loc/dnsmasq2-loc-rfc1876.patch, revision 1.1
1.1 ! misho 1: diff -Nur dnsmasq-2.39-orig/bld/Makefile dnsmasq-2.39/bld/Makefile
! 2: --- dnsmasq-2.39-orig/bld/Makefile 2007-02-17 14:37:06.000000000 +0100
! 3: +++ dnsmasq-2.39/bld/Makefile 2007-05-20 18:23:44.000000000 +0200
! 4: @@ -2,7 +2,7 @@
! 5: PKG_CONFIG ?= pkg-config
! 6:
! 7:
! 8: -OBJS = cache.o rfc1035.o util.o option.o forward.o isc.o network.o \
! 9: +OBJS = cache.o rfc1035.o rfc1876.o util.o option.o forward.o isc.o network.o \
! 10: dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \
! 11: helper.o tftp.o log.o
! 12:
! 13: diff -Nur dnsmasq-2.39-orig/src/dnsmasq.h dnsmasq-2.39/src/dnsmasq.h
! 14: --- dnsmasq-2.39-orig/src/dnsmasq.h 2007-04-20 12:53:38.000000000 +0200
! 15: +++ dnsmasq-2.39/src/dnsmasq.h 2007-05-20 19:50:37.000000000 +0200
! 16: @@ -162,6 +162,12 @@
! 17: struct interface_name *next;
! 18: };
! 19:
! 20: +struct loc_record {
! 21: + char *name, loc[16];
! 22: + unsigned short class;
! 23: + struct loc_record *next;
! 24: +};
! 25: +
! 26: union bigname {
! 27: char name[MAXDNAME];
! 28: union bigname *next; /* freelist */
! 29: @@ -476,6 +482,7 @@
! 30: struct mx_srv_record *mxnames;
! 31: struct txt_record *txt;
! 32: struct ptr_record *ptr;
! 33: + struct loc_record *loc;
! 34: struct interface_name *int_names;
! 35: char *mxtarget;
! 36: char *lease_file;
! 37: @@ -725,3 +732,6 @@
! 38: void tftp_request(struct listener *listen, struct daemon *daemon, time_t now);
! 39: void check_tftp_listeners(struct daemon *daemon, fd_set *rset, time_t now);
! 40: #endif
! 41: +
! 42: +/* rfc1876 */
! 43: +u_int32_t loc_aton(const char *ascii, u_char *binary);
! 44: diff -Nur dnsmasq-2.39-orig/src/option.c dnsmasq-2.39/src/option.c
! 45: --- dnsmasq-2.39-orig/src/option.c 2007-04-19 23:34:49.000000000 +0200
! 46: +++ dnsmasq-2.39/src/option.c 2007-05-20 20:15:15.000000000 +0200
! 47: @@ -43,6 +43,7 @@
! 48: #define LOPT_REMOTE 269
! 49: #define LOPT_SUBSCR 270
! 50: #define LOPT_INTNAME 271
! 51: +#define LOPT_LOC 272
! 52:
! 53: #ifdef HAVE_GETOPT_LONG
! 54: static const struct option opts[] =
! 55: @@ -122,6 +123,7 @@
! 56: {"tftp-root", 1, 0, LOPT_PREFIX },
! 57: {"tftp-max", 1, 0, LOPT_TFTP_MAX },
! 58: {"ptr-record", 1, 0, LOPT_PTR },
! 59: + {"loc-record", 1, 0, LOPT_LOC },
! 60: #if defined(__FreeBSD__) || defined(__DragonFly__)
! 61: {"bridge-interface", 1, 0 , LOPT_BRIDGE },
! 62: #endif
! 63: @@ -235,6 +237,7 @@
! 64: { "-y, --localise-queries", gettext_noop("Answer DNS queries based on the interface a query was sent to."), NULL },
! 65: { "-Y --txt-record=name,txt....", gettext_noop("Specify TXT DNS record."), NULL },
! 66: { " --ptr-record=name,target", gettext_noop("Specify PTR DNS record."), NULL },
! 67: + { " --loc-record=name,lat lon alt", gettext_noop("Specify LOC DNS record."), NULL },
! 68: { " --interface-name=name,interface", gettext_noop("Give DNS name to IPv4 address of interface."), NULL },
! 69: { "-z, --bind-interfaces", gettext_noop("Bind only to interfaces in use."), NULL },
! 70: { "-Z, --read-ethers", gettext_noop("Read DHCP static host information from %s."), ETHERSFILE },
! 71: @@ -1835,6 +1838,37 @@
! 72: new->intr = safe_string_alloc(comma);
! 73: break;
! 74: }
! 75: +
! 76: + case LOPT_LOC:
! 77: + {
! 78: + struct loc_record *new;
! 79: + unsigned char *p, *q;
! 80: +
! 81: + comma = split(arg);
! 82: +
! 83: + if (!canonicalise_opt(arg))
! 84: + {
! 85: + option = '?';
! 86: + problem = _("bad LOC record");
! 87: + break;
! 88: + }
! 89: +
! 90: + new = safe_malloc(sizeof(struct loc_record));
! 91: + new->next = daemon->loc;
! 92: + daemon->loc = new;
! 93: + new->class = C_IN;
! 94: + if (!comma || loc_aton(comma,new->loc)!=16)
! 95: + {
! 96: + option = '?';
! 97: + problem = _("bad LOC record");
! 98: + break;
! 99: + }
! 100: +
! 101: + if (comma)
! 102: + *comma = 0;
! 103: + new->name = safe_string_alloc(arg);
! 104: + break;
! 105: + }
! 106:
! 107: case LOPT_PTR: /* --ptr-record */
! 108: {
! 109: diff -Nur dnsmasq-2.39-orig/src/rfc1035.c dnsmasq-2.39/src/rfc1035.c
! 110: --- dnsmasq-2.39-orig/src/rfc1035.c 2007-04-20 12:54:26.000000000 +0200
! 111: +++ dnsmasq-2.39/src/rfc1035.c 2007-05-20 18:22:46.000000000 +0200
! 112: @@ -1112,6 +1112,27 @@
! 113: }
! 114: }
! 115:
! 116: + if (qtype == T_LOC || qtype == T_ANY)
! 117: + {
! 118: + struct loc_record *t;
! 119: + for(t = daemon->loc; t ; t = t->next)
! 120: + {
! 121: + if (t->class == qclass && hostname_isequal(name, t->name))
! 122: + {
! 123: + ans = 1;
! 124: + if (!dryrun)
! 125: + {
! 126: + log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, 0, NULL, 0);
! 127: + if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
! 128: + daemon->local_ttl, NULL,
! 129: + T_LOC, t->class, "t", 16, t->loc))
! 130: + anscount++;
! 131: +
! 132: + }
! 133: + }
! 134: + }
! 135: + }
! 136: +
! 137: if (qclass == C_IN)
! 138: {
! 139: if (qtype == T_PTR || qtype == T_ANY)
! 140: diff -Nur dnsmasq-2.39-orig/src/rfc1876.c dnsmasq-2.39/src/rfc1876.c
! 141: --- dnsmasq-2.39-orig/src/rfc1876.c 1970-01-01 01:00:00.000000000 +0100
! 142: +++ dnsmasq-2.39/src/rfc1876.c 2007-05-20 19:50:10.000000000 +0200
! 143: @@ -0,0 +1,379 @@
! 144: +/*
! 145: + * routines to convert between on-the-wire RR format and zone file
! 146: + * format. Does not contain conversion to/from decimal degrees;
! 147: + * divide or multiply by 60*60*1000 for that.
! 148: + */
! 149: +
! 150: +#include "dnsmasq.h"
! 151: +
! 152: +static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
! 153: + 1000000,10000000,100000000,1000000000};
! 154: +
! 155: +/* takes an XeY precision/size value, returns a string representation.*/
! 156: +static const char *
! 157: +precsize_ntoa(u_int8_t prec)
! 158: +{
! 159: + static char retbuf[sizeof("90000000.00")];
! 160: + unsigned long val;
! 161: + int mantissa, exponent;
! 162: +
! 163: + mantissa = (int)((prec >> 4) & 0x0f) % 10;
! 164: + exponent = (int)((prec >> 0) & 0x0f) % 10;
! 165: +
! 166: + val = mantissa * poweroften[exponent];
! 167: +
! 168: + (void) sprintf(retbuf,"%d.%.2d", val/100, val%100);
! 169: + return (retbuf);
! 170: +}
! 171: +
! 172: +/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer.*/
! 173: +static u_int8_t
! 174: +precsize_aton(char **strptr)
! 175: +{
! 176: + unsigned int mval = 0, cmval = 0;
! 177: + u_int8_t retval = 0;
! 178: + register char *cp;
! 179: + register int exponent;
! 180: + register int mantissa;
! 181: +
! 182: + cp = *strptr;
! 183: +
! 184: + while (isdigit(*cp))
! 185: + mval = mval * 10 + (*cp++ - '0');
! 186: +
! 187: + if (*cp == '.') { /* centimeters */
! 188: + cp++;
! 189: + if (isdigit(*cp)) {
! 190: + cmval = (*cp++ - '0') * 10;
! 191: + if (isdigit(*cp)) {
! 192: + cmval += (*cp++ - '0');
! 193: + }
! 194: + }
! 195: + }
! 196: + cmval = (mval * 100) + cmval;
! 197: +
! 198: + for (exponent = 0; exponent < 9; exponent++)
! 199: + if (cmval < poweroften[exponent+1])
! 200: + break;
! 201: +
! 202: + mantissa = cmval / poweroften[exponent];
! 203: + if (mantissa > 9)
! 204: + mantissa = 9;
! 205: +
! 206: + retval = (mantissa << 4) | exponent;
! 207: +
! 208: + *strptr = cp;
! 209: +
! 210: + return (retval);
! 211: +}
! 212: +
! 213: +/* converts ascii lat/lon to unsigned encoded 32-bit number.
! 214: + * moves pointer. */
! 215: +static u_int32_t
! 216: +latlon2ul(char **latlonstrptr,int *which)
! 217: +{
! 218: + register char *cp;
! 219: + u_int32_t retval;
! 220: + int deg = 0, min = 0, secs = 0, secsfrac = 0;
! 221: +
! 222: + cp = *latlonstrptr;
! 223: +
! 224: + while (isdigit(*cp))
! 225: + deg = deg * 10 + (*cp++ - '0');
! 226: +
! 227: + while (isspace(*cp))
! 228: + cp++;
! 229: +
! 230: + if (!(isdigit(*cp)))
! 231: + goto fndhemi;
! 232: +
! 233: + while (isdigit(*cp))
! 234: + min = min * 10 + (*cp++ - '0');
! 235: + while (isspace(*cp))
! 236: + cp++;
! 237: +
! 238: + if (!(isdigit(*cp)))
! 239: + goto fndhemi;
! 240: +
! 241: + while (isdigit(*cp))
! 242: + secs = secs * 10 + (*cp++ - '0');
! 243: +
! 244: + if (*cp == '.') { /* decimal seconds */
! 245: + cp++;
! 246: + if (isdigit(*cp)) {
! 247: + secsfrac = (*cp++ - '0') * 100;
! 248: + if (isdigit(*cp)) {
! 249: + secsfrac += (*cp++ - '0') * 10;
! 250: + if (isdigit(*cp)) {
! 251: + secsfrac += (*cp++ - '0');
! 252: + }
! 253: + }
! 254: + }
! 255: + }
! 256: +
! 257: + while (!isspace(*cp)) /* if any trailing garbage */
! 258: + cp++;
! 259: +
! 260: + while (isspace(*cp))
! 261: + cp++;
! 262: +
! 263: + fndhemi:
! 264: + switch (*cp) {
! 265: + case 'N': case 'n':
! 266: + case 'E': case 'e':
! 267: + retval = ((unsigned)1<<31)
! 268: + + (((((deg * 60) + min) * 60) + secs) * 1000)
! 269: + + secsfrac;
! 270: + break;
! 271: + case 'S': case 's':
! 272: + case 'W': case 'w':
! 273: + retval = ((unsigned)1<<31)
! 274: + - (((((deg * 60) + min) * 60) + secs) * 1000)
! 275: + - secsfrac;
! 276: + break;
! 277: + default:
! 278: + retval = 0; /* invalid value -- indicates error */
! 279: + break;
! 280: + }
! 281: +
! 282: + switch (*cp) {
! 283: + case 'N': case 'n':
! 284: + case 'S': case 's':
! 285: + *which = 1; /* latitude */
! 286: + break;
! 287: + case 'E': case 'e':
! 288: + case 'W': case 'w':
! 289: + *which = 2; /* longitude */
! 290: + break;
! 291: + default:
! 292: + *which = 0; /* error */
! 293: + break;
! 294: + }
! 295: +
! 296: + cp++; /* skip the hemisphere */
! 297: +
! 298: + while (!isspace(*cp)) /* if any trailing garbage */
! 299: + cp++;
! 300: +
! 301: + while (isspace(*cp)) /* move to next field */
! 302: + cp++;
! 303: +
! 304: + *latlonstrptr = cp;
! 305: +
! 306: + return (retval);
! 307: +}
! 308: +
! 309: +/* converts a zone file representation in a string to an RDATA
! 310: + * on-the-wire representation. */
! 311: +u_int32_t
! 312: +loc_aton(const char *ascii, u_char *binary)
! 313: +{
! 314: + const char *cp, *maxcp;
! 315: + u_char *bcp;
! 316: +
! 317: + u_int32_t latit = 0, longit = 0, alt = 0;
! 318: + u_int32_t lltemp1 = 0, lltemp2 = 0;
! 319: + int altmeters = 0, altfrac = 0, altsign = 1;
! 320: + u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */
! 321: + u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */
! 322: + u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */
! 323: + int which1 = 0, which2 = 0;
! 324: +
! 325: + cp = ascii;
! 326: + maxcp = cp + strlen(ascii);
! 327: +
! 328: + lltemp1 = latlon2ul(&cp, &which1);
! 329: + lltemp2 = latlon2ul(&cp, &which2);
! 330: +
! 331: + switch (which1 + which2) {
! 332: + case 3: /* 1 + 2, the only valid combination */
! 333: + if ((which1 == 1) && (which2 == 2)) { /* normal case */
! 334: + latit = lltemp1;
! 335: + longit = lltemp2;
! 336: + } else if ((which1 == 2) && (which2 == 1)) {/*reversed*/
! 337: + longit = lltemp1;
! 338: + latit = lltemp2;
! 339: + } else { /* some kind of brokenness */
! 340: + return 0;
! 341: + }
! 342: + break;
! 343: + default: /* we didn't get one of each */
! 344: + return 0;
! 345: + }
! 346: +
! 347: + /* altitude */
! 348: + if (*cp == '-') {
! 349: + altsign = -1;
! 350: + cp++;
! 351: + }
! 352: +
! 353: + if (*cp == '+')
! 354: + cp++;
! 355: +
! 356: + while (isdigit(*cp))
! 357: + altmeters = altmeters * 10 + (*cp++ - '0');
! 358: +
! 359: + if (*cp == '.') { /* decimal meters */
! 360: + cp++;
! 361: + if (isdigit(*cp)) {
! 362: + altfrac = (*cp++ - '0') * 10;
! 363: + if (isdigit(*cp)) {
! 364: + altfrac += (*cp++ - '0');
! 365: + }
! 366: + }
! 367: + }
! 368: +
! 369: + alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
! 370: +
! 371: + while (!isspace(*cp) && (cp < maxcp))
! 372: + /* if trailing garbage or m */
! 373: + cp++;
! 374: +
! 375: + while (isspace(*cp) && (cp < maxcp))
! 376: + cp++;
! 377: + if (cp >= maxcp)
! 378: + goto defaults;
! 379: +
! 380: + siz = precsize_aton(&cp);
! 381: +
! 382: + while (!isspace(*cp) && (cp < maxcp))/*if trailing garbage or m*/
! 383: + cp++;
! 384: +
! 385: + while (isspace(*cp) && (cp < maxcp))
! 386: + cp++;
! 387: +
! 388: + if (cp >= maxcp)
! 389: + goto defaults;
! 390: +
! 391: + hp = precsize_aton(&cp);
! 392: +
! 393: + while (!isspace(*cp) && (cp < maxcp))/*if trailing garbage or m*/
! 394: + cp++;
! 395: +
! 396: + while (isspace(*cp) && (cp < maxcp))
! 397: + cp++;
! 398: +
! 399: + if (cp >= maxcp)
! 400: + goto defaults;
! 401: +
! 402: + vp = precsize_aton(&cp);
! 403: +
! 404: + defaults:
! 405: +
! 406: + bcp = binary;
! 407: + *bcp++ = (u_int8_t) 0; /* version byte */
! 408: + *bcp++ = siz;
! 409: + *bcp++ = hp;
! 410: + *bcp++ = vp;
! 411: + PUTLONG(latit,bcp);
! 412: + PUTLONG(longit,bcp);
! 413: + PUTLONG(alt,bcp);
! 414: +
! 415: + return (16); /* size of RR in octets */
! 416: +}
! 417: +
! 418: +/* takes an on-the-wire LOC RR and prints it in zone file
! 419: + * (human readable) format. */
! 420: +char *
! 421: +loc_ntoa(const u_char *binary,char *ascii)
! 422: +{
! 423: + static char tmpbuf[255*3];
! 424: +
! 425: + register char *cp;
! 426: + register const u_char *rcp;
! 427: +
! 428: + int latdeg, latmin, latsec, latsecfrac;
! 429: + int longdeg, longmin, longsec, longsecfrac;
! 430: + char northsouth, eastwest;
! 431: + int altmeters, altfrac, altsign;
! 432: +
! 433: + const int referencealt = 100000 * 100;
! 434: +
! 435: + int32_t latval, longval, altval;
! 436: + u_int32_t templ;
! 437: + u_int8_t sizeval, hpval, vpval, versionval;
! 438: +
! 439: + char *sizestr, *hpstr, *vpstr;
! 440: +
! 441: + rcp = binary;
! 442: + if (ascii)
! 443: + cp = ascii;
! 444: + else {
! 445: + cp = tmpbuf;
! 446: + }
! 447: +
! 448: + versionval = *rcp++;
! 449: +
! 450: + if (versionval) {
! 451: + sprintf(cp,"; error: unknown LOC RR version");
! 452: + return (cp);
! 453: + }
! 454: +
! 455: + sizeval = *rcp++;
! 456: +
! 457: + hpval = *rcp++;
! 458: + vpval = *rcp++;
! 459: +
! 460: + GETLONG(templ,rcp);
! 461: + latval = (templ - ((unsigned)1<<31));
! 462: +
! 463: + GETLONG(templ,rcp);
! 464: + longval = (templ - ((unsigned)1<<31));
! 465: +
! 466: + GETLONG(templ,rcp);
! 467: + if (templ < referencealt) { /* below WGS 84 spheroid */
! 468: + altval = referencealt - templ;
! 469: + altsign = -1;
! 470: + } else {
! 471: + altval = templ - referencealt;
! 472: + altsign = 1;
! 473: + }
! 474: +
! 475: + if (latval < 0) {
! 476: + northsouth = 'S';
! 477: + latval = -latval;
! 478: + }
! 479: + else
! 480: + northsouth = 'N';
! 481: +
! 482: + latsecfrac = latval % 1000;
! 483: + latval = latval / 1000;
! 484: + latsec = latval % 60;
! 485: + latval = latval / 60;
! 486: + latmin = latval % 60;
! 487: + latval = latval / 60;
! 488: + latdeg = latval;
! 489: +
! 490: + if (longval < 0) {
! 491: + eastwest = 'W';
! 492: + longval = -longval;
! 493: + }
! 494: + else
! 495: + eastwest = 'E';
! 496: +
! 497: + longsecfrac = longval % 1000;
! 498: + longval = longval / 1000;
! 499: + longsec = longval % 60;
! 500: + longval = longval / 60;
! 501: + longmin = longval % 60;
! 502: + longval = longval / 60;
! 503: + longdeg = longval;
! 504: +
! 505: + altfrac = altval % 100;
! 506: + altmeters = (altval / 100) * altsign;
! 507: +
! 508: + sizestr = strdup(precsize_ntoa(sizeval));
! 509: + hpstr = strdup(precsize_ntoa(hpval));
! 510: + vpstr = strdup(precsize_ntoa(vpval));
! 511: +
! 512: + sprintf(cp,
! 513: + "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
! 514: + latdeg, latmin, latsec, latsecfrac, northsouth,
! 515: + longdeg, longmin, longsec, longsecfrac, eastwest,
! 516: + altmeters, altfrac, sizestr, hpstr, vpstr);
! 517: + free(sizestr);
! 518: + free(hpstr);
! 519: + free(vpstr);
! 520: +
! 521: + return (cp);
! 522: +}
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>