⬢ DragonFlyBSD Kernel Audit
DF-3319 / getlif.c
← back to finding ↓ download raw
/*
 * DF-3319 regression helper: SIOCGLIFADDR (unprivileged) on an interface.
 *
 * On the stock kernel this takes the DF-0490 type-confusion path (it can
 * only ever return an AF_INET6 ifaddr).  After the in.c:911 filter fix
 * it must return the interface's first AF_INET address cleanly.
 *
 * Build: cc -O -o getlif getlif.c
 * Run:   ./getlif lo0
 */
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

int
main(int argc, char **argv)
{
	struct if_laddrreq iflr;
	struct sockaddr_in *sin;
	const char *ifname = (argc > 1) ? argv[1] : "lo0";
	int s;

	s = socket(AF_INET, SOCK_DGRAM, 0);
	if (s < 0) {
		perror("socket");
		exit(1);
	}
	memset(&iflr, 0, sizeof(iflr));
	strlcpy(iflr.iflr_name, ifname, sizeof(iflr.iflr_name));

	if (ioctl(s, SIOCGLIFADDR, &iflr) < 0) {
		printf("SIOCGLIFADDR(%s): %s\n", ifname, strerror(errno));
		return (1);
	}
	sin = (struct sockaddr_in *)&iflr.addr;
	printf("SIOCGLIFADDR(%s): family=%u len=%u addr=%s prefixlen=%u\n",
	    ifname, sin->sin_family, sin->sin_len,
	    inet_ntoa(sin->sin_addr), iflr.prefixlen);
	return (0);
}