idnits 2.17.1 draft-davis-dns-loc-01.txt: ** The Abstract section seems to be numbered Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- ** Cannot find the required boilerplate sections (Copyright, IPR, etc.) in this document. Expected boilerplate is as follows today (2024-04-25) according to https://trustee.ietf.org/license-info : IETF Trust Legal Provisions of 28-dec-2009, Section 6.a: This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. IETF Trust Legal Provisions of 28-dec-2009, Section 6.b(i), paragraph 2: Copyright (c) 2024 IETF Trust and the persons identified as the document authors. All rights reserved. IETF Trust Legal Provisions of 28-dec-2009, Section 6.b(i), paragraph 3: This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- ** Missing expiration date. The document expiration date should appear on the first and last page. ** The document seems to lack a 1id_guidelines paragraph about Internet-Drafts being working documents. ** The document seems to lack a 1id_guidelines paragraph about 6 months document validity -- however, there's a paragraph with a matching beginning. Boilerplate error? ** The document seems to lack a 1id_guidelines paragraph about the list of current Internet-Drafts. ** The document seems to lack a 1id_guidelines paragraph about the list of Shadow Directories. ** Expected the document's filename to be given on the first page, but didn't find any == No 'Intended status' indicated for this document; assuming Proposed Standard Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack an Introduction section. ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) ** There are 14 instances of too long lines in the document, the longest one being 9 characters in excess of 72. ** The abstract seems to contain references (RFC, [RFC1034,, 1035]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. ** The document seems to lack a both a reference to RFC 2119 and the recommended RFC 2119 boilerplate, even if it appears to use RFC 2119 keywords. RFC 2119 keyword, line 163: '... LOC RR, it MAY support use of the a...' RFC 2119 keyword, line 165: '...behaviour is the RECOMMENDED default, ...' RFC 2119 keyword, line 180: '...one flow maps do), it MUST check for a...' RFC 2119 keyword, line 185: '...ed with the name MAY be checked for ne...' RFC 2119 keyword, line 200: '...ion might be) it MUST first map the ad...' (2 more instances...) == The 'Updates: ' line in the draft header should list only the _numbers_ of the RFCs which will be updated by this document (if approved); it should not include the word 'RFC' in the list. -- The draft header indicates that this document updates RFC1034, but the abstract doesn't seem to directly say this. It does mention RFC1034 though, so this could be OK. -- The draft header indicates that this document updates RFC1035, but the abstract doesn't seem to directly say this. It does mention RFC1035 though, so this could be OK. Miscellaneous warnings: ---------------------------------------------------------------------------- == Couldn't figure out when the document was first submitted -- there may comments or warnings related to the use of a disclaimer for pre-RFC5378 work that could not be issued because of this. Please check the Legal Provisions document at https://trustee.ietf.org/license-info to determine if you need the pre-RFC5378 disclaimer. -- The document date (December 1994) is 10724 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Missing reference section? 'RFC 1034' on line 281 looks like a reference -- Missing reference section? 'RFC 1035' on line 285 looks like a reference -- Missing reference section? 'WGS 84' on line 293 looks like a reference -- Missing reference section? 'RFC 1101' on line 289 looks like a reference -- Missing reference section? '10' on line 355 looks like a reference Summary: 13 errors (**), 0 flaws (~~), 3 warnings (==), 9 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 1 Network Working Group C. Davis 2 Internet Draft Kapor Enterprises 3 Updates: RFCs 1034, 1035 P. Vixie 4 Vixie Enterprises 5 T. Goodwin 6 PIPEX 7 I. Dickinson 8 University of Warwick 9 December 1994 11 A Means for Expressing Location Information in the Domain Name System 13 Status of this Memo 15 This document is an Internet-Draft. Internet-Drafts are working 16 documents of the Internet Engineering Task Force (IETF), its areas, 17 and its working groups. Note that other groups may also distribute 18 working documents as Internet-Drafts. 20 Internet-Drafts are draft documents valid for a maximum of six months 21 and may be updated, replaced, or obsoleted by other documents at any 22 time. It is inappropriate to use Internet- Drafts as reference 23 material or to cite them other than as ``work in progress.'' 25 To learn the current status of any Internet-Draft, please check the 26 ``1id-abstracts.txt'' listing contained in the Internet- Drafts 27 Shadow Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe), 28 munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or 29 ftp.isi.edu (US West Coast). 31 1. Abstract 33 This Internet-Draft describes a mechanism to allow the DNS to carry 34 location information about hosts, networks, and subnets. Such 35 information for a small subset of hosts is currently contained in the 36 flat-file UUCP maps. However, just as the DNS replaced the use of 37 HOSTS.TXT to carry host and network address information, it is 38 possible to replace the UUCP maps as carriers of location 39 information. 41 This Internet-Draft defines the format of a new Resource Record (RR) 42 for the Domain Name System (DNS), and reserves a corresponding DNS 43 type mnemonic (LOC) and numerical code (29). 45 This Internet-Draft assumes that the reader is familiar with the DNS 46 [RFC 1034, RFC 1035]. The data shown in our examples is for 47 pedagogical use and does not necessarily reflect the real Internet. 49 2. RDATA Format 51 MSB LSB 52 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 53 0| VERSION | SIZE | 54 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 55 2| HORIZ PRE | VERT PRE | 56 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 57 4| LATITUDE | 58 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 59 6| LATITUDE | 60 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 61 8| LONGITUDE | 62 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 63 10| LONGITUDE | 64 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 65 12| ALTITUDE | 66 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 67 14| ALTITUDE | 68 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 69 (octet) 71 where: 73 VERSION Version number of the representation. This must be zero. 74 Implementations are required to check this field and make 75 no assumptions about the format of unrecognized versions. 77 SIZE The size of the described entity, in centimeters, expressed 78 as a pair of four-bit unsigned integers, each ranging from 79 zero to nine, with the most significant four bits 80 representing the base and the second number representing 81 the power of ten by which to multiply the base. This 82 allows sizes from 0e0 (<1cm) to 9e9 (90,000km) to be 83 expressed. This representation was chosen such that the 84 hexadecimal representation can be read by eye; 0xAB = AeB. 86 Since 20000000m (represented by the value 0x29) is greater 87 than the equatorial diameter of the WGS 84 ellipsoid 88 (12756274m), it is therefore suitable for use as a 89 "worldwide" size. 91 HORIZ PRE The horizontal precision of the data, in centimeters, 92 expressed as for SIZE. This is treated as an "accurate to 93 within N centimeters" value. 95 VERT PRE The vertical precision of the data, in centimeters, 96 expressed as for SIZE. This is treated as an "accurate to 97 within N centimeters" value. 99 LATITUDE The latitude of the center of the sphere described by the 100 SIZE field, expressed as a 32-bit integer, most significant 101 octet first (network standard byte order), in thousandsth 102 of a second of arc. 2^31 represents the equator; numbers 103 above that are north latitude. 105 LONGITUDE The longitude of the center of the sphere described by the 106 SIZE field, expressed as a 32-bit integer, most significant 107 octet first (network standard byte order), in thousandths 108 of a second of arc, rounded away from the prime meridian. 109 2^31 represents the prime meridian; numbers above that are 110 east longitude. 112 ALTITUDE The altitude of the center of the sphere described by the 113 SIZE field, expressed as a 32-bit integer, most significant 114 octet first (network standard byte order), in centimeters, 115 from a base of 100,000m below the [WGS 84] reference 116 spheroid used by GPS (semimajor axis a=6378137.0, 117 reciprocal flattening rf=298.257223563). 119 3. Master File Format 121 The LOC record is expressed in a master file in the following format: 123 LOC ( d1 [m1 [s1]] {"N"|"S"} d2 [m2 [s2]] 124 {"E"|"W"} alt["m"] [siz["m"] [hp["m"] 125 [vp["m"]]]] ) 127 (The parentheses are used for multi-line data as specified in [RFC 128 1035] section 5.1.) 130 where: 132 d1: [0 .. 90] (degrees latitude) 133 d2: [0 .. 180] (degrees longitude) 134 m1, m2: [0 .. 59] (minutes latitude/longitude) 135 s1, s2: [0 .. 59.999] (seconds latitude/longitude) 136 alt: [-100000.00 .. 42939672.96] BY .01 (altitude in 137 meters) 138 siz, hp, vp: [0 .. 90000000.00] (size/precision in meters) 140 If omitted, minutes and seconds default to zero, size defaults to 1m, 141 horizontal precision defaults to 10000m, and vertical precision 142 defaults to 10m. These defaults are chosen to represent typical 143 ZIP/postal code area sizes, since it is often easy to find 144 approximate geographical location by ZIP/postal code. 146 4. Application use of the LOC RR 148 4.1 Suggested Uses 150 Some uses for the LOC RR have already been suggested, including the 151 USENET backbone flow maps, a "visual traceroute" application showing 152 the geographical path of an IP packet, and network management 153 applications that could use LOC RRs to generate a map of hosts and 154 routers being managed. 156 4.2 Search Algorithms 158 This section specifies how to use the DNS to translate domain names 159 and/or IP addresses into location information. 161 If an application wishes to have a "fallback" behavior, displaying a 162 less precise or larger area when a host does not have an associated 163 LOC RR, it MAY support use of the algorithm in section 4.2.3, as 164 noted in sections 4.2.1 and 4.2.2. If fallback is desired, this 165 behaviour is the RECOMMENDED default, but in some cases it may need 166 to be modified based on the specific requirements of the application 167 involved. 169 This search algorithm is designed to allow network administrators to 170 specify the location of a network or subnet without requiring LOC RR 171 data for each individual host. For example, a computer lab with 24 172 workstations, all of which are on the same subnet and in basically 173 the same location, would only need a LOC RR for the subnet. 174 (However, if the file server's location has been more precisely 175 measured, a separate LOC RR for it can be placed in the DNS.) 177 4.2.1 Searching by Name 179 If the application is beginning with a name, rather than an IP 180 address (as the USENET backbone flow maps do), it MUST check for a 181 LOC RR associated with that name. (CNAME records should be followed 182 as for any other RR type.) 184 If there is no LOC RR for that name, all A records (if any) 185 associated with the name MAY be checked for network (or subnet) LOC 186 RRs using the "Searching by Network or Subnet" algorithm (4.2.3). If 187 multiple A records exist and have associated network or subnet LOC 188 RRs, the application may choose to use any, some, or all of the LOC 189 RRs found, possibly in combination. It is suggested that multi-homed 190 hosts have LOC RRs for their name in the DNS to avoid any ambiguity 191 in these cases. 193 Note that domain names that do not have associated A records must 194 have a LOC RR associated with their name in order for location 195 information to be accessible. 197 4.2.2 Searching by Address 199 If the application is beginning with an IP address (as a "visual 200 traceroute" application might be) it MUST first map the address to a 201 name using the IN-ADDR.ARPA namespace (see [RFC 1034], section 202 5.2.1), then check for a LOC RR associated with that name. 204 If there is no LOC RR for the name, the address MAY be checked for 205 network (or subnet) LOC RRs using the "Searching by Network or 206 Subnet" algorithm (4.2.3). 208 4.2.3 Searching by Network or Subnet 210 Even if a host's name does not have any associated LOC RRs, the 211 network(s) or subnet(s) it is on may. If the application wishes to 212 search for such less specific data, the following algorithm SHOULD be 213 followed to find a network or subnet LOC RR associated with the IP 214 address. This algorithm is adapted slightly from that specified in 215 [RFC 1101], sections 4.3 and 4.4. 217 Since subnet LOC RRs are (if present) more specific than network LOC 218 RRs, it is best to use them if available. In order to do so, we 219 build a stack of network and subnet names found while performing the 220 [RFC 1101] search, then work our way down the stack until a LOC RR is 221 found. 223 1. create a host-zero address using the network portion of the IP 224 address (one, two, or three bytes for class A, B, or C networks, 225 respectively). For example, for the host 128.9.2.17, on the class 226 B network 128.9, this would result in the address "128.9.0.0". 228 2. Reverse the octets, suffix IN-ADDR.ARPA, and query for PTR and A 229 records. Retrieve: 231 0.0.9.128.IN-ADDR.ARPA. PTR isi-net.isi.edu. 232 A 255.255.255.0 234 Push the name "isi-net.isi.edu" onto the stack of names to be 235 searched for LOC RRs later. 237 3. Since an A RR was found, repeat using mask from RR 238 (255.255.255.0), constructing a query for 0.2.9.128.IN-ADDR.ARPA. 239 Retrieve: 241 0.2.9.128.IN-ADDR.ARPA. PTR div2-subnet.isi.edu. 243 A 255.255.255.240 245 Push the name "div2-subnet.isi.edu" onto the stack of names to be 246 searched for LOC RRs later. 248 4. Since another A RR was found, repeat using mask 255.255.255.240 249 (x'FFFFFFF0'), constructing a query for 16.2.9.128.IN-ADDR.ARPA. 250 Retrieve: 252 16.2.9.128.IN-ADDR.ARPA. PTR inc-subsubnet.isi.edu. 254 Push the name "inc-subsubnet.isi.edu" onto the stack of names to 255 be searched for LOC RRs later. 257 5. Since no A RR is present at 16.2.9.128.IN-ADDR.ARPA., there are no 258 more subnet levels to search. We now pop the top name from the 259 stack and check for an associated LOC RR. Repeat until a LOC RR 260 is found. 262 In this case, assume that inc-subsubnet.isi.edu does not have an 263 associated LOC RR, but that div2-subnet.isi.edu does. We will 264 then use div2-subnet.isi.edu's LOC RR as an approximation of this 265 host's location. (Note that even if isi-net.isi.edu has a LOC RR, 266 it will not be used if a subnet also has a LOC RR.) 268 4.3 Applicability to non-IN Classes and non-IP Addresses 270 The LOC record is defined for all RR classes, and may be used with 271 non-IN classes such as HS and CH. The semantics of such use are not 272 defined by this memo. 274 The search algorithm in section 4.2.3 may be adapted to other 275 addressing schemes by extending [RFC 1101]'s encoding of network 276 names to cover those schemes. Such extensions are not defined by 277 this memo. 279 5. References 281 [RFC 1034] Mockapetris, P., "Domain Names - Concepts and Facilities", 282 STD 13, RFC 1034, USC/Information Sciences Institute, 283 November 1987. 285 [RFC 1035] Mockapetris, P., "Domain Names - Implementation and 286 Specification", STD 13, RFC 1035, USC/Information Sciences 287 Institute, November 1987. 289 [RFC 1101] Mockapetris, P., "DNS Encoding of Network Names and Other 290 Types", RFC 1101, USC/Information Sciences Institute, 291 April 1989. 293 [WGS 84] United States Department of Defense; DoD WGS-1984 - Its 294 Definition and Relationships with Local Geodetic Systems; 295 Washington, D.C.; 1985; Report AD-A188 815 DMA; 6127; 7- 296 R-138-R; CV, KV; 298 6. Security Considerations 300 High-precision LOC RR information could be used to help plan a 301 penetration of physical security, leading to potential denial-of- 302 machine attacks. To avoid any appearance of suggesting this method 303 to potential attackers, we declined the opportunity to name this RR 304 "ICBM". 306 7. Authors' Addresses 308 The authors as a group can be reached as . 310 Christopher Davis 311 Kapor Enterprises, Inc. 312 238 Main Street, Suite 400 313 Cambridge, MA 02142 315 Phone: +1 617 576 4532 317 Email: ckd@kei.com 319 Paul Vixie 320 Vixie Enterprises 321 Star Route Box 159A 322 Woodside, CA 94062 324 Phone: +1 415 747 0204 326 Email: paul@vix.com 328 Tim Goodwin 329 Public IP Exchange Ltd (PIPEX) 330 216 The Science Park 331 Cambridge CB4 4WA 332 UK 334 Phone: +44 1223 250250 336 Email: tim@pipex.net 337 Ian Dickinson 338 Computing Services 339 University of Warwick 340 Coventry CV4 7AL 341 UK 343 Phone: +44 1203 524217 345 Email: cudep@csv.warwick.ac.uk 347 Appendix A: Sample Conversion Routines 349 /* 350 * routines to convert between on-the-wire RR format and zone file format. 351 * Does not contain conversion to/from decimal degrees; divide or multiply 352 * by 60*60*1000 for that. 353 */ 355 static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000, 356 1000000,10000000,100000000,1000000000}; 358 /* takes an XeY precision/size value, returns a string representation. */ 359 static const char * 360 precsize_ntoa(prec) 361 u_int8_t prec; 362 { 363 static char retbuf[sizeof("90000000.00")]; 364 unsigned long val; 365 int mantissa, exponent; 367 mantissa = ((prec >> 4) & 0x0f) % 10; 368 exponent = ((prec >> 0) & 0x0f) % 10; 370 val = mantissa * poweroften[exponent]; 372 (void) sprintf(retbuf,"%d.%.2d", val/100, val%100); 373 return (retbuf); 374 } 376 /* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */ 377 static u_int8_t 378 precsize_aton(strptr) 379 char **strptr; 380 { 381 unsigned int mval = 0, cmval = 0; 382 u_int8_t retval = 0; 383 register char *cp; 384 register int exponent; 385 register int mantissa; 387 cp = *strptr; 389 while (isdigit(*cp)) 390 mval = mval * 10 + (*cp++ - '0'); 392 if (*cp == '.') { /* centimeters */ 393 cp++; 394 if (isdigit(*cp)) { 395 cmval = (*cp++ - '0') * 10; 396 if (isdigit(*cp)) { 397 cmval += (*cp++ - '0'); 398 } 399 } 400 } 401 cmval = (mval * 100) + cmval; 403 for (exponent = 0; exponent < 9; exponent++) 404 if (cmval < poweroften[exponent+1]) 405 break; 407 mantissa = cmval / poweroften[exponent]; 408 if (mantissa > 9) 409 mantissa = 9; 411 retval = (mantissa << 4) | exponent; 413 *strptr = cp; 415 return (retval); 416 } 418 /* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */ 419 static u_int32_t 420 latlon2ul(latlonstrptr,which) 421 char **latlonstrptr; 422 int *which; 423 { 424 register char *cp; 425 u_int32_t retval; 426 int deg = 0, min = 0, secs = 0, secsfrac = 0; 428 cp = *latlonstrptr; 430 while (isdigit(*cp)) 431 deg = deg * 10 + (*cp++ - '0'); 433 while (isspace(*cp)) 434 cp++; 436 if (!(isdigit(*cp))) 437 goto fndhemi; 439 while (isdigit(*cp)) 440 min = min * 10 + (*cp++ - '0'); 442 while (isspace(*cp)) 443 cp++; 445 if (!(isdigit(*cp))) 446 goto fndhemi; 448 while (isdigit(*cp)) 449 secs = secs * 10 + (*cp++ - '0'); 451 if (*cp == '.') { /* decimal seconds */ 452 cp++; 453 if (isdigit(*cp)) { 454 secsfrac = (*cp++ - '0') * 100; 455 if (isdigit(*cp)) { 456 secsfrac += (*cp++ - '0') * 10; 457 if (isdigit(*cp)) { 458 secsfrac += (*cp++ - '0'); 459 } 460 } 461 } 462 } 464 while (!isspace(*cp)) /* if any trailing garbage */ 465 cp++; 467 while (isspace(*cp)) 468 cp++; 470 fndhemi: 471 switch (*cp) { 472 case 'N': case 'n': 473 case 'E': case 'e': 474 retval = (1<<31) 475 + (((((deg * 60) + min) * 60) + secs) * 1000) 476 + secsfrac; 477 break; 478 case 'S': case 's': 479 case 'W': case 'w': 480 retval = (1<<31) 481 - (((((deg * 60) + min) * 60) + secs) * 1000) 482 - secsfrac; 483 break; 484 default: 485 retval = 0; /* invalid value -- indicates error */ 486 break; 487 } 489 switch (*cp) { 490 case 'N': case 'n': 491 case 'S': case 's': 492 *which = 1; /* latitude */ 493 break; 494 case 'E': case 'e': 495 case 'W': case 'w': 496 *which = 2; /* longitude */ 497 break; 498 default: 499 *which = 0; /* error */ 500 break; 501 } 503 cp++; /* skip the hemisphere */ 505 while (!isspace(*cp)) /* if any trailing garbage */ 506 cp++; 508 while (isspace(*cp)) /* move to next field */ 509 cp++; 511 *latlonstrptr = cp; 513 return (retval); 514 } 516 /* converts a zone file representation in a string to an RDATA on-the-wire 517 * representation. */ 518 u_int32_t 519 loc_aton(ascii, binary) 520 const char *ascii; 521 u_char *binary; 522 { 523 const char *cp, *maxcp; 524 u_char *bcp; 526 u_int32_t latit = 0, longit = 0, alt = 0; 527 u_int32_t lltemp1 = 0, lltemp2 = 0; 528 int altmeters = 0, altfrac = 0, altsign = 1; 529 u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */ 530 u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */ 531 u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */ 532 int which1 = 0, which2 = 0; 534 cp = ascii; 535 maxcp = cp + strlen(ascii); 537 lltemp1 = latlon2ul(&cp, &which1); 539 lltemp2 = latlon2ul(&cp, &which2); 541 switch (which1 + which2) { 542 case 3: /* 1 + 2, the only valid combination */ 543 if ((which1 == 1) && (which2 == 2)) { /* normal case */ 544 latit = lltemp1; 545 longit = lltemp2; 546 } else if ((which1 == 2) && (which2 == 1)) { /* reversed */ 547 longit = lltemp1; 548 latit = lltemp2; 549 } else { /* some kind of brokenness */ 550 return 0; 551 } 552 break; 553 default: /* we didn't get one of each */ 554 return 0; 555 } 557 /* altitude */ 558 if (*cp == '-') { 559 altsign = -1; 560 cp++; 561 } 563 if (*cp == '+') 564 cp++; 566 while (isdigit(*cp)) 567 altmeters = altmeters * 10 + (*cp++ - '0'); 569 if (*cp == '.') { /* decimal meters */ 570 cp++; 571 if (isdigit(*cp)) { 572 altfrac = (*cp++ - '0') * 10; 573 if (isdigit(*cp)) { 574 altfrac += (*cp++ - '0'); 575 } 576 } 578 } 580 alt = (10000000 + (altsign * (altmeters * 100 + altfrac))); 582 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */ 583 cp++; 585 while (isspace(*cp) && (cp < maxcp)) 586 cp++; 588 if (cp >= maxcp) 589 goto defaults; 591 siz = precsize_aton(&cp); 593 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */ 594 cp++; 596 while (isspace(*cp) && (cp < maxcp)) 597 cp++; 599 if (cp >= maxcp) 600 goto defaults; 602 hp = precsize_aton(&cp); 604 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */ 605 cp++; 607 while (isspace(*cp) && (cp < maxcp)) 608 cp++; 610 if (cp >= maxcp) 611 goto defaults; 613 vp = precsize_aton(&cp); 615 defaults: 617 bcp = binary; 618 *bcp++ = (u_int8_t) 0; /* version byte */ 619 *bcp++ = siz; 620 *bcp++ = hp; 621 *bcp++ = vp; 622 PUTLONG(latit,bcp); 623 PUTLONG(longit,bcp); 624 PUTLONG(alt,bcp); 625 return (16); /* size of RR in octets */ 626 } 628 /* takes an on-the-wire LOC RR and prints it in zone file (human readable) 629 format. */ 630 char * 631 loc_ntoa(binary,ascii) 632 const u_char *binary; 633 char *ascii; 634 { 635 char tmpbuf[255*3]; 637 register char *cp; 638 register const u_char *rcp; 640 int latdeg, latmin, latsec, latsecfrac; 641 int longdeg, longmin, longsec, longsecfrac; 642 char northsouth, eastwest; 643 int altmeters, altfrac, altsign; 645 const int referencealt = 100000 * 100; 647 int32_t latval, longval, altval; 648 u_int32_t templ; 649 u_int8_t sizeval, hpval, vpval, versionval; 651 char *sizestr, *hpstr, *vpstr; 653 rcp = binary; 654 if (ascii) 655 cp = ascii; 656 else { 657 ascii = tmpbuf; 658 cp = tmpbuf; 659 } 661 versionval = *rcp++; 663 if (versionval) { 664 sprintf(cp,"; error: unknown LOC RR version"); 665 return (cp); 666 } 668 sizeval = *rcp++; 670 hpval = *rcp++; 671 vpval = *rcp++; 672 GETLONG(templ,rcp); 673 latval = (templ - (1<<31)); 675 GETLONG(templ,rcp); 676 longval = (templ - (1<<31)); 678 GETLONG(templ,rcp); 679 if (templ < referencealt) { /* below WGS 84 spheroid */ 680 altval = referencealt - templ; 681 altsign = -1; 682 } else { 683 altval = templ - referencealt; 684 altsign = 1; 685 } 687 if (latval < 0) { 688 northsouth = 'S'; 689 latval = -latval; 690 } 691 else 692 northsouth = 'N'; 694 latsecfrac = latval % 1000; 695 latval = latval / 1000; 696 latsec = latval % 60; 697 latval = latval / 60; 698 latmin = latval % 60; 699 latval = latval / 60; 700 latdeg = latval; 702 if (longval < 0) { 703 eastwest = 'W'; 704 longval = -longval; 705 } 706 else 707 eastwest = 'E'; 709 longsecfrac = longval % 1000; 710 longval = longval / 1000; 711 longsec = longval % 60; 712 longval = longval / 60; 713 longmin = longval % 60; 714 longval = longval / 60; 715 longdeg = longval; 717 altfrac = altval % 100; 718 altmeters = (altval / 100) * altsign; 719 sizestr = savestr(precsize_ntoa(sizeval)); 720 hpstr = savestr(precsize_ntoa(hpval)); 721 vpstr = savestr(precsize_ntoa(vpval)); 723 sprintf(cp, 724 "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm", 725 latdeg, latmin, latsec, latsecfrac, northsouth, 726 longdeg, longmin, longsec, longsecfrac, eastwest, 727 altmeters, altfrac, sizestr, hpstr, vpstr); 729 free(sizestr); 730 free(hpstr); 731 free(vpstr); 733 return (cp); 734 }