// ioctl.c -- check if freebsd returns the correct address in a jail for DA
//   I suspect the ioctl call goes out the jail and get's the masters one
//   instead of using the configured ip in the jail (which is an alias on the
//   master).
//   See if this outputs the correct address in a jail, usage:
//   ioctl interface
//   - axel
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.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>

int main(int argc, char **argv) {
    int dev = 0;
    struct ifreq ifr;
    struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_addr;

    // check arguments
    if (argc != 2) {
        fprintf(stderr, "Usage: %s interface\n", argv[0]);
        return 1;
    }

    // clear struct
    memset(&ifr, 0, sizeof(ifr));

    // open socket
    if ((dev = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        fprintf(stderr, "Can't open socket: %s\n", strerror(errno));
        return 1;
    }

    // we need the ip address of the interface given as argument
    strcpy(ifr.ifr_name, argv[1]);
    sin->sin_family = AF_INET;

    // do ioctl to get ip address
    if (ioctl(dev, SIOCGIFADDR, &ifr) == -1) {
        fprintf(stderr, "Can't get address information: %s\n", strerror(errno));
        close(dev);
        return 1;
    }

    // print the ip address we got...
    printf("found ip address %s on interface %s\n", inet_ntoa(sin->sin_addr),
           ifr.ifr_name);

    // close socket
    close(dev);
    return(0);
}
