+ All Categories
Home > Documents > UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming1 Chapter 16. ioctl Operations.

Date post: 02-Jan-2016
Category:
Upload: bryce-mcgee
View: 226 times
Download: 1 times
Share this document with a friend
Popular Tags:
26
UNIX Network Programming 1 Chapter 16. ioctl ioctl Operations Operations
Transcript
Page 1: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 1

Chapter 16.

ioctlioctl OperationsOperations

Page 2: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 2

16.1 Introduction16.1 Introduction

• The ioctl function has traditionally been the system interface used for everything that didn’t fit into some other nicely defined category.

• Nevertheless numerous ioctls remain for implementation-dependent features related to network programming: obtaining the interface information, accessing the routing table, ARP cache

• A common use of ioctl by network program ( typically server ) is to obtain information on all the host’s interfaces when the program starts : the interface addresses, whether the interface supports broadcasting, whether the interface supports multicasting, and so on.

Page 3: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 3

16.2 16.2 ioctlioctl Function Function

– The third argument is always a pointer, but the type of pointer depends on the request.

– We can divide the requests related to networking into sex categories.

• socket operations

• file operations

• interface operations

• ARP cache operations

• routing table operations

• streams system

#include <unistd.h>

int ioctl ( int fd, int request, . . . /* void *arg */ );

Returns: 0 if OK, -1 on error

Page 4: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 4

Page 5: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 5

16.3 Socket Operations16.3 Socket Operations

• SIOCATMASK• return through the integer pointed to by the third argument a nonzero value if

the socket’s read pointer is currently at the out-of-band mark, of a zero value if the read pointer is not at the out-of-band mark.

• SIOCGPGRP• return through the integer pointed to by the third argument either the process

ID or the process group ID that is set to receive the SIGIO or SIGURG signal for this socket.

• SIOCSPGRP• set either the process ID or the process group ID to receive the SIGIO or

SIGURG signal for this socket from the integer pointed to by third argument.

Page 6: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 6

16.4 File Operations16.4 File Operations

• FIONBIO• the nonblocking flag for the socket is cleared or turned on, depending whether

the third argument to ioclt points to a zero or nonzero value, respectively.

• FIOASYNC• the flag that governs the receipt of asynchronous I/O signals(SIGIO) for the so

cket is cleared or turned on, depending whether the third argument to ioctl points a zero or nonzero value, respectively.

• FIONREAD• return in the integer pointed to by the third argument to ioctl the number of by

tes currently in the socket receive buffer.

• FIOSETOWN - Equivalent to SIOCSPGRP for a socket

• FIOGETOWN - Equivalent to SIOCGPGRP for a socket

Page 7: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 7

16.5 Interface Configuration16.5 Interface Configuration

• From the kernel, get all the network interfaces configured on the system

• In order to do it, use ioctl with SIOCGIFCONF

• Before calling ioctl we allocate a buffer and an ifconf structure and the initialize the latter.

ifc_lenifc_req

1024ifreq{}

Figure 16.3 Initialization of ifconf structure before SIOCGIFCONF.

Page 8: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 8

16.5 Interface Configuration16.5 Interface Configuration

ifr_name[]

sock etad d ress

stru ctu re

ifr_name[]

sock etad d ress

stru ctu re

ifreq{}

ifreq{}

ifc_lenifc_req

64ifreq{}

Figure 16.4 Values returned by SIOCGIFCONF.

Page 9: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 9

16.5 Interface Configuration16.5 Interface Configurationstruct ifconf { int ifc_len; /* Size of buffer. */ union { caddr_t ifcu_buf; struct ifreq *ifcu_req; } ifc_ifcu; };#define ifc_buf ifc_ifcu.ifcu_buf /* Buffer address. */#define ifc_req ifc_ifcu.ifcu_req /* Array of structures. */

#define IFNAMSIZ16struct ifreq { char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */ union { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; short int ifru_flags; int ifru_matric; caddr_t ifru_data; } ifr_ifru;};#define ifr_addr ifr_ifru.ifru_addr /* address */#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */#define ifr_flags ifr_ifru.ifru_flags /* flags */#define ifr_metric ifr_ifru.ifru_ivalue /* metric */#define ifr_data ifr_ifru.ifru_data /* for use by interface */

Page 10: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 10

16.6 get_cli_info function16.6 get_cli_info function

• Since many programs need to know all the interfaces on a system, we will develop a function of our own named get_ifi_info that returns a linked list of structures, one for each interface that is currently “up”.

Page 11: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 11

Figure 16.5 Figure 16.5 unpifi.hunpifi.h header. header.

#include "unp.h"#include <net/if.h>

#define IFI_NAME 16 /* same as IFNAMSIZ in <net/if.h> */#define IFI_HADDR 8 /* allow for 64-bit EUI-64 in future */

struct ifi_info { char ifi_name[IFI_NAME]; /* interface name, null terminated */ u_char ifi_haddr[IFI_HADDR]; /* hardware address */ u_short ifi_hlen; /* #bytes in hardware address: 0, 6, 8 */ short ifi_flags; /* IFF_xxx constants from <net/if.h> */ short ifi_myflags; /* our own IFI_xxx flags */ struct sockaddr *ifi_addr; /* primary address */ struct sockaddr *ifi_brdaddr; /* broadcast address */ struct sockaddr *ifi_dstaddr; /* destination address */ struct ifi_info *ifi_next; /* next of these structures */};#define IFI_ALIAS 1 /* ifi_addr is an alias */

/* function prototypes */struct ifi_info *get_ifi_info(int, int);struct ifi_info *Get_ifi_info(int, int);void free_ifi_info(struct ifi_info *);

Page 12: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 12

Figure 16.6 Figure 16.6 prifinfoprifinfo program that calls our program that calls our get_ifi_infoget_ifi_info function. (1/3) function. (1/3)

#include "unpifi.h"

intmain(int argc, char **argv){

struct ifi_info *ifi, *ifihead;struct sockaddr *sa;u_char *ptr;int i, family, doaliases;

if (argc != 3)err_quit("usage: prifinfo <inet4|inet6> <doaliases>");

if (strcmp(argv[1], "inet4") == 0)family = AF_INET;

#ifdef IPV6else if (strcmp(argv[1], "inet6") == 0)

family = AF_INET6;#endif

elseerr_quit("invalid <address-family>");

doaliases = atoi(argv[2]);

Page 13: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 13

Figure 16.6 Figure 16.6 prifinfoprifinfo program that calls our program that calls our get_ifi_infoget_ifi_info function. (2/3) function. (2/3)

for (ifihead = ifi = Get_ifi_info(family, doaliases);

ifi != NULL; ifi = ifi->ifi_next) {

printf("%s: <", ifi->ifi_name);

if (ifi->ifi_flags & IFF_UP) printf("UP ");

if (ifi->ifi_flags & IFF_BROADCAST) printf("BCAST ");

if (ifi->ifi_flags & IFF_MULTICAST) printf("MCAST ");

if (ifi->ifi_flags & IFF_LOOPBACK) printf("LOOP ");

if (ifi->ifi_flags & IFF_POINTOPOINT) printf("P2P ");

printf(">\n");

Page 14: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 14

Figure 16.6 Figure 16.6 prifinfoprifinfo program that calls our program that calls our get_ifi_infoget_ifi_info function. (3/3) function. (3/3)

if ( (i = ifi->ifi_hlen) > 0) {ptr = ifi->ifi_haddr;do {

printf("%s%x", (i == ifi->ifi_hlen) ? " " : ":", *ptr++);} while (--i > 0);printf("\n");

}

if ( (sa = ifi->ifi_addr) != NULL)printf(" IP addr: %s\n",

Sock_ntop_host(sa, sizeof(*sa)));if ( (sa = ifi->ifi_brdaddr) != NULL)

printf(" broadcast addr: %s\n",Sock_ntop_host(sa, sizeof(*sa)));

if ( (sa = ifi->ifi_dstaddr) != NULL)printf(" destination addr: %s\n",

Sock_ntop_host(sa, sizeof(*sa)));}free_ifi_info(ifihead);exit(0);

}

Page 15: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 15

lib/get_ifi_info.clib/get_ifi_info.c (1/6) (1/6)

#include "unpifi.h"

struct ifi_info *get_ifi_info(int family, int doaliases){

struct ifi_info *ifi, *ifihead, **ifipnext;int sockfd, len, lastlen, flags, myflags;char *ptr, *buf, lastname[IFNAMSIZ], *cptr;struct ifconf ifc;struct ifreq *ifr, ifrcopy;struct sockaddr_in *sinptr;

sockfd = Socket(AF_INET, SOCK_DGRAM, 0);

lastlen = 0;len = 100 * sizeof(struct ifreq); /* initial buffer size guess */

Page 16: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 16

lib/get_ifi_info.clib/get_ifi_info.c (2/6) (2/6)

for ( ; ; ) {buf = Malloc(len);ifc.ifc_len = len;ifc.ifc_buf = buf;if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {

if (errno != EINVAL || lastlen != 0)err_sys("ioctl error");

} else {if (ifc.ifc_len == lastlen)

break; /* success, len has not changed */lastlen = ifc.ifc_len;

}len += 10 * sizeof(struct ifreq); /* increment */free(buf);

}ifihead = NULL;ifipnext = &ifihead;lastname[0] = 0;

Page 17: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 17

lib/get_ifi_info.c lib/get_ifi_info.c (3/6)(3/6)

for (ptr = buf; ptr < buf + ifc.ifc_len; ) {ifr = (struct ifreq *) ptr;

#ifdef HAVE_SOCKADDR_SA_LENlen = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);

#elseswitch (ifr->ifr_addr.sa_family) {

#ifdef IPV6case AF_INET6:

len = sizeof(struct sockaddr_in6);break;

#endifcase AF_INET:default:

len = sizeof(struct sockaddr);break;

}#endif /* HAVE_SOCKADDR_SA_LEN */

ptr += sizeof(ifr->ifr_name) + len; /* for next one in buffer */

Page 18: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 18

lib/get_ifi_info.c lib/get_ifi_info.c (4/6)(4/6)

if (ifr->ifr_addr.sa_family != family)continue; /* ignore if not desired address family */

myflags = 0;if ( (cptr = strchr(ifr->ifr_name, ':')) != NULL)

*cptr = 0; /* replace colon will null */if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {

if (doaliases == 0)continue; /* already processed this interface */

myflags = IFI_ALIAS;}memcpy(lastname, ifr->ifr_name, IFNAMSIZ);

ifrcopy = *ifr;Ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);flags = ifrcopy.ifr_flags;if ((flags & IFF_UP) == 0)

continue; /* ignore if interface not up */

Page 19: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 19

lib/get_ifi_info.c lib/get_ifi_info.c (5/6)(5/6)

ifi = Calloc(1, sizeof(struct ifi_info));*ifipnext = ifi; /* prev points to this new one */ifipnext = &ifi->ifi_next; /* pointer to next one goes here */

ifi->ifi_flags = flags; /* IFF_xxx values */ifi->ifi_myflags = myflags; /* IFI_xxx values */memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME);ifi->ifi_name[IFI_NAME-1] = '\0';

switch (ifr->ifr_addr.sa_family) {case AF_INET:

sinptr = (struct sockaddr_in *) &ifr->ifr_addr;if (ifi->ifi_addr == NULL) {

ifi->ifi_addr = Calloc(1, sizeof(struct sockaddr_in));memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in));

Page 20: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 20

lib/get_ifi_info.c lib/get_ifi_info.c (6/6) (6/6)

#ifdef SIOCGIFBRDADDRif (flags & IFF_BROADCAST) {

Ioctl(sockfd, SIOCGIFBRDADDR, &ifrcopy);sinptr = (struct sockaddr_in *) &ifrcopy.ifr_broadaddr;ifi->ifi_brdaddr = Calloc(1, sizeof(struct sockaddr_in));memcpy(ifi->ifi_brdaddr, sinptr, sizeof(struct sockaddr_in));

}#endif

#ifdef SIOCGIFDSTADDRif (flags & IFF_POINTOPOINT) {

Ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy);sinptr = (struct sockaddr_in *) &ifrcopy.ifr_dstaddr;ifi->ifi_dstaddr = Calloc(1, sizeof(struct sockaddr_in));memcpy(ifi->ifi_dstaddr, sinptr, sizeof(struct sockaddr_in));

}#endif

}break;

default:break;

} } free(buf); return(ifihead); /* pointer to first structure in linked list */}

Page 21: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 21

Figure 16.10 Figure 16.10 free_ifi_infofree_ifi_info function: free dynamic memory allocated by function: free dynamic memory allocated by gget _ifi_infoet _ifi_info..

voidfree_ifi_info(struct ifi_info *ifihead){

struct ifi_info *ifi, *ifinext;

for (ifi = ifihead; ifi != NULL; ifi = ifinext) {if (ifi->ifi_addr != NULL)

free(ifi->ifi_addr);if (ifi->ifi_brdaddr != NULL)

free(ifi->ifi_brdaddr);if (ifi->ifi_dstaddr != NULL)

free(ifi->ifi_dstaddr);ifinext = ifi->ifi_next; /* can't fetch ifi_next after free() */free(ifi); /* the ifi_info{} itself */

}}

Page 22: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 22

16.7 Interface Operations16.7 Interface Operations

• SIOCGIFADDR

– return the unicast address in the ifr_addr member.

• SIOCSIFADDR

– sets the interface address from the ifr_addr member.

• SIOCGIFFLAGS

– return the interface flags in the ifr_flags member.

• SIOCSIFFLAGS

– sets the interface flags from the ifr_flags member.

• SIOCGIFDSTADDR

– return the point-to-point address in the ifr_dstaddr member.

• SIOCSIFDSTADDR

– set the point-to-point address from ifr_dstaddr member.

Page 23: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 23

16.7 Interface Operations16.7 Interface Operations

• SIOCGIFBRDADDR

– return the broadcast address in the ifr_broadaddr emember.

• SIOCSIFBRDADDR

– set the broadcast address from the ifr_boradaddr member.

• SIOCGIFNETMASK

– return the subnet mask in the ifr_addr member.

• SIOCSIFNETMASK

– set the subnet mask from the ifr_addr member.

• SIOCGIFMETRIC

– return the interface metric in the ifr_metric member.

• SIOCSIFMETRIC

– set the interface routing metric from the ifr_metric member.

Page 24: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 24

16.8 ARP Cache Operations16.8 ARP Cache Operations

• SIOCSARP– add a new entry to the ARP cache or modify an existing entry.

• SIOCDARP– delete an entry from the ARP cache.

• SIOCGARP– get an entry from the ARP cache.

struct arpreq {

struct sockaddr arp_pa; /* protocol addesss */

struct sockaddr arp_ha; /* hardware address */

int arp_flags; /* flags */};

#define ATF_INUSE 0x01 /* entry in use */#define ATF_COM 0x02 /* completed entry (hardware addr valid) */#define ATF_PERM 0x04 /* permanent entry */#define ATF_PUBL 0x08 /* published entry (respond for other host) */

Page 25: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 25

Figure 16.12 Print a host’s hardware addresses.Figure 16.12 Print a host’s hardware addresses.

int main(int argc, char **argv){

int family, sockfd;char str[INET6_ADDRSTRLEN];char **pptr;unsigned char *ptr;struct arpreq arpreq;struct sockaddr_in *sin;

pptr = my_addrs(&family);for ( ; *pptr != NULL; pptr++) {

printf("%s: ", Inet_ntop(family, *pptr, str, sizeof(str)));switch (family) {case AF_INET:

sockfd = Socket(AF_INET, SOCK_DGRAM, 0);sin = (struct sockaddr_in *) &arpreq.arp_pa;bzero(sin, sizeof(struct sockaddr_in));sin->sin_family = AF_INET;memcpy(&sin->sin_addr, *pptr, sizeof(struct in_addr));Ioctl(sockfd, SIOCGARP, &arpreq);ptr = &arpreq.arp_ha.sa_data[0];printf("%x:%x:%x:%x:%x:%x\n", *ptr, *(ptr+1),

*(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5));break;

default:err_quit("unsupported address family: %d", family);

} } exit(0); }

Page 26: UNIX Network Programming1 Chapter 16. ioctl Operations.

UNIX Network Programming 26

16.9 Routing Table Operations16.9 Routing Table Operations

• Two ioctl requests are provided to operate on the routing table.

• These two requests require that the third argument to ioctl be a pointer to an rtentry structure,which is defined by including the <net/route.h> header.

• Only the superuser can issue these requests.

• SIOCADDRT - add an entry to the routing table.

• SIOCDELRT - delete an entry to the routing table.


Recommended