blob: d950321ba762a3e7cf2b708c690497a2f1c90ef8 [file] [log] [blame]
San Mehatffd68722010-01-20 09:56:15 -08001diff -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
13diff -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);
44diff -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 {
109diff -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)
140diff -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+}