1 /* $OpenBSD: util.c,v 1.1 2015/11/21 12:37:42 reyk Exp $ */ 2 3 /* 4 * Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 #include <sys/socket.h> 21 #include <sys/time.h> 22 23 #include <stdio.h> 24 #include <string.h> 25 #include <time.h> 26 #include <netdb.h> 27 #include <ctype.h> 28 29 #include "relayd.h" 30 31 const char * 32 host_error(enum host_error he) 33 { 34 switch (he) { 35 case HCE_NONE: 36 return ("none"); 37 break; 38 case HCE_ABORT: 39 return ("aborted"); 40 break; 41 case HCE_INTERVAL_TIMEOUT: 42 return ("interval timeout"); 43 break; 44 case HCE_ICMP_OK: 45 return ("icmp ok"); 46 break; 47 case HCE_ICMP_READ_TIMEOUT: 48 return ("icmp read timeout"); 49 break; 50 case HCE_ICMP_WRITE_TIMEOUT: 51 return ("icmp write timeout"); 52 break; 53 case HCE_TCP_SOCKET_ERROR: 54 return ("tcp socket error"); 55 break; 56 case HCE_TCP_SOCKET_LIMIT: 57 return ("tcp socket limit"); 58 break; 59 case HCE_TCP_SOCKET_OPTION: 60 return ("tcp socket option"); 61 break; 62 case HCE_TCP_CONNECT_FAIL: 63 return ("tcp connect failed"); 64 break; 65 case HCE_TCP_CONNECT_TIMEOUT: 66 return ("tcp connect timeout"); 67 break; 68 case HCE_TCP_CONNECT_OK: 69 return ("tcp connect ok"); 70 break; 71 case HCE_TCP_WRITE_TIMEOUT: 72 return ("tcp write timeout"); 73 break; 74 case HCE_TCP_WRITE_FAIL: 75 return ("tcp write failed"); 76 break; 77 case HCE_TCP_READ_TIMEOUT: 78 return ("tcp read timeout"); 79 break; 80 case HCE_TCP_READ_FAIL: 81 return ("tcp read failed"); 82 break; 83 case HCE_SCRIPT_OK: 84 return ("script ok"); 85 break; 86 case HCE_SCRIPT_FAIL: 87 return ("script failed"); 88 break; 89 case HCE_TLS_CONNECT_OK: 90 return ("tls connect ok"); 91 break; 92 case HCE_TLS_CONNECT_FAIL: 93 return ("tls connect failed"); 94 break; 95 case HCE_TLS_CONNECT_TIMEOUT: 96 return ("tls connect timeout"); 97 break; 98 case HCE_TLS_CONNECT_ERROR: 99 return ("tls connect error"); 100 break; 101 case HCE_TLS_READ_TIMEOUT: 102 return ("tls read timeout"); 103 break; 104 case HCE_TLS_WRITE_TIMEOUT: 105 return ("tls write timeout"); 106 break; 107 case HCE_TLS_READ_ERROR: 108 return ("tls read error"); 109 break; 110 case HCE_TLS_WRITE_ERROR: 111 return ("tls write error"); 112 break; 113 case HCE_SEND_EXPECT_FAIL: 114 return ("send/expect failed"); 115 break; 116 case HCE_SEND_EXPECT_OK: 117 return ("send/expect ok"); 118 break; 119 case HCE_HTTP_CODE_ERROR: 120 return ("http code malformed"); 121 break; 122 case HCE_HTTP_CODE_FAIL: 123 return ("http code mismatch"); 124 break; 125 case HCE_HTTP_CODE_OK: 126 return ("http code ok"); 127 break; 128 case HCE_HTTP_DIGEST_ERROR: 129 return ("http digest malformed"); 130 break; 131 case HCE_HTTP_DIGEST_FAIL: 132 return ("http digest mismatch"); 133 break; 134 case HCE_HTTP_DIGEST_OK: 135 return ("http digest ok"); 136 break; 137 } 138 /* NOTREACHED */ 139 return ("invalid"); 140 } 141 142 const char * 143 host_status(enum host_status status) 144 { 145 switch (status) { 146 case HOST_DOWN: 147 return ("down"); 148 case HOST_UNKNOWN: 149 return ("unknown"); 150 case HOST_UP: 151 return ("up"); 152 }; 153 /* NOTREACHED */ 154 return ("invalid"); 155 } 156 157 const char * 158 table_check(enum table_check check) 159 { 160 switch (check) { 161 case CHECK_NOCHECK: 162 return ("none"); 163 case CHECK_ICMP: 164 return ("icmp"); 165 case CHECK_TCP: 166 return ("tcp"); 167 case CHECK_HTTP_CODE: 168 return ("http code"); 169 case CHECK_HTTP_DIGEST: 170 return ("http digest"); 171 case CHECK_SEND_EXPECT: 172 return ("send expect"); 173 case CHECK_SCRIPT: 174 return ("script"); 175 }; 176 /* NOTREACHED */ 177 return ("invalid"); 178 } 179 180 const char * 181 print_availability(u_long cnt, u_long up) 182 { 183 static char buf[BUFSIZ]; 184 185 if (cnt == 0) 186 return (""); 187 bzero(buf, sizeof(buf)); 188 snprintf(buf, sizeof(buf), "%.2f%%", (double)up / cnt * 100); 189 return (buf); 190 } 191 192 const char * 193 print_host(struct sockaddr_storage *ss, char *buf, size_t len) 194 { 195 if (getnameinfo((struct sockaddr *)ss, ss->ss_len, 196 buf, len, NULL, 0, NI_NUMERICHOST) != 0) { 197 buf[0] = '\0'; 198 return (NULL); 199 } 200 return (buf); 201 } 202 203 const char * 204 print_time(struct timeval *a, struct timeval *b, char *buf, size_t len) 205 { 206 struct timeval tv; 207 u_long h, sec, min; 208 209 timerclear(&tv); 210 timersub(a, b, &tv); 211 sec = tv.tv_sec % 60; 212 min = tv.tv_sec / 60 % 60; 213 h = tv.tv_sec / 60 / 60; 214 215 snprintf(buf, len, "%.2lu:%.2lu:%.2lu", h, min, sec); 216 return (buf); 217 } 218 219 const char * 220 printb_flags(const u_int32_t v, const char *bits) 221 { 222 static char buf[2][BUFSIZ]; 223 static int idx = 0; 224 int i, any = 0; 225 char c, *p, *r; 226 227 p = r = buf[++idx % 2]; 228 bzero(p, BUFSIZ); 229 230 if (bits) { 231 bits++; 232 while ((i = *bits++)) { 233 if (v & (1 << (i - 1))) { 234 if (any) { 235 *p++ = ','; 236 *p++ = ' '; 237 } 238 any = 1; 239 for (; (c = *bits) > 32; bits++) { 240 if (c == '_') 241 *p++ = ' '; 242 else 243 *p++ = tolower((u_char)c); 244 } 245 } else 246 for (; *bits > 32; bits++) 247 ; 248 } 249 } 250 251 return (r); 252 } 253 254 void 255 getmonotime(struct timeval *tv) 256 { 257 struct timespec ts; 258 259 if (clock_gettime(CLOCK_MONOTONIC, &ts)) 260 fatal("clock_gettime"); 261 262 TIMESPEC_TO_TIMEVAL(tv, &ts); 263 } 264