Talk:Ioctl

message: I think this is a fantastic article but may have to rewritten more for the general audience. I sorry I get it but some may not.
: I'm not married to it; what was there before was inaccurate. What do you think it needs? --- tqbf 03:37, 20 November 2007 (UTC)
thread_title:  2007–2009 

message: User:Widefox recently tagged this article with . I've just added a list of references to the article, but they don't cover the whole article. Actually, I suspect that there many not be any WP:Reliable Sources for some of the claims, even they they are common knowledge amongst experienced Unix programmers.
I did not mention The Art of Unix Programming by Eric S. Raymond, which has a subsection titled "ioctl(2) and fcntl(2) Are an Embarrassment" (in chapter 20, online here). Should we use that in the article? If so, how? Does anyone have more sources? Cheers, CWC 11:34, 8 March 2010 (UTC)
thread_title:  References 

message: In the complexity paragraph it is said that one needs a "tangled mess of ioctl()s" to get an IP.
That's BS. You only need one. Like so: ioctl(int sockfd, SIOCGIFADDR, struct ifreq *req);
And voila, ((struct sockaddr_in *)&req.ifr_addr)->sin_addr yields the IP.
Seriously, ioctl()s aren't complex, they are very easy to use and understand. It's only that there are hundreds of request codes(see /usr/include/linux/sockios.h on a Linux machine for a reference).
Maybe some example program should be shown.
That program below will output the IPv4 of the device 'lo' (local loopback on Linux, called lo0 on *BSD), which is of cource 127.0.0.1.
Substitute lo in the macro definition with any device you want the IPv4 address from.
The program will compile cleanly and can be run without rootr ights on Linux(and probably every other UNIX-like OS).
#include <sys/ioctl.h>  /* ioctl() */
#include <sys/socket.h> /* socket types, address families */
#include <net/if.h>     /* struct ifreq */
#include <arpa/inet.h>  /* inet_ntop() */
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> /* close() */
#define DEVICE "lo"
int main()
{
    int sockfd; /* file descriptor returned by socket(), it must be passed to ioctl() */
    char buf[INET_ADDRSTRLEN]; /* buffer for inet_ntop() */
    struct ifreq req = { 0 }; /* initialize to everything 0/NULL(better then memset()) */
    struct in_addr ip;
    strncpy(req.ifr_name, DEVICE, IF_NAMESIZE); /* logically, the name of the device must be passed to ioctl() */
    sockfd = socket(AF_INET, SOCK_DGRAM, 0); /* SOCK_DGRAM or SOCK_RAW .... doesn't matter */
    if (sockfd == -1) {
        perror("Error: socket()");
        exit(EXIT_FAILURE);
    }
    if (ioctl(sockfd, SIOCGIFADDR, &req) == -1) { /* SIOCGIFADDR: gets us the address(see netdevice(7) on Linux) */
        perror("Error: ioctl()");
        close(sockfd);
        exit(EXIT_FAILURE);
    }
    close(sockfd);
    ip = ((struct sockaddr_in *)&req.ifr_addr)->sin_addr; /* ifr_addr is just a generic sockaddr structure; must be cast to sockaddr_in to get IPV4 */
    printf("IP for device " DEVICE ": %s\n", inet_ntop(AF_INET, &ip, buf, INET_ADDRSTRLEN));
    return EXIT_SUCCESS;
}
Maybe that code, with (now added) commentary, could make it as an example of ioctl() usage?
80.226.24.13 (talk) 21:47, 25 January 2013 (UTC)
thread_title:  Complexity of ioctl()