Home | History | Annotate | Download | only in dns-loc
      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 +}
    523