linux系统ioctl函数使用实例

由于源代码注释几乎没有,可能新手较难看懂。因此鄙人加上了注释,有些小错误的地方也改了一下,其它不多说了。

程序1:检测接口的 inet_addr,netmask,broad_addr

程序2:检查接口的物理连接是否正常

程序3:更简单一点测试物理连接

程序4:调节音量

 

程序1:检测接口的 inet_addr,netmask,broad_addr

 

可能用到的资料:

1.ioctl和struct ifreq  

    http://wenku.baidu.com/view/59f4508d680203d8ce2f2412.html

    上面链接中的源代码,头文件需要自己修改一下

 

 
 
  1. //程序1:检测接口的 inet_addr,netmask,broad_addr 
  2. #include <stdio.h> 
  3. #include <string.h> 
  4. #include <stdlib.h> 
  5. #include <errno.h> 
  6. #include <unistd.h> 
  7.  
  8. #include <sys/types.h> 
  9. #include <sys/socket.h> 
  10. #include <netinet/in.h> 
  11. #include <arpa/inet.h> 
  12.  
  13. #include <sys/ioctl.h> 
  14. #include <net/if.h> 
  15.  
  16. static void usage(){ 
  17.         printf("usage : ipconfig interface\n"); 
  18.         exit(0); 
  19.  
  20. int main(int argc,char **argv) 
  21.         struct sockaddr_in *addr;       //套接字地址结构体 
  22.         struct ifreq ifr;               //用于ioctl 
  23.         char *name, *address;           //网络设备的名字,地址 
  24.         int sockfd;                     //套接子描述符 
  25.  
  26.         if(argc != 2) //参数不够 
  27.                 usage(); 
  28.         else 
  29.                 name = argv[1]; 
  30.  
  31.  
  32.         sockfd = socket(AF_INET, SOCK_DGRAM, 0); //打开一个数据流套接子 
  33.         strncpy(ifr.ifr_name, name, IFNAMSIZ-1); //限制设备名的长度并截断,防止溢出 
  34.  
  35.  
  36.         if(ioctl(sockfd, SIOCGIFADDR, &ifr)  == -1)     //用 SIOCGIFADDR 来获得接口地址 
  37.                 perror("ioctl error"), exit(1);         //描述错误代码 
  38.         addr = (struct sockaddr_in *)&(ifr.ifr_addr); 
  39.         address = inet_ntoa(addr->sin_addr);            //地址转换 
  40.         printf("inet addr: %s ",address); 
  41.  
  42.  
  43.         if(ioctl(sockfd, SIOCGIFBRDADDR, &ifr)  ==  -1) //用 SIOCGIFBRDADDR 来获得广播地址 
  44.                 perror("ioctl error"),exit(1); 
  45.         addr = (struct sockaddr_in *)&ifr.ifr_broadaddr; 
  46.         address = inet_ntoa(addr->sin_addr); 
  47.         printf("broad addr: %s ",address); 
  48.  
  49.  
  50.         if(ioctl(sockfd, SIOCGIFNETMASK, &ifr) == -1) //用 SIOCGIFNETMASK 来获得掩码地址 
  51.                 perror("ioctl error"),exit(1); 
  52.         addr = (struct sockaddr_in *)&ifr.ifr_addr; 
  53.         address = inet_ntoa(addr->sin_addr); 
  54.         printf("inet mask: %s ",address); 
  55.  
  56.         printf("\n"); 
  57.         exit(0); 

 

程序2:检查接口的物理连接是否正常

 
 
  1. //程序2:检查接口的物理连接是否正常 
  2. #include <stdio.h> 
  3. #include <string.h> 
  4. #include <errno.h> 
  5. #include <fcntl.h> 
  6. #include <getopt.h> 
  7. #include <sys/socket.h> 
  8. #include <sys/ioctl.h> 
  9. #include <net/if.h> 
  10. #include <stdlib.h> 
  11. #include <unistd.h> 
  12.  
  13. typedef unsigned short u16; 
  14. typedef unsigned int u32; 
  15. typedef unsigned char u8; 
  16.  
  17. #include <linux/ethtool.h> 
  18. #include <linux/sockios.h> 
  19.  
  20.  
  21. int detect_mii(int skfd, char *ifname) 
  22.         struct ifreq ifr; 
  23.         u16 *data, mii_val; 
  24.         unsigned phy_id; 
  25.  
  26.         //Get the vitals from the interface. 
  27.         strncpy(ifr.ifr_name, ifname, IFNAMSIZ); 
  28.  
  29.         //MII=(媒介无关接口) 
  30.         //PHY=物理链路 
  31.         if (ioctl(skfd, SIOCGMIIPHY, &ifr) < 0) 
  32.         { 
  33.                 fprintf(stderr, "SIOCGMIIPHY on %s failed: %s\n", ifname, 
  34.                 strerror(errno)); 
  35.                 (void) close(skfd); 
  36.                 return 2; 
  37.         } 
  38.  
  39.         data = (u16 *)(&ifr.ifr_data); 
  40.         phy_id = data[0]; 
  41.         data[1] = 1; 
  42.  
  43.         //REG regedit 
  44.         if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) 
  45.         { 
  46.                 fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name, 
  47.                 strerror(errno)); 
  48.                 return 2; 
  49.         } 
  50.  
  51.         mii_val = data[3]; 
  52.  
  53.         return(((mii_val & 0x0016) == 0x0004) ? 0 : 1); 
  54.  
  55.  
  56. int detect_ethtool(int skfd, char *ifname) 
  57.         struct ifreq ifr; 
  58.         struct ethtool_value edata; 
  59.  
  60.         memset(&ifr, 0, sizeof(ifr)); 
  61.         edata.cmd = ETHTOOL_GLINK; 
  62.  
  63.         strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)-1); 
  64.         ifr.ifr_data = (char *) &edata; 
  65.  
  66.         //ETH : EtherNet n. 以太网O 
  67.         /\tOOL 工具 
  68.         if (ioctl(skfd, SIOCETHTOOL, &ifr) == -1) 
  69.         { 
  70.                 printf("ETHTOOL_GLINK failed: %s\n", strerror(errno)); 
  71.                 return 2; 
  72.         } 
  73.  
  74.         return (edata.data ? 0 : 1); 
  75.  
  76. int main(int argc, char **argv) 
  77.         int skfd = -1;          //套接子描述符 
  78.         char *ifname;         //接口设备名 
  79.         int retval;             //返回值 
  80.  
  81.         if( argv[1] ) 
  82.                 ifname = argv[1]; 
  83.         else 
  84.                 ifname = "eth0";        //默认值 
  85.  
  86.         //打开一个套接子 
  87.         if (( skfd = socket( AF_INET, SOCK_DGRAM, 0 ) ) < 0 ) 
  88.         { 
  89.                 printf("socket error\n"); 
  90.                 exit(-1); 
  91.         } 
  92.  
  93.         //探测以太网设备 
  94.         retval = detect_ethtool(skfd, ifname); 
  95.  
  96.         if (retval == 2)//上面失败情况下 
  97.                 //探测物理链路 
  98.                 retval = detect_mii(skfd, ifname); 
  99.  
  100.  
  101.         close(skfd); 
  102.  
  103.         if (retval == 2) 
  104.                 printf("Could not determine status\n"); 
  105.  
  106.         if (retval == 1) 
  107.                 printf("Link down\n"); 
  108.  
  109.         if (retval == 0) 
  110.                 printf("Link up\n"); 
  111.  
  112.         return retval; 

 

程序3:更简单一点测试物理连接 

 
 
  1. //程序3:更简单一点测试物理连接 
  2. #include <stdio.h> 
  3. #include <stdlib.h> 
  4. #include <string.h> 
  5. #include <errno.h> 
  6. #include <net/if.h> 
  7. #include <linux/sockios.h> 
  8. #include <sys/ioctl.h> 
  9. #define LINKTEST_GLINK 0x0000000a 
  10.  
  11. struct linktest_value { 
  12.         unsigned int    cmd; 
  13.         unsigned int    data; 
  14. }; 
  15.  
  16. static 
  17. void 
  18. usage(const char * pname) 
  19.         fprintf(stderr, "usage: %s <device>\n", pname); 
  20.         fprintf(stderr, "returns: \n"); 
  21.         fprintf(stderr, "\t 0: link detected\n"); 
  22.         fprintf(stderr, "\t%d: %s\n", ENODEV, strerror(ENODEV)); 
  23.         fprintf(stderr, "\t%d: %s\n", ENONET, strerror(ENONET)); 
  24.         fprintf(stderr, "\t%d: %s\n", EOPNOTSUPP, strerror(EOPNOTSUPP)); 
  25.         exit(EXIT_FAILURE); 
  26.  
  27. static 
  28. int 
  29. linktest(const char * devname) 
  30.         struct ifreq ifr; 
  31.         struct linktest_value edata; 
  32.         int fd; 
  33.  
  34.         // setup our control structures. 
  35.         memset(&ifr, 0, sizeof(ifr)); 
  36.         strcpy(ifr.ifr_name, devname);//为什么没有用strncpy了 
  37.  
  38.         //open control socket. 
  39.         fd = socket(AF_INET, SOCK_DGRAM, 0); 
  40.         if(fd < 0 ) { 
  41.                 return -ECOMM; 
  42.         } 
  43.  
  44.         errno = 0; 
  45.         edata.cmd = LINKTEST_GLINK; 
  46.         ifr.ifr_data = (caddr_t)&edata; 
  47.  
  48.         if(!ioctl(fd, SIOCETHTOOL, &ifr)) { 
  49.                 if(edata.data) { 
  50.                         fprintf(stdout, "link detected on %s\n", devname); 
  51.                         return 0; 
  52.                 } else { 
  53.                         errno=ENONET; 
  54.                 } 
  55.         } 
  56.  
  57.         perror("linktest"); 
  58.         return errno; 
  59.  
  60. int 
  61. main(int argc, char *argv[]) 
  62.         if(argc != 2) { 
  63.                 usage(argv[0]); 
  64.         } 
  65.         return linktest(argv[1]); 

 


 

程序4:调节音量 

可能用到的资料:

Linux的混音设备/dev/mixer  

http://blog.163.com/ji_wei8888/blog/static/48680446201110925825588/

 
 
  1. //程序4:调节音量 
  2. #include <sys/types.h> 
  3. #include <sys/stat.h> 
  4. #include <fcntl.h> 
  5. #include <sys/ioctl.h> 
  6. #include <sys/soundcard.h> 
  7. #include <stdio.h> 
  8. #include <unistd.h> 
  9. #include <math.h> 
  10. #include <string.h> 
  11. #include <stdlib.h> 
  12.  
  13. #define  BASE_VALUE 257 
  14.  
  15. int main(int argc,char *argv[]) 
  16.         int mixer_fd=0; 
  17.         char *names[SOUND_MIXER_NRDEVICES]=SOUND_DEVICE_LABELS; 
  18.         int value,i; 
  19.  
  20.         //检查参数 
  21.         if (argc<3) 
  22.         { 
  23.                 printf("\nusage:%s dev_no.[0..24] value[0..100]\n\n",argv[0]); 
  24.                 printf("eg. %s 0 100\n",argv[0]); 
  25.                 printf("    will change the volume to MAX volume.\n\n"); 
  26.                 printf("The dev_no. are as below:\n"); 
  27.                 for (i=0; i<SOUND_MIXER_NRDEVICES; i++){ 
  28.                         if (i%3==0) 
  29.                                 printf("\n"); 
  30.                         printf("%s:%d\t\t",names[i], i); 
  31.                 } 
  32.                 printf("\n\n"); 
  33.                 exit(1); 
  34.         } 
  35.  
  36.         //打开文件 
  37.         if ((mixer_fd = open("/dev/mixer",O_RDWR))){ 
  38.                 printf("Mixer opened successfully,working...\n"); 
  39.                 value = BASE_VALUE*atoi(argv[2]); 
  40.  
  41.                 //修改文件 
  42.                 if (ioctl(mixer_fd,  MIXER_WRITE(atoi(argv[1])), &value)==0) 
  43.                         printf("successfully....."); 
  44.                 else 
  45.                         printf("unsuccessfully....."); 
  46.                 printf("done.\n"); 
  47.          }else 
  48.                 printf("can't open /dev/mixer error....\n"); 
  49.         exit(0); 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值