/*
* Copyright (c) 2003-2005 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*/
#include "sm/generic.h"
SM_RCSID("@(#)$Id: lookupip.c,v 1.16 2006/11/13 01:40:00 ca Exp $")
#include "sm/assert.h"
#include "sm/error.h"
#include "sm/memops.h"
#include "sm/heap.h"
#include "map.h"
#include "sm/map.h"
#include "sm/maps.h"
#include "sm/mapc.h"
/*
** SM_MAP_LOOKUP_IP -- Lookup IP address and subnets
**
** Parameters:
** map -- map
** ip -- input string (IPv4 address)
** tag -- tag including delimiter (NULL for no tag)
** flags -- flags to control lookup
** rhs -- rhs of matching entry
**
** Returns:
** usual sm_error code
*/
sm_ret_T
sm_map_lookup_ip(sm_map_P map, sm_str_P ip, sm_str_P tag, uint32_t flags, sm_str_P rhs)
{
sm_ret_T ret;
sm_mapc_P mapc;
size_t len;
sm_str_P str;
bool found;
if (NULL == map)
return sm_error_perm(SM_EM_MAP, SM_E_NOMAP);
SM_IS_MAP(map);
mapc = map->sm_map_class;
SM_IS_MAPC(mapc);
if (NULL == mapc->sm_mapc_lookupf)
return sm_error_perm(SM_EM_MAP, SM_E_NOTIMPL);
if (!SMMAP_LT_M_CAPS(map, SMMAP_FL_HAS_IPV4))
return sm_error_perm(SM_EM_MAP, ENOENT); /* XXX */
str = NULL;
len = sm_str_getlen(ip);
if (0 == len)
return sm_error_perm(SM_EM_MAP, SM_E_NOTFOUND); /* XXX */
if (tag != NULL)
len += sm_str_getlen(tag);
str = sm_str_new(NULL, len , len + 2);
if (NULL == str)
return sm_error_perm(SM_EM_MAP, ENOMEM);
/*
** Note: instead of creating the str inside the loop each time
** it would be sufficient to set the length of str accordingly
** because trailing elements are cut off.
*/
found = false;
len = sm_str_getlen(ip) - 1;
do {
sm_str_clr(str);
if (tag != NULL) {
ret = sm_str_cat(str, tag);
if (sm_is_err(ret))
break;
}
ret = sm_str_catpart(str, (sm_rdstr_P) ip, 0, len);
if (sm_is_err(ret))
break;
ret = mapc->sm_mapc_lookupf(map, SMMAP_FL_NONE, str, rhs);
if (SM_MAP_DATA2BIG == ret)
goto done;
if (SM_SUCCESS == ret) {
found = true;
break;
}
while (len > 0) {
if (sm_str_rd_elem(ip, len) == '.') {
--len;
break;
}
--len;
}
} while (len > 0 && SMMAP_IS_LFL(flags, SMMAP_LFL_SUBNETS));
if (!found && SMMAP_IS_LFL(flags, SMMAP_LFL_TAG) && 0 == len
&& tag != NULL)
{
/* lookup default: just tag */
ret = mapc->sm_mapc_lookupf(map, SMMAP_FL_NONE, tag, rhs);
}
done:
sm_str_free(str);
/*
** Who "owns" the data?
** need some flags that tell us what to do? see BDB.
*/
return ret;
}
syntax highlighted by Code2HTML, v. 0.9.1