void setup_globals(pmOptions *opts) { pmID pmids[HOST_NMETRICS]; pmDesc descs[HOST_NMETRICS]; pmResult *result; setup_context(opts); setup_metrics(hostmetrics, &pmids[0], &descs[0], HOST_NMETRICS); fetch_metrics("host", HOST_NMETRICS, pmids, &result); if (HOST_NMETRICS != result->numpmid) { fprintf(stderr, "%s: pmFetch failed to fetch initial metric value(s)\n", pmProgname); cleanstop(1); } hertz = extract_integer(result, descs, HOST_HERTZ); pagesize = extract_integer(result, descs, HOST_PAGESIZE); extract_string(result, descs, HOST_RELEASE, sysname.release, sizeof(sysname.release)); extract_string(result, descs, HOST_VERSION, sysname.version, sizeof(sysname.version)); extract_string(result, descs, HOST_MACHINE, sysname.machine, sizeof(sysname.machine)); extract_string(result, descs, HOST_NODENAME, sysname.nodename, sizeof(sysname.nodename)); nodenamelen = strlen(sysname.nodename); pmFreeResult(result); }
void load_database_contexts(Context_Map* context_map) { int prefix_mask {}; std::ifstream buf; buf.open(DBCONFIG_FILE); assert(buf.is_open()); std::string line {}; while (!buf.eof()) { getline(buf,line); if (ignore_line(line)) continue; else if (str_contains(line,'@')) { int port {}; std::string host {}; int db_num {}; // Complete at 00000111 (7) // One bit is set each time one of the above is found. // This allows for any number of newlines or comments. uint8_t completion {}; Prefix p {match_prefix(prefix_mask, line)}; while ((completion != 7) && !buf.eof()) { getline(buf,line); if (ignore_line(line)) continue; else if (str_contains(line,"port")) { port = extract_integer(line); completion |= 1; } else if (str_contains(line, "number")) { db_num = extract_integer(line); completion |= 2; } else if (str_contains(line, "host")) { host = extract_host(line); completion |= 4; } } assert(completion==7); Redis::Context* c = new Redis::Context(); c->port = port; c->host = host; c->db_num = db_num; context_map->set(p,c); assert(context_map->get(p)); } } buf.close(); assert(prefix_mask >= max_prefix_mask); assert(context_map); }
static struct rr* dlv_parse(char *name, long ttl, int type, char *s) { struct rr_dlv *rr = getmem(sizeof(*rr)); int key_tag, algorithm, digest_type; key_tag = extract_integer(&s, "key tag", NULL); if (key_tag < 0) return NULL; rr->key_tag = key_tag; algorithm = extract_algorithm(&s, "algorithm"); if (algorithm == ALG_UNSUPPORTED) return NULL; rr->algorithm = algorithm; digest_type = extract_integer(&s, "digest type", NULL); if (digest_type < 0) return NULL; rr->digest_type = digest_type; rr->digest = extract_hex_binary_data(&s, "digest", EXTRACT_EAT_WHITESPACE); if (rr->digest.length < 0) return NULL; switch (digest_type) { case 1: if (rr->digest.length != SHA1_BYTES) { return bitch("wrong SHA-1 digest length: %d bytes found, %d bytes expected", rr->digest.length, SHA1_BYTES); } break; case 2: if (rr->digest.length != SHA256_BYTES) { return bitch("wrong SHA-256 digest length: %d bytes found, %d bytes expected", rr->digest.length, SHA256_BYTES); } break; case 3: if (rr->digest.length != GOST_BYTES) { return bitch("wrong GOST R 34.11-94 digest length: %d bytes found, %d bytes expected", rr->digest.length, GOST_BYTES); } break; case 4: if (rr->digest.length != SHA384_BYTES) { return bitch("wrong SHA-384 digest length: %d bytes found, %d bytes expected", rr->digest.length, SHA384_BYTES); } break; default: return bitch("bad or unsupported digest type %d", digest_type); } if (*s) { return bitch("garbage after valid DLV data"); } G.dnssec_active = 1; return store_record(type, name, ttl, rr); }
static struct rr *naptr_parse(char *name, long ttl, int type, char *s) { struct rr_naptr *rr = getmem(sizeof(*rr)); int i; struct binary_data text; i = extract_integer(&s, "order"); if (i < 0) return NULL; if (i >= 65536) return bitch("order range is not valid"); rr->order = i; i = extract_integer(&s, "preference"); if (i < 0) return NULL; if (i >= 65536) return bitch("preference range is not valid"); rr->preference = i; text = extract_text(&s, "flags"); if (text.length < 0) return NULL; for (i = 0; i < text.length; i++) { if (!isalnum(text.data[i])) { return bitch("flags contains illegal characters"); } } rr->flags = text; text = extract_text(&s, "services"); if (text.length < 0) return NULL; rr->services = text; text = extract_text(&s, "regexp"); if (text.length < 0) return NULL; rr->regexp = text; rr->replacement = extract_name(&s, "replacement"); if (!rr->replacement) return NULL; if (*s) { return bitch("garbage after valid NAPTR data"); } return store_record(type, name, ttl, rr); }
static struct rr* soa_parse(char *name, long ttl, int type, char *s) { struct rr_soa *rr = getmem(sizeof(*rr)); long long i; rr->mname = extract_name(&s, "mname", 0); if (!rr->mname) return NULL; rr->rname = extract_name(&s, "rname", 0); if (!rr->rname) return NULL; i = extract_integer(&s, "serial", NULL); if (i < 0) return NULL; if (i > 4294967295UL) return bitch("serial is out of range"); rr->serial = i; rr->refresh = extract_timevalue(&s, "refresh"); if (rr->refresh < 0) return NULL; rr->retry = extract_timevalue(&s, "retry"); if (rr->retry < 0) return NULL; rr->expire = extract_timevalue(&s, "expire"); if (rr->expire < 0) return NULL; rr->minimum = extract_timevalue(&s, "minimum"); if (rr->minimum < 0) return NULL; if (ttl < 0 && G.opt.soa_minttl_as_default_ttl) { ttl = rr->minimum; } if (*s) { return bitch("garbage after valid SOA data"); } return store_record(type, name, ttl, rr); }
static struct rr* cert_parse(char *name, long ttl, int type, char *s) { struct rr_cert *rr = getmem(sizeof(*rr)); int cert_type, key_tag, alg; cert_type = extract_certificate_type(&s, "certificate type"); if (cert_type < 0) return NULL; rr->type = cert_type; key_tag = extract_integer(&s, "key tag"); if (key_tag < 0) return NULL; if (key_tag > 65535) return bitch("bad key tag"); rr->key_tag = key_tag; if (isdigit(*s)) { alg = extract_integer(&s, "algorithm"); if (alg < 0) return NULL; if (alg > 255) return bitch("bad algorithm"); if (alg != 0) { /* 0 is just fine */ if (algorithm_type(alg) == ALG_UNSUPPORTED) return bitch("bad algorithm %d", alg); } } else { alg = extract_algorithm(&s, "algorithm"); if (alg == ALG_UNSUPPORTED) return NULL; } rr->algorithm = alg; if (alg == 0 && key_tag != 0) { /* we might want to bitch here, but RFC says "SHOULD", so we don't */ } rr->certificate = extract_base64_binary_data(&s, "certificate"); if (rr->certificate.length < 0) return NULL; /* TODO validate cert length based on algorithm */ if (*s) { return bitch("garbage after valid CERT data"); } return store_record(type, name, ttl, rr); }
static struct rr* tlsa_smimea_parse(char *name, long ttl, int type, char *s) { struct rr_tlsa_smimea *rr = getmem(sizeof(*rr)); int cert_usage, selector, matching_type; cert_usage = extract_integer(&s, "certificate usage field", NULL); if (cert_usage < 0) return NULL; if (cert_usage > 3) return bitch("bad certificate usage field"); rr->cert_usage = cert_usage; selector = extract_integer(&s, "selector field", NULL); if (selector < 0) return NULL; if (selector > 1) return bitch("bad selector field"); rr->selector = selector; matching_type = extract_integer(&s, "matching type field", NULL); if (matching_type < 0) return NULL; if (matching_type > 2) return bitch("bad matching type field"); rr->matching_type = matching_type; rr->association_data = extract_hex_binary_data(&s, "certificate association data", EXTRACT_EAT_WHITESPACE); if (rr->association_data.length < 0) return NULL; switch (rr->matching_type) { case 1: if (rr->association_data.length != SHA256_BYTES) return bitch("bad SHA-256 hash length"); break; case 2: if (rr->association_data.length != SHA512_BYTES) return bitch("bad SHA-512 hash length"); break; } if (*s) { return bitch("garbage after valid %s data", type == T_TLSA ? "TLSA" : "SMIMEA"); } return store_record(type, name, ttl, rr); }
static struct rr *srv_parse(char *name, long ttl, int type, char *s) { struct rr_srv *rr = getmem(sizeof(*rr)); int i; /* TODO validate `name` (underscores etc) http://tools.ietf.org/html/rfc2782 */ i = extract_integer(&s, "priority"); if (i < 0) return NULL; if (i >= 65536) return bitch("priority range is not valid"); rr->priority = i; i = extract_integer(&s, "weight"); if (i < 0) return NULL; if (i >= 65536) return bitch("weight range is not valid"); rr->weight = i; i = extract_integer(&s, "port"); if (i < 0) return NULL; if (i >= 65536) return bitch("port range is not valid"); rr->port = i; rr->target = extract_name(&s, "target", 0); if (!rr->target) return NULL; if (*s) { return bitch("garbage after valid SRV data"); } return store_record(type, name, ttl, rr); }
static int extract_certificate_type(char **s, char *what) { int type; char *str_type; if (isdigit(**s)) { type = extract_integer(s, what); if (type >= 1 && type <= 8) return type; if (type == 253 || type == 254) return type; if (type >= 65280 && type <= 65534) return type; if (type < 0 || type > 65535) { bitch("bad certificate type %d", type); return -1; } if (type == 0 || type == 255 || type == 65535) { bitch("certificate type %d is reserved by IANA", type); return -1; } bitch("certificate type %d is unassigned", type); return -1; } else { str_type = extract_label(s, what, "temporary"); if (!str_type) return -1; if (strcmp(str_type, "pkix") == 0) return 1; if (strcmp(str_type, "spki") == 0) return 2; if (strcmp(str_type, "pgp") == 0) return 3; if (strcmp(str_type, "ipkix") == 0) return 4; if (strcmp(str_type, "ispki") == 0) return 5; if (strcmp(str_type, "ipgp") == 0) return 6; if (strcmp(str_type, "acpkix") == 0) return 7; if (strcmp(str_type, "iacpkix") == 0) return 8; if (strcmp(str_type, "uri") == 0) return 253; if (strcmp(str_type, "oid") == 0) return 254; bitch("bad certificate type %s", str_type); return -1; } }
static struct rr *rt_parse(char *name, long ttl, int type, char *s) { struct rr_rt *rr = getmem(sizeof(*rr)); rr->preference = extract_integer(&s, "RT preference", NULL); if (rr->preference < 0) return NULL; rr->intermediate_host = extract_name(&s, "intermediate-host", 0); if (!rr->intermediate_host) return NULL; if (*s) { return bitch("garbage after valid RT data"); } return store_record(type, name, ttl, rr); }
static struct rr *mx_parse(char *name, long ttl, int type, char *s) { struct rr_mx *rr = getmem(sizeof(*rr)); rr->preference = extract_integer(&s, "MX preference"); if (rr->preference < 0) return NULL; /* XXX preference range check */ rr->exchange = extract_name(&s, "MX exchange", 0); if (!rr->exchange) return NULL; if (*s) { return bitch("garbage after valid MX data"); } return store_record(type, name, ttl, rr); }
static struct rr *l64_parse(char *name, long ttl, int type, char *s) { struct rr_l64 *rr = getmem(sizeof(*rr)); int preference; rr->preference = preference = extract_integer(&s, "L64 preference"); if (preference < 0) return NULL; if (extract_u64(&s, "Locator64", &rr->locator64) < 0) return NULL; if (*s) { return bitch("garbage after valid L64 data"); } return store_record(type, name, ttl, rr); }
static struct rr *nid_parse(char *name, long ttl, int type, char *s) { struct rr_nid *rr = getmem(sizeof(*rr)); int preference; rr->preference = preference = extract_integer(&s, "NID preference", NULL); if (preference < 0) return NULL; if (extract_u64(&s, "NodeID", &rr->node_id) < 0) return NULL; if (*s) { return bitch("garbage after valid NID data"); } return store_record(type, name, ttl, rr); }
static struct rr *kx_parse(char *name, long ttl, int type, char *s) { struct rr_kx *rr = getmem(sizeof(*rr)); rr->preference = extract_integer(&s, "KX preference", NULL); if (rr->preference < 0) return NULL; rr->exchanger = extract_name(&s, "KX exchanger", 0); if (!rr->exchanger) return NULL; if (*s) { return bitch("garbage after valid KX data"); } return store_record(type, name, ttl, rr); }
static struct rr *l32_parse(char *name, long ttl, int type, char *s) { struct rr_l32 *rr = getmem(sizeof(*rr)); struct in_addr ipv4_like; int preference; rr->preference = preference = extract_integer(&s, "L32 preference", NULL); if (preference < 0) return NULL; if (extract_ipv4(&s, "Locator32", &ipv4_like) <= 0) return NULL; rr->locator32 = ipv4_like.s_addr; if (*s) { return bitch("garbage after valid L32 data"); } return store_record(type, name, ttl, rr); }
static struct rr *afsdb_parse(char *name, long ttl, int type, char *s) { struct rr_afsdb *rr = getmem(sizeof(*rr)); rr->subtype = extract_integer(&s, "AFSDB subtype", NULL); if (rr->subtype < 0) return NULL; if (rr->subtype != 1 && rr->subtype != 2) return bitch("unknown AFSDB subtype"); rr->hostname = extract_name(&s, "AFSDB hostname", 0); if (!rr->hostname) return NULL; if (*s) { return bitch("garbage after valid AFSDB data"); } return store_record(type, name, ttl, rr); }
static struct rr *px_parse(char *name, long ttl, int type, char *s) { struct rr_px *rr = getmem(sizeof(*rr)); rr->preference = extract_integer(&s, "PX preference", NULL); if (rr->preference < 0) return NULL; rr->map822 = extract_name(&s, "map822", 0); if (!rr->map822) return NULL; rr->mapx400 = extract_name(&s, "mapx400", 0); if (!rr->mapx400) return NULL; if (*s) { return bitch("garbage after valid KX data"); } return store_record(type, name, ttl, rr); }
static struct rr* dnskey_parse(char *name, long ttl, int type, char *s) { struct rr_dnskey *rr = getmem(sizeof(*rr)); struct binary_data key; int flags, proto, algorithm; unsigned int ac; int i; static struct rr *result; flags = extract_integer(&s, "flags"); if (flags < 0) return NULL; if (flags & 0xfefe) return bitch("reserved flags bits are set"); if (flags & 0x0001 && !(flags & 0x0100)) return bitch("SEP bit is set but Zone Key bit is unset"); rr->flags = flags; /* TODO validate that `name` is the name of the zone if flags have Zone Key bit set */ proto = extract_integer(&s, "protocol"); if (proto < 0) return NULL; if (proto != 3) return bitch("bad protocol value"); rr->protocol = proto; algorithm = extract_algorithm(&s, "algorithm"); if (algorithm == ALG_UNSUPPORTED) return NULL; if (algorithm == ALG_PRIVATEDNS || algorithm == ALG_PRIVATEOID) { return bitch("private algorithms are not supported in DNSKEY"); } rr->algorithm = algorithm; key = extract_base64_binary_data(&s, "public key"); if (key.length < 0) return NULL; /* TODO validate key length based on algorithm */ rr->pubkey = key; ac = 0; ac += rr->flags; ac += rr->protocol << 8; ac += rr->algorithm; for (i = 0; i < rr->pubkey.length; i++) { ac += (i & 1) ? (unsigned char)rr->pubkey.data[i] : ((unsigned char)rr->pubkey.data[i]) << 8; } ac += (ac >> 16) & 0xFFFF; rr->key_tag = ac & 0xFFFF; rr->pkey_built = 0; rr->pkey = NULL; rr->key_type = KEY_TYPE_UNUSED; if (*s) { return bitch("garbage after valid DNSKEY data"); } result = store_record(type, name, ttl, rr); if (result) { rr->next_key = all_dns_keys; all_dns_keys = rr; } return result; }
static struct rr *ipseckey_parse(char *name, long ttl, int type, char *s) { struct rr_ipseckey *rr = getmem(sizeof(*rr)); int i; rr->precedence = i = extract_integer(&s, "precedence", NULL); if (i < 0) return NULL; if (i >= 256) return bitch("precedence range is not valid"); rr->gateway_type = i = extract_integer(&s, "gateway type", NULL); if (i < 0) return NULL; if (i > 3) return bitch("gateway type is not valid"); rr->algorithm = i = extract_integer(&s, "algorithm", NULL); if (i < 0) return NULL; if (i > 2) return bitch("algorithm is not valid"); switch (rr->gateway_type) { case 0: rr->gateway.gateway_none = extract_name(&s, "gateway/.", KEEP_CAPITALIZATION); if (!rr->gateway.gateway_none) return NULL; if (strcmp(rr->gateway.gateway_none, ".") != 0) return bitch("gateway must be \".\" for gateway type 0"); break; case 1: if (extract_ipv4(&s, "gateway/IPv4", &rr->gateway.gateway_ipv4) <= 0) return NULL; break; case 2: if (extract_ipv6(&s, "gateway/IPv6", &rr->gateway.gateway_ipv6) <= 0) return NULL; break; case 3: rr->gateway.gateway_name = extract_name(&s, "gateway/name", KEEP_CAPITALIZATION); if (!rr->gateway.gateway_name) return NULL; break; default: croakx(7, "assertion failed: gateway type %d not within range", rr->gateway_type); } /* My reading of http://tools.ietf.org/html/rfc4025 is fuzzy on: * * - whether it is possible to have algorithm 0 and non-empty key; * - whether it is possible to have empty key and algorithm != 0. * * Here I assume "not possible" for both. */ switch (rr->algorithm) { case 0: break; case 1: /* DSA key */ rr->public_key = extract_base64_binary_data(&s, "public key"); if (rr->public_key.length < 0) return NULL; break; case 2: /* RSA key */ rr->public_key = extract_base64_binary_data(&s, "public key"); if (rr->public_key.length < 0) return NULL; break; default: croakx(7, "assertion failed: algorithm %d not within range", rr->algorithm); } if (*s) { return bitch("garbage after valid IPSECKEY data"); } return store_record(type, name, ttl, rr); }
static struct rr* nsec3_parse(char *name, long ttl, int type, char *s) { struct rr_nsec3 *rr = getmem(sizeof(*rr)); struct rr *ret_rr; struct binary_data bitmap; int i; int opt_out = 0; char *str_type = NULL; int ltype; i = extract_integer(&s, "hash algorithm"); if (i < 0) return NULL; if (i > 255) return bitch("bad hash algorithm value"); if (i != 1) return bitch("unrecognized or unsupported hash algorithm"); rr->hash_algorithm = i; i = extract_integer(&s, "flags"); if (i < 0) return NULL; if (i > 255) return bitch("bad flags value"); if (!(i == 0 || i == 1)) return bitch("unsupported flags value"); if (i == 1) opt_out = 1; rr->flags = i; i = extract_integer(&s, "iterations"); if (i < 0) return NULL; if (i > 2500) return bitch("bad iterations value"); rr->iterations = i; /* TODO validate iteration count according to key size, * as per http://tools.ietf.org/html/rfc5155#section-10.3 */ if (*s == '-') { rr->salt.length = 0; rr->salt.data = NULL; s++; if (*s && !isspace(*s) && *s != ';' && *s != ')') return bitch("salt is not valid"); s = skip_white_space(s); } else { rr->salt = extract_hex_binary_data(&s, "salt", EXTRACT_DONT_EAT_WHITESPACE); if (rr->salt.length <= 0) return NULL; if (rr->salt.length > 255) return bitch("salt is too long"); } rr->next_hashed_owner = extract_base32hex_binary_data(&s, "next hashed owner"); bitmap = new_set(); while (s && *s) { str_type = extract_label(&s, "type list", "temporary"); if (!str_type) return NULL; ltype = str2rdtype(str_type); add_bit_to_set(&bitmap, ltype); } if (!s) return NULL; rr->type_bitmap = compressed_set(&bitmap); ret_rr = store_record(type, name, ttl, rr); if (ret_rr) { G.nsec3_present = 1; if (opt_out) G.nsec3_opt_out_present = 1; } return ret_rr; }
static struct rr* nsec3param_parse(char *name, long ttl, int type, char *s) { struct rr_nsec3param *rr = getmem(sizeof(*rr)); struct rr *ret_rr; int i; i = extract_integer(&s, "hash algorithm"); if (i < 0) return NULL; if (i > 255) return bitch("bad hash algorithm value"); if (i != 1) return bitch("unrecognized or unsupported hash algorithm"); rr->hash_algorithm = i; i = extract_integer(&s, "flags"); if (i < 0) return NULL; if (i > 255) return bitch("bad flags value"); if (i != 0) return bitch("flags is supposed to be 0 for NSEC3PARAM"); rr->flags = i; i = extract_integer(&s, "iterations"); if (i < 0) return NULL; if (i > 2500) return bitch("bad iterations value"); rr->iterations = i; /* TODO validate iteration count according to key size, * as per http://tools.ietf.org/html/rfc5155#section-10.3 */ if (*s == '-') { rr->salt.length = 0; rr->salt.data = NULL; s++; if (*s && !isspace(*s) && *s != ';' && *s != ')') return bitch("salt is not valid"); s = skip_white_space(s); } else { rr->salt = extract_hex_binary_data(&s, "salt", EXTRACT_DONT_EAT_WHITESPACE); if (rr->salt.length <= 0) return NULL; if (rr->salt.length > 255) return bitch("salt is too long"); } if (*s) { return bitch("garbage after valid NSEC3PARAM data"); } G.dnssec_active = 1; ret_rr = store_record(type, name, ttl, rr); if (ret_rr && !nsec3param && (ret_rr->rr_set->named_rr->flags & NAME_FLAG_APEX)) nsec3param = ret_rr; if (G.opt.policy_checks[POLICY_NSEC3PARAM_NOT_APEX] && (ret_rr->rr_set->named_rr->flags & NAME_FLAG_APEX) == 0) { return bitch("NSEC3PARAM found not at zone apex"); } return ret_rr; }