Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 ioctl Operations Computer Network Programming. 2 Use of ioctl() It is the system interface to set and get attributes of devices, sockets, files, interfaces.

Similar presentations


Presentation on theme: "1 ioctl Operations Computer Network Programming. 2 Use of ioctl() It is the system interface to set and get attributes of devices, sockets, files, interfaces."— Presentation transcript:

1 1 ioctl Operations Computer Network Programming

2 2 Use of ioctl() It is the system interface to set and get attributes of devices, sockets, files, interfaces tables like routing table, arp table... The same operations can be performed by Use of special functions such as tcgetattr() Use of routing domain sockets (AF_ROUTE family) Use of fcntl function

3 3 ioctl function() #include int ioctl (int fd, int request, void *arg); arg pointer type depends on the request. Request can be divided into following categories: - Socket operations - File operations - Interface operations - ARP cache operations - Routing table operations

4 4 Socket Operations –SIOCATMARK: integer Return if the socket’s read pointer is currently on the out-of-band data –SIOCGPGRP: int Return the process ID or the process group ID that is set to receive the SIGIO or SIGURG signal for this socket – SIOCSPGRP: int Set either the process ID or process group ID to receive the SIGIO or SIGURG signal for this socket

5 5 File Operations –FIONBIO: integer –Clear or turn on the non-blocking flag for the socket. –FIOASYNC: integer –Clear or turn on the receipt of asynchronous I/O signals (SIGIO) for the socket. –FIONREAD: integer –Return the number of bytes currently available in the socket receive buffer. –FIOSETOWN; integer –Equivalent to SIOCSPGRP for a socket –FIOGETOWN: integer –Equivalent to SIOCGPGRP for a socket

6 6 Interface Configuration –It is possible to obtain information about all the network interfaces configured on the system –IP address, flags, Bcast address, Interface name,.... –It is possible to set the IP address, bcast address, dest address for ptp links, some flags for the interface

7 7 Interface Operations REQUEST DescriptionDatatype ----------------------------------------------------------------------------------------- SIOCGIFCONFget list of all interfacesstruct ifconf SIOCSIFADDRset interface addressstruct ifreq SIOCGIFADDRget interface addressstruct ifreq SIOCSIFFLAGSset interface flags struct ifreq SIOCGIFFLAGSget interface flagsstruct ifreq SIOCSIFDSTADDRset point-to-point addressstruct ifreq SIOCGIFDSTADDRget point-to-point addressstruct ifreq SIOCSIFBRADDRset broadcast addressstruct ifreq SIOCGIFBRADDRget broadcast addressstruct ifreq SIOCGIFNETMASKget subnet maskstruct ifreq SIOCSIFNETMASKset subnet maskstruct ifreq SIOCGIFMETRICget interface metricstruct ifreq SIOCSIFMETRICset interface metricstruct ifreq

8 8 ifconf and ifreq structures structifconf { intifc_len;/* size of associated buffer */ union { caddr_tifcu_buf; structifreq *ifcu_req; } ifc_ifcu; #defineifc_bufifc_ifcu.ifcu_buf/* buffer address */ #defineifc_reqifc_ifcu.ifcu_req/* array of structures returned */ };

9 9 structifreq { #defineIFNAMSIZ16 charifr_name[IFNAMSIZ];/* if name, e.g. "en0" */ union { structsockaddr ifru_addr; /* size = 16 bytes */ structsockaddr ifru_dstaddr; charifru_oname[IFNAMSIZ];/* other if name */ structsockaddr ifru_broadaddr; intifru_index;/* interface index */ shortifru_flags; intifru_metric; charifru_data[1];/* interface dependent data */ charifru_enaddr[6]; intif_muxid[2];/* mux id's for arp and ip * } ifr_ifru; #defineifr_addrifr_ifru.ifru_addr/* address */ #defineifr_dstaddrifr_ifru.ifru_dstaddr/* other end of p-to-p link */ #defineifr_onameifr_ifru.ifru_oname/* other if name */ #defineifr_broadaddr ifr_ifru.ifru_broadaddr/* broadcast address */ #defineifr_flagsifr_ifru.ifru_flags/* flags */ #defineifr_metricifr_ifru.ifru_metric/* metric */ #defineifr_dataifr_ifru.ifru_data/* for use by interface */ #defineifr_enaddrifr_ifru.ifru_enaddr/* ethernet address */ #defineifr_index ifr_ifru.ifru_index/* interface index */ };

10 10 Getting Interface list get_ifi_info () function Will return the list of interface information Each list entry is a structure of type struct ifi_info Will call ioctl() with request type SIOCGIFCONF to get the list –This call will return a an array of ifreq structures: each structure will include info about the interface For each returned ifreq structure about an interface, it can get more information by calling ioctl again with a different request type

11 11 ifi_info structure #defineIFI_NAME16/* same as IFNAMSIZ in */ #defineIFI_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 */ 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 */ }; get_ifi_info() returns the list of the following structure:

12 12 Use of get_ifi_info Function int main(int argc, char **argv) { struct ifi_info*ifi, *ifihead; struct sockaddr*sa; u_char*ptr; inti, family, doaliases; if (argc != 3) err_quit("usage: prifinfo "); if (strcmp(argv[1], "inet4") == 0) family = AF_INET; #ifdefIPV6 else if (strcmp(argv[1], "inet6") == 0) family = AF_INET6; #endif else err_quit("invalid "); doaliases = atoi(argv[2]);

13 13 for (ifihead = ifi = Get_ifi_info(family, doaliases); ifi != NULL; ifi = ifi->ifi_next) { printf("%s: 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"); if ( (i = ifi->ifi_hlen) > 0) { ptr = ifi->ifi_haddr; do { printf("%s%x", (i == ifi->ifi_hlen) ? " " : ":", *ptr++); } while (--i > 0); printf("\n"); }

14 14 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); }

15 15 Example Run aspendos{korpe}:> prifinfo inet4 doaliases lo0: IP addr: 127.0.0.1 le0: IP addr: 139.179.21.217 broadcast addr: 139.179.21.255

16 16 Implementation of get_ifi_info() Function 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 */ 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); } /* continued on the next page */

17 17 ifihead = NULL; ifipnext = &ifihead; lastname[0] = 0; /* end get_ifi_info1 */ /* include get_ifi_info2 */ for (ptr = buf; ptr < buf + ifc.ifc_len; ) { ifr = (struct ifreq *) ptr; len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len); switch (ifr->ifr_addr.sa_family) { case AF_INET6: len = sizeof(struct sockaddr_in6); break; case AF_INET: default: len = sizeof(struct sockaddr); break; } ptr += sizeof(ifr->ifr_name) + len;/* for next one in buffer */

18 18 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 */ 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 */

19 19 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'; /* end get_ifi_info2 */ /* include get_ifi_info3 */ 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)); #ifdefSIOCGIFBRDADDR if (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

20 20 #ifdefSIOCGIFDSTADDR if (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 */ } /* end get_ifi_info */

21 21 ARP Cache Operations REQUEST DescriptionData Type SIOCSARP add a new entry to arp cache struct arpreq SIOCDARP delete an entry from arp cache struct arpreq SIOCGARP get an entry from arp cachestruct arpreq struct arpreq { struct sockaddr arp_pa; struct sockaddr arp_flags; int arp_flags; }

22 22 Routing Table Operations REQUEST DescriptionData Type SIOCADDRTadd an entry to the routing table struct rtentry SIOCDELRT delete an entry from routing table struct rtentry struct rtentry defined in You have to be “root” in order to add and delete routing table entry.

23 23 /dev/kmem and sysctl() There is no ioctl request type for getting the ARP and Routing table entry list. The list can be obtained by reading the kernel’s memory by opening /dev/kmem and reading from it. Or you can use the sysctl() function.


Download ppt "1 ioctl Operations Computer Network Programming. 2 Use of ioctl() It is the system interface to set and get attributes of devices, sockets, files, interfaces."

Similar presentations


Ads by Google