loc_29.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004, 2005, 2007, 2009  Internet Systems Consortium, Inc. ("ISC")
00003  * Copyright (C) 1999-2003  Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and/or distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00010  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00011  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00012  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00013  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00014  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00015  * PERFORMANCE OF THIS SOFTWARE.
00016  */
00017 
00018 /* $Id: loc_29.c,v 1.50 2009/12/04 21:09:33 marka Exp $ */
00019 
00020 /* Reviewed: Wed Mar 15 18:13:09 PST 2000 by explorer */
00021 
00022 /* RFC1876 */
00023 
00024 #ifndef RDATA_GENERIC_LOC_29_C
00025 #define RDATA_GENERIC_LOC_29_C
00026 
00027 #define RRTYPE_LOC_ATTRIBUTES (0)
00028 
00029 static inline isc_result_t
00030 fromtext_loc(ARGS_FROMTEXT) {
00031         isc_token_t token;
00032         int d1, m1, s1;
00033         int d2, m2, s2;
00034         unsigned char size;
00035         unsigned char hp;
00036         unsigned char vp;
00037         unsigned char version;
00038         isc_boolean_t east = ISC_FALSE;
00039         isc_boolean_t north = ISC_FALSE;
00040         long tmp;
00041         long m;
00042         long cm;
00043         long poweroften[8] = { 1, 10, 100, 1000,
00044                                10000, 100000, 1000000, 10000000 };
00045         int man;
00046         int exp;
00047         char *e;
00048         int i;
00049         unsigned long latitude;
00050         unsigned long longitude;
00051         unsigned long altitude;
00052 
00053         REQUIRE(type == 29);
00054 
00055         UNUSED(type);
00056         UNUSED(rdclass);
00057         UNUSED(origin);
00058         UNUSED(options);
00059 
00060         /*
00061          * Defaults.
00062          */
00063         m1 = s1 = 0;
00064         m2 = s2 = 0;
00065         size = 0x12;    /* 1.00m */
00066         hp = 0x16;      /* 10000.00 m */
00067         vp = 0x13;      /* 10.00 m */
00068         version = 0;
00069 
00070         /*
00071          * Degrees.
00072          */
00073         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
00074                                       ISC_FALSE));
00075         if (token.value.as_ulong > 90U)
00076                 RETTOK(ISC_R_RANGE);
00077         d1 = (int)token.value.as_ulong;
00078         /*
00079          * Minutes.
00080          */
00081         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00082                                       ISC_FALSE));
00083         if (strcasecmp(DNS_AS_STR(token), "N") == 0)
00084                 north = ISC_TRUE;
00085         if (north || strcasecmp(DNS_AS_STR(token), "S") == 0)
00086                 goto getlong;
00087         m1 = strtol(DNS_AS_STR(token), &e, 10);
00088         if (*e != 0)
00089                 RETTOK(DNS_R_SYNTAX);
00090         if (m1 < 0 || m1 > 59)
00091                 RETTOK(ISC_R_RANGE);
00092         if (d1 == 90 && m1 != 0)
00093                 RETTOK(ISC_R_RANGE);
00094 
00095         /*
00096          * Seconds.
00097          */
00098         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00099                                       ISC_FALSE));
00100         if (strcasecmp(DNS_AS_STR(token), "N") == 0)
00101                 north = ISC_TRUE;
00102         if (north || strcasecmp(DNS_AS_STR(token), "S") == 0)
00103                 goto getlong;
00104         s1 = strtol(DNS_AS_STR(token), &e, 10);
00105         if (*e != 0 && *e != '.')
00106                 RETTOK(DNS_R_SYNTAX);
00107         if (s1 < 0 || s1 > 59)
00108                 RETTOK(ISC_R_RANGE);
00109         if (*e == '.') {
00110                 const char *l;
00111                 e++;
00112                 for (i = 0; i < 3; i++) {
00113                         if (*e == 0)
00114                                 break;
00115                         if ((tmp = decvalue(*e++)) < 0)
00116                                 RETTOK(DNS_R_SYNTAX);
00117                         s1 *= 10;
00118                         s1 += tmp;
00119                 }
00120                 for (; i < 3; i++)
00121                         s1 *= 10;
00122                 l = e;
00123                 while (*e != 0) {
00124                         if (decvalue(*e++) < 0)
00125                                 RETTOK(DNS_R_SYNTAX);
00126                 }
00127                 if (*l != '\0' && callbacks != NULL) {
00128                         const char *file = isc_lex_getsourcename(lexer);
00129                         unsigned long line = isc_lex_getsourceline(lexer);
00130 
00131                         if (file == NULL)
00132                                 file = "UNKNOWN";
00133                         (*callbacks->warn)(callbacks, "%s: %s:%u: '%s' extra "
00134                                            "precision digits ignored",
00135                                            "dns_rdata_fromtext", file, line,
00136                                            DNS_AS_STR(token));
00137                 }
00138         } else
00139                 s1 *= 1000;
00140         if (d1 == 90 && s1 != 0)
00141                 RETTOK(ISC_R_RANGE);
00142 
00143         /*
00144          * Direction.
00145          */
00146         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00147                                       ISC_FALSE));
00148         if (strcasecmp(DNS_AS_STR(token), "N") == 0)
00149                 north = ISC_TRUE;
00150         if (!north && strcasecmp(DNS_AS_STR(token), "S") != 0)
00151                 RETTOK(DNS_R_SYNTAX);
00152 
00153  getlong:
00154         /*
00155          * Degrees.
00156          */
00157         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
00158                                       ISC_FALSE));
00159         if (token.value.as_ulong > 180U)
00160                 RETTOK(ISC_R_RANGE);
00161         d2 = (int)token.value.as_ulong;
00162 
00163         /*
00164          * Minutes.
00165          */
00166         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00167                                       ISC_FALSE));
00168         if (strcasecmp(DNS_AS_STR(token), "E") == 0)
00169                 east = ISC_TRUE;
00170         if (east || strcasecmp(DNS_AS_STR(token), "W") == 0)
00171                 goto getalt;
00172         m2 = strtol(DNS_AS_STR(token), &e, 10);
00173         if (*e != 0)
00174                 RETTOK(DNS_R_SYNTAX);
00175         if (m2 < 0 || m2 > 59)
00176                 RETTOK(ISC_R_RANGE);
00177         if (d2 == 180 && m2 != 0)
00178                 RETTOK(ISC_R_RANGE);
00179 
00180         /*
00181          * Seconds.
00182          */
00183         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00184                                       ISC_FALSE));
00185         if (strcasecmp(DNS_AS_STR(token), "E") == 0)
00186                 east = ISC_TRUE;
00187         if (east || strcasecmp(DNS_AS_STR(token), "W") == 0)
00188                 goto getalt;
00189         s2 = strtol(DNS_AS_STR(token), &e, 10);
00190         if (*e != 0 && *e != '.')
00191                 RETTOK(DNS_R_SYNTAX);
00192         if (s2 < 0 || s2 > 59)
00193                 RETTOK(ISC_R_RANGE);
00194         if (*e == '.') {
00195                 const char *l;
00196                 e++;
00197                 for (i = 0; i < 3; i++) {
00198                         if (*e == 0)
00199                                 break;
00200                         if ((tmp = decvalue(*e++)) < 0)
00201                                 RETTOK(DNS_R_SYNTAX);
00202                         s2 *= 10;
00203                         s2 += tmp;
00204                 }
00205                 for (; i < 3; i++)
00206                         s2 *= 10;
00207                 l = e;
00208                 while (*e != 0) {
00209                         if (decvalue(*e++) < 0)
00210                                 RETTOK(DNS_R_SYNTAX);
00211                 }
00212                 if (*l != '\0' && callbacks != NULL) {
00213                         const char *file = isc_lex_getsourcename(lexer);
00214                         unsigned long line = isc_lex_getsourceline(lexer);
00215 
00216                         if (file == NULL)
00217                                 file = "UNKNOWN";
00218                         (*callbacks->warn)(callbacks, "%s: %s:%u: '%s' extra "
00219                                            "precision digits ignored",
00220                                            "dns_rdata_fromtext",
00221                                            file, line, DNS_AS_STR(token));
00222                 }
00223         } else
00224                 s2 *= 1000;
00225         if (d2 == 180 && s2 != 0)
00226                 RETTOK(ISC_R_RANGE);
00227 
00228         /*
00229          * Direction.
00230          */
00231         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00232                                       ISC_FALSE));
00233         if (strcasecmp(DNS_AS_STR(token), "E") == 0)
00234                 east = ISC_TRUE;
00235         if (!east && strcasecmp(DNS_AS_STR(token), "W") != 0)
00236                 RETTOK(DNS_R_SYNTAX);
00237 
00238  getalt:
00239         /*
00240          * Altitude.
00241          */
00242         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00243                                       ISC_FALSE));
00244         m = strtol(DNS_AS_STR(token), &e, 10);
00245         if (*e != 0 && *e != '.' && *e != 'm')
00246                 RETTOK(DNS_R_SYNTAX);
00247         if (m < -100000 || m > 42849672)
00248                 RETTOK(ISC_R_RANGE);
00249         cm = 0;
00250         if (*e == '.') {
00251                 e++;
00252                 for (i = 0; i < 2; i++) {
00253                         if (*e == 0 || *e == 'm')
00254                                 break;
00255                         if ((tmp = decvalue(*e++)) < 0)
00256                                 return (DNS_R_SYNTAX);
00257                         cm *= 10;
00258                         if (m < 0)
00259                                 cm -= tmp;
00260                         else
00261                                 cm += tmp;
00262                 }
00263                 for (; i < 2; i++)
00264                         cm *= 10;
00265         }
00266         if (*e == 'm')
00267                 e++;
00268         if (*e != 0)
00269                 RETTOK(DNS_R_SYNTAX);
00270         if (m == -100000 && cm != 0)
00271                 RETTOK(ISC_R_RANGE);
00272         if (m == 42849672 && cm > 95)
00273                 RETTOK(ISC_R_RANGE);
00274         /*
00275          * Adjust base.
00276          */
00277         altitude = m + 100000;
00278         altitude *= 100;
00279         altitude += cm;
00280 
00281         /*
00282          * Size: optional.
00283          */
00284         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00285                                       ISC_TRUE));
00286         if (token.type == isc_tokentype_eol ||
00287             token.type == isc_tokentype_eof) {
00288                 isc_lex_ungettoken(lexer, &token);
00289                 goto encode;
00290         }
00291         m = strtol(DNS_AS_STR(token), &e, 10);
00292         if (*e != 0 && *e != '.' && *e != 'm')
00293                 RETTOK(DNS_R_SYNTAX);
00294         if (m < 0 || m > 90000000)
00295                 RETTOK(ISC_R_RANGE);
00296         cm = 0;
00297         if (*e == '.') {
00298                 e++;
00299                 for (i = 0; i < 2; i++) {
00300                         if (*e == 0 || *e == 'm')
00301                                 break;
00302                         if ((tmp = decvalue(*e++)) < 0)
00303                                 RETTOK(DNS_R_SYNTAX);
00304                         cm *= 10;
00305                         cm += tmp;
00306                 }
00307                 for (; i < 2; i++)
00308                         cm *= 10;
00309         }
00310         if (*e == 'm')
00311                 e++;
00312         if (*e != 0)
00313                 RETTOK(DNS_R_SYNTAX);
00314         /*
00315          * We don't just multiply out as we will overflow.
00316          */
00317         if (m > 0) {
00318                 for (exp = 0; exp < 7; exp++)
00319                         if (m < poweroften[exp+1])
00320                                 break;
00321                 man = m / poweroften[exp];
00322                 exp += 2;
00323         } else {
00324                 if (cm >= 10) {
00325                         man = cm / 10;
00326                         exp = 1;
00327                 } else {
00328                         man = cm;
00329                         exp = 0;
00330                 }
00331         }
00332         size = (man << 4) + exp;
00333 
00334         /*
00335          * Horizontal precision: optional.
00336          */
00337         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00338                                       ISC_TRUE));
00339         if (token.type == isc_tokentype_eol ||
00340             token.type == isc_tokentype_eof) {
00341                 isc_lex_ungettoken(lexer, &token);
00342                 goto encode;
00343         }
00344         m = strtol(DNS_AS_STR(token), &e, 10);
00345         if (*e != 0 && *e != '.' && *e != 'm')
00346                 RETTOK(DNS_R_SYNTAX);
00347         if (m < 0 || m > 90000000)
00348                 RETTOK(ISC_R_RANGE);
00349         cm = 0;
00350         if (*e == '.') {
00351                 e++;
00352                 for (i = 0; i < 2; i++) {
00353                         if (*e == 0 || *e == 'm')
00354                                 break;
00355                         if ((tmp = decvalue(*e++)) < 0)
00356                                 RETTOK(DNS_R_SYNTAX);
00357                         cm *= 10;
00358                         cm += tmp;
00359                 }
00360                 for (; i < 2; i++)
00361                         cm *= 10;
00362         }
00363         if (*e == 'm')
00364                 e++;
00365         if (*e != 0)
00366                 RETTOK(DNS_R_SYNTAX);
00367         /*
00368          * We don't just multiply out as we will overflow.
00369          */
00370         if (m > 0) {
00371                 for (exp = 0; exp < 7; exp++)
00372                         if (m < poweroften[exp+1])
00373                                 break;
00374                 man = m / poweroften[exp];
00375                 exp += 2;
00376         } else if (cm >= 10) {
00377                 man = cm / 10;
00378                 exp = 1;
00379         } else  {
00380                 man = cm;
00381                 exp = 0;
00382         }
00383         hp = (man << 4) + exp;
00384 
00385         /*
00386          * Vertical precision: optional.
00387          */
00388         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
00389                                       ISC_TRUE));
00390         if (token.type == isc_tokentype_eol ||
00391             token.type == isc_tokentype_eof) {
00392                 isc_lex_ungettoken(lexer, &token);
00393                 goto encode;
00394         }
00395         m = strtol(DNS_AS_STR(token), &e, 10);
00396         if (*e != 0 && *e != '.' && *e != 'm')
00397                 RETTOK(DNS_R_SYNTAX);
00398         if (m < 0 || m > 90000000)
00399                 RETTOK(ISC_R_RANGE);
00400         cm = 0;
00401         if (*e == '.') {
00402                 e++;
00403                 for (i = 0; i < 2; i++) {
00404                         if (*e == 0 || *e == 'm')
00405                                 break;
00406                         if ((tmp = decvalue(*e++)) < 0)
00407                                 RETTOK(DNS_R_SYNTAX);
00408                         cm *= 10;
00409                         cm += tmp;
00410                 }
00411                 for (; i < 2; i++)
00412                         cm *= 10;
00413         }
00414         if (*e == 'm')
00415                 e++;
00416         if (*e != 0)
00417                 RETTOK(DNS_R_SYNTAX);
00418         /*
00419          * We don't just multiply out as we will overflow.
00420          */
00421         if (m > 0) {
00422                 for (exp = 0; exp < 7; exp++)
00423                         if (m < poweroften[exp+1])
00424                                 break;
00425                 man = m / poweroften[exp];
00426                 exp += 2;
00427         } else if (cm >= 10) {
00428                 man = cm / 10;
00429                 exp = 1;
00430         } else {
00431                 man = cm;
00432                 exp = 0;
00433         }
00434         vp = (man << 4) + exp;
00435 
00436  encode:
00437         RETERR(mem_tobuffer(target, &version, 1));
00438         RETERR(mem_tobuffer(target, &size, 1));
00439         RETERR(mem_tobuffer(target, &hp, 1));
00440         RETERR(mem_tobuffer(target, &vp, 1));
00441         if (north)
00442                 latitude = 0x80000000 + ( d1 * 3600 + m1 * 60 ) * 1000 + s1;
00443         else
00444                 latitude = 0x80000000 - ( d1 * 3600 + m1 * 60 ) * 1000 - s1;
00445         RETERR(uint32_tobuffer(latitude, target));
00446 
00447         if (east)
00448                 longitude = 0x80000000 + ( d2 * 3600 + m2 * 60 ) * 1000 + s2;
00449         else
00450                 longitude = 0x80000000 - ( d2 * 3600 + m2 * 60 ) * 1000 - s2;
00451         RETERR(uint32_tobuffer(longitude, target));
00452 
00453         return (uint32_tobuffer(altitude, target));
00454 }
00455 
00456 static inline isc_result_t
00457 totext_loc(ARGS_TOTEXT) {
00458         int d1, m1, s1, fs1;
00459         int d2, m2, s2, fs2;
00460         unsigned long latitude;
00461         unsigned long longitude;
00462         unsigned long altitude;
00463         isc_boolean_t north;
00464         isc_boolean_t east;
00465         isc_boolean_t below;
00466         isc_region_t sr;
00467         char buf[sizeof("89 59 59.999 N 179 59 59.999 E "
00468                         "42849672.95m 90000000m 90000000m 90000000m")];
00469         char sbuf[sizeof("90000000m")];
00470         char hbuf[sizeof("90000000m")];
00471         char vbuf[sizeof("90000000m")];
00472         unsigned char size, hp, vp;
00473         unsigned long poweroften[8] = { 1, 10, 100, 1000,
00474                                         10000, 100000, 1000000, 10000000 };
00475 
00476         UNUSED(tctx);
00477 
00478         REQUIRE(rdata->type == 29);
00479         REQUIRE(rdata->length != 0);
00480 
00481         dns_rdata_toregion(rdata, &sr);
00482 
00483         /* version = sr.base[0]; */
00484         size = sr.base[1];
00485         INSIST((size&0x0f) < 10 && (size>>4) < 10);
00486         if ((size&0x0f)> 1)
00487                 sprintf(sbuf, "%lum", (size>>4) * poweroften[(size&0x0f)-2]);
00488         else
00489                 sprintf(sbuf, "0.%02lum", (size>>4) * poweroften[(size&0x0f)]);
00490         hp = sr.base[2];
00491         INSIST((hp&0x0f) < 10 && (hp>>4) < 10);
00492         if ((hp&0x0f)> 1)
00493                 sprintf(hbuf, "%lum", (hp>>4) * poweroften[(hp&0x0f)-2]);
00494         else
00495                 sprintf(hbuf, "0.%02lum", (hp>>4) * poweroften[(hp&0x0f)]);
00496         vp = sr.base[3];
00497         INSIST((vp&0x0f) < 10 && (vp>>4) < 10);
00498         if ((vp&0x0f)> 1)
00499                 sprintf(vbuf, "%lum", (vp>>4) * poweroften[(vp&0x0f)-2]);
00500         else
00501                 sprintf(vbuf, "0.%02lum", (vp>>4) * poweroften[(vp&0x0f)]);
00502         isc_region_consume(&sr, 4);
00503 
00504         latitude = uint32_fromregion(&sr);
00505         isc_region_consume(&sr, 4);
00506         if (latitude >= 0x80000000) {
00507                 north = ISC_TRUE;
00508                 latitude -= 0x80000000;
00509         } else {
00510                 north = ISC_FALSE;
00511                 latitude = 0x80000000 - latitude;
00512         }
00513         fs1 = (int)(latitude % 1000);
00514         latitude /= 1000;
00515         s1 = (int)(latitude % 60);
00516         latitude /= 60;
00517         m1 = (int)(latitude % 60);
00518         latitude /= 60;
00519         d1 = (int)latitude;
00520         INSIST(latitude <= 90U);
00521 
00522         longitude = uint32_fromregion(&sr);
00523         isc_region_consume(&sr, 4);
00524         if (longitude >= 0x80000000) {
00525                 east = ISC_TRUE;
00526                 longitude -= 0x80000000;
00527         } else {
00528                 east = ISC_FALSE;
00529                 longitude = 0x80000000 - longitude;
00530         }
00531         fs2 = (int)(longitude % 1000);
00532         longitude /= 1000;
00533         s2 = (int)(longitude % 60);
00534         longitude /= 60;
00535         m2 = (int)(longitude % 60);
00536         longitude /= 60;
00537         d2 = (int)longitude;
00538         INSIST(longitude <= 180U);
00539 
00540         altitude = uint32_fromregion(&sr);
00541         isc_region_consume(&sr, 4);
00542         if (altitude < 10000000U) {
00543                 below = ISC_TRUE;
00544                 altitude = 10000000 - altitude;
00545         } else {
00546                 below =ISC_FALSE;
00547                 altitude -= 10000000;
00548         }
00549 
00550         sprintf(buf, "%d %d %d.%03d %s %d %d %d.%03d %s %s%ld.%02ldm %s %s %s",
00551                 d1, m1, s1, fs1, north ? "N" : "S",
00552                 d2, m2, s2, fs2, east ? "E" : "W",
00553                 below ? "-" : "", altitude/100, altitude % 100,
00554                 sbuf, hbuf, vbuf);
00555 
00556         return (str_totext(buf, target));
00557 }
00558 
00559 static inline isc_result_t
00560 fromwire_loc(ARGS_FROMWIRE) {
00561         isc_region_t sr;
00562         unsigned char c;
00563         unsigned long latitude;
00564         unsigned long longitude;
00565 
00566         REQUIRE(type == 29);
00567 
00568         UNUSED(type);
00569         UNUSED(rdclass);
00570         UNUSED(dctx);
00571         UNUSED(options);
00572 
00573         isc_buffer_activeregion(source, &sr);
00574         if (sr.length < 1)
00575                 return (ISC_R_UNEXPECTEDEND);
00576         if (sr.base[0] != 0)
00577                 return (ISC_R_NOTIMPLEMENTED);
00578         if (sr.length < 16)
00579                 return (ISC_R_UNEXPECTEDEND);
00580 
00581         /*
00582          * Size.
00583          */
00584         c = sr.base[1];
00585         if (c != 0)
00586                 if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0)
00587                         return (ISC_R_RANGE);
00588 
00589         /*
00590          * Horizontal precision.
00591          */
00592         c = sr.base[2];
00593         if (c != 0)
00594                 if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0)
00595                         return (ISC_R_RANGE);
00596 
00597         /*
00598          * Vertical precision.
00599          */
00600         c = sr.base[3];
00601         if (c != 0)
00602                 if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0)
00603                         return (ISC_R_RANGE);
00604         isc_region_consume(&sr, 4);
00605 
00606         /*
00607          * Latitude.
00608          */
00609         latitude = uint32_fromregion(&sr);
00610         if (latitude < (0x80000000UL - 90 * 3600000) ||
00611             latitude > (0x80000000UL + 90 * 3600000))
00612                 return (ISC_R_RANGE);
00613         isc_region_consume(&sr, 4);
00614 
00615         /*
00616          * Longitude.
00617          */
00618         longitude = uint32_fromregion(&sr);
00619         if (longitude < (0x80000000UL - 180 * 3600000) ||
00620             longitude > (0x80000000UL + 180 * 3600000))
00621                 return (ISC_R_RANGE);
00622 
00623         /*
00624          * Altitude.
00625          * All values possible.
00626          */
00627 
00628         isc_buffer_activeregion(source, &sr);
00629         isc_buffer_forward(source, 16);
00630         return (mem_tobuffer(target, sr.base, 16));
00631 }
00632 
00633 static inline isc_result_t
00634 towire_loc(ARGS_TOWIRE) {
00635         UNUSED(cctx);
00636 
00637         REQUIRE(rdata->type == 29);
00638         REQUIRE(rdata->length != 0);
00639 
00640         return (mem_tobuffer(target, rdata->data, rdata->length));
00641 }
00642 
00643 static inline int
00644 compare_loc(ARGS_COMPARE) {
00645         isc_region_t r1;
00646         isc_region_t r2;
00647 
00648         REQUIRE(rdata1->type == rdata2->type);
00649         REQUIRE(rdata1->rdclass == rdata2->rdclass);
00650         REQUIRE(rdata1->type == 29);
00651         REQUIRE(rdata1->length != 0);
00652         REQUIRE(rdata2->length != 0);
00653 
00654         dns_rdata_toregion(rdata1, &r1);
00655         dns_rdata_toregion(rdata2, &r2);
00656         return (isc_region_compare(&r1, &r2));
00657 }
00658 
00659 static inline isc_result_t
00660 fromstruct_loc(ARGS_FROMSTRUCT) {
00661         dns_rdata_loc_t *loc = source;
00662         isc_uint8_t c;
00663 
00664         REQUIRE(type == 29);
00665         REQUIRE(source != NULL);
00666         REQUIRE(loc->common.rdtype == type);
00667         REQUIRE(loc->common.rdclass == rdclass);
00668 
00669         UNUSED(type);
00670         UNUSED(rdclass);
00671 
00672         if (loc->v.v0.version != 0)
00673                 return (ISC_R_NOTIMPLEMENTED);
00674         RETERR(uint8_tobuffer(loc->v.v0.version, target));
00675 
00676         c = loc->v.v0.size;
00677         if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0)
00678                 return (ISC_R_RANGE);
00679         RETERR(uint8_tobuffer(loc->v.v0.size, target));
00680 
00681         c = loc->v.v0.horizontal;
00682         if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0)
00683                 return (ISC_R_RANGE);
00684         RETERR(uint8_tobuffer(loc->v.v0.horizontal, target));
00685 
00686         c = loc->v.v0.vertical;
00687         if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0)
00688                 return (ISC_R_RANGE);
00689         RETERR(uint8_tobuffer(loc->v.v0.vertical, target));
00690 
00691         if (loc->v.v0.latitude < (0x80000000UL - 90 * 3600000) ||
00692             loc->v.v0.latitude > (0x80000000UL + 90 * 3600000))
00693                 return (ISC_R_RANGE);
00694         RETERR(uint32_tobuffer(loc->v.v0.latitude, target));
00695 
00696         if (loc->v.v0.longitude < (0x80000000UL - 180 * 3600000) ||
00697             loc->v.v0.longitude > (0x80000000UL + 180 * 3600000))
00698                 return (ISC_R_RANGE);
00699         RETERR(uint32_tobuffer(loc->v.v0.longitude, target));
00700         return (uint32_tobuffer(loc->v.v0.altitude, target));
00701 }
00702 
00703 static inline isc_result_t
00704 tostruct_loc(ARGS_TOSTRUCT) {
00705         dns_rdata_loc_t *loc = target;
00706         isc_region_t r;
00707         isc_uint8_t version;
00708 
00709         REQUIRE(rdata->type == 29);
00710         REQUIRE(target != NULL);
00711         REQUIRE(rdata->length != 0);
00712 
00713         UNUSED(mctx);
00714 
00715         dns_rdata_toregion(rdata, &r);
00716         version = uint8_fromregion(&r);
00717         if (version != 0)
00718                 return (ISC_R_NOTIMPLEMENTED);
00719 
00720         loc->common.rdclass = rdata->rdclass;
00721         loc->common.rdtype = rdata->type;
00722         ISC_LINK_INIT(&loc->common, link);
00723 
00724         loc->v.v0.version = version;
00725         isc_region_consume(&r, 1);
00726         loc->v.v0.size = uint8_fromregion(&r);
00727         isc_region_consume(&r, 1);
00728         loc->v.v0.horizontal = uint8_fromregion(&r);
00729         isc_region_consume(&r, 1);
00730         loc->v.v0.vertical = uint8_fromregion(&r);
00731         isc_region_consume(&r, 1);
00732         loc->v.v0.latitude = uint32_fromregion(&r);
00733         isc_region_consume(&r, 4);
00734         loc->v.v0.longitude = uint32_fromregion(&r);
00735         isc_region_consume(&r, 4);
00736         loc->v.v0.altitude = uint32_fromregion(&r);
00737         isc_region_consume(&r, 4);
00738         return (ISC_R_SUCCESS);
00739 }
00740 
00741 static inline void
00742 freestruct_loc(ARGS_FREESTRUCT) {
00743         dns_rdata_loc_t *loc = source;
00744 
00745         REQUIRE(source != NULL);
00746         REQUIRE(loc->common.rdtype == 29);
00747 
00748         UNUSED(source);
00749         UNUSED(loc);
00750 }
00751 
00752 static inline isc_result_t
00753 additionaldata_loc(ARGS_ADDLDATA) {
00754         REQUIRE(rdata->type == 29);
00755 
00756         UNUSED(rdata);
00757         UNUSED(add);
00758         UNUSED(arg);
00759 
00760         return (ISC_R_SUCCESS);
00761 }
00762 
00763 static inline isc_result_t
00764 digest_loc(ARGS_DIGEST) {
00765         isc_region_t r;
00766 
00767         REQUIRE(rdata->type == 29);
00768 
00769         dns_rdata_toregion(rdata, &r);
00770 
00771         return ((digest)(arg, &r));
00772 }
00773 
00774 static inline isc_boolean_t
00775 checkowner_loc(ARGS_CHECKOWNER) {
00776 
00777         REQUIRE(type == 29);
00778 
00779         UNUSED(name);
00780         UNUSED(type);
00781         UNUSED(rdclass);
00782         UNUSED(wildcard);
00783 
00784         return (ISC_TRUE);
00785 }
00786 
00787 static inline isc_boolean_t
00788 checknames_loc(ARGS_CHECKNAMES) {
00789 
00790         REQUIRE(rdata->type == 29);
00791 
00792         UNUSED(rdata);
00793         UNUSED(owner);
00794         UNUSED(bad);
00795 
00796         return (ISC_TRUE);
00797 }
00798 
00799 static inline int
00800 casecompare_loc(ARGS_COMPARE) {
00801         return (compare_loc(rdata1, rdata2));
00802 }
00803 
00804 #endif  /* RDATA_GENERIC_LOC_29_C */

Generated on Tue Apr 28 17:40:59 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha