1
2 const char *
wdns_rrclass_to_str(uint16_t rrclass)3 wdns_rrclass_to_str(uint16_t rrclass)
4 {
5 switch (rrclass) {
6 case WDNS_CLASS_IN: return ("IN");
7 case WDNS_CLASS_CH: return ("CH");
8 case WDNS_CLASS_HS: return ("HS");
9 case WDNS_CLASS_NONE: return ("NONE");
10 case WDNS_CLASS_ANY: return ("ANY");
11 }
12
13 return (NULL);
14 }
15
16 static struct u16str {
17 uint16_t u16;
18 const char *str;
19 } rrclasses[] = {
20 { WDNS_CLASS_ANY, "ANY" },
21 { WDNS_CLASS_CH, "CH" },
22 { WDNS_CLASS_HS, "HS" },
23 { WDNS_CLASS_IN, "IN" },
24 { WDNS_CLASS_NONE, "NONE" },
25 };
26
27 #define num_rrclasses (sizeof(rrclasses) / sizeof(struct u16str))
28
29 static int
cmp_u16str(const void * a,const void * b)30 cmp_u16str(const void *a, const void *b) {
31 struct u16str *u1 = (struct u16str *) a;
32 struct u16str *u2 = (struct u16str *) b;
33 return (strcasecmp(u1->str, u2->str));
34 }
35
36 static bool
convert_generic_rrclass(const char * s,long int * val)37 convert_generic_rrclass(const char *s, long int *val) {
38 char *endptr = NULL;
39
40 if (strlen(s) <= 5)
41 return (false);
42 if (strncasecmp(s, "CLASS", 5) != 0)
43 return (false);
44
45 s += 5; /* skip leading "CLASS" */
46
47 *val = strtol(s, &endptr, 10);
48 if (endptr != NULL && *endptr != '\0')
49 return (false);
50 if (*val < 0 || *val > 65535)
51 return (false);
52
53 return (true);
54 }
55
56 uint16_t
wdns_str_to_rrclass(const char * str)57 wdns_str_to_rrclass(const char *str) {
58 struct u16str key, *res;
59 key.str = str;
60 res = bsearch(&key, rrclasses, num_rrclasses, sizeof(struct u16str), cmp_u16str);
61 if (res != NULL) {
62 return (res->u16);
63 } else {
64 long int val = 0;
65 if (convert_generic_rrclass(str, &val))
66 return (val);
67 }
68 return (0);
69 }
70