1*09a3aaf3SDag-Erling Smørgrav /* 2*09a3aaf3SDag-Erling Smørgrav * parseutil.h - parse utilities for string and wire conversion 3*09a3aaf3SDag-Erling Smørgrav * 4*09a3aaf3SDag-Erling Smørgrav * (c) NLnet Labs, 2004 5*09a3aaf3SDag-Erling Smørgrav * 6*09a3aaf3SDag-Erling Smørgrav * See the file LICENSE for the license 7*09a3aaf3SDag-Erling Smørgrav */ 8*09a3aaf3SDag-Erling Smørgrav /** 9*09a3aaf3SDag-Erling Smørgrav * \file 10*09a3aaf3SDag-Erling Smørgrav * 11*09a3aaf3SDag-Erling Smørgrav * Utility functions for parsing, base32(DNS variant) and base64 encoding 12*09a3aaf3SDag-Erling Smørgrav * and decoding, Hex, Time units, Escape codes. 13*09a3aaf3SDag-Erling Smørgrav */ 14*09a3aaf3SDag-Erling Smørgrav 15*09a3aaf3SDag-Erling Smørgrav #ifndef LDNS_PARSEUTIL_H 16*09a3aaf3SDag-Erling Smørgrav #define LDNS_PARSEUTIL_H 17*09a3aaf3SDag-Erling Smørgrav struct tm; 18*09a3aaf3SDag-Erling Smørgrav 19*09a3aaf3SDag-Erling Smørgrav /** 20*09a3aaf3SDag-Erling Smørgrav * A general purpose lookup table 21*09a3aaf3SDag-Erling Smørgrav * 22*09a3aaf3SDag-Erling Smørgrav * Lookup tables are arrays of (id, name) pairs, 23*09a3aaf3SDag-Erling Smørgrav * So you can for instance lookup the RCODE 3, which is "NXDOMAIN", 24*09a3aaf3SDag-Erling Smørgrav * and vice versa. The lookup tables themselves are defined wherever needed, 25*09a3aaf3SDag-Erling Smørgrav * for instance in host2str.c 26*09a3aaf3SDag-Erling Smørgrav */ 27*09a3aaf3SDag-Erling Smørgrav struct sldns_struct_lookup_table { 28*09a3aaf3SDag-Erling Smørgrav int id; 29*09a3aaf3SDag-Erling Smørgrav const char *name; 30*09a3aaf3SDag-Erling Smørgrav }; 31*09a3aaf3SDag-Erling Smørgrav typedef struct sldns_struct_lookup_table sldns_lookup_table; 32*09a3aaf3SDag-Erling Smørgrav 33*09a3aaf3SDag-Erling Smørgrav /** 34*09a3aaf3SDag-Erling Smørgrav * Looks up the table entry by name, returns NULL if not found. 35*09a3aaf3SDag-Erling Smørgrav * \param[in] table the lookup table to search in 36*09a3aaf3SDag-Erling Smørgrav * \param[in] name what to search for 37*09a3aaf3SDag-Erling Smørgrav * \return the item found 38*09a3aaf3SDag-Erling Smørgrav */ 39*09a3aaf3SDag-Erling Smørgrav sldns_lookup_table *sldns_lookup_by_name(sldns_lookup_table table[], 40*09a3aaf3SDag-Erling Smørgrav const char *name); 41*09a3aaf3SDag-Erling Smørgrav /** 42*09a3aaf3SDag-Erling Smørgrav * Looks up the table entry by id, returns NULL if not found. 43*09a3aaf3SDag-Erling Smørgrav * \param[in] table the lookup table to search in 44*09a3aaf3SDag-Erling Smørgrav * \param[in] id what to search for 45*09a3aaf3SDag-Erling Smørgrav * \return the item found 46*09a3aaf3SDag-Erling Smørgrav */ 47*09a3aaf3SDag-Erling Smørgrav sldns_lookup_table *sldns_lookup_by_id(sldns_lookup_table table[], int id); 48*09a3aaf3SDag-Erling Smørgrav 49*09a3aaf3SDag-Erling Smørgrav /** 50*09a3aaf3SDag-Erling Smørgrav * Convert TM to seconds since epoch (midnight, January 1st, 1970). 51*09a3aaf3SDag-Erling Smørgrav * Like timegm(3), which is not always available. 52*09a3aaf3SDag-Erling Smørgrav * \param[in] tm a struct tm* with the date 53*09a3aaf3SDag-Erling Smørgrav * \return the seconds since epoch 54*09a3aaf3SDag-Erling Smørgrav */ 55*09a3aaf3SDag-Erling Smørgrav time_t sldns_mktime_from_utc(const struct tm *tm); 56*09a3aaf3SDag-Erling Smørgrav 57*09a3aaf3SDag-Erling Smørgrav /** 58*09a3aaf3SDag-Erling Smørgrav * The function interprets time as the number of seconds since epoch 59*09a3aaf3SDag-Erling Smørgrav * with respect to now using serial arithmitics (rfc1982). 60*09a3aaf3SDag-Erling Smørgrav * That number of seconds is then converted to broken-out time information. 61*09a3aaf3SDag-Erling Smørgrav * This is especially usefull when converting the inception and expiration 62*09a3aaf3SDag-Erling Smørgrav * fields of RRSIG records. 63*09a3aaf3SDag-Erling Smørgrav * 64*09a3aaf3SDag-Erling Smørgrav * \param[in] time number of seconds since epoch (midnight, January 1st, 1970) 65*09a3aaf3SDag-Erling Smørgrav * to be intepreted as a serial arithmitics number relative to now. 66*09a3aaf3SDag-Erling Smørgrav * \param[in] now number of seconds since epoch (midnight, January 1st, 1970) 67*09a3aaf3SDag-Erling Smørgrav * to which the time value is compared to determine the final value. 68*09a3aaf3SDag-Erling Smørgrav * \param[out] result the struct with the broken-out time information 69*09a3aaf3SDag-Erling Smørgrav * \return result on success or NULL on error 70*09a3aaf3SDag-Erling Smørgrav */ 71*09a3aaf3SDag-Erling Smørgrav struct tm * sldns_serial_arithmitics_gmtime_r(int32_t time, time_t now, struct tm *result); 72*09a3aaf3SDag-Erling Smørgrav 73*09a3aaf3SDag-Erling Smørgrav /** 74*09a3aaf3SDag-Erling Smørgrav * converts a ttl value (like 5d2h) to a long. 75*09a3aaf3SDag-Erling Smørgrav * \param[in] nptr the start of the string 76*09a3aaf3SDag-Erling Smørgrav * \param[out] endptr points to the last char in case of error 77*09a3aaf3SDag-Erling Smørgrav * \return the convert duration value 78*09a3aaf3SDag-Erling Smørgrav */ 79*09a3aaf3SDag-Erling Smørgrav uint32_t sldns_str2period(const char *nptr, const char **endptr); 80*09a3aaf3SDag-Erling Smørgrav 81*09a3aaf3SDag-Erling Smørgrav /** 82*09a3aaf3SDag-Erling Smørgrav * Returns the int value of the given (hex) digit 83*09a3aaf3SDag-Erling Smørgrav * \param[in] ch the hex char to convert 84*09a3aaf3SDag-Erling Smørgrav * \return the converted decimal value 85*09a3aaf3SDag-Erling Smørgrav */ 86*09a3aaf3SDag-Erling Smørgrav int sldns_hexdigit_to_int(char ch); 87*09a3aaf3SDag-Erling Smørgrav 88*09a3aaf3SDag-Erling Smørgrav /** 89*09a3aaf3SDag-Erling Smørgrav * calculates the size needed to store the result of b64_ntop 90*09a3aaf3SDag-Erling Smørgrav */ 91*09a3aaf3SDag-Erling Smørgrav size_t sldns_b64_ntop_calculate_size(size_t srcsize); 92*09a3aaf3SDag-Erling Smørgrav 93*09a3aaf3SDag-Erling Smørgrav int sldns_b64_ntop(uint8_t const *src, size_t srclength, 94*09a3aaf3SDag-Erling Smørgrav char *target, size_t targsize); 95*09a3aaf3SDag-Erling Smørgrav 96*09a3aaf3SDag-Erling Smørgrav /** 97*09a3aaf3SDag-Erling Smørgrav * calculates the size needed to store the result of sldns_b64_pton 98*09a3aaf3SDag-Erling Smørgrav */ 99*09a3aaf3SDag-Erling Smørgrav size_t sldns_b64_pton_calculate_size(size_t srcsize); 100*09a3aaf3SDag-Erling Smørgrav 101*09a3aaf3SDag-Erling Smørgrav int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize); 102*09a3aaf3SDag-Erling Smørgrav 103*09a3aaf3SDag-Erling Smørgrav /** 104*09a3aaf3SDag-Erling Smørgrav * calculates the size needed to store the result of b32_ntop 105*09a3aaf3SDag-Erling Smørgrav */ 106*09a3aaf3SDag-Erling Smørgrav size_t sldns_b32_ntop_calculate_size(size_t src_data_length); 107*09a3aaf3SDag-Erling Smørgrav 108*09a3aaf3SDag-Erling Smørgrav size_t sldns_b32_ntop_calculate_size_no_padding(size_t src_data_length); 109*09a3aaf3SDag-Erling Smørgrav 110*09a3aaf3SDag-Erling Smørgrav int sldns_b32_ntop(const uint8_t* src_data, size_t src_data_length, 111*09a3aaf3SDag-Erling Smørgrav char* target_text_buffer, size_t target_text_buffer_size); 112*09a3aaf3SDag-Erling Smørgrav 113*09a3aaf3SDag-Erling Smørgrav int sldns_b32_ntop_extended_hex(const uint8_t* src_data, size_t src_data_length, 114*09a3aaf3SDag-Erling Smørgrav char* target_text_buffer, size_t target_text_buffer_size); 115*09a3aaf3SDag-Erling Smørgrav 116*09a3aaf3SDag-Erling Smørgrav /** 117*09a3aaf3SDag-Erling Smørgrav * calculates the size needed to store the result of b32_pton 118*09a3aaf3SDag-Erling Smørgrav */ 119*09a3aaf3SDag-Erling Smørgrav size_t sldns_b32_pton_calculate_size(size_t src_text_length); 120*09a3aaf3SDag-Erling Smørgrav 121*09a3aaf3SDag-Erling Smørgrav int sldns_b32_pton(const char* src_text, size_t src_text_length, 122*09a3aaf3SDag-Erling Smørgrav uint8_t* target_data_buffer, size_t target_data_buffer_size); 123*09a3aaf3SDag-Erling Smørgrav 124*09a3aaf3SDag-Erling Smørgrav int sldns_b32_pton_extended_hex(const char* src_text, size_t src_text_length, 125*09a3aaf3SDag-Erling Smørgrav uint8_t* target_data_buffer, size_t target_data_buffer_size); 126*09a3aaf3SDag-Erling Smørgrav 127*09a3aaf3SDag-Erling Smørgrav /* 128*09a3aaf3SDag-Erling Smørgrav * Checks whether the escaped value at **s is an octal value or 129*09a3aaf3SDag-Erling Smørgrav * a 'normally' escaped character (and not eos) 130*09a3aaf3SDag-Erling Smørgrav * 131*09a3aaf3SDag-Erling Smørgrav * @param ch_p: the parsed character 132*09a3aaf3SDag-Erling Smørgrav * @param str_p: the string. moved along for characters read. 133*09a3aaf3SDag-Erling Smørgrav * The string pointer at *s is increased by either 0 (on error), 1 (on 134*09a3aaf3SDag-Erling Smørgrav * normal escapes), or 3 (on octals) 135*09a3aaf3SDag-Erling Smørgrav * 136*09a3aaf3SDag-Erling Smørgrav * @return 0 on error 137*09a3aaf3SDag-Erling Smørgrav */ 138*09a3aaf3SDag-Erling Smørgrav int sldns_parse_escape(uint8_t *ch_p, const char** str_p); 139*09a3aaf3SDag-Erling Smørgrav 140*09a3aaf3SDag-Erling Smørgrav /** 141*09a3aaf3SDag-Erling Smørgrav * Parse one character, with escape codes, 142*09a3aaf3SDag-Erling Smørgrav * @param ch_p: the parsed character 143*09a3aaf3SDag-Erling Smørgrav * @param str_p: the string. moved along for characters read. 144*09a3aaf3SDag-Erling Smørgrav * @return 0 on error 145*09a3aaf3SDag-Erling Smørgrav */ 146*09a3aaf3SDag-Erling Smørgrav int sldns_parse_char(uint8_t *ch_p, const char** str_p); 147*09a3aaf3SDag-Erling Smørgrav 148*09a3aaf3SDag-Erling Smørgrav #endif /* LDNS_PARSEUTIL_H */ 149