LCOV - code coverage report
Current view: top level - resolve - dns-type.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 53 100 53.0 %
Date: 2019-08-23 13:36:53 Functions: 16 19 84.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 32 62 51.6 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <sys/socket.h>
       4                 :            : #include <errno.h>
       5                 :            : 
       6                 :            : #include "dns-type.h"
       7                 :            : #include "parse-util.h"
       8                 :            : #include "string-util.h"
       9                 :            : 
      10                 :            : typedef const struct {
      11                 :            :         uint16_t type;
      12                 :            :         const char *name;
      13                 :            : } dns_type;
      14                 :            : 
      15                 :            : static const struct dns_type_name *
      16                 :            : lookup_dns_type (register const char *str, register GPERF_LEN_TYPE len);
      17                 :            : 
      18                 :            : #include "dns_type-from-name.h"
      19                 :            : #include "dns_type-to-name.h"
      20                 :            : 
      21                 :     131088 : int dns_type_from_string(const char *s) {
      22                 :            :         const struct dns_type_name *sc;
      23                 :            : 
      24         [ -  + ]:     131088 :         assert(s);
      25                 :            : 
      26                 :     131088 :         sc = lookup_dns_type(s, strlen(s));
      27         [ +  + ]:     131088 :         if (sc)
      28                 :        308 :                 return sc->id;
      29                 :            : 
      30                 :     130780 :         s = startswith_no_case(s, "TYPE");
      31         [ -  + ]:     130780 :         if (s) {
      32                 :            :                 unsigned x;
      33                 :            : 
      34         [ #  # ]:          0 :                 if (safe_atou(s, &x) >= 0 &&
      35         [ #  # ]:          0 :                     x <= UINT16_MAX)
      36                 :          0 :                         return (int) x;
      37                 :            :         }
      38                 :            : 
      39                 :     130780 :         return _DNS_TYPE_INVALID;
      40                 :            : }
      41                 :            : 
      42                 :       1484 : bool dns_type_is_pseudo(uint16_t type) {
      43                 :            : 
      44                 :            :         /* Checks whether the specified type is a "pseudo-type". What
      45                 :            :          * a "pseudo-type" precisely is, is defined only very weakly,
      46                 :            :          * but apparently entails all RR types that are not actually
      47                 :            :          * stored as RRs on the server and should hence also not be
      48                 :            :          * cached. We use this list primarily to validate NSEC type
      49                 :            :          * bitfields, and to verify what to cache. */
      50                 :            : 
      51         [ +  + ]:       1484 :         return IN_SET(type,
      52                 :            :                       0, /* A Pseudo RR type, according to RFC 2931 */
      53                 :            :                       DNS_TYPE_ANY,
      54                 :            :                       DNS_TYPE_AXFR,
      55                 :            :                       DNS_TYPE_IXFR,
      56                 :            :                       DNS_TYPE_OPT,
      57                 :            :                       DNS_TYPE_TSIG,
      58                 :            :                       DNS_TYPE_TKEY
      59                 :            :         );
      60                 :            : }
      61                 :            : 
      62                 :          8 : bool dns_class_is_pseudo(uint16_t class) {
      63                 :          8 :         return class == DNS_TYPE_ANY;
      64                 :            : }
      65                 :            : 
      66                 :        308 : bool dns_type_is_valid_query(uint16_t type) {
      67                 :            : 
      68                 :            :         /* The types valid as questions in packets */
      69                 :            : 
      70         [ +  + ]:        308 :         return !IN_SET(type,
      71                 :            :                        0,
      72                 :            :                        DNS_TYPE_OPT,
      73                 :            :                        DNS_TYPE_TSIG,
      74                 :            :                        DNS_TYPE_TKEY,
      75                 :            : 
      76                 :            :                        /* RRSIG are technically valid as questions, but we refuse doing explicit queries for them, as
      77                 :            :                         * they aren't really payload, but signatures for payload, and cannot be validated on their
      78                 :            :                         * own. After all they are the signatures, and have no signatures of their own validating
      79                 :            :                         * them. */
      80                 :            :                        DNS_TYPE_RRSIG);
      81                 :            : }
      82                 :            : 
      83                 :          0 : bool dns_type_is_zone_transer(uint16_t type) {
      84                 :            : 
      85                 :            :         /* Zone transfers, either normal or incremental */
      86                 :            : 
      87         [ #  # ]:          0 :         return IN_SET(type,
      88                 :            :                       DNS_TYPE_AXFR,
      89                 :            :                       DNS_TYPE_IXFR);
      90                 :            : }
      91                 :            : 
      92                 :       2212 : bool dns_type_is_valid_rr(uint16_t type) {
      93                 :            : 
      94                 :            :         /* The types valid as RR in packets (but not necessarily
      95                 :            :          * stored on servers). */
      96                 :            : 
      97         [ +  + ]:       2212 :         return !IN_SET(type,
      98                 :            :                        DNS_TYPE_ANY,
      99                 :            :                        DNS_TYPE_AXFR,
     100                 :            :                        DNS_TYPE_IXFR);
     101                 :            : }
     102                 :            : 
     103                 :       1912 : bool dns_class_is_valid_rr(uint16_t class) {
     104                 :       1912 :         return class != DNS_CLASS_ANY;
     105                 :            : }
     106                 :            : 
     107                 :        308 : bool dns_type_may_redirect(uint16_t type) {
     108                 :            :         /* The following record types should never be redirected using
     109                 :            :          * CNAME/DNAME RRs. See
     110                 :            :          * <https://tools.ietf.org/html/rfc4035#section-2.5>. */
     111                 :            : 
     112         [ +  + ]:        308 :         if (dns_type_is_pseudo(type))
     113                 :         24 :                 return false;
     114                 :            : 
     115         [ +  + ]:        284 :         return !IN_SET(type,
     116                 :            :                        DNS_TYPE_CNAME,
     117                 :            :                        DNS_TYPE_DNAME,
     118                 :            :                        DNS_TYPE_NSEC3,
     119                 :            :                        DNS_TYPE_NSEC,
     120                 :            :                        DNS_TYPE_RRSIG,
     121                 :            :                        DNS_TYPE_NXT,
     122                 :            :                        DNS_TYPE_SIG,
     123                 :            :                        DNS_TYPE_KEY);
     124                 :            : }
     125                 :            : 
     126                 :        308 : bool dns_type_may_wildcard(uint16_t type) {
     127                 :            : 
     128                 :            :         /* The following records may not be expanded from wildcard RRsets */
     129                 :            : 
     130         [ +  + ]:        308 :         if (dns_type_is_pseudo(type))
     131                 :         24 :                 return false;
     132                 :            : 
     133         [ +  + ]:        284 :         return !IN_SET(type,
     134                 :            :                        DNS_TYPE_NSEC3,
     135                 :            :                        DNS_TYPE_SOA,
     136                 :            : 
     137                 :            :                        /* Prohibited by https://tools.ietf.org/html/rfc4592#section-4.4 */
     138                 :            :                        DNS_TYPE_DNAME);
     139                 :            : }
     140                 :            : 
     141                 :        324 : bool dns_type_apex_only(uint16_t type) {
     142                 :            : 
     143                 :            :         /* Returns true for all RR types that may only appear signed in a zone apex */
     144                 :            : 
     145         [ +  + ]:        324 :         return IN_SET(type,
     146                 :            :                       DNS_TYPE_SOA,
     147                 :            :                       DNS_TYPE_NS,            /* this one can appear elsewhere, too, but not signed */
     148                 :            :                       DNS_TYPE_DNSKEY,
     149                 :            :                       DNS_TYPE_NSEC3PARAM);
     150                 :            : }
     151                 :            : 
     152                 :        308 : bool dns_type_is_dnssec(uint16_t type) {
     153         [ +  + ]:        308 :         return IN_SET(type,
     154                 :            :                       DNS_TYPE_DS,
     155                 :            :                       DNS_TYPE_DNSKEY,
     156                 :            :                       DNS_TYPE_RRSIG,
     157                 :            :                       DNS_TYPE_NSEC,
     158                 :            :                       DNS_TYPE_NSEC3,
     159                 :            :                       DNS_TYPE_NSEC3PARAM);
     160                 :            : }
     161                 :            : 
     162                 :        308 : bool dns_type_is_obsolete(uint16_t type) {
     163         [ +  + ]:        308 :         return IN_SET(type,
     164                 :            :                       /* Obsoleted by RFC 973 */
     165                 :            :                       DNS_TYPE_MD,
     166                 :            :                       DNS_TYPE_MF,
     167                 :            :                       DNS_TYPE_MAILA,
     168                 :            : 
     169                 :            :                       /* Kinda obsoleted by RFC 2505 */
     170                 :            :                       DNS_TYPE_MB,
     171                 :            :                       DNS_TYPE_MG,
     172                 :            :                       DNS_TYPE_MR,
     173                 :            :                       DNS_TYPE_MINFO,
     174                 :            :                       DNS_TYPE_MAILB,
     175                 :            : 
     176                 :            :                       /* RFC1127 kinda obsoleted this by recommending against its use */
     177                 :            :                       DNS_TYPE_WKS,
     178                 :            : 
     179                 :            :                       /* Declared historical by RFC 6563 */
     180                 :            :                       DNS_TYPE_A6,
     181                 :            : 
     182                 :            :                       /* Obsoleted by DNSSEC-bis */
     183                 :            :                       DNS_TYPE_NXT,
     184                 :            : 
     185                 :            :                       /* RFC 1035 removed support for concepts that needed this from RFC 883 */
     186                 :            :                       DNS_TYPE_NULL);
     187                 :            : }
     188                 :            : 
     189                 :        308 : bool dns_type_needs_authentication(uint16_t type) {
     190                 :            : 
     191                 :            :         /* Returns true for all (non-obsolete) RR types where records are not useful if they aren't
     192                 :            :          * authenticated. I.e. everything that contains crypto keys. */
     193                 :            : 
     194         [ +  + ]:        308 :         return IN_SET(type,
     195                 :            :                       DNS_TYPE_CERT,
     196                 :            :                       DNS_TYPE_SSHFP,
     197                 :            :                       DNS_TYPE_IPSECKEY,
     198                 :            :                       DNS_TYPE_DS,
     199                 :            :                       DNS_TYPE_DNSKEY,
     200                 :            :                       DNS_TYPE_TLSA,
     201                 :            :                       DNS_TYPE_CDNSKEY,
     202                 :            :                       DNS_TYPE_OPENPGPKEY,
     203                 :            :                       DNS_TYPE_CAA);
     204                 :            : }
     205                 :            : 
     206                 :          0 : int dns_type_to_af(uint16_t t) {
     207   [ #  #  #  # ]:          0 :         switch (t) {
     208                 :            : 
     209                 :          0 :         case DNS_TYPE_A:
     210                 :          0 :                 return AF_INET;
     211                 :            : 
     212                 :          0 :         case DNS_TYPE_AAAA:
     213                 :          0 :                 return AF_INET6;
     214                 :            : 
     215                 :          0 :         case DNS_TYPE_ANY:
     216                 :          0 :                 return AF_UNSPEC;
     217                 :            : 
     218                 :          0 :         default:
     219                 :          0 :                 return -EINVAL;
     220                 :            :         }
     221                 :            : }
     222                 :            : 
     223                 :       3952 : const char *dns_class_to_string(uint16_t class) {
     224                 :            : 
     225      [ +  +  + ]:       3952 :         switch (class) {
     226                 :            : 
     227                 :       2932 :         case DNS_CLASS_IN:
     228                 :       2932 :                 return "IN";
     229                 :            : 
     230                 :          4 :         case DNS_CLASS_ANY:
     231                 :          4 :                 return "ANY";
     232                 :            :         }
     233                 :            : 
     234                 :       1016 :         return NULL;
     235                 :            : }
     236                 :            : 
     237                 :          0 : int dns_class_from_string(const char *s) {
     238                 :            : 
     239         [ #  # ]:          0 :         if (!s)
     240                 :          0 :                 return _DNS_CLASS_INVALID;
     241                 :            : 
     242         [ #  # ]:          0 :         if (strcaseeq(s, "IN"))
     243                 :          0 :                 return DNS_CLASS_IN;
     244         [ #  # ]:          0 :         else if (strcaseeq(s, "ANY"))
     245                 :          0 :                 return DNS_CLASS_ANY;
     246                 :            : 
     247                 :          0 :         return _DNS_CLASS_INVALID;
     248                 :            : }
     249                 :            : 
     250                 :         24 : const char* tlsa_cert_usage_to_string(uint8_t cert_usage) {
     251                 :            : 
     252   [ +  -  -  -  :         24 :         switch (cert_usage) {
                   -  - ]
     253                 :            : 
     254                 :         24 :         case 0:
     255                 :         24 :                 return "CA constraint";
     256                 :            : 
     257                 :          0 :         case 1:
     258                 :          0 :                 return "Service certificate constraint";
     259                 :            : 
     260                 :          0 :         case 2:
     261                 :          0 :                 return "Trust anchor assertion";
     262                 :            : 
     263                 :          0 :         case 3:
     264                 :          0 :                 return "Domain-issued certificate";
     265                 :            : 
     266                 :          0 :         case 4 ... 254:
     267                 :          0 :                 return "Unassigned";
     268                 :            : 
     269                 :          0 :         case 255:
     270                 :          0 :                 return "Private use";
     271                 :            :         }
     272                 :            : 
     273                 :            :         return NULL;  /* clang cannot count that we covered everything */
     274                 :            : }
     275                 :            : 
     276                 :         24 : const char* tlsa_selector_to_string(uint8_t selector) {
     277   [ +  -  -  - ]:         24 :         switch (selector) {
     278                 :            : 
     279                 :         24 :         case 0:
     280                 :         24 :                 return "Full Certificate";
     281                 :            : 
     282                 :          0 :         case 1:
     283                 :          0 :                 return "SubjectPublicKeyInfo";
     284                 :            : 
     285                 :          0 :         case 2 ... 254:
     286                 :          0 :                 return "Unassigned";
     287                 :            : 
     288                 :          0 :         case 255:
     289                 :          0 :                 return "Private use";
     290                 :            :         }
     291                 :            : 
     292                 :            :         return NULL;
     293                 :            : }
     294                 :            : 
     295                 :         24 : const char* tlsa_matching_type_to_string(uint8_t selector) {
     296                 :            : 
     297   [ -  +  -  -  :         24 :         switch (selector) {
                      - ]
     298                 :            : 
     299                 :          0 :         case 0:
     300                 :          0 :                 return "No hash used";
     301                 :            : 
     302                 :         24 :         case 1:
     303                 :         24 :                 return "SHA-256";
     304                 :            : 
     305                 :          0 :         case 2:
     306                 :          0 :                 return "SHA-512";
     307                 :            : 
     308                 :          0 :         case 3 ... 254:
     309                 :          0 :                 return "Unassigned";
     310                 :            : 
     311                 :          0 :         case 255:
     312                 :          0 :                 return "Private use";
     313                 :            :         }
     314                 :            : 
     315                 :            :         return NULL;
     316                 :            : }

Generated by: LCOV version 1.14