linux系統ioctl函數使用執行個體注釋版

來源:互聯網
上載者:User

原創作品,允許轉載,轉載時請務必以超連結形式標明文章 原始出處 、作者資訊和本聲明。否則將追究法律責任。http://idear.blog.51cto.com/4097017/853582
原始碼來源:http://www.linuxidc.com/Linux/2007-12/9623p2.htm
由於原始碼注釋幾乎沒有,可能新手較難看懂。因此鄙人加上了注釋,有些小錯誤的地方也改了一下,其它不多說了。
程式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:檢測介面的 inet_addr,netmask,broad_addr #include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/ioctl.h> #include <net/if.h> static void usage(){ printf("usage : ipconfig interface\n"); exit(0); } int main(int argc,char **argv) { struct sockaddr_in *addr; //通訊端地址結構體 struct ifreq ifr; //用於ioctl char *name, *address; //網路裝置的名字,地址 int sockfd; //套接子描述符 if(argc != 2) //參數不夠 usage(); else name = argv[1]; sockfd = socket(AF_INET, SOCK_DGRAM, 0); //開啟一個資料流套接子 strncpy(ifr.ifr_name, name, IFNAMSIZ-1); //限制裝置名稱的長度並截斷,防止溢出 if(ioctl(sockfd, SIOCGIFADDR, &ifr) == -1) //用 SIOCGIFADDR 來獲得介面地址 perror("ioctl error"), exit(1); //描述錯誤碼 addr = (struct sockaddr_in *)&(ifr.ifr_addr); address = inet_ntoa(addr->sin_addr); //地址轉換 printf("inet addr: %s ",address); if(ioctl(sockfd, SIOCGIFBRDADDR, &ifr) == -1) //用 SIOCGIFBRDADDR 來獲得廣播位址 perror("ioctl error"),exit(1); addr = (struct sockaddr_in *)&ifr.ifr_broadaddr; address = inet_ntoa(addr->sin_addr); printf("broad addr: %s ",address); if(ioctl(sockfd, SIOCGIFNETMASK, &ifr) == -1) //用 SIOCGIFNETMASK 來獲得掩碼地址 perror("ioctl error"),exit(1); addr = (struct sockaddr_in *)&ifr.ifr_addr; address = inet_ntoa(addr->sin_addr); printf("inet mask: %s ",address); printf("\n"); exit(0); } 

程式2:檢查介面的物理串連是否正常

//程式2:檢查介面的物理串連是否正常 #include <stdio.h> #include <string.h> #include <errno.h> #include <fcntl.h> #include <getopt.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> #include <stdlib.h> #include <unistd.h> typedef unsigned short u16; typedef unsigned int u32; typedef unsigned char u8; #include <linux/ethtool.h> #include <linux/sockios.h> int detect_mii(int skfd, char *ifname) { struct ifreq ifr; u16 *data, mii_val; unsigned phy_id; //Get the vitals from the interface. strncpy(ifr.ifr_name, ifname, IFNAMSIZ); //MII=(媒介無關介面) //PHY=物理鏈路 if (ioctl(skfd, SIOCGMIIPHY, &ifr) < 0) { fprintf(stderr, "SIOCGMIIPHY on %s failed: %s\n", ifname, strerror(errno)); (void) close(skfd); return 2; } data = (u16 *)(&ifr.ifr_data); phy_id = data[0]; data[1] = 1; //REG regedit if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) { fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name, strerror(errno)); return 2; } mii_val = data[3]; return(((mii_val & 0x0016) == 0x0004) ? 0 : 1); } int detect_ethtool(int skfd, char *ifname) { struct ifreq ifr; struct ethtool_value edata; memset(&ifr, 0, sizeof(ifr)); edata.cmd = ETHTOOL_GLINK; strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)-1); ifr.ifr_data = (char *) &edata; //ETH : EtherNet n. 乙太網路O /\tOOL 工具 if (ioctl(skfd, SIOCETHTOOL, &ifr) == -1) { printf("ETHTOOL_GLINK failed: %s\n", strerror(errno)); return 2; } return (edata.data ? 0 : 1); } int main(int argc, char **argv) { int skfd = -1; //套接子描述符 char *ifname; //介面裝置名稱 int retval; //傳回值 if( argv[1] ) ifname = argv[1]; else ifname = "eth0"; //預設值 //開啟一個套接子 if (( skfd = socket( AF_INET, SOCK_DGRAM, 0 ) ) < 0 ) { printf("socket error\n"); exit(-1); } //探測乙太網路裝置 retval = detect_ethtool(skfd, ifname); if (retval == 2)//上面失敗情況下 //探測物理鏈路 retval = detect_mii(skfd, ifname); close(skfd); if (retval == 2) printf("Could not determine status\n"); if (retval == 1) printf("Link down\n"); if (retval == 0) printf("Link up\n"); return retval; } 

程式3:更簡單一點測試物理串連

//程式3:更簡單一點測試物理串連 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <net/if.h> #include <linux/sockios.h> #include <sys/ioctl.h> #define LINKTEST_GLINK 0x0000000a struct linktest_value { unsigned int cmd; unsigned int data; }; static void usage(const char * pname) { fprintf(stderr, "usage: %s <device>\n", pname); fprintf(stderr, "returns: \n"); fprintf(stderr, "\t 0: link detected\n"); fprintf(stderr, "\t%d: %s\n", ENODEV, strerror(ENODEV)); fprintf(stderr, "\t%d: %s\n", ENONET, strerror(ENONET)); fprintf(stderr, "\t%d: %s\n", EOPNOTSUPP, strerror(EOPNOTSUPP)); exit(EXIT_FAILURE); } static int linktest(const char * devname) { struct ifreq ifr; struct linktest_value edata; int fd; // setup our control structures. memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, devname);//為什麼沒有用strncpy了 //open control socket. fd = socket(AF_INET, SOCK_DGRAM, 0); if(fd < 0 ) { return -ECOMM; } errno = 0; edata.cmd = LINKTEST_GLINK; ifr.ifr_data = (caddr_t)&edata; if(!ioctl(fd, SIOCETHTOOL, &ifr)) { if(edata.data) { fprintf(stdout, "link detected on %s\n", devname); return 0; } else { errno=ENONET; } } perror("linktest"); return errno; } int main(int argc, char *argv[]) { if(argc != 2) { usage(argv[0]); } return linktest(argv[1]); } 

程式4:調節音量
可能用到的資料:
Linux的混音裝置/dev/mixer
http://blog.163.com/ji_wei8888/blog/static/48680446201110925825588/

//程式4:調節音量 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sys/soundcard.h> #include <stdio.h> #include <unistd.h> #include <math.h> #include <string.h> #include <stdlib.h> #define BASE_VALUE 257 int main(int argc,char *argv[]) { int mixer_fd=0; char *names[SOUND_MIXER_NRDEVICES]=SOUND_DEVICE_LABELS; int value,i; //檢查參數 if (argc<3) { printf("\nusage:%s dev_no.[0..24] value[0..100]\n\n",argv[0]); printf("eg. %s 0 100\n",argv[0]); printf(" will change the volume to MAX volume.\n\n"); printf("The dev_no. are as below:\n"); for (i=0; i<SOUND_MIXER_NRDEVICES; i++){ if (i%3==0) printf("\n"); printf("%s:%d\t\t",names[i], i); } printf("\n\n"); exit(1); } //開啟檔案 if ((mixer_fd = open("/dev/mixer",O_RDWR))){ printf("Mixer opened successfully,working...\n"); value = BASE_VALUE*atoi(argv[2]); //修改檔案 if (ioctl(mixer_fd, MIXER_WRITE(atoi(argv[1])), &value)==0) printf("successfully....."); else printf("unsuccessfully....."); printf("done.\n"); }else printf("can't open /dev/mixer error....\n"); exit(0); } 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.