1 /** 2 * @file library/tools.h 3 * @defgroup util Memory Utility Routines 4 * @ingroup library 5 * @{ 6 * 7 * Portions of this file are copyrighted by: 8 * Copyright (c) 2016 VMware, Inc. All rights reserved. 9 * Use is subject to license terms specified in the COPYING file 10 * distributed with the Net-SNMP package. 11 */ 12 13 #ifndef _TOOLS_H 14 #define _TOOLS_H 15 16 #ifdef __cplusplus 17 extern "C" { 18 #endif 19 20 21 22 /* 23 * General acros and constants. 24 */ 25 #ifdef WIN32 26 # define SNMP_MAXPATH MAX_PATH 27 #else 28 # ifdef PATH_MAX 29 # define SNMP_MAXPATH PATH_MAX 30 # else 31 # ifdef MAXPATHLEN 32 # define SNMP_MAXPATH MAXPATHLEN 33 # else 34 # define SNMP_MAXPATH 1024 /* Should be safe enough */ 35 # endif 36 # endif 37 #endif 38 39 #define SNMP_MAXBUF (1024 * 4) 40 #define SNMP_MAXBUF_MEDIUM 1024 41 #define SNMP_MAXBUF_SMALL 512 42 43 #define SNMP_MAXBUF_MESSAGE 1500 44 45 #define SNMP_MAXOID 64 46 #define SNMP_MAX_CMDLINE_OIDS 128 47 48 #define SNMP_FILEMODE_CLOSED 0600 49 #define SNMP_FILEMODE_OPEN 0644 50 51 #define BYTESIZE(bitsize) ((bitsize + 7) >> 3) 52 #define ROUNDUP8(x) ( ( (x+7) >> 3 ) * 8 ) 53 54 #define SNMP_STRORNULL(x) ( x ? x : "(null)") 55 56 /** @def SNMP_FREE(s) 57 Frees a pointer only if it is !NULL and sets its value to NULL */ 58 #define SNMP_FREE(s) do { if (s) { free((void *)s); s=NULL; } } while(0) 59 60 /** @def SNMP_SWIPE_MEM(n, s) 61 Frees pointer n only if it is !NULL, sets n to s and sets s to NULL */ 62 #define SNMP_SWIPE_MEM(n,s) do { if (n) free((void *)n); n = s; s=NULL; } while(0) 63 64 /* 65 * XXX Not optimal everywhere. 66 */ 67 /** @def SNMP_MALLOC_STRUCT(s) 68 Mallocs memory of sizeof(struct s), zeros it and returns a pointer to it. */ 69 #define SNMP_MALLOC_STRUCT(s) (struct s *) calloc(1, sizeof(struct s)) 70 71 /** @def SNMP_MALLOC_TYPEDEF(t) 72 Mallocs memory of sizeof(t), zeros it and returns a pointer to it. */ 73 #define SNMP_MALLOC_TYPEDEF(td) (td *) calloc(1, sizeof(td)) 74 75 /** @def SNMP_ZERO(s,l) 76 Zeros l bytes of memory starting at s. */ 77 #define SNMP_ZERO(s,l) do { if (s) memset(s, 0, l); } while(0) 78 79 80 /** 81 * @def NETSNMP_REMOVE_CONST(t, e) 82 * 83 * Cast away constness without that gcc -Wcast-qual prints a compiler warning, 84 * similar to const_cast<> in C++. 85 * 86 * @param[in] t A pointer type. 87 * @param[in] e An expression of a type that can be assigned to the type (const t). 88 */ 89 #if defined(__GNUC__) 90 #define NETSNMP_REMOVE_CONST(t, e) \ 91 (__extension__ ({ const t tmp = (e); (t)(size_t)tmp; })) 92 #else 93 #define NETSNMP_REMOVE_CONST(t, e) ((t)(size_t)(e)) 94 #endif 95 96 97 #define TOUPPER(c) (c >= 'a' && c <= 'z' ? c - ('a' - 'A') : c) 98 #define TOLOWER(c) (c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c) 99 100 #define HEX2VAL(s) \ 101 ((isalpha(s) ? (TOLOWER(s)-'a'+10) : (TOLOWER(s)-'0')) & 0xf) 102 #define VAL2HEX(s) ( (s) + (((s) >= 10) ? ('a'-10) : '0') ) 103 104 105 /** @def SNMP_MAX(a, b) 106 Computers the maximum of a and b. */ 107 #define SNMP_MAX(a,b) ((a) > (b) ? (a) : (b)) 108 109 /** @def SNMP_MIN(a, b) 110 Computers the minimum of a and b. */ 111 #define SNMP_MIN(a,b) ((a) > (b) ? (b) : (a)) 112 113 /** @def SNMP_MACRO_VAL_TO_STR(s) 114 * Expands to string with value of the s. 115 * If s is macro, the resulting string is value of the macro. 116 * Example: 117 * \#define TEST 1234 118 * SNMP_MACRO_VAL_TO_STR(TEST) expands to "1234" 119 * SNMP_MACRO_VAL_TO_STR(TEST+1) expands to "1234+1" 120 */ 121 #define SNMP_MACRO_VAL_TO_STR(s) SNMP_MACRO_VAL_TO_STR_PRIV(s) 122 #define SNMP_MACRO_VAL_TO_STR_PRIV(s) #s 123 124 #ifndef FALSE 125 #define FALSE 0 126 #endif 127 #ifndef TRUE 128 #define TRUE 1 129 #endif 130 131 #define NETSNMP_IGNORE_RESULT(e) do { if (e) { } } while (0) 132 133 /* 134 * QUIT the FUNction: 135 * e Error code variable 136 * l Label to goto to cleanup and get out of the function. 137 * 138 * XXX It would be nice if the label could be constructed by the 139 * preprocessor in context. Limited to a single error return value. 140 * Temporary hack at best. 141 */ 142 #define QUITFUN(e, l) \ 143 if ( (e) != SNMPERR_SUCCESS) { \ 144 rval = SNMPERR_GENERR; \ 145 goto l ; \ 146 } 147 148 /** 149 * Compute res = a + b. 150 * 151 * @pre a and b must be normalized 'struct timeval' values. 152 * 153 * @note res may be the same variable as one of the operands. In other 154 * words, &a == &res || &b == &res may hold. 155 */ 156 #define NETSNMP_TIMERADD(a, b, res) do { \ 157 (res)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ 158 (res)->tv_usec = (a)->tv_usec + (b)->tv_usec; \ 159 if ((res)->tv_usec >= 1000000L) { \ 160 (res)->tv_usec -= 1000000L; \ 161 (res)->tv_sec++; \ 162 } \ 163 } while (0) 164 165 /** 166 * Compute res = a - b. 167 * 168 * @pre a and b must be normalized 'struct timeval' values. 169 * 170 * @note res may be the same variable as one of the operands. In other 171 * words, &a == &res || &b == &res may hold. 172 */ 173 #define NETSNMP_TIMERSUB(a, b, res) do { \ 174 (res)->tv_sec = (a)->tv_sec - (b)->tv_sec - 1; \ 175 (res)->tv_usec = (a)->tv_usec - (b)->tv_usec + 1000000L; \ 176 if ((res)->tv_usec >= 1000000L) { \ 177 (res)->tv_usec -= 1000000L; \ 178 (res)->tv_sec++; \ 179 } \ 180 } while (0) 181 182 #define ENGINETIME_MAX 2147483647 /* ((2^31)-1) */ 183 #define ENGINEBOOT_MAX 2147483647 /* ((2^31)-1) */ 184 185 186 struct timeval; 187 188 189 /* 190 * Prototypes. 191 */ 192 193 NETSNMP_IMPORT 194 int snmp_realloc(u_char ** buf, size_t * buf_len); 195 196 void free_zero(void *buf, size_t size); 197 198 u_char *malloc_random(size_t * size); 199 u_char *malloc_zero(size_t size); 200 NETSNMP_IMPORT 201 void *netsnmp_memdup(const void * from, size_t size); 202 NETSNMP_IMPORT 203 void *netsnmp_memdup_nt(const void *from, size_t from_len, size_t *to_len); 204 205 void netsnmp_check_definedness(const void *packet, 206 size_t length); 207 208 NETSNMP_IMPORT 209 u_int netsnmp_binary_to_hex(u_char ** dest, size_t *dest_len, 210 int allow_realloc, 211 const u_char * input, size_t len); 212 213 NETSNMP_IMPORT 214 u_int binary_to_hex(const u_char * input, size_t len, 215 char **output); 216 /* preferred */ 217 int netsnmp_hex_to_binary(u_char ** buf, size_t * buf_len, 218 size_t * offset, int allow_realloc, 219 const char *hex, const char *delim); 220 /* calls netsnmp_hex_to_binary w/delim of " " */ 221 NETSNMP_IMPORT 222 int snmp_hex_to_binary(u_char ** buf, size_t * buf_len, 223 size_t * offset, int allow_realloc, 224 const char *hex); 225 /* handles odd lengths */ 226 NETSNMP_IMPORT 227 int hex_to_binary2(const u_char * input, size_t len, 228 char **output); 229 230 NETSNMP_IMPORT 231 int snmp_decimal_to_binary(u_char ** buf, size_t * buf_len, 232 size_t * out_len, 233 int allow_realloc, 234 const char *decimal); 235 #define snmp_cstrcat(b,l,o,a,s) snmp_strcat(b,l,o,a,(const u_char *)s) 236 NETSNMP_IMPORT 237 int snmp_strcat(u_char ** buf, size_t * buf_len, 238 size_t * out_len, int allow_realloc, 239 const u_char * s); 240 NETSNMP_IMPORT 241 char *netsnmp_strdup_and_null(const u_char * from, 242 size_t from_len); 243 244 NETSNMP_IMPORT 245 void dump_chunk(const char *debugtoken, const char *title, 246 const u_char * buf, int size); 247 char *dump_snmpEngineID(const u_char * buf, size_t * buflen); 248 249 /** A pointer to an opaque time marker value. */ 250 typedef void *marker_t; 251 typedef const void* const_marker_t; 252 253 NETSNMP_IMPORT 254 marker_t atime_newMarker(void); 255 NETSNMP_IMPORT 256 void atime_setMarker(marker_t pm); 257 NETSNMP_IMPORT 258 void netsnmp_get_monotonic_clock(struct timeval* tv); 259 NETSNMP_IMPORT 260 void netsnmp_set_monotonic_marker(marker_t *pm); 261 NETSNMP_IMPORT 262 long atime_diff(const_marker_t first, const_marker_t second); 263 NETSNMP_IMPORT 264 u_long uatime_diff(const_marker_t first, const_marker_t second); /* 1/1000th sec */ 265 NETSNMP_IMPORT 266 u_long uatime_hdiff(const_marker_t first, const_marker_t second); /* 1/100th sec */ 267 NETSNMP_IMPORT 268 int atime_ready(const_marker_t pm, int delta_ms); 269 NETSNMP_IMPORT 270 int netsnmp_ready_monotonic(const_marker_t pm, int delta_ms); 271 int uatime_ready(const_marker_t pm, unsigned int delta_ms); 272 273 int marker_tticks(const_marker_t pm); 274 int timeval_tticks(const struct timeval *tv); 275 NETSNMP_IMPORT 276 char *netsnmp_getenv(const char *name); 277 NETSNMP_IMPORT 278 int netsnmp_setenv(const char *envname, const char *envval, 279 int overwrite); 280 281 int netsnmp_addrstr_hton(char *ptr, size_t len); 282 283 NETSNMP_IMPORT 284 int netsnmp_string_time_to_secs(const char *time_string); 285 286 #ifdef __cplusplus 287 } 288 #endif 289 #endif /* _TOOLS_H */ 290 /* @} */ 291