]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - contrib/bind9/doc/rfc/rfc1876.txt
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / contrib / bind9 / doc / rfc / rfc1876.txt
1
2
3
4
5
6
7 Network Working Group                                           C. Davis
8 Request for Comments: 1876                             Kapor Enterprises
9 Updates: 1034, 1035                                             P. Vixie
10 Category: Experimental                                 Vixie Enterprises
11                                                               T. Goodwin
12                                                             FORE Systems
13                                                             I. Dickinson
14                                                    University of Warwick
15                                                             January 1996
16
17
18  A Means for Expressing Location Information in the Domain Name System
19
20 Status of this Memo
21
22    This memo defines an Experimental Protocol for the Internet
23    community.  This memo does not specify an Internet standard of any
24    kind.  Discussion and suggestions for improvement are requested.
25    Distribution of this memo is unlimited.
26
27 1. Abstract
28
29    This memo defines a new DNS RR type for experimental purposes.  This
30    RFC describes a mechanism to allow the DNS to carry location
31    information about hosts, networks, and subnets.  Such information for
32    a small subset of hosts is currently contained in the flat-file UUCP
33    maps.  However, just as the DNS replaced the use of HOSTS.TXT to
34    carry host and network address information, it is possible to replace
35    the UUCP maps as carriers of location information.
36
37    This RFC defines the format of a new Resource Record (RR) for the
38    Domain Name System (DNS), and reserves a corresponding DNS type
39    mnemonic (LOC) and numerical code (29).
40
41    This RFC assumes that the reader is familiar with the DNS [RFC 1034,
42    RFC 1035].  The data shown in our examples is for pedagogical use and
43    does not necessarily reflect the real Internet.
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 Davis, et al                  Experimental                      [Page 1]
59 \f
60 RFC 1876            Location Information in the DNS         January 1996
61
62
63 2. RDATA Format
64
65        MSB                                           LSB
66        +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
67       0|        VERSION        |         SIZE          |
68        +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
69       2|       HORIZ PRE       |       VERT PRE        |
70        +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
71       4|                   LATITUDE                    |
72        +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
73       6|                   LATITUDE                    |
74        +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
75       8|                   LONGITUDE                   |
76        +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
77      10|                   LONGITUDE                   |
78        +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
79      12|                   ALTITUDE                    |
80        +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
81      14|                   ALTITUDE                    |
82        +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
83    (octet)
84
85 where:
86
87 VERSION      Version number of the representation.  This must be zero.
88              Implementations are required to check this field and make
89              no assumptions about the format of unrecognized versions.
90
91 SIZE         The diameter of a sphere enclosing the described entity, in
92              centimeters, expressed as a pair of four-bit unsigned
93              integers, each ranging from zero to nine, with the most
94              significant four bits representing the base and the second
95              number representing the power of ten by which to multiply
96              the base.  This allows sizes from 0e0 (<1cm) to 9e9
97              (90,000km) to be expressed.  This representation was chosen
98              such that the hexadecimal representation can be read by
99              eye; 0x15 = 1e5.  Four-bit values greater than 9 are
100              undefined, as are values with a base of zero and a non-zero
101              exponent.
102
103              Since 20000000m (represented by the value 0x29) is greater
104              than the equatorial diameter of the WGS 84 ellipsoid
105              (12756274m), it is therefore suitable for use as a
106              "worldwide" size.
107
108 HORIZ PRE    The horizontal precision of the data, in centimeters,
109              expressed using the same representation as SIZE.  This is
110              the diameter of the horizontal "circle of error", rather
111
112
113
114 Davis, et al                  Experimental                      [Page 2]
115 \f
116 RFC 1876            Location Information in the DNS         January 1996
117
118
119              than a "plus or minus" value.  (This was chosen to match
120              the interpretation of SIZE; to get a "plus or minus" value,
121              divide by 2.)
122
123 VERT PRE     The vertical precision of the data, in centimeters,
124              expressed using the sane representation as for SIZE.  This
125              is the total potential vertical error, rather than a "plus
126              or minus" value.  (This was chosen to match the
127              interpretation of SIZE; to get a "plus or minus" value,
128              divide by 2.)  Note that if altitude above or below sea
129              level is used as an approximation for altitude relative to
130              the [WGS 84] ellipsoid, the precision value should be
131              adjusted.
132
133 LATITUDE     The latitude of the center of the sphere described by the
134              SIZE field, expressed as a 32-bit integer, most significant
135              octet first (network standard byte order), in thousandths
136              of a second of arc.  2^31 represents the equator; numbers
137              above that are north latitude.
138
139 LONGITUDE    The longitude of the center of the sphere described by the
140              SIZE field, expressed as a 32-bit integer, most significant
141              octet first (network standard byte order), in thousandths
142              of a second of arc, rounded away from the prime meridian.
143              2^31 represents the prime meridian; numbers above that are
144              east longitude.
145
146 ALTITUDE     The altitude of the center of the sphere described by the
147              SIZE field, expressed as a 32-bit integer, most significant
148              octet first (network standard byte order), in centimeters,
149              from a base of 100,000m below the [WGS 84] reference
150              spheroid used by GPS (semimajor axis a=6378137.0,
151              reciprocal flattening rf=298.257223563).  Altitude above
152              (or below) sea level may be used as an approximation of
153              altitude relative to the the [WGS 84] spheroid, though due
154              to the Earth's surface not being a perfect spheroid, there
155              will be differences.  (For example, the geoid (which sea
156              level approximates) for the continental US ranges from 10
157              meters to 50 meters below the [WGS 84] spheroid.
158              Adjustments to ALTITUDE and/or VERT PRE will be necessary
159              in most cases.  The Defense Mapping Agency publishes geoid
160              height values relative to the [WGS 84] ellipsoid.
161
162
163
164
165
166
167
168
169
170 Davis, et al                  Experimental                      [Page 3]
171 \f
172 RFC 1876            Location Information in the DNS         January 1996
173
174
175 3. Master File Format
176
177    The LOC record is expressed in a master file in the following format:
178
179    <owner> <TTL> <class> LOC ( d1 [m1 [s1]] {"N"|"S"} d2 [m2 [s2]]
180                                {"E"|"W"} alt["m"] [siz["m"] [hp["m"]
181                                [vp["m"]]]] )
182
183    (The parentheses are used for multi-line data as specified in [RFC
184    1035] section 5.1.)
185
186    where:
187
188        d1:     [0 .. 90]            (degrees latitude)
189        d2:     [0 .. 180]           (degrees longitude)
190        m1, m2: [0 .. 59]            (minutes latitude/longitude)
191        s1, s2: [0 .. 59.999]        (seconds latitude/longitude)
192        alt:    [-100000.00 .. 42849672.95] BY .01 (altitude in meters)
193        siz, hp, vp: [0 .. 90000000.00] (size/precision in meters)
194
195    If omitted, minutes and seconds default to zero, size defaults to 1m,
196    horizontal precision defaults to 10000m, and vertical precision
197    defaults to 10m.  These defaults are chosen to represent typical
198    ZIP/postal code area sizes, since it is often easy to find
199    approximate geographical location by ZIP/postal code.
200
201 4. Example Data
202
203 ;;;
204 ;;; note that these data would not all appear in one zone file
205 ;;;
206
207 ;; network LOC RR derived from ZIP data.  note use of precision defaults
208 cambridge-net.kei.com.        LOC   42 21 54 N 71 06 18 W -24m 30m
209
210 ;; higher-precision host LOC RR.  note use of vertical precision default
211 loiosh.kei.com.               LOC   42 21 43.952 N 71 5 6.344 W
212                                     -24m 1m 200m
213
214 pipex.net.                    LOC   52 14 05 N 00 08 50 E 10m
215
216 curtin.edu.au.                LOC   32 7 19 S 116 2 25 E 10m
217
218 rwy04L.logan-airport.boston.  LOC   42 21 28.764 N 71 00 51.617 W
219                                     -44m 2000m
220
221
222
223
224
225
226 Davis, et al                  Experimental                      [Page 4]
227 \f
228 RFC 1876            Location Information in the DNS         January 1996
229
230
231 5. Application use of the LOC RR
232
233 5.1 Suggested Uses
234
235    Some uses for the LOC RR have already been suggested, including the
236    USENET backbone flow maps, a "visual traceroute" application showing
237    the geographical path of an IP packet, and network management
238    applications that could use LOC RRs to generate a map of hosts and
239    routers being managed.
240
241 5.2 Search Algorithms
242
243    This section specifies how to use the DNS to translate domain names
244    and/or IP addresses into location information.
245
246    If an application wishes to have a "fallback" behavior, displaying a
247    less precise or larger area when a host does not have an associated
248    LOC RR, it MAY support use of the algorithm in section 5.2.3, as
249    noted in sections 5.2.1 and 5.2.2.  If fallback is desired, this
250    behaviour is the RECOMMENDED default, but in some cases it may need
251    to be modified based on the specific requirements of the application
252    involved.
253
254    This search algorithm is designed to allow network administrators to
255    specify the location of a network or subnet without requiring LOC RR
256    data for each individual host.  For example, a computer lab with 24
257    workstations, all of which are on the same subnet and in basically
258    the same location, would only need a LOC RR for the subnet.
259    (However, if the file server's location has been more precisely
260    measured, a separate LOC RR for it can be placed in the DNS.)
261
262 5.2.1 Searching by Name
263
264    If the application is beginning with a name, rather than an IP
265    address (as the USENET backbone flow maps do), it MUST check for a
266    LOC RR associated with that name.  (CNAME records should be followed
267    as for any other RR type.)
268
269    If there is no LOC RR for that name, all A records (if any)
270    associated with the name MAY be checked for network (or subnet) LOC
271    RRs using the "Searching by Network or Subnet" algorithm (5.2.3).  If
272    multiple A records exist and have associated network or subnet LOC
273    RRs, the application may choose to use any, some, or all of the LOC
274    RRs found, possibly in combination.  It is suggested that multi-homed
275    hosts have LOC RRs for their name in the DNS to avoid any ambiguity
276    in these cases.
277
278
279
280
281
282 Davis, et al                  Experimental                      [Page 5]
283 \f
284 RFC 1876            Location Information in the DNS         January 1996
285
286
287    Note that domain names that do not have associated A records must
288    have a LOC RR associated with their name in order for location
289    information to be accessible.
290
291 5.2.2 Searching by Address
292
293    If the application is beginning with an IP address (as a "visual
294    traceroute" application might be) it MUST first map the address to a
295    name using the IN-ADDR.ARPA namespace (see [RFC 1034], section
296    5.2.1), then check for a LOC RR associated with that name.
297
298    If there is no LOC RR for the name, the address MAY be checked for
299    network (or subnet) LOC RRs using the "Searching by Network or
300    Subnet" algorithm (5.2.3).
301
302 5.2.3 Searching by Network or Subnet
303
304    Even if a host's name does not have any associated LOC RRs, the
305    network(s) or subnet(s) it is on may.  If the application wishes to
306    search for such less specific data, the following algorithm SHOULD be
307    followed to find a network or subnet LOC RR associated with the IP
308    address.  This algorithm is adapted slightly from that specified in
309    [RFC 1101], sections 4.3 and 4.4.
310
311    Since subnet LOC RRs are (if present) more specific than network LOC
312    RRs, it is best to use them if available.  In order to do so, we
313    build a stack of network and subnet names found while performing the
314    [RFC 1101] search, then work our way down the stack until a LOC RR is
315    found.
316
317    1. create a host-zero address using the network portion of the IP
318       address (one, two, or three bytes for class A, B, or C networks,
319       respectively).  For example, for the host 128.9.2.17, on the class
320       B network 128.9, this would result in the address "128.9.0.0".
321
322    2. Reverse the octets, suffix IN-ADDR.ARPA, and query for PTR and A
323       records.  Retrieve:
324
325                0.0.9.128.IN-ADDR.ARPA.  PTR    isi-net.isi.edu.
326                                         A      255.255.255.0
327
328       Push the name "isi-net.isi.edu" onto the stack of names to be
329       searched for LOC RRs later.
330
331
332
333
334
335
336
337
338 Davis, et al                  Experimental                      [Page 6]
339 \f
340 RFC 1876            Location Information in the DNS         January 1996
341
342
343    3. Since an A RR was found, repeat using mask from RR
344       (255.255.255.0), constructing a query for 0.2.9.128.IN-ADDR.ARPA.
345       Retrieve:
346
347                0.2.9.128.IN-ADDR.ARPA.  PTR    div2-subnet.isi.edu.
348                                         A      255.255.255.240
349
350       Push the name "div2-subnet.isi.edu" onto the stack of names to be
351       searched for LOC RRs later.
352
353    4. Since another A RR was found, repeat using mask 255.255.255.240
354       (x'FFFFFFF0'), constructing a query for 16.2.9.128.IN-ADDR.ARPA.
355       Retrieve:
356
357                16.2.9.128.IN-ADDR.ARPA. PTR    inc-subsubnet.isi.edu.
358
359       Push the name "inc-subsubnet.isi.edu" onto the stack of names to
360       be searched for LOC RRs later.
361
362    5. Since no A RR is present at 16.2.9.128.IN-ADDR.ARPA., there are no
363       more subnet levels to search.  We now pop the top name from the
364       stack and check for an associated LOC RR.  Repeat until a LOC RR
365       is found.
366
367       In this case, assume that inc-subsubnet.isi.edu does not have an
368       associated LOC RR, but that div2-subnet.isi.edu does.  We will
369       then use div2-subnet.isi.edu's LOC RR as an approximation of this
370       host's location.  (Note that even if isi-net.isi.edu has a LOC RR,
371       it will not be used if a subnet also has a LOC RR.)
372
373 5.3 Applicability to non-IN Classes and non-IP Addresses
374
375    The LOC record is defined for all RR classes, and may be used with
376    non-IN classes such as HS and CH.  The semantics of such use are not
377    defined by this memo.
378
379    The search algorithm in section 5.2.3 may be adapted to other
380    addressing schemes by extending [RFC 1101]'s encoding of network
381    names to cover those schemes.  Such extensions are not defined by
382    this memo.
383
384
385
386
387
388
389
390
391
392
393
394 Davis, et al                  Experimental                      [Page 7]
395 \f
396 RFC 1876            Location Information in the DNS         January 1996
397
398
399 6. References
400
401    [RFC 1034] Mockapetris, P., "Domain Names - Concepts and Facilities",
402               STD 13, RFC 1034, USC/Information Sciences Institute,
403               November 1987.
404
405    [RFC 1035] Mockapetris, P., "Domain Names - Implementation and
406               Specification", STD 13, RFC 1035, USC/Information Sciences
407               Institute, November 1987.
408
409    [RFC 1101] Mockapetris, P., "DNS Encoding of Network Names and Other
410               Types", RFC 1101, USC/Information Sciences Institute,
411               April 1989.
412
413    [WGS 84] United States Department of Defense; DoD WGS-1984 - Its
414             Definition and Relationships with Local Geodetic Systems;
415             Washington, D.C.; 1985; Report AD-A188 815 DMA; 6127; 7-R-
416             138-R; CV, KV;
417
418 7. Security Considerations
419
420    High-precision LOC RR information could be used to plan a penetration
421    of physical security, leading to potential denial-of-machine attacks.
422    To avoid any appearance of suggesting this method to potential
423    attackers, we declined the opportunity to name this RR "ICBM".
424
425 8. Authors' Addresses
426
427    The authors as a group can be reached as <loc@pipex.net>.
428
429    Christopher Davis
430    Kapor Enterprises, Inc.
431    238 Main Street, Suite 400
432    Cambridge, MA 02142
433
434    Phone: +1 617 576 4532
435    EMail: ckd@kei.com
436
437
438    Paul Vixie
439    Vixie Enterprises
440    Star Route Box 159A
441    Woodside, CA 94062
442
443    Phone: +1 415 747 0204
444    EMail: paul@vix.com
445
446
447
448
449
450 Davis, et al                  Experimental                      [Page 8]
451 \f
452 RFC 1876            Location Information in the DNS         January 1996
453
454
455    Tim Goodwin
456    Public IP Exchange Ltd (PIPEX)
457    216 The Science Park
458    Cambridge CB4 4WA
459    UK
460
461    Phone: +44 1223 250250
462    EMail: tim@pipex.net
463
464
465    Ian Dickinson
466    FORE Systems
467    2475 The Crescent
468    Solihull Parkway
469    Birmingham Business Park
470    B37 7YE
471    UK
472
473    Phone: +44 121 717 4444
474    EMail: idickins@fore.co.uk
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506 Davis, et al                  Experimental                      [Page 9]
507 \f
508 RFC 1876            Location Information in the DNS         January 1996
509
510
511 Appendix A: Sample Conversion Routines
512
513 /*
514  * routines to convert between on-the-wire RR format and zone file
515  * format.  Does not contain conversion to/from decimal degrees;
516  * divide or multiply by 60*60*1000 for that.
517  */
518
519 static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
520                                  1000000,10000000,100000000,1000000000};
521
522 /* takes an XeY precision/size value, returns a string representation.*/
523 static const char *
524 precsize_ntoa(prec)
525         u_int8_t prec;
526 {
527         static char retbuf[sizeof("90000000.00")];
528         unsigned long val;
529         int mantissa, exponent;
530
531         mantissa = (int)((prec >> 4) & 0x0f) % 10;
532         exponent = (int)((prec >> 0) & 0x0f) % 10;
533
534         val = mantissa * poweroften[exponent];
535
536         (void) sprintf(retbuf,"%d.%.2d", val/100, val%100);
537         return (retbuf);
538 }
539
540 /* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer.*/
541 static u_int8_t
542 precsize_aton(strptr)
543         char **strptr;
544 {
545         unsigned int mval = 0, cmval = 0;
546         u_int8_t retval = 0;
547         register char *cp;
548         register int exponent;
549         register int mantissa;
550
551         cp = *strptr;
552
553         while (isdigit(*cp))
554                 mval = mval * 10 + (*cp++ - '0');
555
556         if (*cp == '.') {               /* centimeters */
557                 cp++;
558                 if (isdigit(*cp)) {
559
560
561
562 Davis, et al                  Experimental                     [Page 10]
563 \f
564 RFC 1876            Location Information in the DNS         January 1996
565
566
567                         cmval = (*cp++ - '0') * 10;
568                         if (isdigit(*cp)) {
569                                 cmval += (*cp++ - '0');
570                         }
571                 }
572         }
573         cmval = (mval * 100) + cmval;
574
575         for (exponent = 0; exponent < 9; exponent++)
576                 if (cmval < poweroften[exponent+1])
577                         break;
578
579         mantissa = cmval / poweroften[exponent];
580         if (mantissa > 9)
581                 mantissa = 9;
582
583         retval = (mantissa << 4) | exponent;
584
585         *strptr = cp;
586
587         return (retval);
588 }
589
590 /* converts ascii lat/lon to unsigned encoded 32-bit number.
591  *  moves pointer. */
592 static u_int32_t
593 latlon2ul(latlonstrptr,which)
594         char **latlonstrptr;
595         int *which;
596 {
597         register char *cp;
598         u_int32_t retval;
599         int deg = 0, min = 0, secs = 0, secsfrac = 0;
600
601         cp = *latlonstrptr;
602
603         while (isdigit(*cp))
604                 deg = deg * 10 + (*cp++ - '0');
605
606         while (isspace(*cp))
607                 cp++;
608
609         if (!(isdigit(*cp)))
610                 goto fndhemi;
611
612         while (isdigit(*cp))
613                 min = min * 10 + (*cp++ - '0');
614
615
616
617
618 Davis, et al                  Experimental                     [Page 11]
619 \f
620 RFC 1876            Location Information in the DNS         January 1996
621
622
623         while (isspace(*cp))
624                 cp++;
625
626         if (!(isdigit(*cp)))
627                 goto fndhemi;
628
629         while (isdigit(*cp))
630                 secs = secs * 10 + (*cp++ - '0');
631
632         if (*cp == '.') {               /* decimal seconds */
633                 cp++;
634                 if (isdigit(*cp)) {
635                         secsfrac = (*cp++ - '0') * 100;
636                         if (isdigit(*cp)) {
637                                 secsfrac += (*cp++ - '0') * 10;
638                                 if (isdigit(*cp)) {
639                                         secsfrac += (*cp++ - '0');
640                                 }
641                         }
642                 }
643         }
644
645         while (!isspace(*cp))   /* if any trailing garbage */
646                 cp++;
647
648         while (isspace(*cp))
649                 cp++;
650
651  fndhemi:
652         switch (*cp) {
653         case 'N': case 'n':
654         case 'E': case 'e':
655                 retval = ((unsigned)1<<31)
656                         + (((((deg * 60) + min) * 60) + secs) * 1000)
657                         + secsfrac;
658                 break;
659         case 'S': case 's':
660         case 'W': case 'w':
661                 retval = ((unsigned)1<<31)
662                         - (((((deg * 60) + min) * 60) + secs) * 1000)
663                         - secsfrac;
664                 break;
665         default:
666                 retval = 0;     /* invalid value -- indicates error */
667                 break;
668         }
669
670         switch (*cp) {
671
672
673
674 Davis, et al                  Experimental                     [Page 12]
675 \f
676 RFC 1876            Location Information in the DNS         January 1996
677
678
679         case 'N': case 'n':
680         case 'S': case 's':
681                 *which = 1;     /* latitude */
682                 break;
683         case 'E': case 'e':
684         case 'W': case 'w':
685                 *which = 2;     /* longitude */
686                 break;
687         default:
688                 *which = 0;     /* error */
689                 break;
690         }
691
692         cp++;                   /* skip the hemisphere */
693
694         while (!isspace(*cp))   /* if any trailing garbage */
695                 cp++;
696
697         while (isspace(*cp))    /* move to next field */
698                 cp++;
699
700         *latlonstrptr = cp;
701
702         return (retval);
703 }
704
705 /* converts a zone file representation in a string to an RDATA
706  * on-the-wire representation. */
707 u_int32_t
708 loc_aton(ascii, binary)
709         const char *ascii;
710         u_char *binary;
711 {
712         const char *cp, *maxcp;
713         u_char *bcp;
714
715         u_int32_t latit = 0, longit = 0, alt = 0;
716         u_int32_t lltemp1 = 0, lltemp2 = 0;
717         int altmeters = 0, altfrac = 0, altsign = 1;
718         u_int8_t hp = 0x16;    /* default = 1e6 cm = 10000.00m = 10km */
719         u_int8_t vp = 0x13;    /* default = 1e3 cm = 10.00m */
720         u_int8_t siz = 0x12;   /* default = 1e2 cm = 1.00m */
721         int which1 = 0, which2 = 0;
722
723         cp = ascii;
724         maxcp = cp + strlen(ascii);
725
726         lltemp1 = latlon2ul(&cp, &which1);
727
728
729
730 Davis, et al                  Experimental                     [Page 13]
731 \f
732 RFC 1876            Location Information in the DNS         January 1996
733
734
735         lltemp2 = latlon2ul(&cp, &which2);
736
737         switch (which1 + which2) {
738         case 3:                 /* 1 + 2, the only valid combination */
739                 if ((which1 == 1) && (which2 == 2)) { /* normal case */
740                         latit = lltemp1;
741                         longit = lltemp2;
742                 } else if ((which1 == 2) && (which2 == 1)) {/*reversed*/
743                         longit = lltemp1;
744                         latit = lltemp2;
745                 } else {        /* some kind of brokenness */
746                         return 0;
747                 }
748                 break;
749         default:                /* we didn't get one of each */
750                 return 0;
751         }
752
753         /* altitude */
754         if (*cp == '-') {
755                 altsign = -1;
756                 cp++;
757         }
758
759         if (*cp == '+')
760                 cp++;
761
762         while (isdigit(*cp))
763                 altmeters = altmeters * 10 + (*cp++ - '0');
764
765         if (*cp == '.') {               /* decimal meters */
766                 cp++;
767                 if (isdigit(*cp)) {
768                         altfrac = (*cp++ - '0') * 10;
769                         if (isdigit(*cp)) {
770                                 altfrac += (*cp++ - '0');
771                         }
772                 }
773         }
774
775         alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
776
777         while (!isspace(*cp) && (cp < maxcp))
778                                            /* if trailing garbage or m */
779                 cp++;
780
781         while (isspace(*cp) && (cp < maxcp))
782                 cp++;
783
784
785
786 Davis, et al                  Experimental                     [Page 14]
787 \f
788 RFC 1876            Location Information in the DNS         January 1996
789
790
791         if (cp >= maxcp)
792                 goto defaults;
793
794         siz = precsize_aton(&cp);
795
796         while (!isspace(*cp) && (cp < maxcp))/*if trailing garbage or m*/
797                 cp++;
798
799         while (isspace(*cp) && (cp < maxcp))
800                 cp++;
801
802         if (cp >= maxcp)
803                 goto defaults;
804
805         hp = precsize_aton(&cp);
806
807         while (!isspace(*cp) && (cp < maxcp))/*if trailing garbage or m*/
808                 cp++;
809
810         while (isspace(*cp) && (cp < maxcp))
811                 cp++;
812
813         if (cp >= maxcp)
814                 goto defaults;
815
816         vp = precsize_aton(&cp);
817
818  defaults:
819
820         bcp = binary;
821         *bcp++ = (u_int8_t) 0;  /* version byte */
822         *bcp++ = siz;
823         *bcp++ = hp;
824         *bcp++ = vp;
825         PUTLONG(latit,bcp);
826         PUTLONG(longit,bcp);
827         PUTLONG(alt,bcp);
828
829         return (16);            /* size of RR in octets */
830 }
831
832 /* takes an on-the-wire LOC RR and prints it in zone file
833  * (human readable) format. */
834 char *
835 loc_ntoa(binary,ascii)
836         const u_char *binary;
837         char *ascii;
838 {
839
840
841
842 Davis, et al                  Experimental                     [Page 15]
843 \f
844 RFC 1876            Location Information in the DNS         January 1996
845
846
847         static char tmpbuf[255*3];
848
849         register char *cp;
850         register const u_char *rcp;
851
852         int latdeg, latmin, latsec, latsecfrac;
853         int longdeg, longmin, longsec, longsecfrac;
854         char northsouth, eastwest;
855         int altmeters, altfrac, altsign;
856
857         const int referencealt = 100000 * 100;
858
859         int32_t latval, longval, altval;
860         u_int32_t templ;
861         u_int8_t sizeval, hpval, vpval, versionval;
862
863         char *sizestr, *hpstr, *vpstr;
864
865         rcp = binary;
866         if (ascii)
867                 cp = ascii;
868         else {
869                 cp = tmpbuf;
870         }
871
872         versionval = *rcp++;
873
874         if (versionval) {
875                 sprintf(cp,"; error: unknown LOC RR version");
876                 return (cp);
877         }
878
879         sizeval = *rcp++;
880
881         hpval = *rcp++;
882         vpval = *rcp++;
883
884         GETLONG(templ,rcp);
885         latval = (templ - ((unsigned)1<<31));
886
887         GETLONG(templ,rcp);
888         longval = (templ - ((unsigned)1<<31));
889
890         GETLONG(templ,rcp);
891         if (templ < referencealt) { /* below WGS 84 spheroid */
892                 altval = referencealt - templ;
893                 altsign = -1;
894         } else {
895
896
897
898 Davis, et al                  Experimental                     [Page 16]
899 \f
900 RFC 1876            Location Information in the DNS         January 1996
901
902
903                 altval = templ - referencealt;
904                 altsign = 1;
905         }
906
907         if (latval < 0) {
908                 northsouth = 'S';
909                 latval = -latval;
910         }
911         else
912                 northsouth = 'N';
913
914         latsecfrac = latval % 1000;
915         latval = latval / 1000;
916         latsec = latval % 60;
917         latval = latval / 60;
918         latmin = latval % 60;
919         latval = latval / 60;
920         latdeg = latval;
921
922         if (longval < 0) {
923                 eastwest = 'W';
924                 longval = -longval;
925         }
926         else
927                 eastwest = 'E';
928
929         longsecfrac = longval % 1000;
930         longval = longval / 1000;
931         longsec = longval % 60;
932         longval = longval / 60;
933         longmin = longval % 60;
934         longval = longval / 60;
935         longdeg = longval;
936
937         altfrac = altval % 100;
938         altmeters = (altval / 100) * altsign;
939
940         sizestr = savestr(precsize_ntoa(sizeval));
941         hpstr = savestr(precsize_ntoa(hpval));
942         vpstr = savestr(precsize_ntoa(vpval));
943
944         sprintf(cp,
945                 "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm
946                 %sm %sm %sm",
947                 latdeg, latmin, latsec, latsecfrac, northsouth,
948                 longdeg, longmin, longsec, longsecfrac, eastwest,
949                 altmeters, altfrac, sizestr, hpstr, vpstr);
950
951
952
953
954 Davis, et al                  Experimental                     [Page 17]
955 \f
956 RFC 1876            Location Information in the DNS         January 1996
957
958
959         free(sizestr);
960         free(hpstr);
961         free(vpstr);
962
963         return (cp);
964 }
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010 Davis, et al                  Experimental                     [Page 18]
1011 \f