• 《网络编程》ioctl 操作


    概要

             ioctl 功能与 fcntl 功能类似,它可以被用于描述操作的叙述字符,获取或设置属性的描述是开放式的叙事休息,但在网络编程的两个功能有关的不同类型的操作。fcntl 作、文件操作,而 ioctl 函数除了能够操作 fcntl 函数可操作的类型之外,还能够进行接口操作、路由表操作、 ARP 快速缓存操作以及流系统操作。

    ioctl 函数

    该函数能够实现对已打开描写叙述符进程操作。其定义例如以下:

    /* 函数功能:操作描写叙述符,设置已打开的描写叙述符属性。
     * 函数原型:
     */
    #include <sys/ioctl.h>
    /* Perform the I/O control operation specified by REQUEST on FD.
       One argument may follow; its presence and type depend on REQUEST.
       Return value depends on REQUEST.  Usually -1 indicates error.  */
    int ioctl (int fd, unsigned long int request, .../* void *arg */);
    /*
     * 说明:
     * 把和网络相关的请求request划分为下面 6 类:
     * (1)套接字操作
     * (2)文件操作
     * (3)接口操作
     * (4)ARP快速缓存操作
     * (5)路由表操作
     * (6)流系统
     */
    /*
    *fcntl函数
    *功能:操纵文件描写叙述符,设置已打开的文件的属性*/
    int fcntl(int fd, int cmd, ... /* arg */ );
    /*说明:
     * fcntl 函数提供了与网络编程相关的特性例如以下:
     * (1)非堵塞式IO。标志:O_NONBLOCK
     * (2)信号驱动式IO;标志:O_ASYNC
     * (3)套接字属性;标志:F_GETOWN、F_SETOWN
     *
     * cmd的取值能够例如以下:
     * 拷贝文件描写叙述符
     *   F_DUPFD (long)
     * 设置/获取文件描写叙述符标志
     *   F_GETFD (void)
     *   F_SETFD (long)
     * 设置/获取文件状态标志
     *   F_GETFL (void)
     *   F_SETFL (long)
     * 获取/设置文件锁
     *   F_GETLK
     *   F_SETLK,F_SETLKW
     */
    
    当中 request 參数以及 arg 地址指向的数据类型与网络相关。下面列出了不同网络类型相应的信息:


    以下针对由请求 request 划分的 6 大类进行分析。


    套接字操作

    由上面表格能够知道,在套接字操作中,ioctl 函数的请求 request 參数有 3 可选值,而且这 3 个值相应的第三个參数的数据类型是一个指向整数的指针。

    1. SIOCATMARK:若套接字的 读指针 当前位于带外标记,则 ioctl 函数通过第三个參数指向的整数返回非 0 值;否则返回 0 值;
    2. SIOCGPRP:通过由第三个參数指向的整数返回套接字的 进程 ID进程组 ID。该 ID 指定针对套接字的 SIGIO 或 SIGURG 信号的接收进程;等价于 fcntl 函数指定 F_GETOWN 命令;
    3. SIOCSPGRP:把套接字的 进程 ID 或 进程组 ID 设置成由第三个參数指向的整数,该 ID 指定针对套接字的 SIGIO 或 SIGURG 信号的接收进程。等价于 fcntl 函数指定 F_SETOWN 命令。


    文件操作

    依据 请求 request 參数和第三个參数不同有下面的内容:

    1. FIONBIO:依据 ioctl 函数第三个參数指向一个 0 值或非 0 值,可清除或设置套接字的非堵塞 I/O 标志;
    2. FIOASYNC:依据 ioctl 函数第三个參数指向一个 0 值或非 0 值,可清除或设置套接字的信号驱动异步 I/O 标志,决定是否接收针对套接字的异步 I/O 信号(SIGIO);
    3. FIONREAD:依据 ioctl 函数第三个參数指向的整数返回当前套接字接收缓冲区的字节数;
    4. FIOSETOWN:对于套接字和前面的 SIOCSPGRP 等效:
    5. FIOGETOWN:对于套接字和前面的 SIOCGPGRP 等效:


    接口操作

            须要处理网络接口。首先必须从内核获取配置在系统上的全部接口信息。详细请求 request 參数的取值由上表可知。SIOCGIFCONF:从内核中获取系统中配置的全部接口。它使用了结构 ifconf,ifconf 又使用了 ifreq 结构。

    在调用 ioctl 之前分配一个缓冲区和一个 ifconf 结构,然后初始化后者,iotctl 的第三个參数指向 ifconf 结构。

    /* 结构定义例如以下:*/
    struct ifconf {
        int ifc_len; /* size of buffer, value-result */
        union {
            caddr_t ifcu_buf; /* input from user->kernel */
            struct ifreq *ifcu_req; /* return from kernel->user */
        }ifc_ifcu;
    };
    #define ifc_buf     ifc_ifcu.ifcu_buf
    #define ifc_req     ifc_ifcu.ifcu_req
    #define IFNAMSIZ    16
    struct ifreq {
        char ifr_name[IFNAMSIZ];
        union {
            struct sockaddr ifru_addr;
            struct sockaddr ifru_dstaddr;
            struct sockaddr ifru_broadaddr;
            short ifru_flags;
            int ifru_metric;
            caddr_t ifru_data;
        }ifr_ifru;
    };
    #define ifr_addr        ifr_ifru.ifru_addr
    #define ifr_dstaddr     ifr_ifru.ifru_dstaddr
    #define ifr_broadaddr   ifr_ifru.broadaddr
    #define ifr_flags       ifr_ifru.ifru_flags
    #define ifr_metric      ifr_ifru.ifru_metric
    #define ifr_data        ifr_ifru.ifru_data
    

    ARP 快速缓存操作

    能够使用 ioctl 函数操作 ARP 快速缓存,ioctl 函数的第三个參数必须指向一个 arpreq 结构,其结构定义例如以下:

    /* ARP ioctl request.  */
    struct arpreq
      {
        struct sockaddr arp_pa;		/* Protocol address.  */
        struct sockaddr arp_ha;		/* Hardware address.  */
        int arp_flags;			/* Flags.  */
        struct sockaddr arp_netmask;	/* Netmask (only for proxy arps).  */
        char arp_dev[16];
      };
    
    
    /* ARP Flag values.  */
    #define ATF_COM		0x02		/* Completed entry (ha valid).  */
    #define	ATF_PERM	0x04		/* Permanent entry.  */
    #define	ATF_PUBL	0x08		/* Publish entry.  */
    #define	ATF_USETRAILERS	0x10		/* Has requested trailers.  */
    #define ATF_NETMASK     0x20            /* Want to use a netmask (only
    					   for proxy entries).  */
    #define ATF_DONTPUB	0x40		/* Don't answer this addresses.  */
    #define ATF_MAGIC	0x80		/* Automatically added entry.  */
    
    
    /* Support for the user space arp daemon, arpd.  */
    #define ARPD_UPDATE	0x01
    #define ARPD_LOOKUP	0x02
    #define ARPD_FLUSH	0x03
    
    下面是请求參数的值及其功能:

    1. SIOCSARP:把一个新的表项加入到 ARP 快速缓存,或改动当中已经存在的一个表项。
    2. SIOCDARP:从 ARP 快速缓存中删除指定的一个表项;
    3. SIOCGARP:从 ARP 快速缓存中获取一个表项;


    路由表操作

    ioctl 函数有 2 个请求能够操作路由,其相应的第三个參数是指向 rtentry 结构的指针,该结构定义例如以下

    /* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */
    struct rtentry
      {
        unsigned long int rt_pad1;
        struct sockaddr rt_dst;		/* Target address.  */
        struct sockaddr rt_gateway;		/* Gateway addr (RTF_GATEWAY).  */
        struct sockaddr rt_genmask;		/* Target network mask (IP).  */
        unsigned short int rt_flags;
        short int rt_pad2;
        unsigned long int rt_pad3;
        unsigned char rt_tos;
        unsigned char rt_class;
    #if __WORDSIZE == 64
        short int rt_pad4[3];
    #else
        short int rt_pad4;
    #endif
        short int rt_metric;		/* +1 for binary compatibility!  */
        char *rt_dev;			/* Forcing the device at add.  */
        unsigned long int rt_mtu;		/* Per route MTU/Window.  */
        unsigned long int rt_window;	/* Window clamping.  */
        unsigned short int rt_irtt;		/* Initial RTT.  */
      };
    
    下面是请求參数的值及其功能:

    1. SIOCADDRT:往路由表中添加一个表项;
    2. SIOCDELRT:往路由表中删除一个表项;

    总结

            这章内容基本是环绕 ioctl 函数中的请求參数和第三个參数进行的。感觉不好记忆,由于都是一些參数标志,相关信息还是查看书本上的解说,书本上有给出几个样例。

    參考资料:
    《Unix 网络编程》

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    Codeforces 841 D
    Codeforces 838 B
    Codeforces 833 C
    Codeforces 101572 D
    Codeforces 101173 C
    Codeforces 444 C
    POJ 3076 Sudoku
    Codeforces 1025 D
    算法笔记--基环树
    Codeforces 1016 E
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4814052.html
Copyright © 2020-2023  润新知