/* * util.c * - contains miscellaneous routines */ #import #import #import #import #import #import #import #import #import #import #import #import #import "util.h" int ipRangeCmp(ip_range_t * a_p, ip_range_t * b_p, boolean_t * overlap) { u_long b_start = iptohl(b_p->start); u_long b_end = iptohl(b_p->end); u_long a_start = iptohl(a_p->start); u_long a_end = iptohl(a_p->end); int result = 0; *overlap = TRUE; if (a_start == b_start) { result = 0; } else if (a_start < b_start) { result = -1; if (a_end < b_start) *overlap = FALSE; } else { result = 1; if (b_end < a_start) *overlap = FALSE; } return (result); } /* * Function: nbits_host * Purpose: * Return the number of bits of host address */ int nbits_host(struct in_addr mask) { u_long l = iptohl(mask); int i; for (i = 0; i < 32; i++) { if (l & (1 << i)) return (32 - i); } return (32); } /* * Function: inet_nettoa * Purpose: * Turns a network address (expressed as an IP address and mask) * into a string e.g. 17.202.40.0 and mask 255.255.252.0 yields * the string "17.202.40/22". */ u_char * inet_nettoa(struct in_addr addr, struct in_addr mask) { u_char * addr_p; int nbits = nbits_host(mask); int nbytes; static u_char sbuf[32]; u_char tmp[8]; #define NBITS_PER_BYTE 8 sbuf[0] = '\0'; nbytes = (nbits + NBITS_PER_BYTE - 1) / NBITS_PER_BYTE; // printf("-- nbits %d, nbytes %d--", nbits, nbytes); for (addr_p = (u_char *)&addr.s_addr; nbytes > 0; addr_p++) { sprintf(tmp, "%d%s", *addr_p, nbytes > 1 ? "." : ""); strcat(sbuf, tmp); nbytes--; } if (nbits % NBITS_PER_BYTE) { sprintf(tmp, "/%d", nbits); strcat(sbuf, tmp); } return (sbuf); } /* * Function: random_range * Purpose: * Return a random number in the given range. */ long random_range(long bottom, long top) { long ret; long number = top - bottom + 1; long range_size = LONG_MAX / number; if (range_size == 0) return (bottom); ret = (random() / range_size) + bottom; return (ret); } /* * Function: timeval_subtract * * Purpose: * Computes result = tv1 - tv2. */ void timeval_subtract(struct timeval tv1, struct timeval tv2, struct timeval * result) { result->tv_sec = tv1.tv_sec - tv2.tv_sec; result->tv_usec = tv1.tv_usec - tv2.tv_usec; if (result->tv_usec < 0) { result->tv_usec += USECS_PER_SEC; result->tv_sec--; } return; } /* * Function: timeval_add * * Purpose: * Computes result = tv1 + tv2. */ void timeval_add(struct timeval tv1, struct timeval tv2, struct timeval * result) { result->tv_sec = tv1.tv_sec + tv2.tv_sec; result->tv_usec = tv1.tv_usec + tv2.tv_usec; if (result->tv_usec > USECS_PER_SEC) { result->tv_usec -= USECS_PER_SEC; result->tv_sec++; } return; } /* * Function: timeval_compare * * Purpose: * Compares two timeval values, tv1 and tv2. * * Returns: * -1 if tv1 is less than tv2 * 0 if tv1 is equal to tv2 * 1 if tv1 is greater than tv2 */ int timeval_compare(struct timeval tv1, struct timeval tv2) { struct timeval result; timeval_subtract(tv1, tv2, &result); if (result.tv_sec < 0 || result.tv_usec < 0) return (-1); if (result.tv_sec == 0 && result.tv_usec == 0) return (0); return (1); } /* * Function: print_data * Purpose: * Displays the buffer as a series of 8-bit hex numbers with an ASCII * representation off to the side. */ void print_data(u_char * data_p, int n_bytes) { #define CHARS_PER_LINE 16 char line_buf[CHARS_PER_LINE + 1]; int line_pos; int offset; for (line_pos = 0, offset = 0; offset < n_bytes; offset++, data_p++) { if (line_pos == 0) printf("%04x ", offset); line_buf[line_pos] = isprint(*data_p) ? *data_p : '.'; printf(" %02x", *data_p); line_pos++; if (line_pos == CHARS_PER_LINE) { line_buf[CHARS_PER_LINE] = '\0'; printf(" %s\n", line_buf); line_pos = 0; } else if (line_pos == (CHARS_PER_LINE / 2)) printf(" "); } if (line_pos) { /* need to finish up the line */ for (; line_pos < CHARS_PER_LINE; line_pos++) { printf(" "); line_buf[line_pos] = ' '; } line_buf[CHARS_PER_LINE] = '\0'; printf(" %s\n", line_buf); } } /* * Function: create_path * * Purpose: * Create the given directory hierarchy. Return -1 if anything * went wrong, 0 if successful. */ int create_path(u_char * dirname, mode_t mode) { boolean_t done = FALSE; u_char * scan; if (mkdir(dirname, mode) == 0 || errno == EEXIST) return (0); if (errno != ENOENT) return (-1); { u_char path[PATH_MAX]; for (path[0] = '\0', scan = dirname; done == FALSE;) { u_char * next_sep; if (scan == NULL || *scan != '/') return (FALSE); scan++; next_sep = strchr(scan, '/'); if (next_sep == 0) { done = TRUE; next_sep = dirname + strlen(dirname); } strncpy(path, dirname , next_sep - dirname); path[next_sep - dirname] = '\0'; if (mkdir(path, mode) == 0 || errno == EEXIST) ; else return (-1); scan = next_sep; } } return (0); } static __inline__ char * find_char(char ch, char * data, char * data_end) { char * scan; for (scan = data; scan < data_end; scan++) { if (*scan == ch) return (scan); } return (NULL); } char * tagtext_get(char * data, char * data_end, char * tag, char * * end_p) { int tag_len = strlen(tag); char * start = NULL; char * scan; *end_p = NULL; for (scan = data; scan < data_end; ) { scan = find_char('<', scan, data_end); if (scan == NULL) goto done; if (start == NULL) { if ((scan + 1 + tag_len + 1) > data_end) goto done; if (strncmp(scan + 1, tag, tag_len) == 0 && scan[tag_len + 1] == '>') { start = scan + tag_len + 1 + 1; #ifdef DEBUG printf("start of %s found at %d\n", tag, start - data); #endif DEBUG scan += 1 + tag_len + 1; } else scan++; } else { if ((scan + 1 + tag_len + 1 + 1) > data_end) { goto done; } if (scan[1] == '/' && strncmp(scan + 2, tag, tag_len) == 0 && scan[1 + tag_len + 1] == '>') { *end_p = scan; #ifdef DEBUG printf("end of %s found at %d\n", tag, *end_p - data); #endif DEBUG goto done; } else scan++; } } done: if (*end_p == NULL) return (NULL); return (start); } /* * Function: timestamp_syslog * * Purpose: * Log a timestamped event message to the syslog. */ void timestamp_syslog(char * msg) { static struct timeval tvp = {0,0}; struct timeval tv; gettimeofday(&tv, 0); if (tvp.tv_sec) { struct timeval result; timeval_subtract(tv, tvp, &result); syslog(LOG_INFO, "%d.%06d (%d.%06d): %s", tv.tv_sec, tv.tv_usec, result.tv_sec, result.tv_usec, msg); } else syslog(LOG_INFO, "%d.%06d (%d.%06d): %s", tv.tv_sec, tv.tv_usec, 0, 0, msg); tvp = tv; } /* * Function: timestamp_printf * * Purpose: * Log a timestamped event message to the printf. */ void timestamp_printf(char * msg) { static struct timeval tvp = {0,0}; struct timeval tv; gettimeofday(&tv, 0); if (tvp.tv_sec) { struct timeval result; timeval_subtract(tv, tvp, &result); printf("%d.%06d (%d.%06d): %s\n", tv.tv_sec, tv.tv_usec, result.tv_sec, result.tv_usec, msg); } else printf("%d.%06d (%d.%06d): %s\n", tv.tv_sec, tv.tv_usec, 0, 0, msg); tvp = tv; } int ether_cmp(struct ether_addr * e1, struct ether_addr * e2) { int i; u_char * c1 = e1->octet; u_char * c2 = e2->octet; for (i = 0; i < sizeof(e1->octet); i++, c1++, c2++) { if (*c1 == *c2) continue; return ((int)*c1 - (int)*c2); } return (0); } #include #include #include #include #include /* * Function: dns_hostname_clean * Purpose: * Check whether the given hostname is DNS clean. * Returns: * TRUE if the hostname is clean, FALSE otherwise */ int dns_hostname_is_clean(const char * source_str) { int i; int len = strlen(source_str); char prev_ch = '\0'; const char *scan; if (len == 0) { return (NULL); } for (scan = source_str, i = 0; i < len; i++, scan++) { char ch = *scan; char next_ch = *(scan + 1); if (prev_ch == '.' || prev_ch == '\0') { if (isalpha(ch) == 0) { goto failed; } } else if (next_ch == '\0' || next_ch == '.') { if (isalnum(ch) == 0) { goto failed; } } else if (isalnum(ch) == 0) { switch (ch) { case '.': case '-': if (prev_ch == '.' || prev_ch == '-') { goto failed; } break; default: goto failed; break; } } prev_ch = ch; } return (TRUE); failed: return (FALSE); }