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
5 PKG_CONFIG ?= pkg-config
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 \
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
17 struct interface_name *next;
21 + char *name, loc[16];
22 + unsigned short class;
23 + struct loc_record *next;
28 union bigname *next; /* freelist */
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;
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);
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
48 #define LOPT_REMOTE 269
49 #define LOPT_SUBSCR 270
50 #define LOPT_INTNAME 271
53 #ifdef HAVE_GETOPT_LONG
54 static const struct option opts[] =
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 },
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);
78 + struct loc_record *new;
79 + unsigned char *p, *q;
83 + if (!canonicalise_opt(arg))
86 + problem = _("bad LOC record");
90 + new = safe_malloc(sizeof(struct loc_record));
91 + new->next = daemon->loc;
94 + if (!comma || loc_aton(comma,new->loc)!=16)
97 + problem = _("bad LOC record");
103 + new->name = safe_string_alloc(arg);
107 case LOPT_PTR: /* --ptr-record */
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 @@
116 + if (qtype == T_LOC || qtype == T_ANY)
118 + struct loc_record *t;
119 + for(t = daemon->loc; t ; t = t->next)
121 + if (t->class == qclass && hostname_isequal(name, t->name))
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))
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
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.
150 +#include "dnsmasq.h"
152 +static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
153 + 1000000,10000000,100000000,1000000000};
155 +/* takes an XeY precision/size value, returns a string representation.*/
157 +precsize_ntoa(u_int8_t prec)
159 + static char retbuf[sizeof("90000000.00")];
161 + int mantissa, exponent;
163 + mantissa = (int)((prec >> 4) & 0x0f) % 10;
164 + exponent = (int)((prec >> 0) & 0x0f) % 10;
166 + val = mantissa * poweroften[exponent];
168 + (void) sprintf(retbuf,"%d.%.2d", val/100, val%100);
172 +/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer.*/
174 +precsize_aton(char **strptr)
176 + unsigned int mval = 0, cmval = 0;
177 + u_int8_t retval = 0;
179 + register int exponent;
180 + register int mantissa;
184 + while (isdigit(*cp))
185 + mval = mval * 10 + (*cp++ - '0');
187 + if (*cp == '.') { /* centimeters */
189 + if (isdigit(*cp)) {
190 + cmval = (*cp++ - '0') * 10;
191 + if (isdigit(*cp)) {
192 + cmval += (*cp++ - '0');
196 + cmval = (mval * 100) + cmval;
198 + for (exponent = 0; exponent < 9; exponent++)
199 + if (cmval < poweroften[exponent+1])
202 + mantissa = cmval / poweroften[exponent];
206 + retval = (mantissa << 4) | exponent;
213 +/* converts ascii lat/lon to unsigned encoded 32-bit number.
214 + * moves pointer. */
216 +latlon2ul(char **latlonstrptr,int *which)
220 + int deg = 0, min = 0, secs = 0, secsfrac = 0;
222 + cp = *latlonstrptr;
224 + while (isdigit(*cp))
225 + deg = deg * 10 + (*cp++ - '0');
227 + while (isspace(*cp))
230 + if (!(isdigit(*cp)))
233 + while (isdigit(*cp))
234 + min = min * 10 + (*cp++ - '0');
235 + while (isspace(*cp))
238 + if (!(isdigit(*cp)))
241 + while (isdigit(*cp))
242 + secs = secs * 10 + (*cp++ - '0');
244 + if (*cp == '.') { /* decimal seconds */
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');
257 + while (!isspace(*cp)) /* if any trailing garbage */
260 + while (isspace(*cp))
265 + case 'N': case 'n':
266 + case 'E': case 'e':
267 + retval = ((unsigned)1<<31)
268 + + (((((deg * 60) + min) * 60) + secs) * 1000)
271 + case 'S': case 's':
272 + case 'W': case 'w':
273 + retval = ((unsigned)1<<31)
274 + - (((((deg * 60) + min) * 60) + secs) * 1000)
278 + retval = 0; /* invalid value -- indicates error */
283 + case 'N': case 'n':
284 + case 'S': case 's':
285 + *which = 1; /* latitude */
287 + case 'E': case 'e':
288 + case 'W': case 'w':
289 + *which = 2; /* longitude */
292 + *which = 0; /* error */
296 + cp++; /* skip the hemisphere */
298 + while (!isspace(*cp)) /* if any trailing garbage */
301 + while (isspace(*cp)) /* move to next field */
304 + *latlonstrptr = cp;
309 +/* converts a zone file representation in a string to an RDATA
310 + * on-the-wire representation. */
312 +loc_aton(const char *ascii, u_char *binary)
314 + const char *cp, *maxcp;
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;
326 + maxcp = cp + strlen(ascii);
328 + lltemp1 = latlon2ul(&cp, &which1);
329 + lltemp2 = latlon2ul(&cp, &which2);
331 + switch (which1 + which2) {
332 + case 3: /* 1 + 2, the only valid combination */
333 + if ((which1 == 1) && (which2 == 2)) { /* normal case */
336 + } else if ((which1 == 2) && (which2 == 1)) {/*reversed*/
339 + } else { /* some kind of brokenness */
343 + default: /* we didn't get one of each */
356 + while (isdigit(*cp))
357 + altmeters = altmeters * 10 + (*cp++ - '0');
359 + if (*cp == '.') { /* decimal meters */
361 + if (isdigit(*cp)) {
362 + altfrac = (*cp++ - '0') * 10;
363 + if (isdigit(*cp)) {
364 + altfrac += (*cp++ - '0');
369 + alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
371 + while (!isspace(*cp) && (cp < maxcp))
372 + /* if trailing garbage or m */
375 + while (isspace(*cp) && (cp < maxcp))
380 + siz = precsize_aton(&cp);
382 + while (!isspace(*cp) && (cp < maxcp))/*if trailing garbage or m*/
385 + while (isspace(*cp) && (cp < maxcp))
391 + hp = precsize_aton(&cp);
393 + while (!isspace(*cp) && (cp < maxcp))/*if trailing garbage or m*/
396 + while (isspace(*cp) && (cp < maxcp))
402 + vp = precsize_aton(&cp);
407 + *bcp++ = (u_int8_t) 0; /* version byte */
411 + PUTLONG(latit,bcp);
412 + PUTLONG(longit,bcp);
415 + return (16); /* size of RR in octets */
418 +/* takes an on-the-wire LOC RR and prints it in zone file
419 + * (human readable) format. */
421 +loc_ntoa(const u_char *binary,char *ascii)
423 + static char tmpbuf[255*3];
426 + register const u_char *rcp;
428 + int latdeg, latmin, latsec, latsecfrac;
429 + int longdeg, longmin, longsec, longsecfrac;
430 + char northsouth, eastwest;
431 + int altmeters, altfrac, altsign;
433 + const int referencealt = 100000 * 100;
435 + int32_t latval, longval, altval;
437 + u_int8_t sizeval, hpval, vpval, versionval;
439 + char *sizestr, *hpstr, *vpstr;
448 + versionval = *rcp++;
451 + sprintf(cp,"; error: unknown LOC RR version");
460 + GETLONG(templ,rcp);
461 + latval = (templ - ((unsigned)1<<31));
463 + GETLONG(templ,rcp);
464 + longval = (templ - ((unsigned)1<<31));
466 + GETLONG(templ,rcp);
467 + if (templ < referencealt) { /* below WGS 84 spheroid */
468 + altval = referencealt - templ;
471 + altval = templ - referencealt;
482 + latsecfrac = latval % 1000;
483 + latval = latval / 1000;
484 + latsec = latval % 60;
485 + latval = latval / 60;
486 + latmin = latval % 60;
487 + latval = latval / 60;
492 + longval = -longval;
497 + longsecfrac = longval % 1000;
498 + longval = longval / 1000;
499 + longsec = longval % 60;
500 + longval = longval / 60;
501 + longmin = longval % 60;
502 + longval = longval / 60;
505 + altfrac = altval % 100;
506 + altmeters = (altval / 100) * altsign;
508 + sizestr = strdup(precsize_ntoa(sizeval));
509 + hpstr = strdup(precsize_ntoa(hpval));
510 + vpstr = strdup(precsize_ntoa(vpval));
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);