Detailed analysis of IOCTL Functions

Source: Internet
Author: User

IPv4 and IPv6 network interface operations
Use the socket IOCTL command

 
Level: Intermediate

Katiyar Manish (manish.katiyar@in.ibm.com), software engineer, IBM, Intel, Microsoft, HP
Shweta Gupta, Senior Software Engineer, IBM

March 13, 2007

Learn more about socket I/O Control (IOCTL) commands and how to use them to perform various network-related operations. the operating system provides control operations for sockets, route tables, ARP tables, global network parameters, and interfaces. This article applies to AIX version 5.3 developers interested in Internet Protocol Version 4 (IPv4) and Internet Protocol version 6 (IPv6) stack network-level operations.
Introduction

The file descriptor is a low-level input and output interface. Descriptors can represent connections to devices, pipelines, or sockets. These connections are used to communicate with another process or common file. The I/O Control (IOCTL) function call can be used to operate the basic device parameters of special files. They can complete the control function associated with the opened file descriptor. These commands involve file, stream, Common Data Link Control, and various other devices.

This article will discuss the network operations and socket-related commands provided in Aix Version 5.3. The socket-related commands and structures are listed in the following files:

Sys/IOCTL. h
Net/if_arp.h
Net/If. h
Net/netopt. h
Netinet/in. h
Application developers can use these commands and provide detailed descriptions of these commands in the documents of AIX version 5.3. This document describes common commands for Internet Protocol version 6 (IPv6) addresses and Internet Protocol Version 4 (IPv4) stacks.

Use IOCTL socket control options

Generally, network programs need to know all available information about network interfaces and IP addresses in the system. Now, future applications can support both IPv4 and IPv6 protocol stacks. The IOCTL structure needs to traverse and operate the pointer to handle the difference in length between IPv4 and IPv6 addresses (except for using the appropriate Socket Structure sockaddr_in6 or sockaddr_storage ).

AIX version 5.3 provides many IOCTL socket control options to extract information about network interfaces. These IOCTL commands are used to query the interface status and perform operations on its attributes. The following section contains the code snippet of some useful commands. For a complete list of IOCTL commands, see references.

Structure Used by the ioctl command

The following list describes some of the most important structures, which are often used in IOCTL socket commands.

Listing 1. struct ifreq (/usr/include/NET/If. h)

/* Interface request structure used for socket
* IOCTL's. All interface IOCTL's must have Parameter
* Definitions which begin with ifr_name.
* Remainder may be interface specific.
*/
Struct ifreq {
# Ifndef ifnamsiz
# Define ifnamsiz 16
# Endif
Char ifr_name [ifnamsiz];
Union {
Struct sockaddr ifru_addr;
Struct sockaddr ifru_dstaddr;
Struct sockaddr ifru_broadaddr;
_ Ulong32_t ifru_flags;
Int ifru_metric;
Caddr_t ifru_data;
U_short ifru_site6;
_ Ulong32_t ifru_mtu;
Int ifru_baudrate;
} Ifr_ifru;

Following macros are provided for convenience

# Define ifr_addr ifr_ifru.ifru_addr/* address */
# Define ifr_dstaddr ifr_ifru.ifru_dstaddr/* Other end of p-to-P link */
# Define ifr_broadaddr ifr_ifru.ifru_broadaddr/* broadcast address */
# Define ifr_flags ifr_ifru.ifru_flags/* flags */
# Define ifr_metric ifr_ifru.ifru_metric/* Metric */
# Define ifr_data ifr_ifru.ifru_data/* for use by interface */
# Define ifr_site6 ifr_ifru.ifru_site6/* IPv6 Site Index */
# Define ifr_mtu ifr_ifru.ifru_mtu/* MTU of interface */
# Define ifr_isno ifr_ifru.ifru_data/* pointer to if_netopts */
# Define ifr_baudrate ifr_ifru.ifru_baudrate/* baudrate of interface */
};

Listing 2. struct ifconf (/usr/include/NET/If. h)

/*
* Structure used in siocgifconf request.
* Used to retrieve Interface Configuration
* For machine (useful for programs which
* Must know all networks accessible ).
*/
Struct ifconf {
Int ifc_len;/* size of associated buffer */
Union {
Caddr_t ifcu_buf;
Struct ifreq * ifcu_req;
} Ifc_ifcu;

Following macros are provided for convenience

# Define ifc_buf ifc_ifcu.ifcu_buf/* buffer address */
# Define ifc_req ifc_ifcu.ifcu_req/* array of structures returned */
};

 

 

Back to Top
 

 

Sample Code

Table 1 below describes some interface retrieval commands. This information comes from IBM system P and Aix.

Table 1. Interface retrieval commands
IOCTL command description
Siocgsizifconf obtains the memory required to obtain the configuration information of all interfaces returned by siocgifconf.
IOCTL (FD, siocgsizifconf, (caddr_t) & ifconfsize );
Int ifconfsize;

 
Siocgifaddr

Siocsifaddr siocgifaddr obtains the interface address, while siocsifaddr sets the interface address. The return address of the IFR. ifr_addr field. IOCTL (FD, siocgifaddr, (caddr_t) & IFR, sizeof (struct ifreq ));
IOCTL (FD, siocsifaddr, (caddr_t) & IFR, sizeof (struct ifreq ));
Struct ifreq IFR;

 
Siocgifconf returns the configuration information of all interfaces configured in the system. IOCTL (FD, siocgifconf, (caddr_t) & IFC );
Struct ifconf;

 

Siocgsizifconf

The following code snippet obtains the buffer size required to fill in information for all configuration interfaces.

Listing 3. Use siocgsizifconf to obtain the required buffer size

/* Function to get the size needed to allocate for buffers */
Int get_interface_size (int sd ){
Int ret, size;
Ret = IOCTL (SD, siocgsizifconf, & size );
If (ret =-1 ){
Perror ("error getting size of Interface :");
Return ret;
}
Return size;
}

Main
{
Struct ifconf IFC;
Int SD;
SD = socket (af_inet6, sock_dgram, 0 );
Printf ("size of memory needed = % d/N", get_interface_size (SD ));
}
 

The output of the above Code is:

$>./Myprog
Size of memory needed = 628

Siocgifconf and siocgifaddr

The siocgifconf and siocgifaddr commands can be used to retrieve the interface address. Siocgifconf can be used to obtain information about all configuration interfaces, and siocgifaddr can be used to retrieve the addresses of specific interfaces.

Listing 4. Use siocgifconf to obtain configuration information

/* This function uses loops to find out buffer size instead of siocgsizifconf
Allocates the buffer and gets the information list */
Int alloc_buffer_size (int sd, struct ifconf * IFC ){
Int ret =-1, bsz = sizeof (struct ifreq );
Int prevsz = bsz;
IFC-> ifc_req = NULL;
IFC-> ifc_len = bsz;
Do {
IFC-> ifc_req = (struct ifreq *) realloc (IFC-> ifc_req, bsz );
If (! IFC-> ifc_req ){
Perror ("malloc failed :");
Return ret;
}
IFC-> ifc_len = bsz;
Ret = IOCTL (SD, siocgifconf, (caddr_t) IFC );
If (ret =-1 ){
Perror ("error getting size of Interface :");
Return ret;
}
If (prevsz = IFC-> ifc_len)
Break;
Else {
Bsz * = 2;
Prevsz = (0 = IFC-> ifc_len? Bsz: IFC-> ifc_len );
}
} While (1 );
IFC-> ifc_req = (struct ifreq *) realloc (IFC-> ifc_req, prevsz );
Return IFC-> ifc_len;
}

 

After filling the list with configuration information in the ifreq structure, you can traverse it to retrieve the required data. The pointer can be moved based on the length of the socket address filled in the structure after the call. Listing 5 below shows the available IP addresses in the system obtained from the code list above.

Listing 5. retrieving information from the configuration list

# Define max (x, y) (x)> (y )? (X): (y ))
# Define size (P) max (P). sa_len, sizeof (p ))

/* This function prints all the configured IPs on
* System given the ifconf structure allocated previusly */
Void print_ips (struct ifconf * IFC ){
Char * CP, * cplim, ADDR [inet6_addrstrlen];
Struct ifreq * IFR = IFC-> ifc_req;
CP = (char *) IFC-> ifc_req;
Cplim = CP + IFC-> ifc_len;
For (; CP <cplim; CP + = (sizeof (IFR-> ifr_name) + size (IFR-> ifr_addr ))){
/* Note: you cannot just increment CP with sizeof (struct ifreq)
* As structures returned are of different length.
*/
IFR = (struct ifreq *) CP;
Printf ("% s:", IFR-> ifr_name );
Getip (IFR, ADDR );
Printf ("% s/n", ADDR );
}
Return;
}
Main
{
Struct ifconf IFC;
Int SD;
SD = socket (af_inet6, sock_dgram, 0 );
Alloc_buffer_size (SD, & IFC );
Print_ips (& IFC );
}

The output of the above Code is:

$>./Myprog
En0: 6.3.6.0
En0: 9.182.192139
En0: fe80: 209: 6bff: feeb: 70b2
Sit0: 1.4.4.0
Sit0: 9.182.192139
Lo0: 24.3.0.0
Lo0: 127.0.0.1
Lo0: 1

Listing 6. Use siocgifaddr to obtain the interface address

/* Given A ifreq structure this function returns its IP address */
Void getip (struct ifreq * IFR, char * ADDR ){
Struct sockaddr * Sa;
Sa = (struct sockaddr *) & (IFR-> ifr_addr );
Switch (SA-> sa_family ){
Case af_inet6:
Inet_ntop (af_inet6, (struct in6_addr *) & (struct sockaddr_in6 *) SA)-> sin6_addr ),
ADDR, inet6_addrstrlen );
Break;
Default: strcpy (ADDR, inet_ntoa (struct sockaddr_in *) SA)-> sin_addr ));
}
Return;
}

Main
{
Char netaddr [inet_addrstrlen];
Int SD;
SD = socket (af_inet, sock_dgram, 0 );
Strcpy (IFR. ifr_name, "en0 ");
If (IOCTL (SD, siocgifaddr, (caddr_t) & IFR, sizeof (struct ifreq) <0)
Perror ("error :");
Getip (& IFR, netaddr );
Printf ("% s/n", netaddr );
}

The output of the above Code is:

$./Myprog
9.182.192.35

Table 2 below describes the interface flag and some attribute retrieval commands.

Table 2. Interface flag and attribute retrieval commands
IOCTL command description
Siocgifflags

Siocsifflags siocgifflags can obtain interface flags.
You can set the interface flag for siocsifflags.

IOCTL (FD, CMD, (caddr_t) & IFR );
Struct ifreq IFR;

 

Siocgifflags

After getting the list of interfaces using siocgifconf, you can use SIOCGIFFLAGS-SIOCSIFFLAGS pairs to get and set interface properties. The interface flag is iff_xxx. For a complete list, see the file/usr/include/NET/If. h.

The following example uses an interface flag to retrieve the current status and check the loop. You can also use other options.

Listing 7. Verify the interface status and type

For (; CP <cplim ;){
IFR = (struct ifreq *) CP;
CP + = (sizeof (IFR-> ifr_name) + size (IFR-> ifr_addr ));
Printf ("%-9 s", IFR-> ifr_name );
Ret = IOCTL (SD, siocgifflags, (caddr_t) IFR );
If (ret =-1 ){
Perror ("error getting flags for interface :");
Return;
}
If (IFR-> ifr_flags) & iff_up)
Printf ("up ");
Else printf ("down ");
If (IFR-> ifr_flags) & iff_loopback)
Printf (", loopback ");
Printf ("/N ");
}

The output of the above Code is:

$>./Myprog
En0 up
En0 up
En0 up
Sit0 up
Sit0 up
Lo0 up, loopback
Lo0 up, loopback
Lo0 up, loopback

Listing 8. Set the interface flag

Partial output of ifconfig before setting the flag

Sit0: Flags = 4900041 <up, running, link0, 64bit>
Inet6: 9.182.192139/96

Code to set the interface flag

Int set_interface_flag (int sd, short flag, char * interface ){
Struct ifreq IFR;
Int oldflags;
Strcpy (IFR. ifr_name, interface );
If (IOCTL (SD, siocgifflags, (caddr_t) & IFR) =-1 ){
Perror ("error getting interface flags :");
Return-1;
}
Printf ("setting new interface flag 0x % x/N", flag );
IFR. ifr_flags | = flag;
If (IOCTL (SD, siocsifflags, (caddr_t) & IFR) =-1 ){
Perror ("error setting interface flags :");
Return-1;
}
Return 0;
}

Main
{
Int SD;
SD = socket (af_inet6, sock_dgram, 0 );
Set_interface_flag (SD, iff_notrailers, "sit0 ");
}
 

The output of the above Code is:

You must have permission to change the flag

$./Myprog
Setting new interface flag 0x20

$ Ifconfig-
.............
.............
Sit0: Flags = 4900061 <up, notrailers, running, link0, 64bit>
Inet6: 9.182.192139/96
.............
.............

Table 3 describes some commands for network optimization.

Table 3. Network Optimization commands
IOCTL command description
Siocgifmtu can obtain the maximum transmission unit (MTU) of the interface ).
IOCTL (FD, CMD, (caddr_t) & IFR );
Struct ifreq IFR;

The MTU value is stored in the IFR. ifr_mtu field.
 
Siocgnetopt
Siocgnetopt1 siocgnetopt can be used to obtain the value of a Network option.
IOCTL (FD, CMD, (caddr_t) & oreq );
Struct optreq oreq;

Siocgnetopt1 can be used to obtain the range of the current value, default value, and network options.

IOCTL (FD, siocgnetopt1, (caddr_t) & oreq );
Struct optreq1 oreq;

 

Siocgifmtu

 

Listing 9. Retrieving MTU from the ifreq Structure

Ret = IOCTL (SD, siocgifmtu, IFR );
If (ret =-1 ){
Perror ("error getting MTU for interface :");
Return;
}
Printf ("% d/N", IFR-> ifr_mtu );

Siocgnetopt1

Siocgnetopt1 specifies the range of the current value, default value, and network options.

 

Listing 10. Obtain network options from the optreq1 Structure

/* Function to get the network options */
Int print_network_options (int sd ){
Int ret;
Struct optreq1 oreq;
Oreq. getnext = 1;
While (IOCTL (SD, siocgnetopt1, (caddr_t) & oreq ))! =-1)
Printf ("% s = % s/n", oreq. Name, oreq. data );
Return 0;
}

The output of the above Code is:

$>./Myprog
Arpqsize = 12
Arpt_killc = 20
Arptab_bsiz = 7
Arptab_nb= 149
........
........
........
........
Image size = 256
Inet_stack_size = 16
Ip6_defttl = 64
........

In Aix, you can also use the no command to manage various network optimization parameters. For more information, see the corresponding man page.

Listing 11. Output of the "no" command on the AIX computer

$> NO-A | more
Arpqsize = 12
Arpt_killc = 20
Arptab_bsiz = 7
Arptab_nb= 149
Bcastping = 0
Clean_partial_conns = 0
Delayack = 0
Delayackports = {}
Dgd_packets_lost = 3
Dgd_ping_time = 5
Dgd_retry_time = 5
Directed_broadcast = 0
Extendednetstats = 0
Fasttimo= 200
........
........

 

 

Back to Top
 

 

Summary

IOCTL commands are very powerful. You can use them to access or modify configurable parameters of Network (or other) devices. They use a variety of data structures and should be filled with the correct data structure to achieve the expected results. You will find the differences between af_inet and af_inet6 series. This section provides sample code for a small subset of Common commands. For a complete command list in Aix Version 5.3, go to the references section. We hope that the ioctl information will be useful to you.
 

This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/weixiuc/archive/2008/09/11/2914865.aspx

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.