Return to dnsmasq2-loc-rfc1876.patch CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / dnsmasq / contrib / dns-loc |
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: +}