/*
 *===========================================================================
 *                    ipnet_cmd_qc_parse_port_range
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC int
ipnet_cmd_qc_parse_port_range(const char *str, Ip_u16 *lo_port, Ip_u16 *hi_port)
{
    char *end;

    if (*str != '-')
        *lo_port = (Ip_u16) ipcom_strtol(str, &end, 10);
    else
    {
        *lo_port = 0;
        end = (char *) str + 1;
    }

    if (end == IP_NULL || ipcom_strlen(end) == 0)
        *hi_port = *lo_port;
    else
    {
        if (*end == '-')
            end++;
        if (ipcom_strlen(end) == 0)
            *hi_port = 0xffff;
        else
            *hi_port = (Ip_u16) ipcom_strtol(end, &end, 10);
    }
    if (*hi_port < *lo_port)
        return -IP_ERRNO_EINVAL;

    return 0;
}
/*
 *===========================================================================
 *                    ipdnsc_hostent_insert_name
 *===========================================================================
 * Description: Inserts a host name in a hostent structure
 * Parameters:  he - pointer to the hostent structure
 *              name - the name to insert
 * Returns:     0 for OK, -1 for fail.
 */
IP_GLOBAL Ip_s32
ipdnsc_hostent_insert_name(struct Ip_hostent *he, char *name)
{
    if (he == IP_NULL)
        return -1;

    if (ipcom_strlen(name) > (IPDNSC_MAXNAME-1))
        return -1;

    /* Free the memory for the current name if any */
    if (he != IP_NULL && he->h_name != IP_NULL)
    {
        ipcom_free(he->h_name);
    }
    /* Allocate storage for the host name */
    he->h_name = ipcom_malloc(ipcom_strlen(name)+1);
    if (he->h_name == IP_NULL)
    {
        return -1;
    }
    /* Copy the host name */
    ipcom_strcpy(he->h_name, name);

    return 0;

}
IP_PUBLIC int
ipcom_strerror_r(int errnum, char * buf, Ip_size_t buflen)
{
    char * name;
    int n;

    if (buf == NULL)
        return -1;

#if IP_PORT_VXWORKS >= 60
    name = ipcom_strerror_int_vxworks(errnum);
#else
    name = ipcom_strerror_int(errnum);
#endif

    if (name)
    {
        ipcom_strncpy(buf, name, buflen);
        buf[buflen-1] = '\0';
        n = ipcom_strlen(name);
    }
    else
    {

#ifdef IP_PORT_VXWORKS
        n = ipcom_snprintf(buf, buflen, "errno = %#x", errnum);
#else
        n = ipcom_snprintf(buf, buflen, "Unknown error: %d", 0xffff & errnum);
#endif
    }

    return (n < buflen) ? 0 : IP_ERRNO_ERANGE;
}
/*
 *===========================================================================
 *                    ipnet_cmd_qc_parse_rate
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC Ip_bool
ipnet_cmd_qc_parse_rate(const char *str_rate, Ip_u32 *rate)
{
    char   *end;

    *rate = (Ip_u32) ipcom_strtol(str_rate, &end, 10);
    if (end && ipcom_strlen(end) > 0)
    {
        if (ipcom_strcmp(end, "kbps") == 0)
            *rate *= 1000;
        else if (ipcom_strcmp(end, "Mbps") == 0)
            *rate *= 1000000;
        else if (ipcom_strcmp(end, "kbit") == 0)
            *rate *= 1000 / 8;
        else if (ipcom_strcmp(end, "Mbit") == 0)
            *rate *= 1000000 / 8;
        else if (ipcom_strcmp(end, "bit") == 0)
            *rate /= 8;
        else if (ipcom_strcmp(end, "bps") == 0)
            ;
        else
        {
            ipcom_printf("'%s' is an unsupported rate suffix"IP_LF, end);
            return IP_FALSE;
        }
    }
    return IP_TRUE;
}
/*
 *===========================================================================
 *                    ipnet_cmd_qc_parse_number
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC Ip_bool
ipnet_cmd_qc_parse_number(const char *str_num, Ip_u32 *num)
{
    char *end;
    long  lnum;

    lnum = ipcom_strtol(str_num, &end, 10);
    if (lnum < 0)
        *num = 0;
    else
        *num = (Ip_u32) lnum;

    if (end && ipcom_strlen(end) > 0)
    {
        if (ipcom_strcmp(end, "k") == 0 || ipcom_strcmp(end, "kb") == 0)
            *num *= 1000;
        else if (ipcom_strcmp(end, "M") == 0 || ipcom_strcmp(end, "Mb") == 0)
            *num *= 1000000;
        else
        {
            ipcom_printf("'%s' is an unsupported number suffix"IP_LF, str_num);
            return IP_FALSE;
        }
    }
    return IP_TRUE;
}
/*
 *===========================================================================
 *                    ipnet_nat_proxy_sip_keyfind
 *===========================================================================
 * Description: Find a string in a structured message.
 *              This routine searches a string in a structured message.
 *              It assumes the searched string always starts at the beginning
 *              of each line of data terminated by \r\n characters. A message
 *              should be terminated by \r\n preceded by the line terminator
 *              \r\n.
 * Parameters:  pdata     - pointer to message.
 *              pstr      - key to look for.
 *              ppos      - found string position relative to pdata.
 *              searchlen - searchlen.
 * Returns:     IP_TRUE  = found key.
 *              IP_FALSE = key not found.
 */
IP_STATIC Ip_bool
ipnet_nat_proxy_sip_keyfind(char *pdata,
                            char *pstr,
                            int  *ppos,
                            int  searchlen)
{
    char *pstart = pdata;
    int        i = 0;

    if (!searchlen)
        searchlen = 1000;  /* max default search length */

    while (IP_TRUE)
    {
        if (pstr)
        {
            /* skip all space */
            while (*pdata == ' ')
                pdata++;

            if (ipcom_memcmp(pdata, pstr, ipcom_strlen(pstr)) == 0)
                break;
        }

        /* advance to next line */
        for (i = 0; i < (searchlen - 1); i++)
        {
            if (pdata[i] == '\r')
                if (pdata[i+1] == '\n')
                    break;
        }

        if (i >= (searchlen - 1))
        {
            IPCOM_LOG1(ERR, "ipnet_nat_proxy_sip_keyfind() :: single message exceeds max len: %d", searchlen);
            *ppos = searchlen;  /* reaches the end */
            return IP_FALSE;
        }

        pdata += i + 2;
        searchlen -= (i + 2);

        if ((pdata[0] == '\r' && pdata[1] == '\n') || (searchlen <= 0))
        {
            /* reach the end mark \r\n\r\n */
            if (searchlen)
                pdata += 2;

            *ppos = pdata - pstart;

            return (pstr ? IP_FALSE : IP_TRUE);
        }
    }

    *ppos = pdata - pstart;
    return IP_TRUE;
}
/*
 *===========================================================================
 *                    ipdnsc_hostent_insert_alias
 *===========================================================================
 * Description: Inserts an alias name in a hostent structure
 * Parameters:  he - pointer to the hostent structure
 *              name - the name to insert
 * Returns:     0 for OK, -1 for fail.
 */
IP_GLOBAL Ip_s32
ipdnsc_hostent_insert_alias(struct Ip_hostent *he, char *name)
{
    Ip_s32 num_alias, i=0;
    char **tmp;

    if (ipcom_strlen(name) > (IPDNSC_MAXNAME-1))
        return -1;

    /* Find out the current number of aliases */
    num_alias = ipdnsc_hostent_alias_count(he);

    /* Allocate memory for the another alias list entry */
    tmp = ipcom_realloc(he->h_aliases, (num_alias+1) * sizeof(char *));
    if(tmp == IP_NULL)
        return -1;
    he->h_aliases = tmp;

    /* Allocate memory for the alias */
    he->h_aliases[num_alias-1] = ipcom_malloc(ipcom_strlen(name)+1);
    if (he->h_aliases[num_alias-1] == IP_NULL)
    {
        /* We have to free to whole list here */
        while (he->h_aliases[i] != IP_NULL)
        {
		    ipcom_free(he->h_aliases[i]);
            i++;
        }
        /* Free the alias list */
	    ipcom_free(he->h_aliases);
        he->h_aliases = IP_NULL;
        return -1;
    }

    /* Set the alias */
    ipcom_strcpy(he->h_aliases[num_alias-1], name);

    /* Null terminate the list */
    he->h_aliases[num_alias] = IP_NULL;

    return 0;

}
/*
 *===========================================================================
 *                           netsysctlname2oid
 *===========================================================================
 * Description:
 * Parameters:  ctl -
 *              name -
 *              pNewName -
 *              nameLen -
 * Returns:
 *
 */
IP_PUBLIC int
netsysctlname2oid(Ipnet_cmd_sysctl *ctl, char* name, int* pNewName, int* nameLen)
{
#ifdef IPCOM_USE_INET
    int i;
  
    if(ctl == IP_NULL)
    {
        ctl = ipnet_sysctl_inet_table;
        pNewName[(*nameLen)++] = IP_IPPROTO_IP;
    }
    
    /* if you want to support trunk node, pls change this function */
    while (ctl->comp != IP_NULL)
    {
        if (IP_BIT_ISSET(ctl->argument, IPNET_CMD_SYSCTL_NETIF_NO))
        {
            if (ipcom_strcasecmp(name, ctl->comp) == 0)
            {
                for (i = 0; ctl->ctl[i] != -1; i++);
                pNewName[(*nameLen)++] = ctl->ctl[i ? i-1 : i];
            }
        }
        
        /* Do the netifs */
        if (IP_BIT_ISSET(ctl->argument, IPNET_CMD_SYSCTL_NETIF_YES))
        {
            /* Dump the arguments */
            char **argv = ipnet_cmd_sysctl_dump_netif();

            if (argv)
            {
                for (i = 0; argv[i] != IP_NULL; i++)
                {
                    if(ipcom_strcasecmp(name, argv[i])==0)
                    {
                        name += ipcom_strlen(argv[i]) + 1;
                        pNewName[(*nameLen)++] = i;
                        netsysctlname2oid(ipnet_sysctl_inet_table, name, pNewName, nameLen);
                    }
                    
                    ipcom_free(argv[i]);
                }
                
                ipcom_free(argv);
            }
        }
        
        ctl++;
    }
#endif
    
    return 0;
}
IP_PUBLIC char *
ipcom_strdup(const char *s1)
{
    char *s2;

    s2 = ipcom_malloc(ipcom_strlen(s1) + 1);
    if(s2 == IP_NULL)
        return IP_NULL;

    ipcom_strcpy(s2, s1);
    return s2;
}
/*
 *===========================================================================
 *                    ipcom_env_create
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_STATIC Ipcom_env_entry *
ipcom_env_create(const char *name, const char *value)
{
    Ip_size_t        name_length;
    Ip_size_t        value_length;
    Ipcom_env_entry *env;

    /* Create environment variable */
    name_length = ipcom_strlen(name) + 1;
    value_length = ipcom_strlen(value) + 1;
    env = ipcom_malloc(sizeof(Ipcom_env_entry) + name_length + value_length);
    if(env == IP_NULL)
        return IP_NULL;

    /* Init environment variable */
    env->name  = (const char *)env + sizeof(Ipcom_env_entry);
    ipcom_memcpy((void *)env->name, name, name_length);
    env->value = env->name + name_length;
    ipcom_memcpy((void *)env->value, value, value_length);

    return env;
}
/*
 *===========================================================================
 *                    ipnet_nat_proxy_dns_ptr_name
 *===========================================================================
 * Description: Convert an Internet address to a domain name.
 * Parameters:  buf    - buffer to store the domain name in.
 *              buflen - length of domain name buffer.
 *              addr   - pointer to Internet address.
 *              family - address family.
 *              zone   - top level domain.
 * Returns:     The length of the domain name or -1 if failed.
 */
IP_STATIC int
ipnet_nat_proxy_dns_ptr_name(Ip_u8 *buf, int buflen, Ip_u8 *addr, int family, Ip_u8 *zone)
{
    int i, j, second, zonelen;
    Ip_u8 tmp;

    zonelen = ipcom_strlen((char *)zone) + 1;
    i = 0;
    if (family == IP_AF_INET)
    {
        /* Reverse ipv4 address */
        for (j=3; j>=0; j--)
        {
            second = 0;

            /* possible hundreds digit */
            tmp = addr[j] / 100;
            if (tmp)
            {
                if (buflen - i < 1)
                    return -1;                  /* Too small buffer */
                buf[i++] = '0' + tmp;
                second = 1;
            }
            tmp = addr[j] % 100;

            /* possible tens digit */
            if ((tmp / 10) || second)
            {
                if (buflen - i < 1)
                    return -1;                  /* Too small buffer */
                buf[i++] = '0' + tmp / 10;
            }

            /* always print ones digit */
            if (buflen - i < 2)
                return -1;                      /* Too small buffer */
            buf[i++] = '0' + tmp % 10;
            buf[i++] = '.';
        }

        /* Append the zone */
        if (buflen - i < zonelen)
            return -1;                          /* Too small buffer */
        ipcom_strcpy((char *)&buf[i], (char *)zone);
        i += zonelen;
    }
    return i;
}
Beispiel #12
0
/*
 *===========================================================================
 *                    ipcom_sysvar_unset
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_PUBLIC Ip_err
ipcom_sysvar_unset(const char *name)
{
    Ipcom_sysvar_entry *sysvar;
    Ip_err              retval;
    Ip_size_t           namelen;
    Ipcom_sysvar_tree   *tree;

    retval = ipcom_once(&ipcom_sysvar_once, ipcom_sysvar_init, IP_NULL);
    if (retval != IPCOM_SUCCESS)
        return retval;

    namelen = ipcom_strlen(name);
    if (name[namelen-1] == '*')
        return ipcom_sysvar_for_each(name, ipcom_sysvar_unset_cb, IP_NULL);

    IPCOM_CODE_LOCK();

    tree = ipcom_sysvar_tree_get(-1);
    if (tree == IP_NULL)
    {
        retval = IPCOM_ERR_NO_MEMORY;
        goto leave;
    }

    retval = IPCOM_ERR_NOT_FOUND;
    sysvar = ipcom_hash_get(tree->sysvars, name);
    if (sysvar)
    {
        if(IP_BIT_ISSET(sysvar->flags, IPCOM_SYSVAR_FLAG_READONLY))
            retval = IPCOM_ERR_READONLY;
        else
        {
            ipcom_sysvar_release(tree, sysvar);
            retval = IPCOM_SUCCESS;
        }
    }

 leave:
    ipcom_sysvar_tree_done(tree);
    IPCOM_CODE_UNLOCK();
    return retval;
}
/*****************************************************************************
 *
 * example_get_line - Fetch the next available line into the tokenizer buffer
 *
 * .IP <tok>
 * The tokenizer buffer
 *
 * RETURNS:
 * IP_TRUE on success, IP_FALSE if we're at EOF.
 *
 * NOMANUAL
 */
IP_STATIC Ip_bool
example_get_line(example_token_buffer_t *tok)
{
    char *line;
    char *t;

restart:
    /* Already EOF */
    if (tok->eof)
        return IP_FALSE;

    /* Get next */
    line =  ipcom_strtok_r(tok->lines, "\r\n", &tok->llines);
    tok->curline++;
    tok->lines = IP_NULL;

    /* No more lines? */
    if (line == IP_NULL)
    {
        tok->eof = IP_TRUE;
        return IP_FALSE;
    }

    /* Discard comments */
    t = ipcom_strchr(line, '#');
    if (t)
        *t = '\0';

    /* Empty line; restart */
    if (ipcom_strlen(line) == 0)
        goto restart;

    /* Set the tokens; discard any stored values */
    tok->tokens     = line;
    tok->spec       = IP_NULL;

    return IP_TRUE;
}
Beispiel #14
0
/*
 *===========================================================================
 *                      ipnet_if_mib_table_search_ifTable
 *===========================================================================
 * Description: Searches ifTable and ifXTable for a matching entry
 * Parameters: id, buf, best, cmd
 * Returns:    The best matching interface or IP_NULL if no match was found,
 *             error code is stored in 'ret' in that case.
 *
 */
IP_STATIC Ipnet_netif *
ipnet_if_mib_table_search_ifTable(char *id,
                                  char *buf,
                                  char *best,
                                  Ip_s32 cmd,
                                  Ip_s32 *error_code)
{
    Ip_u32       bestindex = 0;
    Ip_u32       ifIndex;
    Ip_u32      *ifindexes;
    unsigned     ifTable_num_entries;
    unsigned     i;

    ifindexes = ipnet_if_get_index_array(IPCOM_VR_ANY, 0, &ifTable_num_entries);
    if (ifindexes == IP_NULL)
    {
        *error_code = IPSNMP_ERROR_GENERROR;
        return IP_NULL;
    }

    for (i = 0; i < ifTable_num_entries; i++)
    {
        Ip_s32 lex, len = 0;

        buf[0] = '\0';

        ifIndex = ifindexes[i];

        if (ipcom_snprintf(&buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, "%d.", (int)ifIndex) < 0)
        {
            *error_code = IPSNMP_ERROR_GENERROR;
            ipcom_free(ifindexes);
            return IP_NULL;
        }
        len = ipcom_strlen(buf);
        if (len)
            buf[len - 1] = '\0';

        lex = ipsnmp_util_lexcmp_oid(buf, id);
        if (cmd == IPSNMP_MIB_COMMAND_NEXT)
        {
            if (lex > 0)
            {
                if (bestindex == 0 || ipsnmp_util_lexcmp_oid(buf, best) < 0)
                {
                    ipcom_strcpy(best, buf);
                    bestindex = ifIndex;
                }
            }
        }
        else
        {
            if (lex == 0)
            {
                ipcom_strcpy(best, buf);
                bestindex = ifIndex;
                break;
            }
        }
    }

    if (bestindex == 0)
        *error_code = IPSNMP_ERROR_NOSUCHNAME;
    ipcom_free(ifindexes);
    return ipnet_if_indextonetif(IPCOM_VR_ANY, bestindex);
}
Beispiel #15
0
/*
 *===========================================================================
 *                    ipcom_sysvar_getvr
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_GLOBAL char *
ipcom_sysvar_getvr(const char *name, char *value, Ip_size_t *value_size, Ip_bool usr, int vr)
{
    Ipcom_sysvar_entry  *sysvar;
    Ip_size_t           value_length;
    char                *ret_value = IP_NULL;
    Ip_err              retval;
    Ipcom_sysvar_tree   *tree;

    if (name == IP_NULL)
        return IP_NULL;

    retval = ipcom_once(&ipcom_sysvar_once, ipcom_sysvar_init, IP_NULL);
    if (retval != IPCOM_SUCCESS)
    {
        IP_PANIC();
        return IP_NULL;
    }

    IPCOM_CODE_LOCK();

    tree = ipcom_sysvar_tree_get(vr);
    if (tree == IP_NULL)
        goto leave;

    sysvar = ipcom_hash_get(tree->sysvars, name);
    if (sysvar)
    {
        if (value == IP_NULL)
        {
#ifdef IP_PORT_OSE5
            if (usr)
                ret_value = ipcom_strdup_usr(sysvar->value);
            else
#else
                (void)usr;
#endif
                ret_value = ipcom_strdup(sysvar->value);
        }
        else
        {
            value_length = ipcom_strlen(sysvar->value) + 1;
            if (value_length > *value_size)
            {
                ret_value = IP_NULL;
                *value_size = value_length;
            }
            else
            {
                ret_value = value;
                ipcom_memcpy(ret_value, sysvar->value, value_length);
                *value_size = value_length - 1;
            }
        }
    }
#ifdef IP_PORT_OSE5
    else
    {
        ret_value = ipcom_sysvar_get_ose5(name, value, value_size);
    }
#endif /* IP_PORT_OSE5 */

 leave:
    ipcom_sysvar_tree_done(tree);
    IPCOM_CODE_UNLOCK();
    return ret_value;
}
Beispiel #16
0
/*
 *===========================================================================
 *                    ipcom_sysvar_set_internal
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_GLOBAL Ip_err
ipcom_sysvar_set_tree(const char *name, const char *value, int flags, Ipcom_sysvar_tree *tree)
{
    Ip_size_t           name_length;
    Ip_size_t           value_length;
    Ipcom_sysvar_entry  *sysvar;
    Ip_err              retval = IPCOM_SUCCESS;

    /* Check for duplicate. */
    sysvar = ipcom_hash_get(tree->sysvars, name);
    if (sysvar)
    {
        if (IP_BIT_ISSET(sysvar->flags, IPCOM_SYSVAR_FLAG_READONLY))
        {
            retval = IPCOM_ERR_READONLY;
            goto leave;
        }
        else if (IP_BIT_ISFALSE(flags, IPCOM_SYSVAR_FLAG_OVERWRITE))
        {
            retval = IPCOM_ERR_DUPLICATE;
            goto leave;
        }
        else
        {
            flags |= sysvar->flags & IPCOM_SYSVAR_FLAG_KERNEL;
            ipcom_hash_remove(tree->sysvars, sysvar);
            ipcom_free(sysvar);
            goto set;
        }
    }

    /* No current entry found and not allowed to create a new entry. */
    if(IP_BIT_ISSET(flags, IPCOM_SYSVAR_FLAG_NOCREATE))
    {
        retval = IPCOM_ERR_FAILED;
        goto leave;
    }

    /* Add the new sysvar. */
 set:
     name_length = ipcom_strlen(name) + 1;
     value_length = ipcom_strlen(value) + 1;
     sysvar = ipcom_malloc(sizeof(Ipcom_sysvar_entry) + name_length + value_length);

     if(sysvar == IP_NULL)
     {
         retval = IPCOM_ERR_NO_MEMORY;
         goto leave;
     }

     sysvar->refcount = 1;
     sysvar->flags    = flags;
     if (IP_BIT_ISFALSE(flags, IPCOM_SYSVAR_FLAG_INIT))
     {
         tree->modified = IP_TRUE;
         sysvar->flags |= IPCOM_SYSVAR_FLAG_MODIFIED;
     }
     sysvar->name     = (const char *)sysvar + sizeof(Ipcom_sysvar_entry);
     ipcom_memcpy((void *)sysvar->name, name, name_length);
     sysvar->value    = sysvar->name + name_length;
     ipcom_memcpy((void *)sysvar->value, value, value_length);

     retval = ipcom_hash_add(tree->sysvars, sysvar);

 leave:
    return retval; /*lint !e429 Custodial pointer 'sysvar' has not been freed or returned */
}
/*
 *===========================================================================
 *                    ipnet_nat_proxy_sip_payload_parse
 *===========================================================================
 * Description: Parse SIP payload.
 * Parameters:  appdata   - pointer to application data.
 *              applen    - pointer to length of application data.
 *              growspace - space available to extend application data.
 *              param     - pointer to proxy parameters.
 *              newdata   - pointer to pointer to new application data.
 * Returns:     IP_TRUE  = Packet modified.
 *              IP_FALSE = Packet untouched.
 */
IP_STATIC Ip_bool
ipnet_nat_proxy_sip_payload_parse(Ip_u8 *appdata,
                                  int   *applen,
                                  int    growspace,
                                  Ipnet_nat_proxy_param *param,
                                  Ip_u8 **newdata)

{
    char    *psipmsg = (char *)appdata;
    char    *pcallid = IP_NULL;
    char    *pendstr, *pstartstr, *psearch;
    Ip_bool  retcode = IP_FALSE;
    int      pos, sdpdatalen, searchlen, msgtype = 0;
    char     tmpholder[50];
    char     laddrstr[20];
    char     gaddrstr[20];
    char    *pend = (char *)sipbuf + *applen - 1;
    char    *sdplen_start, *sdplen_end, *sdp_end;
    int      newlen, diff;

    if (param->incoming == IP_TRUE)
    {
        /* Incoming message*/
        goto parseFalseExit;
    }

    if (param->inbound == IP_FALSE)
    {
        /* Outbound session */
        if ((psipmsg = ipnet_nat_proxy_sip_outboundmsgtypecheck(psipmsg, &msgtype, *applen)) == IP_NULL)
            return IP_FALSE;   /* not the message we're looking for */
    }
    else
    {
        /* Inbound session */
        if ((psipmsg = ipnet_nat_proxy_sip_inboundmsgtypecheck(psipmsg, &msgtype, *applen)) == IP_NULL)
            return IP_FALSE;   /* not the message we're looking for */
    }

    /* find the call-id field */
    if (ipnet_nat_proxy_sip_keyfind(psipmsg, SIP_CALLID_STR, &pos, *applen - (psipmsg - (char *)appdata)) == IP_FALSE)
    {
        IPCOM_LOG0(ERR, "ipnet_nat_proxy_sip_payload_parse() :: no callid field");
        return IP_FALSE;
    }

    /* get callid string */
    pcallid = ipnet_nat_proxy_sip_callidstr(psipmsg + pos + SIP_TAG_TO_DATAPOS(SIP_CALLID_STR));
    if (pcallid == IP_NULL)
    {
        IPCOM_LOG0(ERR, "ipnet_nat_proxy_sip_payload_parse() :: failed to parse callid string");
        return IP_FALSE;
    }

    if (msgtype == SIP_MSG_TYPE_INVITE)
    {
        if (param->inbound == IP_FALSE)
        {
            /* Update the mapping timeout */
            IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: setting mapping timeout to %d seconds",
                       IPNET_NAT_SIP_ENTRY_INVITE_TIMEOUT);
            ipnet_nat_proxy_set_mapping_timeout(IPNET_NAT_SIP_ENTRY_INVITE_TIMEOUT, param->mapping);
        }
        else
        {
            /* ALG will not detect the ACK for inbound calls so use the INVITE response to set established timeout */
            IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: setting mapping timeout to %d seconds",
                       IPNET_NAT_SIP_ENTRY_ESTABLISHED_TIMEOUT);
            ipnet_nat_proxy_set_mapping_timeout(IPNET_NAT_SIP_ENTRY_ESTABLISHED_TIMEOUT, param->mapping);
        }
    }
    else if (msgtype == SIP_MSG_TYPE_ACK)
    {
        /* Update the mapping timeout */
        IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: setting mapping timeout to %d seconds",
                   IPNET_NAT_SIP_ENTRY_ESTABLISHED_TIMEOUT);
        ipnet_nat_proxy_set_mapping_timeout(IPNET_NAT_SIP_ENTRY_ESTABLISHED_TIMEOUT, param->mapping);
    }

    /* Copy the message to scratch buffer and set pointer */
    if (*applen > (int)sizeof(sipbuf))
    {
        IPCOM_LOG0(ERR, "ipnet_nat_proxy_sip_payload_parse() :: message to long");
        goto parseFalseExit;
    }
    ipcom_memcpy(sipbuf, appdata, *applen);
    psipmsg = (char *)sipbuf + (psipmsg - (char *)appdata);

    /* first the via field
     * For response message, the Via field will not contain the private address.
     * The localAddrProcess() will check if the address is private.
     */

    laddrstr[0] = gaddrstr[0] = 0;
    if (ipnet_nat_proxy_sip_keyfind(psipmsg, SIP_VIA_STR, &pos, (pend - psipmsg) + 1) == IP_TRUE)
	{
        /* advance to IP/Port string */

        psipmsg += (pos + ipcom_strlen(SIP_VIA_STR) + SIP_VIA_FIELD_IPADDR_DIS);

        IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: parse via field");

        psipmsg = ipnet_nat_proxy_sip_localaddrprocess(psipmsg, laddrstr, gaddrstr, pcallid,
                                                       SIP_ADDRESS_PORT_STRING, param, &pend);

        if (psipmsg == IP_NULL)
            goto parseFalseExit;

    }

    /* find the contact field */

    if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_CONTACT_STR, &pos, (pend - psipmsg) + 1) == IP_TRUE)
    {
        /* advance to IP/Port string */

        psipmsg += (pos + ipcom_strlen(SIP_CONTACT_STR) + SIP_CTAC_FIELD_IPADDR_DIS);

        IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: parse contact field");

        psipmsg = ipnet_nat_proxy_sip_localaddrprocess(psipmsg, laddrstr, gaddrstr, pcallid,
                                                       SIP_ADDRESS_PORT_STRING, param, &pend);

        if (psipmsg == IP_NULL)
            goto parseFalseExit;
    }

    /* exit if there isn't any private info in SIP message header */

    if (laddrstr[0] == 0 || gaddrstr[0] == 0)
        goto parseFalseExit;

    /* When program reaches here, it indicates at least one place in the
     * packet should be modified. Use parseFalseExit only if it is an error
     */

    /* find the Content-Type field */

    if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_CONTYPE_STR, &pos, (pend - psipmsg) + 1) == IP_FALSE)
        goto parseTrueExit;

    /* advance to start of data field */

    psipmsg += (pos + SIP_TAG_TO_DATAPOS(SIP_CONTYPE_STR));

    SIP_SKIP_SPACES(psipmsg);

    /*check the application/sdp type, if not, exit */

    if (!SIP_IS_STRING_SAME(psipmsg, SIP_APPSDP_STR))
        goto parseTrueExit;

    /* find the content length field */

    if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_CONTLEN_STR, &pos, (pend - psipmsg) + 1) == IP_FALSE)
        goto parseTrueExit;

    IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: parse Content-Length field");

    /* reach to the content length field, advance to length data */

    psipmsg += (pos + SIP_TAG_TO_DATAPOS(SIP_CONTLEN_STR));

    SIP_SKIP_SPACES(psipmsg);

    sdpdatalen = ipcom_strtol(psipmsg, &pendstr, 10);

    IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: data length = %d", sdpdatalen);

    if (sdpdatalen == 0)
        goto parseTrueExit;

    /* store start and end of sdp datalength string as well as end of message */
    sdplen_start = psipmsg;
    sdplen_end   = pendstr;
    sdp_end      = pend;

    /* advance to the start of SDP data */

    if (ipnet_nat_proxy_sip_keyfind (psipmsg, IP_NULL, &pos, (pend - psipmsg) + 1) == IP_FALSE)
    {
        IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: Can't find header end mark");
        goto parseTrueExit;
    }

    /* start of the SIP data field */

    psipmsg += pos;
    searchlen = sdpdatalen;

    /* search the local IP address, and replace it with global address */

    pstartstr = psipmsg;
    while (IP_TRUE)
    {
        psearch = ipnet_nat_proxy_sip_faststrsearch(laddrstr, ipcom_strlen(laddrstr),
                                                    pstartstr, searchlen, IP_FALSE);
        if (psearch != IP_NULL)
        {
            IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: Local IP address in SDP: %s", laddrstr);

            if (ipnet_nat_proxy_sip_modmsg(gaddrstr, ipcom_strlen(gaddrstr),
                                           psearch, ipcom_strlen(laddrstr), &pend) < 0)
            {
                goto parseFalseExit;
            }

            searchlen = searchlen - (psearch + ipcom_strlen(gaddrstr) - pstartstr);
            pstartstr = psearch + ipcom_strlen(gaddrstr);
        }
        else
            break;
    }

    IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_payload_parse() :: the last search length %d", searchlen);

    /* search for the audio port */

    if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_AUDIO_STR, &pos, sdpdatalen) == IP_TRUE)
    {
        /* advance to the port field */

        psipmsg += (pos + SIP_TAG_TO_DATAPOS(SIP_AUDIO_STR));

        SIP_SKIP_SPACES(psipmsg);
        ipnet_nat_proxy_sip_localaddrprocess(psipmsg, laddrstr, gaddrstr, pcallid, SIP_PORT_STRING, param, &pend);
    }

    /* search for the audio control port */

    if (ipnet_nat_proxy_sip_keyfind (psipmsg, SIP_RTCP_STR, &pos, sdpdatalen) == IP_TRUE)
	{
        /* advance to the port field */

        psipmsg += (pos + SIP_TAG_TO_DATAPOS(SIP_RTCP_STR));

        SIP_SKIP_SPACES(psipmsg);
        ipnet_nat_proxy_sip_localaddrprocess(psipmsg, laddrstr, gaddrstr, pcallid, SIP_PORT_STRING, param, &pend);
    }

    /* adjust the length node */

    sdpdatalen += pend - sdp_end;
    ipcom_sprintf(tmpholder, "%d", sdpdatalen);
    if (ipnet_nat_proxy_sip_modmsg(tmpholder, ipcom_strlen(tmpholder),
                                   sdplen_start, sdplen_end - sdplen_start, &pend) < 0)
    {
        goto parseFalseExit;
    }

parseTrueExit:
    /* Update application data with the modified buffer */
    newlen = pend - (char *)sipbuf + 1;
    diff = newlen - *applen;
    if (diff > growspace)
    {
        /* Must allocate a new buffer */
        *newdata = ipcom_malloc(*applen + diff);
        if (*newdata == IP_NULL)
        {
            IPCOM_LOG1(ERR, "ipnet_nat_proxy_sip_payload_parse() :: ipcom_malloc(%d) failed",
                            *applen + diff);
            goto parseFalseExit;
        }
        ipcom_memcpy(*newdata, sipbuf, newlen);
    }
    else
    {
        /* Let the current buffer grow */
        ipcom_memcpy(appdata, sipbuf, newlen);
    }
    *applen = newlen;
    IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_msg() :: the delta length = %d ", diff);
    retcode = IP_TRUE;

parseFalseExit:
    if (msgtype == SIP_MSG_TYPE_BYE)
        ipnet_nat_proxy_sip_endmsgprocess(pcallid, param);
    if (pcallid)
        ipcom_free(pcallid);
    return retcode;
}
Beispiel #18
0
/*
 *===========================================================================
 *                    ipcom_sysvar_hash_key
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_STATIC unsigned
ipcom_sysvar_hash_key(const char *key)
{
    return ipcom_hash_update(key, ipcom_strlen(key), 0);
}
/*
 *===========================================================================
 *                    ipnet_nat_proxy_sip_inboundmsgtypecheck
 *===========================================================================
 * Description: Find the type of inbound SIP message
 * Parameters:  psipmsg - pointer to buffer message
 *              ptype   - pointer to buffer for returned status
 * Returns:     Pointer to message after the type or IP_NULL
 *              if type not found.
 */
IP_STATIC char *
ipnet_nat_proxy_sip_inboundmsgtypecheck(char *psipmsg, int *ptype, int searchlen)
{
    int pos;

    /* check if the first 3 char is "SIP" */
    if (SIP_IS_STRING_SAME(psipmsg, SIP_SIP_STR))
    {
        /* yes, it is, check if it is status code 200 */
        psipmsg += 8;

        if (SIP_IS_STRING_SAME(psipmsg, SIP_200_OK_STR))
        {
            /* this is the status 200 OK message */
            psipmsg += ipcom_strlen(SIP_200_OK_STR);

            *ptype = SIP_MSG_TYPE_STATUS;

            /* check if the INVITE or BYE code */
            if (ipnet_nat_proxy_sip_keyfind(psipmsg, SIP_CSEQ_STR, &pos, searchlen) == IP_TRUE)
            {
                char * pbye;

                pbye = psipmsg + pos + SIP_TAG_TO_DATAPOS(SIP_CSEQ_STR);

                SIP_SKIP_SPACES(pbye);

                /* skip the number field */
                while (*pbye != ' ')
                    pbye++;

                SIP_SKIP_SPACES(pbye);

                if (SIP_IS_STRING_SAME (pbye, SIP_INVITE_STR))
                {
                    IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_inboundmsgtypecheck() :: STATUS(INVITE) message");
                    *ptype = SIP_MSG_TYPE_INVITE;
                }
                else if (SIP_IS_STRING_SAME (pbye, SIP_BYE_STR))
                {
                    IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_inboundmsgtypecheck() :: STATUS(BYE) message");
                    *ptype = SIP_MSG_TYPE_BYE;
                }
                else if (SIP_IS_STRING_SAME (pbye, SIP_CANCEL_STR))
                {
                    IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_inboundmsgtypecheck() :: STATUS(BYE) message");
                    *ptype = SIP_MSG_TYPE_BYE;
                }
            }
            return psipmsg;
        }
        return IP_NULL;
    }

    if (SIP_IS_STRING_SAME(psipmsg, SIP_BYE_STR))
    {
        IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_inboundmsgtypecheck() :: BYE message");
        psipmsg += ipcom_strlen(SIP_BYE_STR);
        *ptype = SIP_MSG_TYPE_BYE;
        return psipmsg;
    }
    else if (SIP_IS_STRING_SAME(psipmsg, SIP_MESSAGE_STR))
    {
        IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_sip_inboundmsgtypecheck() :: MESSAGE message");
        psipmsg += ipcom_strlen(SIP_MESSAGE_STR);
        *ptype = SIP_MSG_TYPE_MESSAGE;
        return psipmsg;
    }

    return IP_NULL;  /* not the SIP messages we want */
}
/*
 *===========================================================================
 *                    ipnet_nat_proxy_sip_localaddrprocess
 *===========================================================================
 * Description: Process the private transport address
 * Parameters:  pmsgstr    - pointer to message
 *              pipaddrstr - pointer to buffer for the local address string
 *              pgaddrstr  - pointer to buffer for the gloab address string
 *              pcallid    - pointer to the call id string
 *              type       - type of search
 *              ppend      - pointer to pointer to last byte of message
 * Returns:     The next character position after the parsed string or
 *	            IP_NULL if parse fails
 */
IP_STATIC char *
ipnet_nat_proxy_sip_localaddrprocess(char *pmsgstr,
                                     char *pipaddrstr,
                                     char *pgaddrstr,
                                     char *pcallid,
                                     int  type,
                                     Ipnet_nat_proxy_param *param,
                                     char **ppend)
{
    int localport, newport;
    int len, diff;
    Ip_u32 ipaddr;
    char *pstart;
    char tmpholder[30];
    Ipnet_nat_proxy_tuple proxy_tuple;

    (void)pcallid;
    SIP_SKIP_SPACES(pmsgstr);

    pstart = pmsgstr;
    pmsgstr = ipnet_nat_proxy_sip_addrportstrparse(pmsgstr, &ipaddr, &localport, type);

    if (pmsgstr == IP_NULL)
        return IP_NULL;

    if (!localport)
        localport = SIP_DEFAULT_PORT;

    if (type == SIP_ADDRESS_PORT_STRING)
    {
        ipaddr = ip_htonl(ipaddr);
        (void)ipcom_inet_ntop(IP_AF_INET, &ipaddr, pipaddrstr, 16);
        ipaddr = ip_ntohl(ipaddr);
    }
    else  /* PORT string only */
    {
        ipaddr = ipcom_inet_addr(pipaddrstr);
        ipaddr = ip_ntohl(ipaddr);
    }

    /* make sure it is the private address, otherwise no translation */

    if (ipaddr != param->tuple.private_addr)
        return pmsgstr;

    /* create a bind entry for this transport address if it hasn't been created yet */
    if (param->tuple.private_port != localport)
    {
        ipcom_memset(&proxy_tuple, 0, sizeof(proxy_tuple));
        proxy_tuple.protocol     = IP_IPPROTO_UDP;
        proxy_tuple.private_addr = ipaddr;
        proxy_tuple.private_port = localport;
        newport = ipnet_nat_proxy_add_mapping(&proxy_tuple,
                                              IPNET_NAT_SIP_ENTRY_MEDIA_TIMEOUT,
                                              param->mapping,
                                              IP_FALSE,         /* Use port translation */
                                              IP_TRUE,          /* Inbound session */
                                              IP_NULL,
                                              IP_NULL);

        if (newport < 0)
        {
            IPCOM_LOG2(ERR, "ipnet_nat_proxy_sip_localaddrprocess() :: Failed to add mapping for address = 0x%08x, port = %d",
                       ipaddr, localport);
        }
        else
        {
            IPCOM_LOG2(DEBUG, "ipnet_nat_proxy_sip_localaddrprocess() :: Added mapping for address = 0x%08x, port = %d",
                       ipaddr, localport);
        }
    }
    else
    {
        newport = param->nat_port;
        IPCOM_LOG2(DEBUG, "ipnet_nat_proxy_sip_localaddrprocess() :: Mapping already existed for address = 0x%08x, port = %d",
                   ipaddr, localport);
    }

    /* compose the new modified string */

    len = 0;
    if (type == SIP_ADDRESS_PORT_STRING)
    {
        ipaddr = ip_htonl(param->nat_addr);
        (void)ipcom_inet_ntop(IP_AF_INET, &ipaddr, tmpholder, 16);
        ipcom_strcpy(pgaddrstr, tmpholder);
        len = ipcom_strlen(tmpholder);
        tmpholder[len++]= ':';
    }
    ipcom_sprintf(tmpholder + len, "%d", newport);

    IPCOM_LOG1(DEBUG, "ipnet_nat_proxy_sip_localaddrprocess() new str: %s", tmpholder);


    if (ipnet_nat_proxy_sip_modmsg(tmpholder, ipcom_strlen(tmpholder),
                                   pstart, pmsgstr - pstart, ppend) < 0)
    {
        return IP_NULL;
    }

    diff = ipcom_strlen(tmpholder) - (pmsgstr - pstart);
    return pmsgstr + diff;
}
Beispiel #21
0
/*
 *===========================================================================
 *                      ipnet_if_mib_handler_ifTable
 *===========================================================================
 * Description: MIB handler for variables in ifTable
 * Parameters: See file 'ipsnmp.h'
 * Returns: IPSNMP_ERROR_XXX
 *
 */
IP_STATIC Ip_s32
ipnet_if_mib_handler_ifTable(Ip_s32 cmd,
                             char *id,
                             Ipsnmp_varbind *vb,
                             Ip_s32 magic,
                             struct Ipsnmp_node_object *nodeobj)
{
    Ip_s32          lid, ret = -1;
    Ipnet_netif    *best_netif;
    Ip_s32          ifAdminStatus = 0;
    char           *iid;
    char           *buf = ipcom_malloc(IPSNMP_CONFIG_MAX_OBJECT_ID);
    char           *best = ipcom_malloc(IPSNMP_CONFIG_MAX_OBJECT_ID);
    struct Ip_ifreq ifreq;
    Ip_fd           fd;

    if (buf == IP_NULL || best == IP_NULL)
    {
        ret = IPSNMP_ERROR_GENERROR;
        goto exit;
    }

    lid = ipsnmp_util_last_subid(nodeobj->id);
    ip_assert(lid >= 1 && lid <= 20);
    ip_assert(lid != 12 && lid != 18);
    best_netif = ipnet_if_mib_table_search_ifTable(id, buf, best, cmd, &ret);
    if (best_netif == IP_NULL)
        goto exit;

    if (cmd == IPSNMP_MIB_COMMAND_GET || cmd == IPSNMP_MIB_COMMAND_NEXT)
    {
        iid = ipsnmp_create_iid_direct(nodeobj->id, best);
        if (iid == IP_NULL)
        {
            ret = IPSNMP_ERROR_GENERROR;
            goto exit;
        }

        switch(lid)
        {
            case 1: /* ifIndex */
                ret = ipsnmp_util_put_integer(magic, iid, best_netif->ipcom.ifindex);
                break;
            case 2: /* ifDescr */
                ret = ipsnmp_util_put_octetstring(magic, iid, (Ip_u8 *)best_netif->ipcom.name, ipcom_strlen(best_netif->ipcom.name));
                break;
            case 3: /* ifType */
                ret = ipsnmp_util_put_integer(magic, iid, best_netif->ipcom.type);
                break;
            case 4: /* ifMtu */
                ret = ipsnmp_util_put_integer(magic, iid, best_netif->ipcom.mtu);
                break;
            case 5: /* ifSpeed */
                if (best_netif->ipcom.type == IP_IFT_PPP)
                    ret = ipsnmp_util_put_gauge32(magic, iid, IPCOM_DRV_PPP_BAUDRATE);
                else
                    ret = ipsnmp_util_put_gauge32(magic, iid, 100000000);
                break;
            case 6: /* ifPhysAddr */
                ret = ipsnmp_util_put_octetstring(magic, iid, best_netif->ipcom.link_addr, best_netif->ipcom.link_addr_size);
                break;
            case 7: /* ifAdminStatus */
                if (IP_BIT_ISSET(best_netif->ipcom.flags, IP_IFF_UP))
                    ret = ipsnmp_util_put_integer(magic, iid, 1);
                else
                    ret = ipsnmp_util_put_integer(magic, iid, 2);
                break;
            case 8: /* ifOperStatus */
                if (IP_BIT_ISSET(best_netif->ipcom.flags, IP_IFF_UP))
                    ret = ipsnmp_util_put_integer(magic, iid, 1);
                else
                    ret = ipsnmp_util_put_integer(magic, iid, 2);
                break;
            case 9: /* ifLastChange */
                ret = ipsnmp_util_put_timeticks(magic, iid, best_netif->ipcom.mib2.ifLastChange);
                break;
            case 10: /* ifInOctets */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInOctets);
                break;
            case 11: /* ifInUcastPkts */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInUcastPkts);
                break;
            case 13: /* ifInDiscards */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInDiscards);
                break;
            case 14: /* ifInErrors */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInErrors);
                break;
            case 15: /* ifInUnknownProtos */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInUnknownProtos);
                break;
            case 16: /* ifOutOctets */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutOctets);
                break;
            case 17: /* ifOutUcastPkts */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutUcastPkts);
                break;
            case 19: /* ifOutDiscards */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutDiscards);
                break;
            case 20: /* ifOutErrors */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutErrors);
                break;
            default:
                IP_PANIC();
                ret = IPSNMP_ERROR_GENERROR;
                break;
        }

        ipcom_free(iid);
    }

    if (cmd == IPSNMP_MIB_COMMAND_TEST || cmd == IPSNMP_MIB_COMMAND_SET)
    {
        switch(lid)
        {
            case 7: /* ifAdminStatus */
                ret = ipsnmp_util_get_integer(vb, &ifAdminStatus);
                if (ret == IPSNMP_ERROR_NOERROR)
                {
                    if (ifAdminStatus != 1 && ifAdminStatus != 2)
                    {
                        ret = IPSNMP_ERROR_WRONGVALUE;
                    }
                }

                if (ret == IPSNMP_ERROR_NOERROR && cmd == IPSNMP_MIB_COMMAND_SET)
                {
                    fd = ipnet_do_socket(IP_AF_INET, IP_SOCK_DGRAM, IP_IPPROTO_UDP, IP_FALSE);
                    if(fd != IP_INVALID_SOCKET)
                    {
                        /* Change interface status */
                        ipcom_memset(&ifreq, 0, sizeof(struct Ip_ifreq));
                        ipcom_strcpy(ifreq.ifr_name, best_netif->ipcom.name);
                        if (ipnet_sys_socketioctl(fd, IP_SIOCGIFFLAGS, &ifreq) < 0)
                        {
                            IPCOM_LOG1(ERR, "Failed to get interface flags: %s", ipcom_strerror(ipcom_errno));
                            ret = IPSNMP_ERROR_GENERROR;
                        }
                        if (ifAdminStatus == 1)
                            IP_BIT_SET(ifreq.ip_ifr_flags, IP_IFF_UP);
                        else
                            IP_BIT_CLR(ifreq.ip_ifr_flags, IP_IFF_UP);
                        if (ipnet_sys_socketioctl(fd, IP_SIOCSIFFLAGS, &ifreq) < 0)
                        {
                            IPCOM_LOG1(ERR, "Failed to set interface flags: %s", ipcom_strerror(ipcom_errno));
                            ret = IPSNMP_ERROR_GENERROR;
                        }
                        ipnet_sys_socketclose(fd);
                    }
                    else
                    {
                        IPCOM_LOG0(ERR, "Failed to create socket for ioctl call");
                        ret = IPSNMP_ERROR_GENERROR;
                    }
                }
                break;
            default:
                IP_PANIC();
                ret = IPSNMP_ERROR_GENERROR;
                break;
        }
    }

exit:
    if (buf != IP_NULL)
        ipcom_free(buf);
    if (best != IP_NULL)
        ipcom_free(best);
    return ret;
}
/*
 *===========================================================================
 *                      ipwlan_cmd_wlan_en
 *===========================================================================
 * Description: Parses and executes wlan shell commands.
 * Parameters:  'en' == 0 => Do not print to console,
 * Returns:     0 on success
 */
IP_STATIC int
ipwlan_cmd_wlan_en(int en, int argc, char **argv)
{
    int i;
    int j;
    int k;

    Ip_fd fd;
    char *endp;
    char ssid[32];
    Ipcom_iwreq iwreq;
    unsigned char oid_data[10];
    Ip_err ret = IPCOM_SUCCESS;

    if (argc < 3)
    {
        /* To few arguments */
        ipwlan_print_usage(en);

        return ret;
    }

#ifdef IPCOM_USE_INET
    fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0);
#else
    fd = ipcom_socket(IP_AF_INET6, IP_SOCK_DGRAM, 0);
#endif
    if (fd == IP_SOCKERR)
    {
        ipwlan_printf(en, "Error: unable to create command socket"IP_LF);

        return IPCOM_ERR_FAILED;
    }

    /* Verify interface existance */
    ipcom_sprintf(iwreq.if_name, "%.*s", IP_IFNAMSIZ - 1, argv[1]);
    if(ipcom_if_nametoindex(iwreq.if_name) < 1)
    {
        ipwlan_printf(en, "Error: Interface '%s' does not exist"IP_LF, iwreq.if_name);

        goto error;
    }

    /* Reset WLAN device */
    if (!ipcom_strcmp(argv[2], "reset"))
    {
        ipcom_socketioctl(fd, IP_SIOCSIWRESET, &iwreq);

        goto done;
    }

    /* Set/Get mode */
    if (!ipcom_strcmp(argv[2], "mode"))
    {
        if(argc < 4)
        {
            if(ipcom_socketioctl(fd, IP_SIOCGIWMODE, &iwreq) < 0)
            {
                goto error;
            }
            if(iwreq.u.mode == IP_IW_MODE_INFRA)
            {
                i = wlan_mode_client_infra;
            }
            else if(iwreq.u.mode == IP_IW_MODE_AUTO)
            {
                i = wlan_mode_client_auto;
            }
            else if(iwreq.u.mode == IP_IW_MODE_ADHOC)
            {
                i = wlan_mode_client_adhoc;
            }
            else if(iwreq.u.mode == IP_IW_MODE_MASTER)
            {
                i = wlan_mode_ap;
            }
            else
            {
                i = wlan_mode_unknown;
            }
            ipwlan_printf(en, "Current mode is: %s"IP_LF, wlan_mode_text[i]);
        }
        else
        {
            /* Set mode */
            if (!strcmp(argv[3], "client"))
            {
                if(argc < 5 || (strcmp(argv[4], "adhoc") && strcmp(argv[4], "auto") && strcmp(argv[4], "infra")))
                {
                    ipwlan_printf(en, "prism <interface> mode client [auto|adhoc|infra]"IP_LF);

                    goto done;
                }
                iwreq.u.mode = !strcmp(argv[4], "auto") ? IP_IW_MODE_AUTO : (!strcmp(argv[4], "infra") ? IP_IW_MODE_INFRA : IP_IW_MODE_ADHOC);

            }
            else if (!strcmp(argv[3], "ap"))
            {
                iwreq.u.mode = IP_IW_MODE_MASTER;
            }
            else
            {
                ipwlan_printf(en, "prism <interface> mode ap"IP_LF);
                ipwlan_printf(en, "prism <interface> mode client auto|adhoc|infra"IP_LF);

                goto done;
            }
            if (ipcom_socketioctl(fd, IP_SIOCSIWMODE, &iwreq) < 0)
            {
                goto error;
            }
        }
        goto done;
    }

    /* Get/Set SSID */
    if (!ipcom_strcmp(argv[2], "ssid"))
    {
        iwreq.u.essid.pointer = ssid;
        if (argc < 4)
        {
            /* Get SSID */
            iwreq.u.essid.length = sizeof(ssid);
            if (ipcom_socketioctl(fd, IP_SIOCGIWESSID, &iwreq) == 0)
            {
                if(ssid[0])
                {
                    ipwlan_printf(en, "ssid: %s"IP_LF, ssid);
                }
                else
                {
                    ipwlan_printf(en, "-- Not associated --"IP_LF);
                }
                goto done;
            }
        }
        else
        {
            /* Set SSID */
            iwreq.u.essid.length = ipcom_sprintf(ssid, "%.*s", sizeof(ssid) - 1, argv[3]);
            if (ipcom_socketioctl(fd, IP_SIOCSIWESSID, &iwreq) == 0)
            {
                goto done;
            }
        }
        goto error;
    }

    /* Get/Set frequency */
    if (!ipcom_strcmp(argv[2], "freq"))
    {
        if(argc < 4)
        {
            /* Get frequency */
            if (ipcom_socketioctl(fd, IP_SIOCGIWFREQ, &iwreq) < 0)
            {
                goto error;
            }
            ipwlan_printf(en, "RF frequency: %d kHz"IP_LF, iwreq.u.freq.m);
        }
        else
        {
            /* Set frequency */
            if (!strcmp(argv[3], "auto"))
            {
                iwreq.u.freq.flags = IP_IW_FREQ_AUTO;
                iwreq.u.freq.m = WLAN_FREQUENCY_BAND;
                iwreq.u.freq.e = 0;
            }
            else
            {
                i = ipcom_strtol(argv[3], &endp, 10);
                if (*endp != '\0')
                {
                    ipwlan_printf(en, "Error: invalid frequency value, '%s'"IP_LF, argv[3]);

                    goto done;
                }
                iwreq.u.freq.flags = IP_IW_FREQ_FIXED;
                iwreq.u.freq.m = i;
                iwreq.u.freq.e = 0;
                if (ipcom_socketioctl(fd, IP_SIOCSIWFREQ, &iwreq) < 0)
                {
                    goto error;
                }
            }
        }
        goto done;
    }

    /* Get/Set authentication */
    if (!ipcom_strcmp(argv[2], "auth"))
    {
        if (argc < 4)
        {
            /* Get authentication policy */
            ipwlan_printf(en, "Cannot get authentication policy. Try device specific shell command"IP_LF);
        }
        else
        {
            /* Set authentication policy */
            if (strcmp(argv[3], "open") && strcmp(argv[3], "shared-key") && strcmp(argv[3], "wpa-psk") && strcmp(argv[3], "wpa") && strcmp(argv[3], "wpa2-psk") && strcmp(argv[3], "wpa2"))
            {
                ipwlan_printf(en, "Error: invalid authentication policy, valid policies are 'open', 'shared-key', 'wpa-psk or 'wpa'" IP_LF);

                goto done;
            }
            if(strcmp(argv[3], "open") == 0)
                iwreq.u.auth_type = IP_IW_AUTH_ALG_OPEN_SYSTEM;
            else if(strcmp(argv[3], "shared-key") == 0)
                iwreq.u.auth_type = IP_IW_AUTH_ALG_SHARED_KEY;
            else if(strcmp(argv[3], "wpa2-psk") == 0)
                iwreq.u.auth_type = IP_IW_AUTH_ALG_WPA2_PSK;
            else if(strcmp(argv[3], "wpa2") == 0)
                iwreq.u.auth_type = IP_IW_AUTH_ALG_WPA2;
            else if(strcmp(argv[3], "wpa-psk") == 0)
                iwreq.u.auth_type = IP_IW_AUTH_ALG_WPA_PSK;
            else
                iwreq.u.auth_type = IP_IW_AUTH_ALG_WPA;

            if (ipcom_socketioctl(fd, IP_SIOCSIWAUTHTYPE, &iwreq) < 0)
            {
                goto error;
            }
        }
        goto done;
    }

    /* Get/Set encryption */
    if (!ipcom_strcmp(argv[2], "encr"))
    {
        if (argc < 4)
        {
            if (ipcom_socketioctl(fd, IP_SIOCGIWENCRTYPE, &iwreq) < 0)
            {
                goto error;
            }
            for(i = 0; i < (int) (sizeof(ipwlan_encr_policy)/sizeof(ipwlan_encr_policy[0])); i++)
            {
                if ((unsigned) ipwlan_encr_policy[i] == iwreq.u.encr_type)
                {
                    break;
                }
            }
            ipwlan_printf(en, "privacy: %s"IP_LF, wlan_encr_text[i]);
        }
        else
        {
            /* Set encryption parameters */
            if (!strcmp(argv[3], "wep"))
            {
                if (argc < 5 || argc > 6)
                {
                    ipwlan_printf(en, "Usage: wlan <interface> encr wep 1|2|3|4 [<key>]"IP_LF);

                    goto done;
                }
                i = ipcom_strtol(argv[4], &endp, 10);
                if (*endp != '\0' || i < 1 || i > 4)
                {
                    ipwlan_printf(en, "Error: Invalid index value allowed are 1 to 4" IP_LF);

                    goto done;
                }
                if(argc == 6)
                {
                    if (argv[5][0] == '0' && argv[5][1] == 'x')
                    {
                        if (ipcom_strspn(argv[5] + 2, "012345678ABCDEFabcdef") != ipcom_strlen(argv[5] + 2) || ipcom_strlen(argv[5] + 2) > 32 || (ipcom_strlen(argv[5] + 2) % 2) != 0) /* 32 nibbles => 128 bits */
                        {
                            ipwlan_printf(en, "Usage: wlan <interface> encr wep <index> 0x<hex key>|<string key>"IP_LF);

                            goto done;
                        }
                        for (j = 0; ipcom_sscanf(argv[5] + 2 + 2 * j, "%2x", &k); j++)
                        {
                            iwreq.u.key.key[j] = (unsigned char)k;
                        }
                        iwreq.u.key.len = j;
                    }
                    else
                    {
                        /* key is a text string */
                        iwreq.u.key.len = ipcom_sprintf((char *)iwreq.u.key.key, "%.*s", MIN(sizeof(iwreq.u.key.key) - 1, ipcom_strlen(argv[5])), argv[5]);
                    }
                    iwreq.u.key.flags = 0;
                }
                else
                {
                    iwreq.u.key.flags = IP_IW_KEY_FLAG_NOKEY;
                }
                iwreq.u.key.type = IP_IW_ENCR_ALG_WEP;
                iwreq.u.key.index = i - 1; /* Index 1 - 4 */
                if (ipcom_socketioctl(fd, IP_SIOCSIWENCRKEY, &iwreq) < 0)
                {
                    goto error;
                }

                iwreq.u.encr_type = IP_IW_ENCR_ALG_WEP;
                if (ipcom_socketioctl(fd, IP_SIOCSIWENCRTYPE, &iwreq) < 0)
                {
                    goto error;
                }
            }
            else if (!strcmp(argv[3], "none"))
            {
                iwreq.u.encr_type = IP_IW_ENCR_ALG_NONE;

                if (ipcom_socketioctl(fd, IP_SIOCSIWENCRTYPE, &iwreq) < 0)
                {
                    goto error;
                }
            }
            else if (!strcmp(argv[3], "tkip"))
            {
                iwreq.u.encr_type = IP_IW_ENCR_ALG_TKIP;

                if (ipcom_socketioctl(fd, IP_SIOCSIWENCRTYPE, &iwreq) < 0)
                {
                    goto error;
                }
            }
            else if (!strcmp(argv[3], "ccmp"))
            {
                iwreq.u.encr_type = IP_IW_ENCR_ALG_CCMP;

                if (ipcom_socketioctl(fd, IP_SIOCSIWENCRTYPE, &iwreq) < 0)
                {
                    goto error;
                }
            }
            else
            {
                goto error;
            }
        }

        goto done;
    }

    /* Commit changes */
    if (!ipcom_strcmp(argv[2], "commit"))
    {
        if (ipcom_socketioctl(fd, IP_SIOCSIWCOMMIT, &iwreq) < 0)
        {
            goto error;
        }

        goto done;
    }

    /* Get link quality */
    if (!ipcom_strcmp(argv[2], "quality"))
    {
        ipcom_socketioctl(fd, IP_SIOCGIWAP, &iwreq);
        ipcom_memcpy(oid_data, iwreq.u.addr.sa_data, 6);
        ipcom_memcpy(iwreq.u.quality.bssid, oid_data, 6);
        if (ipcom_socketioctl(fd, IP_SIOCGIWQUALITY, &iwreq) < 0)
        {
            goto error;
        }

        ipwlan_printf(en, "\r\nLink quality\r\n============\r\n");
        ipwlan_printf(en, "RSSI:   % 3d dBm\r\n", (int)iwreq.u.quality.level);
        ipwlan_printf(en, "Rate:   % 3d Mbps\r\n", (unsigned int)iwreq.u.quality.qual);

        goto done;
    }

error:

    ipwlan_printf(en, "Error: command %s failed"IP_LF, argv[2]);
    ret = IPCOM_ERR_FAILED;

done:
    (void)ipcom_socketclose(fd);

    return ret;
}
Beispiel #23
0
/*
 *===========================================================================
 *                    ipcom_sysvar_for_each
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_PUBLIC Ip_err
ipcom_sysvar_for_each(const char            *name,
                      Ipcom_sysvar_for_each cb_func,
                      void                  *cookie)
{
    Ipcom_sysvar_entry *sysvar;
    Ipcom_sysvar_tree  *tree;
    Ip_size_t           namelen = 0;
    Ip_err              retval;
    Ipcom_pqueue       *pq;

    retval = ipcom_once(&ipcom_sysvar_once, ipcom_sysvar_init, IP_NULL);
    if (retval != IPCOM_SUCCESS)
        return retval;

    if (name)
    {
        namelen = ipcom_strlen(name);
        if (name[namelen-1] == '*')
            namelen--; /* ignore trailing wildcard sign */
    }

    pq = ipcom_pqueue_new((Ipcom_pqueue_cmp_func)ipcom_sysvar_pqueue_cmp,
                          ipcom_pqueue_nop_store_index);
    if (pq == IP_NULL)
        return IPCOM_ERR_NO_MEMORY;

    IPCOM_CODE_LOCK();

    tree = ipcom_sysvar_tree_get(-1);
    if (tree == IP_NULL)
    {
        ipcom_pqueue_delete(pq);
        IPCOM_CODE_UNLOCK();
        return IPCOM_ERR_NO_MEMORY;
    }

    /* Add all sysvars to the priority queue so they can be extracted
       sorted in lexicographical order */
    ipcom_hash_for_each(tree->sysvars,
                        (Ipcom_hash_foreach_cb_func)ipcom_sysvar_pqueue_insert_cb,
                        pq);

    while (IP_NULL != (sysvar = ipcom_pqueue_remove_next(pq)))
    {
        if (name == IP_NULL
            || ipcom_strncmp(sysvar->name, name, namelen) == 0)
        {
            IPCOM_CODE_UNLOCK();
            (void)cb_func(sysvar->name, sysvar->value, sysvar->flags, cookie);
            IPCOM_CODE_LOCK();
        }
        ipcom_sysvar_release(tree, sysvar);
    }

    ipcom_pqueue_delete(pq);
    ipcom_sysvar_tree_done(tree);

    IPCOM_CODE_UNLOCK();

#ifdef IP_PORT_OSE5_DISABLED
    return ipcom_sysvar_for_each_ose5(name, cb_func, cookie);
#else
    return IPCOM_SUCCESS;
#endif
}
/*
 *===========================================================================
 *                    ipnet_nat_proxy_dns_parse_questions
 *===========================================================================
 * Description: Parses and modifies DNS questions in a DNS packet.
 * Parameters:  buf     - pointer to buffer with the DNS questions.
 *              buflen  - length of buffer with DNS questions.
 *              offset  - offset in the buffer where the DNS questions begin.
 *              newlen  - pointer to the length of the message if modified.
 *              dns_hdr - pointer to the DNS protocol header.
 *              param   - pointer to NAT proxy parameters.
 * Returns:     The number of bytes parsed or -1 if failed.
 */
IP_STATIC Ip_s32
ipnet_nat_proxy_dns_parse_questions(Ip_u8 *buf,
                                int buflen,
                                int offset,
                                int *newlen,
                                Ipnet_nat_dns_hdr *dns_hdr,
                                Ipnet_nat_proxy_param *param)
{
    int i, j, k, count, origoffset, numq, numa, request;
    Ip_u16 type, cla, flags;
    Ip_u8 addr[4];
    Ipnet_nat_dns_transaction *trans;
    int newbuflen = sizeof(dnsbuf);
    Ip_u8 c, *zone;

    numq = IP_GET_NTOHS(&dns_hdr->no_ques);
    if (numq != 1)
    {
        IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: supports only one question per message");
        return -1;
    }
    numa = IP_GET_NTOHS(&dns_hdr->no_answ);
    flags = IP_GET_NTOHS(&dns_hdr->flags);
    request = (flags & IPNET_NAT_DNS_QR_FLAG) != 0 ? 0 : 1;
    origoffset = offset;
    for (i=0; i<numq; i++)
    {
        /* Get the name */
        count = ipnet_nat_proxy_dns_decode_name(buf, buflen, offset, dnsname, sizeof(dnsname));
        if (count < 0)
        {
            IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: could not decode dns name");
            return -1;
        }

        /* Copy the name */
        if (newbuflen - *newlen < count)
        {
            IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: no space left in modified buffer");
            return -1;
        }
        ipcom_memcpy(&dnsbuf[*newlen], buf+offset, count);
        *newlen += count;
        offset += count;

        /* Check space for type and class */
        if (buflen - offset < 4)
        {
            IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: message too short to parse question");
            return -1;
        }

        /* Get the type */
        type = (Ip_u16)(IP_GET_NTOHS(buf+offset));
        switch(type)
        {
            case IPNET_NAT_DNS_QTYPE_AAAA:
                if (request)
                {
                    trans = ipnet_nat_proxy_dns_add_transaction(IPNET_NAT_DNS_QTYPE_A, dns_hdr, param, IP_NULL);
                    if (trans == IP_NULL)
                    {
                        IPCOM_LOG0(ERR, "ipnet_nat_proxy_dns_parse_questions() :: could not add transaction to list");
                        return -1;
                    }
                    else
                    {
                        IPCOM_LOG4(DEBUG, "ipnet_nat_proxy_dns_parse_questions() :: added transaction:"
                                          "id=%d port=%d addr=0x%08x type=%d",
                                           trans->id, trans->srcport, trans->dstaddr, trans->type);

                    }
                    type = IPNET_NAT_DNS_QTYPE_A;      /* Change type to A */
                }
                break;
            case IPNET_NAT_DNS_QTYPE_A:
                if (!request)
                {
                    trans = ipnet_nat_proxy_dns_find_transaction(IPNET_NAT_DNS_QTYPE_A, dns_hdr, param);
                    if (trans != IP_NULL)
                    {
                        IPCOM_LOG4(DEBUG, "ipnet_nat_proxy_dns_parse_questions() :: found transaction:"
                                          "id=%d port=%d addr=0x%08x type=%d",
                                           trans->id, trans->srcport, trans->dstaddr, trans->type);
                        ipnet_nat_proxy_dns_remove_transaction(trans);
                    }
                    else
                    {
                        return -1;
                    }
                    type = IPNET_NAT_DNS_QTYPE_AAAA;   /* Change type back to AAAA */
                }
                break;
            case IPNET_NAT_DNS_QTYPE_PTR:
                if (request)
                {
                    zone = (Ip_u8 *)ipcom_strstr((char *)dnsname, "ip6.int");
                    if (zone == IP_NULL)
                        zone = (Ip_u8 *)ipcom_strstr((char *)dnsname, "ip6.arpa");
                    if (zone == IP_NULL)
                    {
                        IPCOM_LOG0(DEBUG, "ipnet_nat_proxy_dns_parse_questions() :: unhandled zone in PTR request");
                        return -1;
                    }
                    /* Extract IPv4 part */
                    if (ipcom_strlen((char *)dnsname) != 64 + ipcom_strlen((char *)zone))
                    {
                        IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: invalid name in PTR request");
                        return -1;
                    }
                    k=0;
                    for (j=3; j>=0; j--)
                    {
                        c = ipcom_tolower(dnsname[k]);
                        c = c > '9' ? c - 'a' + 10 : c - '0';
                        addr[j] = c;
                        k += 2;
                        c = ipcom_tolower(dnsname[k]);
                        c = c > '9' ? c - 'a' + 10 : c - '0';
                        c <<= 4;
                        addr[j] += c;
                        k += 2;
                    }

                    trans = ipnet_nat_proxy_dns_add_transaction(IPNET_NAT_DNS_QTYPE_PTR, dns_hdr, param, dnsname);
                    if (trans == IP_NULL)
                    {
                        IPCOM_LOG0(ERR, "ipnet_nat_proxy_dns_parse_questions() :: could not add transaction to list");
                        return -1;
                    }
                    else
                    {
                        IPCOM_LOG4(DEBUG, "ipnet_nat_proxy_dns_parse_questions() :: added transaction:"
                                          "id=%d port=%d addr=0x%08x type=%d",
                                           trans->id, trans->srcport, trans->dstaddr, trans->type);
                    }

                    /* Convert address to PTR name */
                    if (ipnet_nat_proxy_dns_ptr_name(dnsname, sizeof(dnsname), addr, IP_AF_INET, (Ip_u8 *)"in-addr.arpa") < 0)
                    {
                        ipnet_nat_proxy_dns_remove_transaction(trans);
                        IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: could not encode PTR name");
                        return -1;
                    }
                    *newlen -= count;   /* Move index back to before the name */
                    count = ipnet_nat_proxy_dns_encode_name(dnsbuf, newbuflen, *newlen, dnsname);
                    if (count < 0)
                    {
                        ipnet_nat_proxy_dns_remove_transaction(trans);
                        IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: could not encode dns name");
                        return -1;
                    }
                    *newlen += count;
                }
                else
                {
                    trans = ipnet_nat_proxy_dns_find_transaction(IPNET_NAT_DNS_QTYPE_PTR, dns_hdr, param);
                    if (trans != IP_NULL)
                    {
                        IPCOM_LOG4(DEBUG, "ipnet_nat_proxy_dns_parse_questions() :: found transaction:"
                                          "id=%d port=%d addr=0x%08x type=%d",
                                           trans->id, trans->srcport, trans->dstaddr, trans->type);
                        *newlen -= count;   /* Move index back to before the name */
                        count = ipnet_nat_proxy_dns_encode_name(dnsbuf, newbuflen, *newlen, trans->ptrname);
                        if (count < 0)
                        {
                            ipnet_nat_proxy_dns_remove_transaction(trans);
                            IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: could not encode dns name");
                            return -1;
                        }
                        *newlen += count;
                        if (numa == 0)
                        {
                            /* Remove the transaction if there are no answers */
                            ipnet_nat_proxy_dns_remove_transaction(trans);
                        }
                    }
                    else
                    {
                        return -1;
                    }
                }
                break;
            default:
                return -1;
        }
        /* Copy the type */
        if (newbuflen - *newlen < 2)
        {
            IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: no space left in modified buffer");
            return -1;
        }
        IP_SET_HTONS(&dnsbuf[*newlen], type);
        *newlen += 2;
        offset += 2;

        /* Get the class */
        cla = (Ip_u16)(IP_GET_NTOHS(buf+offset));
        if (cla != IPNET_NAT_DNS_QCLASS_INET)
        {
            IPCOM_LOG1(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: unhandled class: %d", cla);
            return -1;
        }
        /* Copy the class */
        if (newbuflen - *newlen < 2)
        {
            IPCOM_LOG0(WARNING, "ipnet_nat_proxy_dns_parse_questions() :: no space left in modified buffer");
            return -1;
        }
        IP_SET_HTONS(&dnsbuf[*newlen], cla);
        *newlen += 2;
        offset += 2;
    }

    return offset - origoffset;
}
Beispiel #25
0
/*
 *===========================================================================
 *                      ipnet_if_mib_handler_ifXTable
 *===========================================================================
 * Description: MIB handler for variables in ifXTable
 * Parameters: See file 'ipsnmp.h'
 * Returns: IPSNMP_ERROR_XXX
 *
 */
IP_STATIC Ip_s32
ipnet_if_mib_handler_ifXTable(Ip_s32 cmd,
                              char *id,
                              Ipsnmp_varbind *vb,
                              Ip_s32 magic,
                              struct Ipsnmp_node_object *nodeobj)
{
    Ip_s32       lid, ret = -1;
    Ip_s32       ifLinkUpDownTrapEnable = 0;
    char        *iid;
    char        *buf = ipcom_malloc(IPSNMP_CONFIG_MAX_OBJECT_ID);
    char        *best = ipcom_malloc(IPSNMP_CONFIG_MAX_OBJECT_ID);
    Ipnet_netif *best_netif;

    if (buf == IP_NULL || best == IP_NULL)
    {
        ret = IPSNMP_ERROR_GENERROR;
        goto exit;
    }

    lid = ipsnmp_util_last_subid(nodeobj->id);
    ip_assert((lid >= 1 && lid <= 5) || (lid >= 14 && lid <= 19));
    best_netif = ipnet_if_mib_table_search_ifTable(id, buf, best, cmd, &ret);
    if (best_netif == IP_NULL)
        goto exit;

    if (cmd == IPSNMP_MIB_COMMAND_GET || cmd == IPSNMP_MIB_COMMAND_NEXT)
    {
        iid = ipsnmp_create_iid_direct(nodeobj->id, best);
        if (iid == IP_NULL)
        {
            ret = IPSNMP_ERROR_GENERROR;
            goto exit;
        }

        switch(lid)
        {
            case 1: /* ifName */
                ret = ipsnmp_util_put_octetstring(magic, iid, (Ip_u8 *)best_netif->ipcom.name, ipcom_strlen(best_netif->ipcom.name));
                break;
            case 2: /* ifInMulticastPkts */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInMulticastPkts);
                break;
            case 3: /* ifInBroadcastPkts */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifInBroadcastPkts);
                break;
            case 4: /* ifOutMulticastPkts */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutMulticastPkts);
                break;
            case 5: /* ifOutBroadcastPkts */
                ret = ipsnmp_util_put_counter32(magic, iid, best_netif->ipcom.mib2.ifOutBroadcastPkts);
                break;
            case 14: /* ifLinkUpDownTrapEnable */
                if (best_netif->ipcom.mib2.ifLinkUpDownTrapEnable == 0)
                    best_netif->ipcom.mib2.ifLinkUpDownTrapEnable = 1;
                ret = ipsnmp_util_put_integer(magic, iid, best_netif->ipcom.mib2.ifLinkUpDownTrapEnable);
                break;
            case 15: /* ifHighSpeed */
                if (best_netif->ipcom.type == IP_IFT_PPP)
                    ret = ipsnmp_util_put_gauge32(magic, iid, 0);
                else
                    ret = ipsnmp_util_put_gauge32(magic, iid, 100);
                break;
            case 16: /* ifPromiscuousMode */
                if (IP_BIT_ISSET(best_netif->ipcom.flags, IP_IFF_PROMISC))
                    ret = ipsnmp_util_put_integer(magic, iid, 1);
                else
                    ret = ipsnmp_util_put_integer(magic, iid, 2);
                break;
            case 17: /* ifConnectorPresent */
                ret = ipsnmp_util_put_integer(magic, iid, 2);
                break;
            case 18: /* ifAlias */
                ret = ipsnmp_util_put_octetstring(magic, iid, IP_NULL, 0);
                break;
            case 19: /* ifCounterDiscontinuityTime */
                ret = ipsnmp_util_put_timeticks(magic, iid, 0);
                break;
            default:
                IP_PANIC();
                ret = IPSNMP_ERROR_GENERROR;
                break;
        }

        ipcom_free(iid);
    }

    if (cmd == IPSNMP_MIB_COMMAND_TEST || cmd == IPSNMP_MIB_COMMAND_SET)
    {
        switch(lid)
        {
            case 14: /* ifLinkUpDownTrapEnable */
                ret = ipsnmp_util_get_integer(vb, &ifLinkUpDownTrapEnable);
                if (ret == IPSNMP_ERROR_NOERROR)
                {
                    if (ifLinkUpDownTrapEnable != 1 && ifLinkUpDownTrapEnable != 2)
                    {
                        ret = IPSNMP_ERROR_WRONGVALUE;
                    }
                }

                if (ret == IPSNMP_ERROR_NOERROR && cmd == IPSNMP_MIB_COMMAND_SET)
                {
                    best_netif->ipcom.mib2.ifLinkUpDownTrapEnable = ifLinkUpDownTrapEnable;
                }
                break;
            case 16: /* ifPromiscuousMode */
            case 18: /* ifAlias */
                ret = IPSNMP_ERROR_NOSUCHNAME;
                break;
            default:
                IP_PANIC();
                ret = IPSNMP_ERROR_GENERROR;
                break;
        }
    }

exit:
    if (buf != IP_NULL)
        ipcom_free(buf);
    if (best != IP_NULL)
        ipcom_free(best);
    return ret;
}
/*
 *===========================================================================
 *                    ipcom_shell_print_prompt
 *===========================================================================
 * Description:     Print shell prompt.
 * Parameters:
 * Returns:         0 = success, <0 = error code.
 *
 */
IP_STATIC int
ipcom_shell_print_prompt(char *prompt_template, char *prompt_addr, int *promptlen, Ip_pid_t ppid, Ip_u32 seqno)
{
    int    baselen;
    int    ret = 0;
    int    buflen = 0;
    char  *buf;
#if IPCOM_USE_FILE != IPCOM_FILE_NONE
    char  *cwd;
    char  *base;
    char   cwdbuf[128];
#endif

    buf = ipcom_malloc(IPCOM_STDIO_BUFSIZE);
    if (buf == IP_NULL)
        return -1;

    for (; *prompt_template != '\0'; ++prompt_template)
    {
        ip_assert(buflen < (int)IPCOM_STDIO_BUFSIZE - 1);
        if (*prompt_template != '\\')
        {
            /* 'Normal' character */
            buf[buflen++] = *prompt_template;
        }
        else
        {
            /* New special character*/
            switch (*++prompt_template)
            {
            case 'w':
            /* Print current working directory */
            case 'W':
#if IPCOM_USE_FILE != IPCOM_FILE_NONE
                /* Print basename of the current workning directory */
                cwd = ipcom_getcwd(cwdbuf, sizeof(cwdbuf));
                if (cwd == IP_NULL)
                {
                    IPCOM_LOG0(DEBUG, "ipcom_shell_print_prompt :: ipcom_getcwd() failed");
                    break;
                }
                if (*prompt_template == 'w')
                    base = cwd;
                else
                {
                    base = ipcom_strrchr(cwd, '/');
                    if (base != IP_NULL && base != cwd)
                        base++;
                    else
                    {
                        base = ipcom_strrchr(cwd, '\\');
                        if (base == IP_NULL)
                            base = cwd;
                        else
                            base++;
                    }
                }
                baselen = ipcom_strlen(base);
                ipcom_memcpy(buf + buflen, base, baselen);
                buflen += baselen;
#endif
                break;

            case 'p':
                /* Print the shell process name */
            {
                char procname[40];
                ipcom_sprintf(procname, "ipcom_shell_%lx_%lx", (Ip_u32)ppid, seqno);
                baselen = ipcom_strlen(procname);
                ipcom_memcpy(buf + buflen, procname, baselen);
                buflen += baselen;
            }
            break;

            case 'P':
                /* Print the shell process pid */
            {
                char pid[14];
                ipcom_sprintf(pid, "0x%lx", ipcom_getpid());
                baselen = ipcom_strlen(pid);
                ipcom_memcpy(buf + buflen, pid, baselen);
                buflen += baselen;
            }
            break;

            case 'i':
                /* Print the IP address */
                if (*prompt_addr)
                {
                    baselen = ipcom_strlen(prompt_addr);
                    ipcom_memcpy(buf + buflen, prompt_addr, baselen);
                    buflen += baselen;
                }
                break;

#if IPCOM_USE_ENV != IPCOM_ENV_NONE
            case 'V':
            {
                char vrbuf[16];
                baselen = ipcom_sprintf(vrbuf, "%d", ipcom_proc_vr_get());
                ipcom_memcpy(buf + buflen, vrbuf, baselen);
                buflen += baselen;
            }
            break;
#endif

            default:
                /* Unknown code. */
                IPCOM_LOG1(DEBUG, "ipcom_shell_print_prompt :: unknown code: %c", *prompt_template);
                buf[buflen++] = '\\';
                buf[buflen++] = '\\';
                buf[buflen++] = *prompt_template;
                break;
            }
        }
    }

    if (buflen > 0)
    {
        buf[buflen] = '\0';
        if (promptlen != IP_NULL)
            *promptlen = ipcom_strlen(buf);
        ipcom_printf(buf);
    }
    ipcom_free(buf);
    if (ret < 0)
        IPCOM_LOG0(WARNING, "ipcom_shell_print_prompt :: ipcom_printf() failed");
    return ret;
}
IP_PUBLIC Ip_err
ipcom_sysvar_ext_setv(const Ipcom_sysvar_ext entries[], int flags)
{
    /* !!TODO: make atomic */
    int i;
    int len = 0;
    int  param_len = 0;
    char *sysvar_name = IP_NULL;
    char *sysvar_param = IP_NULL;
    char *conf = IP_NULL;
    char *last = IP_NULL;
    char *value = IP_NULL;
    char *ifparam = IP_NULL;
    Ip_err err = IPCOM_SUCCESS;

    sysvar_name = ipcom_calloc(1, sizeof(char) * 256);
    if (sysvar_name == IP_NULL)
        return IPCOM_ERR_NO_MEMORY;

    for (i = 0; ; i++)
    {
        /*
         * The syntax {IP_NULL,IP_NULL,IP_NULL} terminates the configuration
         * array. Otherwise, <name1> and/or <name2> must be specified.
         */
        if ((entries[i].name1 == IP_NULL) && (entries[i].name2 == IP_NULL))
        {
            err = (entries[i].param == IP_NULL) ? IPCOM_SUCCESS :
                  IPCOM_ERR_INVALID_CONFIG;
            goto done;
        }

        /*
         * The expected string should contain <ifparam>=<value>. If the
         * separator is not found, assume the string does not contain
         * any valid configuration values.
         */
        if (entries[i].param == IP_NULL ||
            ipcom_strchr(entries[i].param, '=') == IP_NULL)
            continue;

        len = ipcom_strlen(entries[i].param);
        if ((len > param_len) || (sysvar_param == IP_NULL))
        {
            if (sysvar_param)
                ipcom_free(sysvar_param);  /* free previously allocated mem */
            param_len = len;
            sysvar_param = ipcom_calloc(1, param_len+1);
            if (sysvar_param == IP_NULL)
            {
                ipcom_free(sysvar_name);
                return IPCOM_ERR_NO_MEMORY;
            }
        }
        else
            ipcom_memset(sysvar_param, 0, param_len+1);

        ipcom_strcpy(sysvar_param, entries[i].param);

        /*
         * Expected format: <ifparam1>=<value1>;<ifparam2>=<value2>;...
         */
        conf = ipcom_strtok_r(sysvar_param,
                              IPCOM_IFPARAM_LIST_DELIMITER, &last);
        if (conf == IP_NULL)
        {
            err = IPCOM_ERR_INVALID_CONFIG;
            goto done;
        }

        do {
            /* Expected format: <ifparam>=<value> */
            ifparam = ipcom_strtok_r(conf, IPCOM_IFPARAM_DELIMITER, &value);
            if ((ifparam == IP_NULL) || (value == IP_NULL))
            {
                err = IPCOM_ERR_INVALID_CONFIG;
                goto done;
            }

            ipcom_memset(sysvar_name, 0, sizeof(sysvar_name));
            if (entries[i].name1 != IP_NULL)
            {
                ipcom_strcpy(sysvar_name, entries[i].name1);
                ipcom_strcat(sysvar_name, ".");
            }
            ipcom_strcat(sysvar_name, ifparam);
            if (entries[i].name2 != IP_NULL)
            {
                ipcom_strcat(sysvar_name, ".");
                ipcom_strcat(sysvar_name, entries[i].name2);
            }
            err = ipcom_sysvar_set(sysvar_name, value, flags);
            if (err == IPCOM_ERR_DUPLICATE)
                err = IPCOM_SUCCESS;
            else if (err != IPCOM_SUCCESS)
                goto done;
        } while (IP_NULL != (conf = ipcom_strtok_r(IP_NULL,
                                                   IPCOM_IFPARAM_LIST_DELIMITER, &last)));
    }

done:
    ipcom_free(sysvar_name);
    if (sysvar_param)
        ipcom_free(sysvar_param);
    return err;
}
Beispiel #28
0
/*
 *===========================================================================
 *                    ipcom_cmd_ipd
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 */
IP_PUBLIC int
ipcom_cmd_ipd(int argc, char **argv)
{
    Ipcom_getopt   opt;
    int            i, c, msgtype;
    Ip_err         err = IPCOM_SUCCESS;
#if IPCOM_VR_MAX > 1
    int            vr = ipcom_proc_vr_get();
    int            vr_new = vr;
#endif

    if (argc < 2)
    {
usage:
        ipcom_fprintf(ip_stderr,
                      "Interpeak daemon (IPD) command, version 1.2"IP_LF
                      "usage:  "IP_LF
                      "   ipd [-V <vr>] list"IP_LF
                      "   ipd [-V <vr>] start <service>"IP_LF
                      "   ipd [-V <vr>] kill <service>"IP_LF
                      "   ipd [-V <vr>] reconfigure <service>"IP_LF
                      "   ipd [-V <vr>] <#> <service>"IP_LF
                      IP_LF);
        return 0;
    }

    ipcom_getopt_clear_r(&opt);
    while ((c = ipcom_getopt_r(argc, argv, "V:", &opt)) != -1)
    {
        switch(c)
        {
        case 'V':
#if IPCOM_VR_MAX > 1
            vr_new = ipcom_atoi(opt.optarg);
#endif
            break;
        default:
            ipcom_printf("ipd: unknown option %c"IP_LF, (char)c);
            return -1;
        }
    }

    if (opt.optind >= argc)
    {
        ipcom_printf("ipd: missing <command> argument"IP_LF);
        goto usage;
    }


    if(ipcom_strcmp(argv[opt.optind], "list") == 0)
    {
#if IPCOM_VR_MAX > 1
        if (vr != vr_new)
            ipcom_proc_vr_set(vr_new);
#endif
        ipcom_printf("Services:"IP_LF);
        for (i = 0; ipcom_ipd_products[i].name != IP_NULL; i++)
        {
            if ((argc - (opt.optind + 1)) > 0)
            {
                int p;
                for (p = opt.optind + 1; p < argc; p++)
                {
                    if (ipcom_strcasecmp(ipcom_ipd_products[i].name, argv[p]) == 0)
                        goto print_service;
                }
                continue;
            }

print_service:
            if (IP_BIT_ISSET(ipcom_ipd_products[i].flags, IPCOM_IPD_FLAG_IPD_START))
            {
#ifdef IP_PORT_OSE5
                if (ipcom_ipd_products[i].start == IP_NULL
                    && ipcom_ipd_isinstalled_ose5(ipcom_ipd_products[i].name) != IPCOM_SUCCESS)
                    continue;
#endif
                err = ipcom_ipd_send(ipcom_ipd_products[i].name, IPCOM_IPD_MSGTYPE_PING);
                ipcom_printf("%-20s %-s"IP_LF,
                             ipcom_ipd_products[i].name,
                             err == IPCOM_SUCCESS ? "started" : "killed");
            }
            else if (ipcom_ipd_products[i].start)
                ipcom_printf("%-20s %-s"IP_LF,
                             ipcom_ipd_products[i].name, "started");

        }
        ipcom_printf(IP_LF);
#if IPCOM_VR_MAX > 1
        if (vr != vr_new)
            ipcom_proc_vr_set(vr);
#endif
        return 0;
    }

    if ((argc - opt.optind) < 2)
    {
        ipcom_printf("ipd: missing <service> argument"IP_LF);
        return -1;
    }

    for (i = 0; ipcom_cmd_ipd_messages[i].name; i++)
        if (ipcom_strcmp(argv[opt.optind], ipcom_cmd_ipd_messages[i].name) == 0)
        {
            msgtype = ipcom_cmd_ipd_messages[i].msgtype;
            goto sendmsg;
        }

    if (*argv[opt.optind] == '-' && ipcom_isdigit(argv[opt.optind][1]))
    {
        /* "UNIX" signal support (using negative numbers) */
        msgtype = -ipcom_atoi(argv[opt.optind] + 1);
        goto sendmsg;
    }

    if (ipcom_isdigit(argv[opt.optind][0]))
    {
        /* positive numbers */
        msgtype = ipcom_atoi(argv[1]);
        goto sendmsg;
    }

    /* unknown command. */
    ipcom_printf ("ipd: unknown command '%s'"IP_LF, argv[opt.optind]);
    return -1;

    /* send msg */
 sendmsg:
#if IPCOM_VR_MAX > 1
    if (vr != vr_new)
        ipcom_proc_vr_set(vr_new);
#endif


    if ((argc - opt.optind) < 3)
        err = ipcom_ipd_send(argv[opt.optind+1], msgtype);
    else
    {
        Ipcom_ipd_msg   *msg;
        int             sz  = ipcom_strlen(argv[opt.optind + 2]) + 1;

        msg = ipcom_calloc(1, sz + sizeof(*msg));
        if (msg != IP_NULL)
        {
            msg->msgtype = msgtype;
            ipcom_memcpy(msg + 1, argv[opt.optind + 2], sz);
            err = ipcom_ipd_sendmsg(argv[opt.optind+1], msg, sz + sizeof(*msg));
            ipcom_free(msg);
        }
    }

    if(err == IPCOM_SUCCESS)
        ipcom_printf("ipd: %s %s ok"IP_LF, argv[opt.optind], argv[opt.optind+1]);
    else
        ipcom_printf("ipd: %s %s failed: %s"IP_LF, argv[opt.optind], argv[opt.optind+1], ipcom_err_string(err));

#if IPCOM_VR_MAX > 1
    if (vr != vr_new)
        ipcom_proc_vr_set(vr);
#endif
    return 0;
}
/*
 *===========================================================================
 *                      ipnet_ip_mib_cb_ipCidrRouteTable
 *===========================================================================
 * Description:
 * Parameters:
 * Returns:
 *
 */
IP_STATIC Ip_bool
ipnet_ip_mib_cb_ipCidrRouteTable(Ipnet_route_entry *rt, Ipsnmp_route_walk *rwp)
{
    Ip_s32 tmp, lex, len = 0;

    /* Early exit if exact match was found previously */
    if(rwp->bestrt != IP_NULL &&
        (rwp->cmd == IPSNMP_MIB_COMMAND_GET
        || rwp->cmd == IPSNMP_MIB_COMMAND_TEST
        || rwp->cmd == IPSNMP_MIB_COMMAND_SET))
        goto exit;

    if(rt->netif == IP_NULL)
        goto exit;

    /* Do not use hidden entries */
    if(IP_BIT_ISSET(rt->hdr.flags, IPNET_RTF_X_HIDDEN))
        goto exit;

    /* Route must be usable */
    if(IP_BIT_ISFALSE(rt->hdr.flags, IPNET_RTF_UP))
        goto exit;

    /* Do not use link layer entries */
    if(IP_BIT_ISSET(rt->hdr.flags, IPNET_RTF_LLINFO))
        goto exit;

    /* Do not use loopback entries */
    if (IP_BIT_ISSET(rt->netif->ipcom.flags, IP_IFF_LOOPBACK))
        goto exit;

    ip_assert(rt->hdr.key != IP_NULL);

    /* Do not use multicast entries */
    if(IP_IN_CLASSD(*(Ip_u32 *)rt->hdr.key))
        goto exit;

    /* Do not use broadcast entries */
    if(ip_ntohl(*(Ip_u32 *)rt->hdr.key) == IP_INADDR_BROADCAST)
        goto exit;

    if(rwp->count_only == IP_TRUE)
    {
        count++;
        goto exit;
    }

    rwp->buf[0] = '\0';
    /* ipCidrRouteDest */
    if(ipcom_inet_ntop(IP_AF_INET, rt->hdr.key, &rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len) == IP_NULL)
        goto exit;
    len = ipcom_strlen(rwp->buf);
    if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, ".") < 0)
        goto exit;
    len = ipcom_strlen(rwp->buf);

    /* ipCidrRouteMask */
    if(rt->hdr.mask == IP_NULL)
    {
        if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, "255.255.255.255") < 0)
            goto exit;
    }
    else
    {
        if(ipcom_inet_ntop(IP_AF_INET, rt->hdr.mask, &rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len) == IP_NULL)
            goto exit;
    }
    len = ipcom_strlen(rwp->buf);
    if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, ".") < 0)
        goto exit;
    len = ipcom_strlen(rwp->buf);

    /* ipCidrRouteTos */
    tmp = 0;
    if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, "%d.", (int)tmp) < 0)
        goto exit;
    len = ipcom_strlen(rwp->buf);

    /* ipCidrRouteNextHop */
    if(IP_BIT_ISSET(rt->hdr.flags, IPNET_RTF_GATEWAY))
    {
        struct Ip_sockaddr_in *sa;

        ip_assert(rt->gateway != IP_NULL);
        sa = (struct Ip_sockaddr_in *)rt->gateway;
        if(ipcom_inet_ntop(IP_AF_INET, &sa->sin_addr.s_addr, &rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID - len) == IP_NULL)
            goto exit;
    }
    else
    {
        if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, "0.0.0.0") < 0)
            goto exit;
    }
    len = ipcom_strlen(rwp->buf);
    if(ipcom_snprintf(&rwp->buf[len], IPSNMP_CONFIG_MAX_OBJECT_ID-len, ".") < 0)
        goto exit;
    len = ipcom_strlen(rwp->buf);
    if(len)
        rwp->buf[len-1] = '\0';

    lex = ipsnmp_util_lexcmp_oid(rwp->buf, rwp->id);
    if(rwp->cmd == IPSNMP_MIB_COMMAND_NEXT)
    {
        if(lex > 0)
        {
            if(rwp->bestrt == IP_NULL || ipsnmp_util_lexcmp_oid(rwp->buf, rwp->best) < 0)
            {
                ipcom_strcpy(rwp->best, rwp->buf);
                rwp->bestrt = rt;
            }
        }
    }
    else
    {
        if(lex == 0)
        {
            ipcom_strcpy(rwp->best, rwp->buf);
            rwp->bestrt = rt;
        }
    }

exit:
    /* Do not delete the entry */
    return IP_FALSE;
}