/*
 * Copyright (c) 2003-2006 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_IDSTR(id, "@(#)$Id: t-ipv4-0.c,v 1.10 2006/12/24 17:55:29 ca Exp $")

#include "sm/debug.h"
#include "sm/heap.h"
#include "sm/rpool.h"
#include "sm/test.h"
#include "sm/net.h"
#include "sm/str.h"
#include "sm/io.h"

static int Verbose;

static void
test(uint step)
{
	ipv4_T ipv4;
	sm_ret_T ret;
	uint i;
	char *endptr, ipv4str[20];
	sm_str_P str, rvrs;

	str = sm_str_new(NULL, 16, 32);
	SM_TEST(str != NULL);
	if (str == NULL)
		return;
	rvrs = sm_str_new(NULL, 32, 48);
	SM_TEST(rvrs != NULL);
	if (rvrs == NULL)
		return;

	strlcpy(ipv4str, "1.2.3.4 ", sizeof(ipv4str));
	ret = sm_inet_a2ipv4(ipv4str, &endptr, &ipv4);
	SM_TEST(ret == SM_SUCCESS);
	SM_TEST(endptr == ipv4str + 7);

	strlcpy(ipv4str, "[1.2.3.4]", sizeof(ipv4str));
	ret = sm_inet_a2ipv4(ipv4str, &endptr, &ipv4);
	SM_TEST(ret == SM_SUCCESS);
	SM_TEST(endptr == ipv4str + 9);

	strlcpy(ipv4str, "[1.2.3.4] ", sizeof(ipv4str));
	ret = sm_inet_a2ipv4(ipv4str, &endptr, &ipv4);
	SM_TEST(ret == SM_SUCCESS);
	SM_TEST(endptr == ipv4str + 9);

	for (i = 0; i < UINT32_MAX - step; i += step)
	{
		sm_str_clr(str);
		ret = sm_inet_ipv4str(i, str);
		SM_TEST(ret == SM_SUCCESS);
		if (ret != SM_SUCCESS)
			break;
		if (Verbose > 0)
			sm_io_fprintf(smioout, "i=%X, str=%S\n", i, str);

		if (i == 0)
			SM_TEST(strcmp((char *) sm_str_getdata(str), "0.0.0.0") == 0);
		ret = sm_inet_a2ipv4((const char *)sm_str_getdata(str), NULL, &ipv4);
		SM_TEST(ret == SM_SUCCESS);
		if (ret != SM_SUCCESS)
			break;
		SM_TEST(ipv4 == i);
		if (ret != SM_SUCCESS)
			break;

		sm_str_clr(rvrs);
		ret = sm_inet_ipv42arpastr(i, rvrs);
		SM_TEST(ret == SM_SUCCESS);
		if (ret != SM_SUCCESS)
			break;
		if (i == 0)
			SM_TEST(strcmp((char *) sm_str_getdata(rvrs),
				"0.0.0.0.in-addr.arpa") == 0);
		ret = sm_inet_arpa2ipv4((const char *)sm_str_getdata(rvrs), &ipv4);
		SM_TEST(ret == SM_SUCCESS);
		if (ret != SM_SUCCESS)
			break;
		SM_TEST(ipv4 == i);
		if (ret != SM_SUCCESS)
			break;

	}
	i = UINT32_MAX;
	sm_str_clr(str);
	ret = sm_inet_ipv4str(i, str);
	SM_TEST(strcmp((char *) sm_str_getdata(str), "255.255.255.255") == 0);
	SM_TEST(ret == SM_SUCCESS);
	ret = sm_inet_a2ipv4((const char *)sm_str_getdata(str), NULL, &ipv4);
	SM_TEST(ret == SM_SUCCESS);
	SM_TEST(ipv4 == i);

	sm_str_clr(rvrs);
	ret = sm_inet_ipv42arpastr(i, rvrs);
	SM_TEST(strcmp((char *) sm_str_getdata(rvrs),
			"255.255.255.255.in-addr.arpa") == 0);
	ret = sm_inet_arpa2ipv4((const char *)sm_str_getdata(rvrs), &ipv4);
	SM_TEST(ret == SM_SUCCESS);
	SM_TEST(ipv4 == i);

	sm_str_free(str);
	sm_str_free(rvrs);

	/* test "overflow" (str too short) */
	str = sm_str_new(NULL, 8, 8);
	SM_TEST(str != NULL);
	if (str == NULL)
		return;
	sm_str_clr(str);
	i = UINT32_MAX;
	ret = sm_inet_ipv4str(i, str);
	SM_TEST(ret != SM_SUCCESS);
	sm_str_free(str);

	/* test "overflow": str too short but can be expanded */
	str = sm_str_new(NULL, 8, 32);
	SM_TEST(str != NULL);
	if (str == NULL)
		return;
	sm_str_clr(str);
	i = UINT32_MAX;
	ret = sm_inet_ipv4str(i, str);
	SM_TEST(strcmp((char *) sm_str_getdata(str), "255.255.255.255") == 0);
	SM_TEST(ret == SM_SUCCESS);
	sm_str_free(str);
}

int
main(int argc, char *argv[])
{
	int c;
	uint step;

	opterr = 0;
	Verbose = 0;
	while ((c = getopt(argc, argv, "V")) != -1)
	{
		switch (c)
		{
		  case 'V':
			++Verbose;
			break;
		  default:
			exit(1);
		}
	}
	step = 12345;
	sm_test_begin(argc, argv, "test ipv4 conversions");
	argc -= optind;
	argv += optind;
	if (argc > 0)
		step = (uint) strtoul(argv[0], NULL, 0);
	test(step);
	return sm_test_end();
}


syntax highlighted by Code2HTML, v. 0.9.1