/* ****************************************************************************** * INTERPEAK SOURCE FILE * * Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmip_util.c,v $ $Revision: 1.24.10.5 $ * $Source: /home/interpeak/CVSRoot/ipmip/src/ipmip_util.c,v $ * $Author: svc-cmnet $ * $State: Exp $ $Locker: $ * * INTERPEAK_COPYRIGHT_STRING * Design and implementation by Joel Hortelius ****************************************************************************** */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #include "ipmip_config.h" /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include #include #include #include #include #include #ifdef IPMIP_USE_INET6 #include #endif #include #include #include #include /* **************************************************************************** * 4 DEFINES **************************************************************************** */ #define IPMIP_CMD_HDRSIZE 20 #define IPCOM_SYSLOG_PRIORITY IPCOM_LOG_DEBUG2 #define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPMIP /* **************************************************************************** * 5 TYPES **************************************************************************** */ struct Ipmip_util_cbinfo { Ipmip_context_t *ctx; Ipmip_proc_t *proc; Ipmip_util_hash_foreach_t func; void *arg1; void *arg2; }; struct Ipmip_util_freeinfo { Ipmip_util_hash_free_t func; Ipcom_hash *hash; }; /* **************************************************************************** * 6 EXTERN PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 7 LOCAL PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 8 DATA **************************************************************************** */ static Ipmip_sysvar_key_map_t ipmip_util_sysvar_ops[] = { { IPCOM_LOG_EMERG, "emerg" }, { IPCOM_LOG_EMERG, "emergency" }, { IPCOM_LOG_CRIT, "crit" }, { IPCOM_LOG_CRIT, "critical" }, { IPCOM_LOG_ERR, "err" }, { IPCOM_LOG_ERR, "error" }, { IPCOM_LOG_WARNING, "warn" }, { IPCOM_LOG_WARNING, "warning" }, { IPCOM_LOG_NOTICE, "notice" }, { IPCOM_LOG_INFO, "info" }, { IPCOM_LOG_DEBUG, "debug" }, { IPCOM_LOG_DEBUG2, "debug2" }, { 0, 0 } }; /* **************************************************************************** * 9 STATIC FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipmip6_bc_purge_bc *=========================================================================== * Description: Will purge the indicated binding cache entry. * Parameters: bc - The binding cache entry. * Returns: IP_TRUE * */ IP_STATIC void ipmip_util_hash_free_cb(void *entry, struct Ipmip_util_freeinfo *cbinfo) { ipcom_hash_remove(cbinfo->hash, entry); if (cbinfo->func) (*cbinfo->func) (entry); else ipcom_free(entry); } /* *=========================================================================== * ipmip6_bc_purge_bc *=========================================================================== * Description: Will purge the indicated binding cache entry. * Parameters: bc - The binding cache entry. * Returns: IP_TRUE * */ IP_STATIC void ipmip_util_hash_foreach_cb(void *entry, struct Ipmip_util_cbinfo *cbinfo) { /* Invoke with all parameters */ (*cbinfo->func) (cbinfo->ctx, cbinfo->proc, entry, cbinfo->arg1, cbinfo->arg2); } IP_STATIC void ipmip_util_print_tabs(int tabs) { while (tabs--) ipcom_printf("\t"); } IP_STATIC void ipmip_util_print_hdr(Ipmip_proc_t *proc, const char *header, Ip_size_t hdr_size, const char *delim) { unsigned int i = ipcom_strlen(header); i = IP_MIN(i, hdr_size); ipcom_memset(proc->ntop.ntop_pbuf, ' ', hdr_size - i); proc->ntop.ntop_pbuf[hdr_size - i] = '\0'; ipcom_printf("%s%s%s", header, i? delim : "", proc->ntop.ntop_pbuf); } /* *=========================================================================== * ipmip_util_identprintf *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC void ipmip_util_bidentprintf(Ipmip_proc_t *proc, int tabs, char *tmp) { char *sep; IPMIP_UNUSED_PARAMETER(proc); while ((sep = ipcom_strstr(tmp, IP_LF)) != IP_NULL) { if (sep == tmp) ipcom_printf(IP_LF); else { *sep = '\0'; ipmip_util_print_tabs(tabs); ipcom_printf("%s"IP_LF, tmp); sep += ipcom_strlen(IP_LF); if (ipcom_strlen(sep) == 0) return; tmp = sep; } } ipmip_util_print_tabs(tabs); ipcom_printf(tmp); } /* **************************************************************************** * 10 GLOBAL FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipmip_util_vstrdup *=========================================================================== * Description: Do a strdup on a varargs format list * Parameters: format - The format * ap - The 'printf' arguments. * Returns: An allocated string created using the format and arguments * */ IP_GLOBAL char * ipmip_util_vstrdup(const char *format, va_list ap) { char *buf = IP_NULL; Ip_size_t slen; buf = ipcom_malloc(256); if (buf == IP_NULL) return IP_NULL; /**/ slen = ipcom_vsnprintf(buf, 256, format, ap); if (slen >= 256) { ipcom_free(buf); return IP_NULL; } return buf; } /* *=========================================================================== * ipmip_util_strdup *=========================================================================== * Description: Do a strdup on a varargs format list * Parameters: format - The format * ... - The 'printf' arguments. * Returns: An allocated string created using the format and arguments * */ IP_GLOBAL char * ipmip_util_strdup(const char *format, /* args */ ...) { va_list ap; char *buf; va_start(ap, format); buf = ipmip_util_vstrdup(format, ap); va_end(ap); return buf; } /* *=========================================================================== * ipmip_util_strnlen *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL Ip_size_t ipmip_util_strnlen(const char *str, Ip_size_t mlen) { Ip_size_t sz = 0; for (; sz < mlen && *str != '\0'; sz++) str++; return sz; } /* *=========================================================================== * ipmip_util_strnlen *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL const char * ipmip_util_strnchr(const char *str, const char ch, Ip_size_t mlen) { Ip_size_t sz = 0; for (; sz < mlen && *str != '\0'; sz++) { if (*str == ch) return str; } /**/ return IP_NULL; } /* *=========================================================================== * ipmip_util_sock_clear *=========================================================================== * Description: Clear error on socket * Parameters: fd - The filedescriptor to clear * Returns: * */ IP_GLOBAL void ipmip_util_sock_clear(Ip_fd fd) { int err; Ip_socklen_t errlen; errlen = sizeof(int); (void)ipcom_getsockopt(fd, IP_SOL_SOCKET, IP_SO_ERROR, &err, &errlen); } /* *=========================================================================== * ipmip_util_tunnel_to_proto *=========================================================================== * Description: Convert a tunnel index number to an internet protocol * Parameters: tunnel - Tunnel index * Returns: Internet protocol or 0 if no match. * */ IP_GLOBAL Ip_u8 ipmip_util_tunnel_to_proto(Ip_u8 tunnel) { switch (tunnel) { case IPMIP_TUNNELTYPE_IPIP: return IP_IPPROTO_IPIP; case IPMIP_TUNNELTYPE_GRE: case IPMIP_TUNNELTYPE_GRE6: return IP_IPPROTO_GRE; case IPMIP_TUNNELTYPE_MINENC: return IP_IPPROTO_MOBILE; case IPMIP_TUNNELTYPE_IP6IP6: return IP_IPPROTO_IPV6; default: return 0; } } /* *=========================================================================== * ipmip_util_tunnel_to_desc *=========================================================================== * Description: Convert a tunnel index number to a human readable description * Parameters: tunnel - Tunnel index * Returns: Internet protocol or 0 if no match. * */ IP_GLOBAL const char * ipmip_util_tunnel_to_desc(Ip_u8 tunnel) { switch (tunnel) { case IPMIP_TUNNELTYPE_IPIP: return "inet.ipip"; case IPMIP_TUNNELTYPE_GRE: return "inet.gre"; case IPMIP_TUNNELTYPE_GRE6: return "inet6.gre"; case IPMIP_TUNNELTYPE_MINENC: return "inet.minenc"; case IPMIP_TUNNELTYPE_IP6IP6: return "inet6.ip6ip6"; default: return "unknown"; } } IP_GLOBAL Ip_u8 ipmip_util_tunnelmask_to_type(Ip_u32 mask) { int i; if (mask == 0) return IPMIP_TUNNELTYPE_NONE; i = ipcom_ffs(mask); if (i == 0 || i > IPMIP_TUNNELTYPE_MAX) return IPMIP_TUNNELTYPE_NONE; return i - 1; } /* *=========================================================================== * ipmip_util_proto_to_tunnel *=========================================================================== * Description: Convert a protocol number to a tunnel index * Parameters: proto - Protocol number * Returns: Tunnel index or IPMIP4_TUNNELTYPE_NONE if no match. * */ IP_GLOBAL Ip_u8 ipmip_util_proto_to_tunnel(Ip_u8 proto) { switch (proto) { case IP_IPPROTO_IPIP: return IPMIP_TUNNELTYPE_IPIP; case IP_IPPROTO_GRE: return IPMIP_TUNNELTYPE_GRE; case IP_IPPROTO_MOBILE: return IPMIP_TUNNELTYPE_MINENC; case IP_IPPROTO_IPV6: return IPMIP_TUNNELTYPE_IP6IP6; default: return IPMIP_TUNNELTYPE_NONE; } } /* *=========================================================================== * ipmip_util_tunnel_to_bsdname *=========================================================================== * Description: Convert a tunnel index number to a BSD tunnel name * Parameters: tunnel - Tunnel index * Returns: Tunnel name * */ IP_GLOBAL const char * ipmip_util_tunnel_to_bsdname(Ip_u8 tunnel) { switch (tunnel) { case IPMIP_TUNNELTYPE_IP6IP6: case IPMIP_TUNNELTYPE_IPIP: return "gif"; case IPMIP_TUNNELTYPE_GRE6: case IPMIP_TUNNELTYPE_GRE: return "gre"; case IPMIP_TUNNELTYPE_MINENC: return "gremin"; default: return "unknown"; } } /* *=========================================================================== * ipmip_util_tunnel_to_bsdname *=========================================================================== * Description: Convert a tunnel index number to a BSD tunnel name * Parameters: tunnel - Tunnel index * Returns: Tunnel name * */ IP_GLOBAL const char * ipmip_util_tunnel_to_name(Ip_u8 tunnel) { switch (tunnel) { case IPMIP_TUNNELTYPE_IP6IP6: return "ip6ip6"; case IPMIP_TUNNELTYPE_IPIP: return "ipip"; case IPMIP_TUNNELTYPE_GRE6: return "gre6"; case IPMIP_TUNNELTYPE_GRE: return "gre"; case IPMIP_TUNNELTYPE_MINENC: return "minenc"; default: return "unknown"; } } #ifdef IPMIP_USE_INET /* *=========================================================================== * ipmip_util_inet *=========================================================================== * Description: Parse an string to the subnet and prefix length it specifies. * Parameters: addrstr - The address string * addr - Where to store the address * plen - The prefix length. * Returns: IP_TRUE if successful. * */ IP_GLOBAL Ip_bool ipmip_util_inet(const char *addrstr, Ip_u32 *addr, Ip_u32 *plen) { char *a; char *p = IP_NULL; char *n; char *buf = ipcom_strdup(addrstr); if (buf == IP_NULL) return IP_FALSE; /* Get first token */ if ((a = ipcom_strtok_r(buf, " \t/-", &n)) == IP_NULL) goto errout; /* Get second token */ if (plen) { if ((p = ipcom_strtok_r(IP_NULL, " \t/", &n)) == IP_NULL) { *plen = 32; } else { int prefix = ipcom_atoi(p); /* Sanity */ if (prefix < 0 || prefix > 32) goto errout; /* Store it */ *plen = (Ip_u8) prefix; } } /* Convert address */ if (ipcom_inet_pton(IP_AF_INET, a, addr) != 1) goto errout; ipcom_free(buf); return IP_TRUE; errout: ipcom_free(buf); return IP_FALSE; } #endif #ifdef IPMIP_USE_INET6 /* *=========================================================================== * ipmip_util_inet6 *=========================================================================== * Description: Parse an string to the subnet and prefix length it specifies. * Parameters: addrstr - The address string * addr6 - Where to store the address * plen - The prefix length. * Returns: IP_TRUE if successful. * */ IP_GLOBAL Ip_bool ipmip_util_inet6(const char *addrstr, struct Ip_in6_addr *addr6, Ip_u8 *plen) { char *a; char *p = IP_NULL; char *n; char *buf = ipcom_strdup(addrstr); if (buf == IP_NULL) return IP_FALSE; /* Get first token */ if ((a = ipcom_strtok_r(buf, " \t/", &n)) == IP_NULL) goto errout; /* Get second token */ if (plen) { if ((p = ipcom_strtok_r(IP_NULL, " \t/", &n)) == IP_NULL) { *plen = 128; } else { int prefix = ipcom_atoi(p); /* Sanity */ if (prefix < 0 || prefix > 128) goto errout; /* Store it */ *plen = (Ip_u8) prefix; } } /* Convert address */ if (ipcom_inet_pton(IP_AF_INET6, a, addr6) != 1) goto errout; ipcom_free(buf); return IP_TRUE; errout: ipcom_free(buf); return IP_FALSE; } #endif /* *=========================================================================== * ipmip_util_inet6 *=========================================================================== * Description: Parse an string to the subnet and prefix length it specifies. * Parameters: addrstr - The address string * addr6 - Where to store the address * plen - The prefix length. * Returns: IP_TRUE if successful. * */ IP_GLOBAL Ip_bool ipmip_util_inetX(const char *addrstr, Ip_u8 *domain, union Ip_in_addr_union *addrX, Ip_u8 *plen) { #ifdef IPMIP_USE_INET6 if (ipmip_util_inet6(addrstr, &addrX->in6, plen)) { *domain = IP_AF_INET6; return IP_TRUE; } #endif #ifdef IPMIP_USE_INET { Ip_u32 plen32; if (ipmip_util_inet(addrstr, &addrX->in.s_addr, &plen32)) { *domain = IP_AF_INET; if (plen) *plen = (Ip_u8)plen32; return IP_TRUE; } } #endif return IP_FALSE; } /* *=========================================================================== * ipmip_util_inet6 *=========================================================================== * Description: Parse an string to the subnet and prefix length it specifies. * Parameters: addrstr - The address string * addr6 - Where to store the address * plen - The prefix length. * Returns: IP_TRUE if successful. * */ IP_GLOBAL Ip_bool ipmip_util_sockaddrX(const char *addrstr, union Ip_sockaddr_union *unX) { char *buf = ipcom_strdup(addrstr); char *ntok; char *addr; char *n; Ip_u16 port = 0; ipcom_memset(unX, 0, sizeof(*unX)); if (buf == IP_NULL) return IP_FALSE; if ((addr = ipcom_strtok_r(buf, " \t", &n)) == IP_NULL) { ipcom_free(buf); return IP_FALSE; } if ((ntok = ipcom_strtok_r(IP_NULL, " \t", &n)) != IP_NULL) port = (Ip_u16)ipcom_strtoul(ntok, IP_NULL, 0); #ifdef IPMIP_USE_INET6 if (ipcom_getsockaddrbyaddr(IP_AF_INET6, addr, &unX->sa) == 0) { ipcom_free(buf); unX->sin6.sin6_port = ip_htons(port); return IP_TRUE; } #endif #ifdef IPMIP_USE_INET if (ipcom_getsockaddrbyaddr(IP_AF_INET, addr, &unX->sa) == 0) { ipcom_free(buf); unX->sin.sin_port = ip_htons(port); return IP_TRUE; } #endif ipcom_free(buf); return IP_FALSE; } /* *=========================================================================== * ipmip_util_duplicate *=========================================================================== * Description: Create a duplicate buffer and store in ptr; if ptr is already * set, free it. * Parameters: ptr - [IN/OUT] Set pointer will be freed, and newly * allocated will be set. * value - Value to copy * sz - Size of value * Returns: * */ IP_GLOBAL void ipmip_util_duplicate(void **ptr, void *value, Ip_size_t sz) { void * tmp = ipcom_malloc(sz); if(IP_NULL != tmp) { if (*ptr) ipcom_free(*ptr); *ptr = tmp; ipcom_memcpy(*ptr, value, sz); } } /* *=========================================================================== * ipmip_util_ioctl *=========================================================================== * Description: Do an ioctl * Parameters: ioreq - The ioctl * argp - Value to provide * Returns: The return value. * */ IP_GLOBAL int ipmip_util_ioctl(Ipmip_context_t *ctx, Ipmip_proc_t *proc, unsigned long ioreq, void *argp) { IPMIP_UNUSED_PARAMETER(proc); return ipcom_socketioctl(ctx->fd_ioctl, ioreq, argp); } /* *=========================================================================== * ipmip4_util_create_mask *=========================================================================== * Description: Creates a mask which contains 'netbits' number of '1' bits * staring with the most significant bit. * Parameters: mask - Mask buffer. * netbits - Number of bits. * Returns: * */ IP_GLOBAL void ipmip_util_create_mask(Ip_u8 *mask, int netbits) { #if 1 int i; int j; for (i = 0; i < netbits / 8; i++) mask[i] = 0xff; for (j = 0; j < netbits % 8; j++) IP_BIT_SET(mask[i], 0x80 >> j); #else int i; for (i = 0; i < netbits; i++) { IP_BIT_SET(((Ip_u16*) mask)[i / 16], ip_htons(0x8000 >> (i % 16))); } #endif } /* *=========================================================================== * ipmip_util_cmp_bitarray *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL Ip_bool ipmip_util_cmp_bitarray(void *bitarray1, void *bitarray2, int bits) { int blen; int plen; /* Convert to bytes. */ plen = bits >> 3; /* Any bits left in the next byte that we need to match? */ blen = bits & 7; /* Check the whole bytes. */ if (ipcom_memcmp(bitarray1, bitarray2, plen) != 0) return IP_FALSE; if (blen) { /* Create a usable mask */ blen = (Ip_u8) (0xff00 >> blen); /* Match */ return (((Ip_u8 *)bitarray1)[plen] & blen) == (((Ip_u8 *)bitarray2)[plen] & blen); } /* Match? */ return IP_TRUE; } /* *=========================================================================== * ipmip_util_hash_foreach *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL void ipmip_util_hash_foreach(Ipmip_context_t *ctx, Ipmip_proc_t *proc, Ipcom_hash *hash, Ipmip_util_hash_foreach_t func, void *arg1, void *arg2) { struct Ipmip_util_cbinfo cbinfo; cbinfo.arg1 = arg1; cbinfo.arg2 = arg2; cbinfo.ctx = ctx; cbinfo.func = func; cbinfo.proc = proc; ipcom_hash_for_each(hash, (Ipcom_hash_foreach_cb_func) ipmip_util_hash_foreach_cb, &cbinfo); } IP_GLOBAL void ipmip_util_hash_free(Ipcom_hash *hash, Ipmip_util_hash_free_t func) { struct Ipmip_util_freeinfo cbinfo; cbinfo.func = func; cbinfo.hash = hash; ipcom_hash_for_each(hash, (Ipcom_hash_foreach_cb_func) ipmip_util_hash_free_cb, &cbinfo); } #define IPMIP_UTIL_STRLIST_SPACE " \t,;" /* *=========================================================================== * ipmip_sysvar_explode *=========================================================================== * Description: Parses a command string to the traditional argc and argv * arguments. * Parameters: * Returns: */ IP_GLOBAL Ip_u8 * ipmip_util_explode(const char *arg_str) { int pos = 0; int arg_str_len; Ip_bool endreq = IP_FALSE; Ip_bool escaped = IP_FALSE; char *endstr = IP_NULL; Ip_u8 *cptr = IP_NULL; Ip_u8 *sptr = IP_NULL; Ip_u8 *nptr = IP_NULL; Ip_u8 *dblock; enum { skipping_space, searching_end_of_arg } state; state = skipping_space; arg_str_len = ipcom_strlen(arg_str); endstr = IPMIP_UTIL_STRLIST_SPACE; dblock = ipcom_malloc((arg_str_len + 1) * 2 + 1); if(dblock == IP_NULL) return IP_NULL; nptr = dblock; sptr = cptr = dblock + 1; *nptr = 0; while(pos < arg_str_len) { switch(state) { case skipping_space: endstr = IPMIP_UTIL_STRLIST_SPACE; if (!escaped) { if(ipcom_strchr(IPMIP_UTIL_STRLIST_SPACE, arg_str[pos])) break; if(arg_str[pos] == '\'') { endstr = "\'"; endreq = IP_TRUE; pos++; } else if(arg_str[pos] == '"') { endstr = "\""; endreq = IP_TRUE; pos++; } else if (arg_str[pos] == '\\') escaped = IP_TRUE; } #if 0 else /* We've processed the escaped character */ escaped = IP_FALSE; #endif /* Start building the argument */ sptr = cptr++; *sptr = 1; (*nptr)++; /* Unless escaped; advance past the first character */ if (!escaped) { *cptr++ = (Ip_u8)arg_str[pos]; (*sptr)++; } state = searching_end_of_arg; break; case searching_end_of_arg: if (!escaped) { if (arg_str[pos] == '\\') escaped = IP_TRUE; else if(ipcom_strchr(endstr, arg_str[pos])) { state = skipping_space; *cptr++ = '\0'; (*sptr)++; endreq = IP_FALSE; } else { *cptr++ = (Ip_u8)arg_str[pos]; (*sptr)++; } } else { escaped = IP_FALSE; *cptr++ = (Ip_u8)arg_str[pos]; (*sptr)++; } break; default: IP_PANIC(); break; } pos++; } if(state == searching_end_of_arg && endreq == IP_TRUE) goto err; else { *cptr++ = '\0'; (*sptr)++; } /* Zero termination */ *cptr++ = 0; return dblock; err: if(dblock != IP_NULL) ipcom_free(dblock); return IP_NULL; } /* *=========================================================================== * ipmip_sysvar_explode *=========================================================================== * Description: Parses a command string to the traditional argc and argv * arguments. * Parameters: * Returns: */ IP_GLOBAL char ** ipmip_util_strarr(const char *buf, Ip_size_t *numelem) { Ip_u8 *dblock = ipmip_util_explode(buf); if (dblock) { Ip_u8 *sptr; Ip_size_t i; Ip_u8 *sbuf; char **ptrarr; if (*dblock == 0) { ipcom_free(dblock); return IP_NULL; } for (i = 0, sptr = dblock + 1; *sptr != 0; sptr += *sptr) i += *sptr; sbuf = ipcom_calloc(1, (sizeof(char **) * (*dblock + 1)) + i); ptrarr = (char **)sbuf; sbuf += sizeof(char **) * (*dblock + 1); /* OK */ for (i = 0, sptr = dblock + 1; *sptr != 0; sptr += *sptr, i++) { ptrarr[i] = (char *)sbuf; ipcom_memcpy(ptrarr[i], sptr + 1, *sptr - 1); sbuf += *sptr - 1; } ipcom_free(dblock); if (numelem) *numelem = i; return ptrarr; } return IP_NULL; } /* *=========================================================================== * ipmip_util_strnncmp *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL Ip_bool ipmip_util_strnncmp(const char *str1, Ip_size_t str1_len, const char *str2, Ip_size_t str2_len) { str1_len = ipmip_util_strnlen(str1, str1_len); str2_len = ipmip_util_strnlen(str2, str2_len); if (str1_len != str2_len) return IP_FALSE; return ipcom_strncmp(str1, str2, str1_len) == 0; } /* *=========================================================================== * ipmip_util_strnncmp *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL Ip_size_t ipmip_util_strstrip0(const char *str1, Ip_size_t str1_len) { while (str1_len > 0) { if (str1[str1_len - 1] == '\0') str1_len--; else break; } /* Return the stripped value */ return str1_len; } /* *=========================================================================== * ipmip_util_strnncmp *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL Ip_bool ipmip_util_strnnmatch(const char *str1, Ip_size_t str1_len, const char *str2, Ip_size_t str2_len) { str1_len = ipmip_util_strnlen(str1, str1_len); str2_len = ipmip_util_strnlen(str2, str2_len); /* Exact match? */ if (str1_len == str2_len && ipcom_strncmp(str1, str2, str1_len) == 0) return IP_TRUE; if (str1[0] == '@' || str1[0] == '*') { /* Match tail */ str1 = &str1[1]; str1_len--; if (str2_len >= str1_len) { if (ipcom_strncmp(str1, &str2[str2_len - str1_len], str1_len) == 0) return IP_TRUE; } } if (str2[0] == '@' || str2[0] == '*') { str2 = &str2[1]; str2_len--; if (str1_len >= str2_len) { if (ipcom_strncmp(str2, &str1[str1_len - str2_len], str2_len) == 0) return IP_TRUE; } } return IP_FALSE; } /* *=========================================================================== * ipmip_util_hdrprintf *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL void ipmip_util_hdrprintf(Ipmip_proc_t *proc, int tabs, const char *header, Ip_size_t hdr_size, const char *format, ...) { va_list ap; ipmip_util_print_tabs(tabs); ipmip_util_print_hdr(proc, header? header : "", hdr_size, ":"); va_start(ap, format); ipcom_vsnprintf(proc->ntop.ntop_pbuf, sizeof(proc->ntop.ntop_pbuf), format , ap); ipcom_printf(proc->ntop.ntop_pbuf); va_end(ap); } /* *=========================================================================== * ipmip_util_identprintf *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL void ipmip_util_identprintf(Ipmip_proc_t *proc, int tabs, const char *format, ...) { va_list ap; va_start(ap, format); ipcom_vsnprintf(proc->ntop.ntop_pbuf, sizeof(proc->ntop.ntop_pbuf), format , ap); ipmip_util_bidentprintf(proc, tabs, proc->ntop.ntop_pbuf); va_end(ap); } /* *=========================================================================== * ipmip_util_hdrprintf *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL void ipmip_util_cmdprintf(Ipmip_proc_t *proc, int tabs, const char *cmd, const char *format, ...) { va_list ap; ipmip_util_print_tabs(tabs); ipcom_printf("%s"IP_LF, cmd); va_start(ap, format); ipcom_vsnprintf(proc->ntop.ntop_pbuf, sizeof(proc->ntop.ntop_pbuf), format , ap); va_end(ap); if (ipcom_strstr(proc->ntop.ntop_pbuf, IP_LF)) { ipmip_util_bidentprintf(proc, tabs + 1, proc->ntop.ntop_pbuf); ipcom_printf(IP_LF); } else { ipmip_util_print_tabs(tabs + 1); ipcom_printf("%s"IP_LF, proc->ntop.ntop_pbuf); } } /* *=========================================================================== * ipmip_util_bool_safe *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL Ip_bool ipmip_util_bool_safe(const Ip_bool *bptr) { Ip_bool sbool; ipcom_memcpy(&sbool, bptr, sizeof(sbool)); return sbool; } /* *=========================================================================== * ipmip_util_syslog_priority *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL int ipmip_util_syslog_priority(const char *val) { /**/ return ipmip_sysvar_cmd_str_to_key(ipmip_util_sysvar_ops, val); } /* *=========================================================================== * ipmip_util_syslog_priority_name *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL const char * ipmip_util_syslog_priority_name(Ip_u32 val) { int i; for (i = 0; ipmip_util_sysvar_ops[i].str != 0; i++) { if (ipmip_util_sysvar_ops[i].key == (signed)val) return ipmip_util_sysvar_ops[i].str; } return "Unknown"; } IP_GLOBAL Ip_u32 ipmip_util_route_table_alloc(struct Ipmip_context *ctx, struct Ipmip_proc *proc) { struct Ip_sioc_route_table iftable; ipcom_memset(&iftable, 0, sizeof(iftable)); iftable.table = IPCOM_ROUTE_TABLE_ANY; iftable.vr = ctx->vr; (void)ipmip_util_ioctl(ctx, proc, IP_SIOCADDROUTETAB, &iftable); return iftable.table; } IP_GLOBAL void ipmip_util_route_table_free(struct Ipmip_context *ctx, struct Ipmip_proc *proc, Ip_u32 table) { struct Ip_sioc_route_table iftable; ipcom_memset(&iftable, 0, sizeof(iftable)); iftable.table = table; iftable.vr = ctx->vr; /* Delete the route tables */ (void)ipmip_util_ioctl(ctx, proc, IP_SIOCDELROUTETAB, &iftable); } IP_GLOBAL Ip_u8 * ipmip_util_values_to_hexarray(const char *value, Ip_size_t *size) { char **values = ipmip_util_strarr(value, IP_NULL); Ip_u8 *ptrarr; int i; Ip_size_t sz = 0; if (values == IP_NULL) return IP_NULL; for (i = 0; values[i] != IP_NULL; i++) { Ip_size_t vlen = ipcom_strlen(values[i]); if (ipcom_strncasecmp(values[i], "0x", 2) == 0) { vlen -= 2; vlen = (vlen + 1) / 2; if (vlen == 3) vlen++; if (vlen > 4) { ipcom_free(values); return IP_NULL; } } sz += vlen; } ptrarr = ipcom_malloc(sz); if (ptrarr == IP_NULL) { ipcom_free(values); return IP_NULL; } for (sz = 0, i = 0; values[i] != IP_NULL; i++) { Ip_size_t vlen = ipcom_strlen(values[i]); if (ipcom_strncasecmp(values[i], "0x", 2) == 0) { Ip_u32 v = ipcom_strtoul(values[i], IP_NULL, 0); vlen -= 2; vlen = (vlen + 1) / 2; switch (vlen) { case 1: ptrarr[sz] = (Ip_u8)v; break; case 2: IP_SET_HTONS(&ptrarr[sz], (Ip_u16)v); break; /* coverity[unterminated_case] */ case 3: vlen++; /* this is an intentional fall through to the next case */ case 4: IP_SET_HTONL(&ptrarr[sz], (Ip_u32)v); break; } } else { /* Copy */ ipcom_memcpy(&ptrarr[sz], values[i], vlen); } sz += vlen; } *size = sz; ipcom_free(values); return ptrarr; } IP_GLOBAL Ip_u64 ipmip_util_bswap64(Ip_u64 *u64) { Ip_u64 val; ipcom_memcpy(&val, u64, sizeof(val)); return IPMIP_BSWAP64(val); } IP_GLOBAL Ip_time_t ipmip_util_safe_time_t(const Ip_time_t *tt) { Ip_time_t ntt; ipcom_memcpy(&ntt, tt, sizeof(ntt)); return ntt; } IP_GLOBAL Ip_u64 ipmip_util_safe_u64(const Ip_u64 *tt) { Ip_u64 ntt; ipcom_memcpy(&ntt, tt, sizeof(ntt)); return ntt; } /* **************************************************************************** * 11 PUBLIC FUNCTIONS **************************************************************************** */ /* **************************************************************************** * END OF FILE **************************************************************************** */