/*
 * Check decoding of SIOCGIFCONF command of ioctl syscall.
 *
 * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
 * Copyright (c) 2016-2018 The strace developers.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "tests.h"

#include <stdio.h>
#include <string.h>

#include <arpa/inet.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

#define MAX_STRLEN 1

static void
print_ifc_len(int val)
{
	if (val % (int) sizeof(struct ifreq))
		printf("%d", val);
	else
		printf("%d * sizeof(struct ifreq)",
		       val / (int) sizeof(struct ifreq));
}

static void
print_ifconf(struct ifconf *ifc, int in_len, char *in_buf, long rc)
{
	if (in_buf) {
		printf("{ifc_len=");
		print_ifc_len(in_len);

		if (in_len != ifc->ifc_len) {
			printf(" => ");
			print_ifc_len(ifc->ifc_len);
		}
	} else {
		printf("{ifc_len=");
		print_ifc_len(ifc->ifc_len);
	}

	printf(", ifc_buf=");

	if ((rc < 0) || !in_buf) {
		if (in_buf)
			printf("%p", in_buf);
		else
			printf("NULL");
	} else {
		int i;

		printf("[");
		for (i = 0; i < (ifc->ifc_len) &&
		    i < (int) (MAX_STRLEN * sizeof(struct ifreq));
		    i += sizeof(struct ifreq)) {
			struct ifreq *ifr = (struct ifreq *) (ifc->ifc_buf + i);
			struct sockaddr_in *const sa_in =
				(struct sockaddr_in *) &(ifr->ifr_addr);

			if (i)
				printf(", ");
			printf("{ifr_name=\"%s\", ifr_addr={sa_family=AF_INET, "
			       "sin_port=htons(%u), sin_addr=inet_addr(\"%s\")}"
			       "}", ifr->ifr_name, ntohs(sa_in->sin_port),
			       inet_ntoa(sa_in->sin_addr));
		}

		if ((size_t) (ifc->ifc_len - i) >= sizeof(struct ifreq))
			printf(", ...");

		printf("]");
	}

	printf("}");
}

static void
gifconf_ioctl(int fd, struct ifconf *ifc, bool ifc_valid)
{
	const char *errstr;
	int in_len;
	char *in_buf;
	long rc;

	if (ifc_valid) {
		in_len = ifc->ifc_len;
		in_buf = ifc->ifc_buf;
	}

	rc = ioctl(fd, SIOCGIFCONF, ifc);
	errstr = sprintrc(rc);

	printf("ioctl(%d, SIOCGIFCONF, ", fd);
	if (ifc_valid) {
		print_ifconf(ifc, in_len, in_buf, rc);
	} else {
		if (ifc)
			printf("%p", ifc);
		else
			printf("NULL");
	}

	printf(") = %s\n", errstr);
}

int
main(int argc, char *argv[])
{
	struct ifreq *ifr = tail_alloc(2 * sizeof(*ifr));
	TAIL_ALLOC_OBJECT_CONST_PTR(struct ifconf, ifc);

	struct sockaddr_in addr;
	int fd;

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
		perror_msg_and_skip("socket AF_INET");

	gifconf_ioctl(fd, NULL, false);
	gifconf_ioctl(fd, ifc + 1, false);

	ifc->ifc_len = 3141592653U;
	ifc->ifc_buf = NULL;
	gifconf_ioctl(fd, ifc, true);

	ifc->ifc_len = 0;
	ifc->ifc_buf = (char *) (ifr + 2);
	gifconf_ioctl(fd, ifc, true);

	ifc->ifc_len = 1;
	ifc->ifc_buf = (char *) (ifr + 1);
	gifconf_ioctl(fd, ifc, true);

	ifc->ifc_len = 1 * sizeof(*ifr);
	ifc->ifc_buf = (char *) (ifr + 1);
	gifconf_ioctl(fd, ifc, true);

	ifc->ifc_len = 2 * sizeof(*ifr);
	ifc->ifc_buf = (char *) (ifr + 1);
	gifconf_ioctl(fd, ifc, true);

	ifc->ifc_len = 2 * sizeof(*ifr) + 2;
	ifc->ifc_buf = (char *) ifr;
	gifconf_ioctl(fd, ifc, true);

	ifc->ifc_len = 3 * sizeof(*ifr) + 4;
	ifc->ifc_buf = (char *) ifr;
	gifconf_ioctl(fd, ifc, true);

	puts("+++ exited with 0 +++");
	return 0;
}
