linux C获取网络信息
来源:互联网 发布:java 游戏服务器架构 编辑:程序博客网 时间:2024/05/19 20:18
转载地址:http://www.cnblogs.com/landy-weiai/p/3752665.html
[基础知识说明]
结构原型:
/*
* Interface request structure used for socket
* ioctl's. All interface ioctl's must have parameter
* definitions which begin with ifr_name. The
* remainder may be interface specific.
*/
struct ifreq
{
#define IFHWADDRLEN 6
union
{
char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
} ifr_ifrn;
union {
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
struct sockaddr ifru_netmask;
struct sockaddr ifru_hwaddr;
short ifru_flags;
int ifru_ivalue;
int ifru_mtu;
struct ifmap ifru_map;
char ifru_slave[IFNAMSIZ]; /* Just fits the size */
char ifru_newname[IFNAMSIZ];
void __user * ifru_data;
struct if_settings ifru_settings;
} ifr_ifru;
};
#define ifr_name ifr_ifrn.ifrn_name /* interface name */
#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
#define ifr_addr ifr_ifru.ifru_addr /* address */
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
#define ifr_flags ifr_ifru.ifru_flags /* flags */
#define ifr_metric ifr_ifru.ifru_ivalue /* metric */
#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
#define ifr_map ifr_ifru.ifru_map /* device map */
#define ifr_slave ifr_ifru.ifru_slave /* slave device */
#define ifr_data ifr_ifru.ifru_data /* for use by interface */
#define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */
#define ifr_bandwidth ifr_ifru.ifru_ivalue /* link bandwidth */
#define ifr_qlen ifr_ifru.ifru_ivalue /* Queue length */
#define ifr_newname ifr_ifru.ifru_newname /* New name */
#define ifr_settings ifr_ifru.ifru_settings /* Device/proto settings*/
基本介绍:
ifreq结构定义在/usr/include/net/if.h,用来配置ip地址,激活接口,配置MTU等接口信息的。其中包含了一个接口的名字和具体内容——(是个共用体,有可能是IP地址,广播地址,子网掩码,MAC号,MTU或其他内容)。ifreq包含在ifconf结构中。而ifconf结构通常是用来保存所有接口的信息的。
举例说明:
在Linux系统中,ifconfig命令是通过ioctl接口与内核通信,例如,当系统管理员输入如下命令来改变接口eth0的MTU大小:
ifconfig eth0 mtu 1250
ifconfig命令首先打开一个socket,然后通过系统管理员输入的参数初始化一个数据结构,并通过ioctl调用将数据传送到内核。SIOCSIFMTU是命令标识符。
struct ifreq data;
fd = socket(PF_INET, SOCK_DGRAM, 0);
< ... initialize "data" ...>
err = ioctl(fd, SIOCSIFMTU, &data);
[举例应用]
/**** \brief 通过广播socket获取系统eth0当前IP地址** \param pAddr 存储IP地址的内存地址,不小于16个字节。** \Return 0 成功* else 失败*/int GetSysIpBySocket(char* pAddr){ if ( pAddr == NULL ) { return RET_ERR_PARAM; } struct sockaddr_in *sin; struct ifreq ifr; int sock = socket(AF_INET,SOCK_DGRAM,0); if(sock <= 0) { perror("socket error!\n"); return RET_ERROR; } strcpy(ifr.ifr_name,"eth0"); if(ioctl(sock,SIOCGIFADDR,&ifr) < 0) { perror("ioctl error\n"); close(sock); return RET_ERROR; } else { sin = (struct sockaddr_in *)&(ifr.ifr_addr); strcpy(pAddr, inet_ntoa(sin->sin_addr)); close(sock); } return RET_OK;}
/** * * \brief 通过广播socket获取系统eth0当前子网掩码 * * \param pMask 存储子网掩码的内存地址,不小于16个字节。 * * \Return 0 成功 * else 失败 */int GetSysMaskBySocket(char* pMask){ if ( pMask == NULL ) { return RET_ERR_PARAM; } struct sockaddr_in *sin; struct ifreq ifr; int sock = socket(AF_INET,SOCK_DGRAM,0); if(sock <= 0) { perror("socket error!\n"); return RET_ERROR; } strcpy(ifr.ifr_name,"eth0"); if(ioctl(sock,SIOCGIFNETMASK,&ifr) < 0) { perror("ioctl error\n"); close(sock); return RET_ERROR; } else { sin = (struct sockaddr_in *)&(ifr.ifr_netmask); strcpy(pMask, inet_ntoa(sin->sin_addr)); close(sock); } return RET_OK;}
/** * * \brief 通过广播socket获取系统eth0当前IP地址和子网掩码 * * \param pAddr 存储IP地址的内存地址,不小于16个字节。 * \param pMask 存储子网掩码的内存地址,不小于16个字节。 * * \Return 0 成功 * else 失败 */int GetSysIpMaskBySocket(char* pAddr, char* pMask){ if ( pAddr == NULL || pMask == NULL ) { return RET_ERR_PARAM; } struct sockaddr_in *sin; struct ifreq ifr; int sock = socket(AF_INET,SOCK_DGRAM,0); if(sock <= 0) { perror("socket error!\n"); return RET_ERROR; } strcpy(ifr.ifr_name,"eth0"); if(ioctl(sock,SIOCGIFADDR,&ifr) < 0) { perror("ioctl SIOCGIFADDR error\n"); close(sock); return RET_ERROR; } else { sin = (struct sockaddr_in *)&(ifr.ifr_addr); strcpy(pAddr, inet_ntoa(sin->sin_addr)); } if(ioctl(sock,SIOCGIFNETMASK,&ifr) < 0) { perror("ioctl SIOCGIFNETMASK error\n"); close(sock); return RET_ERROR; } else { sin = (struct sockaddr_in *)&(ifr.ifr_netmask); strcpy(pMask, inet_ntoa(sin->sin_addr)); } close(sock); return RET_OK;}
/** * * \brief 通过ioctl获取系统eth0 Mac地址 * * \param pMask 存储 Mac地址的内存地址,不小于18个字节。 * * \Return 0 成功 * else 失败 */int GetSysMacBySocket(char* pMac){ if ( pMac == NULL ) { return RET_ERR_PARAM; } struct ifreq ifr; int sock = socket(AF_INET,SOCK_DGRAM,0); if(sock <= 0) { perror("socket error!\n"); return RET_ERROR; } strcpy(ifr.ifr_name,"eth0"); if(ioctl(sock,SIOCGIFHWADDR,&ifr) < 0) { perror("ioctl SIOCGIFHWADDR error\n"); close(sock); return RET_ERROR; } else { sprintf(pMac, "%02x:%02x:%02x:%02x:%02x:%02x", (unsigned char)ifr.ifr_hwaddr.sa_data[0], (unsigned char)ifr.ifr_hwaddr.sa_data[1], (unsigned char)ifr.ifr_hwaddr.sa_data[2], (unsigned char)ifr.ifr_hwaddr.sa_data[3], (unsigned char)ifr.ifr_hwaddr.sa_data[4], (unsigned char)ifr.ifr_hwaddr.sa_data[5]); } close(sock); return RET_OK;}
参考H CPP文件
/* * ===================================================================================== * * Filename: ipconfig.h * * Description: 基于ifconfig命令,获取、配置系统当前网络配置参数。 * * Version: 1.0 * Created: 11/23/2012 01:42:16 PM HKT * Revision: none * Compiler: gcc * * Author: * Company: * * ===================================================================================== */#ifndef IPCONFIG_INC#define IPCONFIG_INCbool IsIpValid (const char* pAddr);bool IsMaskValid (const char* pNetMask);bool IsMacValid (const char* pMac);bool IsGatewayValid(const char* pGateway);int GetSysIp (char* pAddr);int GetSysMask (char* pMask);int GetSysIpMask(char* pAddr, char* pMask);int GetSysMac (char* pMac);int GetSysGateway(char* pGateway);int GetSysBroadcast(const char* pAddr, const char* pMask, char* pBc); int GetSysIpBySocket (char* pAddr);int GetSysMaskBySocket (char* pMask);int GetSysIpMaskBySocket(char* pAddr, char* pMask);int GetSysMacBySocket (char* pMac);int SetSysIp (const char* pAddr);int SetSysMask (const char* pNetMask);int SetSysMac (const char* pMac);int SetSysIpMask(const char* pAddr, const char* pNetMask);int SetSysGateway(const char* pGateway);#endif /* ----- #ifndef IPCONFIG_INC ----- */
/* * ===================================================================================== * * Filename: ipconfig.cpp * * Description: 基于ifconfig命令,获取、配置系统当前网络配置参数。 * * Version: 1.0 * Created: 11/23/2012 11:35:52 AM HKT * Revision: none * Compiler: gcc * * Author: (), * Company: * * ===================================================================================== */#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#ifdef __linux__#include <unistd.h>#endif#include <sys/file.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <net/if.h>#include <sys/ioctl.h>#include "RcsFile.h"#include "lederror.h"static const unsigned int IPADDR_LEN = 15;//IP地址长度static const unsigned int MACADDR_LEN = 17;//MAC地址长度/** * \brief 判断字符是否为十六进制表示字符,即0~f。 */bool IsHexChar(char hex){ return ( ( hex >= '0' && hex <= '9' ) || ( hex >= 'a' && hex <= 'f' ) || ( hex >= 'A' && hex <= 'F' ) );}int HexCharToInt(char hex){ int val = -1; if( hex >= '0' && hex <= '9' ) { val = hex - '0'; } else if( hex >= 'a' && hex <= 'f' ) { val = hex - 'a' + 10; } else if( hex >= 'A' && hex <= 'F' ) { val = hex - 'A' + 10; } return val;}/** * \brief 判断输入ip是否有效 * * \return true 有效 * false 无效 */bool IsIpValid(const char* pAddr){ if ( NULL == pAddr ) { return false; } struct in_addr addr; if ( inet_aton ( pAddr, &addr ) == 0 ) { return false; } char* destIp = ( char* ) inet_ntoa ( addr ); if ( 0 != strcmp ( pAddr, destIp ) ) { return false; } return true;}/** * \brief 判断输入netmask字符串是否有效 * * \param pNetMask 表示netmask的字符串指针 * * \return true 有效 * \return false 无效 */bool IsMaskValid(const char* pNetMask){ bool ret = false; if ( !IsIpValid(pNetMask) ) { return ret; } unsigned int mask = ntohl( inet_addr(pNetMask) ); //最高8位必须全为0,且不能为0xffffff if ( mask < 0xff || mask == 0xffffffff ) { return ret; } for ( int i = 23; i >= 0; --i ) { if ( (mask & (1 << i)) > 0 ) { continue; } if ( (mask << (8 + 23 - i)) > 0 ) { ret = false; break; } ret = true; break; } return ret;}/** * \brief 判断输入mac字符串是否有效 * * \param pMac 表示mac地址的字符串指针 * * \return true 有效 * \return false 无效 */bool IsMacValid(const char* pMac){ if ( NULL == pMac || strlen ( pMac ) != MACADDR_LEN ) { return false; } //MAC的第一个字节必须为偶数 if( HexCharToInt(*(pMac+1)) % 2 != 0 ) { return false; } for ( unsigned int index = 0; index < MACADDR_LEN; ++index ) { if ( 0 == ( ( index + 1 ) % 3 ) ) //不检查间隔为3的字符 { continue; } //字符必须为十六进制表示字符,即0~f。 char val = ( * ( pMac + index ) ); if ( !IsHexChar(val) ) { return false; } } return true;}/** * \brief 判断输入网关字符串是否有效 * * \param pGateway 表示网关地址的字符串指针 * * \return true 有效 * \return false 无效 */bool IsGatewayValid(const char* pGateway){ return IsIpValid(pGateway);}/** * * \brief 获取系统eth0当前IP地址 * * \param pAddr 存储IP地址的内存地址,不小于16个字节。 * * \Return 0 成功 * else 失败 */int GetSysIp(char* pAddr){ const char FILE_NAME[] = "/tmp/ipaddr.txt"; const char SCRIPT[] = "ifconfig eth0 | grep inet | cut -d: -f2 | cut -d' ' -f1 > /tmp/ipaddr.txt"; FILE* handle = NULL; char* delimiter = NULL; if ( pAddr == NULL ) { return RET_ERR_PARAM; } if ( system(SCRIPT) != 0 ) { fprintf(stderr, "Execute command '%s'error: %s\n", SCRIPT, strerror(errno)); goto FAILED; } if ( (handle = fopen(FILE_NAME, "r")) != NULL ) { fgets(pAddr, IPADDR_LEN-1, handle); } else { fprintf(stderr, "Open file %s error: %s\n", FILE_NAME, strerror(errno)); goto FAILED; } fclose(handle); if ( (delimiter = strchr(pAddr, '\x0a')) != NULL ) { *delimiter = '\0'; } unlink(FILE_NAME); return RET_OK;FAILED: unlink(FILE_NAME); return RET_ERROR;}/** * * \brief 获取系统eth0当前子网掩码 * * \param pMask 存储子网掩码的内存地址,不小于16个字节。 * * \Return 0 成功 * else 失败 */int GetSysMask(char* pMask){ const char FILE_NAME[] = "/tmp/netmask.txt"; const char SCRIPT[] = "ifconfig eth0 | grep Mask | cut -dk -f2 | cut -d: -f2 > /tmp/netmask.txt"; FILE* handle = NULL; char* delimiter = NULL; if ( pMask == NULL ) { return RET_ERR_PARAM; } if ( system(SCRIPT) != 0 ) { fprintf(stderr, "Execute command '%s'error: %s\n", SCRIPT, strerror(errno)); goto FAILED; } if ( (handle = fopen(FILE_NAME, "r")) != NULL ) { fgets(pMask, IPADDR_LEN+1, handle); } else { fprintf(stderr, "Open file %s error: %s\n", FILE_NAME, strerror(errno)); goto FAILED; } fclose(handle); if ( (delimiter = strchr(pMask, '\x0a')) != NULL ) { *delimiter = '\0'; } unlink(FILE_NAME); return RET_OK;FAILED: unlink(FILE_NAME); return RET_ERROR;}/** * * \brief 获取系统eth0当前IP地址和子网掩码 * * \param pAddr 存储IP地址的内存地址,不小于16个字节。 * \param pMask 存储子网掩码的内存地址,不小于16个字节。 * * \Return 0 成功 * else 失败 */int GetSysIpMask(char* pAddr, char* pMask){ const char FILE_NAME[] = "/tmp/ipmask.txt"; const char SCRIPT[] = "ifconfig eth0 | grep -i mask > /tmp/ipmask.txt"; char info[128] = {0}; char *delimiter = NULL; FILE *handle = NULL; if ( pAddr == NULL || pMask == NULL ) { return RET_ERR_PARAM; } if ( system(SCRIPT) != 0 ) { fprintf(stderr, "Execute command '%s'error: %s\n", SCRIPT, strerror(errno)); goto FAILED; } if ( (handle = fopen(FILE_NAME, "r")) != NULL ) { fread(info, 128, 1, handle); char* ipbegin = strstr(info, "addr:"); if( ipbegin ) { ipbegin += 5; sscanf(ipbegin, "%s", pAddr); } char* maskbegin = strstr(info, "Mask:"); if( maskbegin ) { maskbegin += 5; sscanf(maskbegin, "%s", pMask); } fclose(handle); } else { fprintf(stderr, "Open file %s error: %s\n", FILE_NAME, strerror(errno)); goto FAILED; } if ( (delimiter = strchr(pAddr, '\x0a')) != NULL ) { *delimiter = '\0'; } if ( (delimiter = strchr(pMask, '\x0a')) != NULL ) { *delimiter = '\0'; } unlink(FILE_NAME); return RET_OK;FAILED: unlink(FILE_NAME); return RET_ERROR;}/** * * \brief 获取系统eth0 Mac地址 * * \param pMask 存储 Mac地址的内存地址,不小于18个字节。 * * \Return 0 成功 * else 失败 */int GetSysMac(char* pMac){ const char FILE_NAME[] = "/tmp/ipmac.txt"; const char SCRIPT[] = "ifconfig eth0 | grep HWaddr|tr -s ' '|cut -d ' ' -f 5 > /tmp/ipmac.txt"; FILE* handle = NULL; char* delimiter = NULL; if ( pMac == NULL ) { return RET_ERR_PARAM; } if ( system(SCRIPT) != 0 ) { fprintf(stderr, "Execute command '%s'error: %s\n", SCRIPT, strerror(errno)); goto FAILED; } if ( (handle = fopen(FILE_NAME, "r")) != NULL ) { fgets(pMac, MACADDR_LEN+1, handle); } else { fprintf(stderr, "Open file %s error: %s\n", FILE_NAME, strerror(errno)); goto FAILED; } fclose(handle); if ( (delimiter = strchr(pMac, '\x0a')) != NULL ) { *delimiter = '\0'; } unlink(FILE_NAME); return RET_OK;FAILED: unlink(FILE_NAME); return RET_ERROR;}/** * \brief 获取系统网关地址。 * * \return RET_OK 成功 * \return RET_ERROR 失败 */int GetSysGateway(char* pGateway){ const char FILE_NAME[] = "/tmp/ipgateway.txt"; const char SCRIPT[] = "route | grep default | cut -d' ' -f10 | cut -d' ' -f1 > /tmp/ipgateway.txt"; FILE* handle = NULL; char* delimiter = NULL; if ( pGateway == NULL ) { return RET_ERR_PARAM; } if ( system(SCRIPT) != 0 ) { fprintf(stderr, "Execute command '%s'error: %s\n", SCRIPT, strerror(errno)); goto FAILED; } if ( (handle = fopen(FILE_NAME, "r")) != NULL ) { fgets(pGateway, IPADDR_LEN+1, handle); } else { fprintf(stderr, "Open file %s error: %s\n", FILE_NAME, strerror(errno)); goto FAILED; } fclose(handle); if ( (delimiter = strchr(pGateway, '\x0a')) != NULL ) { *delimiter = '\0'; } unlink(FILE_NAME); return RET_OK;FAILED: unlink(FILE_NAME); return RET_ERROR;}int SetSysIp(const char* pAddr){ if ( !IsIpValid(pAddr) ) { fprintf(stderr, "Input ip %s is invalid\n", pAddr); return RET_ERROR; } char localip[80] = {0}; GetSysIp(localip); if ( strcmp(localip, pAddr) == 0 ) { return RET_OK; } fprintf(stderr, "[%s]: ip is %s\n", __FUNCTION__, pAddr); sprintf(localip, "ifconfig eth0 %s up ", pAddr); if ( system(localip) != 0 ) { fprintf(stderr, "Execute command '%s' error: %s\n", localip, strerror(errno)); return RET_ERROR; } return ModifyRcs("LED_IP",pAddr);}int SetSysMask(const char* pMask){ if ( !IsMaskValid(pMask) ) { fprintf(stderr, "Input netmask %s is invalid\n", pMask); return RET_ERROR; } char netmask[80] = {0}; GetSysIp(netmask); if ( strcmp(netmask, pMask) == 0 ) { return RET_OK; } fprintf(stderr, "[%s]: netmask is %s\n", __FUNCTION__, pMask); sprintf(netmask, "ifconfig eth0 netmask %s up ", pMask); if ( system(netmask) != 0 ) { fprintf(stderr, "Execute command '%s' error: %s\n", netmask, strerror(errno)); return RET_ERROR; } return ModifyRcs("LED_MASK",pMask);}int SetSysMac(const char* pMac){ if ( !IsMacValid(pMac) ) { fprintf(stderr, "Input mac addr %s is invalid\n", pMac); return RET_ERROR; } char mac[80] = {0}; GetSysMac(mac); if ( strcmp(mac, pMac) == 0 ) { return RET_OK; } fprintf(stderr, "[%s]: mac addr is %s\n", __FUNCTION__, pMac); //shut down network memset(mac, 0, sizeof(mac)); sprintf(mac, "ifconfig eth0 down"); if ( system(mac) != 0 ) { fprintf(stderr, "Execute command '%s' error: %s\n", mac, strerror(errno)); return RET_ERROR; } //config mac address memset(mac, 0, sizeof(mac)); sprintf(mac, "ifconfig eth0 hw ether %s", pMac); if ( system(mac) != 0 ) { fprintf(stderr, "Execute command '%s' error: %s\n", mac, strerror(errno)); return RET_ERROR; } //start network memset(mac, 0, sizeof(mac)); sprintf(mac, "ifconfig eth0 up"); if ( system(mac) != 0 ) { fprintf(stderr, "Execute command '%s' error: %s\n", mac, strerror(errno)); return RET_ERROR; } return ModifyRcs("LED_MAC",pMac);}/** * \brief 设置ip和mask。 * * \return RET_OK 成功 * \return RET_ERROR 失败 */int SetSysIpMask(const char* pAddr, const char* pNetMask){ //判断ip和mask的有效性 if ( (!IsIpValid(pAddr)) || (!IsMaskValid(pNetMask)) ) { fprintf(stderr, "Input ip %s or netmask %s is invalid\n", pAddr, pNetMask); return RET_ERROR; } //设置ip和netmask char script[80] = {0}; sprintf(script, "ifconfig eth0 %s netmask %s up ", pAddr, pNetMask); if ( system(script) != 0 ) { fprintf(stderr, "Execute command '%s' error: %s\n", script, strerror(errno)); return RET_ERROR; } ModifyRcs("LED_IP",pAddr); return ModifyRcs("LED_MASK",pNetMask);}/** * \brief 设置gateway。 * * \return RET_OK 成功 * \return RET_ERROR 失败 */int SetSysGateway(const char* pGateway){ if( pGateway && strlen(pGateway) == 0 ) { //把网关删除,设为空 } else { //判断gateway的有效性 if ( (!IsGatewayValid(pGateway)) ) { fprintf(stderr, "Input Gateway %s is invalid\n", pGateway); return RET_ERROR; } } //设置gateway char script[80] = {0}; sprintf(script, "route del default "); if ( system(script) != 0 ) { fprintf(stderr, "Execute command '%s' error: %s\n", script, strerror(errno)); } if( strlen(pGateway) ) { sprintf(script, "route add default gw %s ", pGateway); if ( system(script) != 0 ) { fprintf(stderr, "Execute command '%s' error: %s\n", script, strerror(errno)); return RET_ERROR; } } return ModifyRcs("LED_GATEWAY",pGateway);}/** * \brief 根据IP和子网掩码获取本网段广播地址。 */int GetSysBroadcast(const char* pAddr, const char* pMask, char* pBc){ if( !pAddr || !pMask || !pBc ) { return RET_ERR_PARAM; } if( !IsIpValid(pAddr) || !IsMaskValid(pMask) ) { return RET_ERR_PARAM; } unsigned int ip = ntohl( inet_addr(pAddr) ); unsigned int mask = ntohl( inet_addr(pMask) ); unsigned int bc = (ip & mask) | (~mask); struct in_addr bcAddr; bcAddr.s_addr = htonl(bc); char *tmp = inet_ntoa(bcAddr); memcpy(pBc, tmp, strlen(tmp)); return RET_OK;}/** * * \brief 通过广播socket获取系统eth0当前IP地址 * * \param pAddr 存储IP地址的内存地址,不小于16个字节。 * * \Return 0 成功 * else 失败 */int GetSysIpBySocket(char* pAddr){ if ( pAddr == NULL ) { return RET_ERR_PARAM; } struct sockaddr_in *sin; struct ifreq ifr; int sock = socket(AF_INET,SOCK_DGRAM,0); if(sock <= 0) { perror("socket error!\n"); return RET_ERROR; } strcpy(ifr.ifr_name,"eth0"); if(ioctl(sock,SIOCGIFADDR,&ifr) < 0) { perror("ioctl error\n"); close(sock); return RET_ERROR; } else { sin = (struct sockaddr_in *)&(ifr.ifr_addr); strcpy(pAddr, inet_ntoa(sin->sin_addr)); close(sock); } return RET_OK;}/** * * \brief 通过广播socket获取系统eth0当前子网掩码 * * \param pMask 存储子网掩码的内存地址,不小于16个字节。 * * \Return 0 成功 * else 失败 */int GetSysMaskBySocket(char* pMask){ if ( pMask == NULL ) { return RET_ERR_PARAM; } struct sockaddr_in *sin; struct ifreq ifr; int sock = socket(AF_INET,SOCK_DGRAM,0); if(sock <= 0) { perror("socket error!\n"); return RET_ERROR; } strcpy(ifr.ifr_name,"eth0"); if(ioctl(sock,SIOCGIFNETMASK,&ifr) < 0) { perror("ioctl error\n"); close(sock); return RET_ERROR; } else { sin = (struct sockaddr_in *)&(ifr.ifr_netmask); strcpy(pMask, inet_ntoa(sin->sin_addr)); close(sock); } return RET_OK;}/** * * \brief 通过广播socket获取系统eth0当前IP地址和子网掩码 * * \param pAddr 存储IP地址的内存地址,不小于16个字节。 * \param pMask 存储子网掩码的内存地址,不小于16个字节。 * * \Return 0 成功 * else 失败 */int GetSysIpMaskBySocket(char* pAddr, char* pMask){ if ( pAddr == NULL || pMask == NULL ) { return RET_ERR_PARAM; } struct sockaddr_in *sin; struct ifreq ifr; int sock = socket(AF_INET,SOCK_DGRAM,0); if(sock <= 0) { perror("socket error!\n"); return RET_ERROR; } strcpy(ifr.ifr_name,"eth0"); if(ioctl(sock,SIOCGIFADDR,&ifr) < 0) { perror("ioctl SIOCGIFADDR error\n"); close(sock); return RET_ERROR; } else { sin = (struct sockaddr_in *)&(ifr.ifr_addr); strcpy(pAddr, inet_ntoa(sin->sin_addr)); } if(ioctl(sock,SIOCGIFNETMASK,&ifr) < 0) { perror("ioctl SIOCGIFNETMASK error\n"); close(sock); return RET_ERROR; } else { sin = (struct sockaddr_in *)&(ifr.ifr_netmask); strcpy(pMask, inet_ntoa(sin->sin_addr)); } close(sock); return RET_OK;}/** * * \brief 通过ioctl获取系统eth0 Mac地址 * * \param pMask 存储 Mac地址的内存地址,不小于18个字节。 * * \Return 0 成功 * else 失败 */int GetSysMacBySocket(char* pMac){ if ( pMac == NULL ) { return RET_ERR_PARAM; } struct ifreq ifr; int sock = socket(AF_INET,SOCK_DGRAM,0); if(sock <= 0) { perror("socket error!\n"); return RET_ERROR; } strcpy(ifr.ifr_name,"eth0"); if(ioctl(sock,SIOCGIFHWADDR,&ifr) < 0) { perror("ioctl SIOCGIFHWADDR error\n"); close(sock); return RET_ERROR; } else { sprintf(pMac, "%02x:%02x:%02x:%02x:%02x:%02x", (unsigned char)ifr.ifr_hwaddr.sa_data[0], (unsigned char)ifr.ifr_hwaddr.sa_data[1], (unsigned char)ifr.ifr_hwaddr.sa_data[2], (unsigned char)ifr.ifr_hwaddr.sa_data[3], (unsigned char)ifr.ifr_hwaddr.sa_data[4], (unsigned char)ifr.ifr_hwaddr.sa_data[5]); } close(sock); return RET_OK;}
linux 利用ioctl函数获取IP地址、子网掩码、MAC地址和修改本机IP地址、子网掩码、网关。
ioctl函数原型:
int ioctl(int fd, int request, ..../*void *arg*/)
int fd:为socket函数返回值
int request:SIOCSIFADDR 修改ip地址
SIOCSIFNETMASK 修改子网掩码
SIOCADDRT 修改网关
第三个参数:ip和子网掩码对应的结构体struct ifreq;网关的结构体struct rtentry
//.h
#include <stdlib.h>#include <string.h>#include <pcap.h> #include <sys/types.h>#include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h>#include <netinet/ether.h> #include <net/if.h> #include <arpa/inet.h> #include <net/if_arp.h> #include <sys/ioctl.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <net/route.h>
//.cpp 修改ip地址
bool SetLocalIp(char *ipaddr) { if (NULL == ipaddr) { printf("SetLocalIp: ipaddr is null\n"); return false; } int sock_set_ip; struct sockaddr_in sin_set_ip; struct ifreq ifr_set_ip; bzero( &ifr_set_ip,sizeof(ifr_set_ip)); if( ipaddr == NULL ) return false; if(sock_set_ip = socket(PF_INET, SOCK_STREAM, 0 ) == -1); { perror("socket create failse...SetLocalIp!/n"); return false; } memset( &sin_set_ip, 0, sizeof(sin_set_ip)); strncpy(ifr_set_ip.ifr_name, "eth0", sizeof(ifr_set_ip.ifr_name)-1); sin_set_ip.sin_family = AF_INET; sin_set_ip.sin_addr.s_addr = inet_addr(ipaddr); memcpy( &ifr_set_ip.ifr_addr, &sin_set_ip, sizeof(sin_set_ip)); if( ioctl( sock_set_ip, SIOCSIFADDR, &ifr_set_ip) < 0 ) { perror( "Not setup interface/n"); return false; } ifr_set_ip.ifr_flags |= IFF_UP |IFF_RUNNING; //get the status of the device if( ioctl( sock_set_ip, SIOCSIFFLAGS, &ifr_set_ip ) < 0 ) { perror("SIOCSIFFLAGS"); return false; } close( sock_set_ip); return true; }
//.cpp 修改子网掩码
bool SetLocalNetMask(char *netMask){ int socketfd; if (NULL == netMask) { printf("SetLocalNetMask: netMask is null\n"); return false; } if(socketfd = socket(PF_INET, SOCK_STREAM, 0 ) == -1); { perror("socket create failse...SetLocalNetMask!/n"); return false; } struct ifreq ifr_mask; struct sockaddr_in *sin_net_mask; memset(&ifr_mask, 0, sizeof(ifr_mask)); strncpy(ifr_mask.ifr_name, "eth0", sizeof(ifr_mask.ifr_name) - 1); sin_net_mask = (struct sockaddr_in *)&ifr_mask.ifr_addr; sin_net_mask->sin_family = AF_INET; inet_pton(AF_INET, netMask, &sin_net_mask->sin_addr); if (ioctl(socketfd, SIOCSIFNETMASK, &ifr_mask) < 0) { printf("socket_netmask ioctl error!\n"); return false; } close( socketfd ); return true;}
//.cpp 修改网关
bool SetLocalRoute(char *szGateWay){ int sockfd; sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd == -1) { return false; } struct rtentry rmten; struct sockaddr_in ic_gateway ;// Gateway IP address int err; memset(&rmten, 0, sizeof(rmten)); ic_gateway.sin_family = AF_INET; ic_gateway.sin_addr.s_addr = inet_addr(szGateWay); ic_gateway.sin_port = 0; ((struct sockaddr_in*)&rmten.rt_dst)->sin_family = AF_INET; ((struct sockaddr_in*)&rmten.rt_dst)->sin_addr.s_addr = 0; ((struct sockaddr_in*)&rmten.rt_dst)->sin_port = 0; ((struct sockaddr_in*)&rmten.rt_genmask)->sin_family = AF_INET; ((struct sockaddr_in*)&rmten.rt_genmask)->sin_addr.s_addr = 0; ((struct sockaddr_in*)&rmten.rt_genmask)->sin_port = 0; memcpy((void *) &rmten.rt_gateway, &ic_gateway, sizeof(ic_gateway)); rmten.rt_flags = RTF_UP | RTF_GATEWAY; if ((err = ioctl(sockfd, SIOCADDRT, &rmten)) < 0) { printf("ioctl net error!\n"); return false; } close( sockfd ); return true;}
//.cpp 获得IP地址、子网掩码、MAC物理地址
bool GetIpMacMaskAddress(){ unsigned char ipaddress[INET_MACADDRESSLEN]; unsigned char macaddress[INET_MACADDRESSLEN]; unsigned char netmask[INET_MACADDRESSLEN]; struct ifreq struReq; memset(&struReq, 0x00, sizeof(struct ifreq)); strncpy(struReq.ifr_name, "eth0", sizeof(struReq.ifr_name)); socketfd = socket(PF_INET, SOCK_STREAM, 0); if (-1 == ioctl(socketfd, SIOCGIFHWADDR, &struReq)) { printf("ioctl hwaddr error!\n"); return false; } strcpy((char *)macaddress, ether_ntoa((ether_addr*)struReq.ifr_hwaddr.sa_data)); if (-1 == ioctl(socketfd, SIOCGIFADDR, &struReq)) { printf("ioctl ip address error!\n"); return false; } strcpy((char *)ipaddress, inet_ntoa(((struct sockaddr_in *)&(struReq.ifr_addr))->sin_addr)); if (-1 == ioctl(socketfd, SIOCGIFNETMASK, &struReq)) { printf("ioctl net mask error!\n"); exit(1); } strcpy((char *)netmask, inet_ntoa(((struct sockaddr_in *)&(struReq.ifr_netmask))->sin_addr)); printf("MacAddress: %s\n", macaddress); printf("IpAddress: %s\n", ipaddress); printf("NetMask: %s\n",netmask); close(socketfd); return true; }
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <net/if.h>
- #include <net/if_arp.h>
- #include <unistd.h>
- #include <errno.h>
- #include <sys/time.h>
- #include <sys/stat.h>
- #include <stdio.h>
- #include <netdb.h>
- #include <netinet/in.h>
- #include <sys/ioctl.h>
- #include <ctype.h>
- #include <net/route.h>
- #include <fcntl.h>
- #include <string.h>
- #include <pthread.h>
- #if defined(__GLIBC__)&& __GLIBC__>=2 && __GLIBC_MINOR__ >= 1
- #include <netpacket/packet.h>
- #include <net/ethernet.h>
- #else
- #include <sys/types.h>
- #include <netinet/if_ether.h>
- #endif
- #include "xxx_ip.h"
- static int set_addr(unsigned char ip[16],int flag);
- static int get_addr(unsigned char ip[16],int flag);
- int get_ip(unsigned char ip[16])
- {
- return get_addr(ip, SIOCGIFADDR);
- }
- int get_ip_netmask(unsigned char ip[16])
- {
- return get_addr(ip, SIOCGIFNETMASK);
- }
- int get_mac(unsigned char addr[6])
- {
- return get_addr(addr, SIOCGIFHWADDR);
- }
- static int get_addr(unsigned char*addr, int flag)
- {
- SINT32 sockfd = 0;
- struct sockaddr_in *sin;
- struct ifreq ifr;
- if ((sockfd= socket(AF_INET, SOCK_STREAM, 0))< 0)
- {
- perror("socket error!\n");
- return FALSE;
- }
- memset(&ifr, 0, sizeof(ifr));
- snprintf(ifr.ifr_name,(sizeof(ifr.ifr_name)- 1),"%s", DEFAULT_ETH);
- if(ioctl(sockfd, flag,&ifr) < 0 )
- {
- perror("ioctl error!\n");
- close(sockfd);
- return FALSE;
- }
- close(sockfd);
- if (SIOCGIFHWADDR== flag){
- memcpy((void*)addr,(const void*)&ifr.ifr_ifru.ifru_hwaddr.sa_data, 6);
- /*printf("mac address: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", addr[0],addr[1],addr[2],addr[3],addr[4],addr[5]);*/
- }else{
- sin =(struct sockaddr_in *)&ifr.ifr_addr;
- snprintf((char*)addr, IP_LENGTH,"%s", inet_ntoa(sin->sin_addr));
- }
- return TRUE;
- }
- int is_valid_ip(unsigned char ipaddr[16])
- {
- int ret = 0;
- struct in_addr inp;
- ret = inet_aton(ipaddr,&inp);
- if (0== ret)
- {
- return FALSE;
- }
- else
- {
- printf("inet_aton:ip=%lu\n",ntohl(inp.s_addr));
- }
- return TRUE;
- }
- /*
- * 先验证是否为合法IP,然后将掩码转化成32无符号整型,取反为000...00111...1,
- * 然后再加1为00...01000...0,此时为2^n,如果满足就为合法掩码
- *
- * */
- int is_valid_netmask(unsigned char netmask[16])
- {
- if(is_valid_ip(netmask)> 0)
- {
- unsigned int b = 0, i, n[4];
- sscanf(netmask,"%u.%u.%u.%u",&n[3],&n[2],&n[1],&n[0]);
- for(i= 0; i < 4; ++i)//将子网掩码存入32位无符号整型
- b += n[i]<< (i * 8);
- b = ~b+ 1;
- if((b& (b - 1))== 0)//判断是否为2^n
- return TRUE;
- }
- return FALSE;
- }
- int set_ip_netmask(unsigned char ip[16])
- {
- return set_addr(ip, SIOCSIFNETMASK);
- }
- int set_ip(unsigned char ip[16])
- {
- return set_addr(ip, SIOCSIFADDR);
- }
- static int set_addr(unsigned char ip[16],int flag)
- {
- struct ifreq ifr;
- struct sockaddr_in sin;
- int sockfd;
- if (is_valid_ip(ip)< 0)
- {
- printf("ip was invalid!\n");
- return FALSE;
- }
- sockfd = socket(AF_INET, SOCK_DGRAM, 0);
- if(sockfd== -1){
- fprintf(stderr,"Could not get socket.\n");
- perror("eth0\n");
- return FALSE;
- }
- snprintf(ifr.ifr_name,(sizeof(ifr.ifr_name)- 1),"%s", DEFAULT_ETH);
- /* Read interface flags*/
- if (ioctl(sockfd, SIOCGIFFLAGS,&ifr) < 0) {
- fprintf(stderr,"ifdown: shutdown ");
- perror(ifr.ifr_name);
- return FALSE;
- }
- memset(&sin, 0, sizeof(struct sockaddr));
- sin.sin_family= AF_INET;
- inet_aton(ip,&sin.sin_addr.s_addr);
- memcpy(&ifr.ifr_addr,&sin, sizeof(struct sockaddr));
- if (ioctl(sockfd, flag,&ifr) < 0){
- fprintf(stderr,"Cannot set IP address. ");
- perror(ifr.ifr_name);
- return FALSE;
- }
- return TRUE;
- }
- int set_gateway(unsigned char ip[16])
- {
- int sockFd;
- struct sockaddr_in sockaddr;
- struct rtentry rt;
- if (is_valid_ip(ip)< 0)
- {
- printf("gateway was invalid!\n");
- return FALSE;
- }
- sockFd = socket(AF_INET, SOCK_DGRAM, 0);
- if (sockFd< 0)
- {
- perror("Socket create error.\n");
- return FALSE;
- }
- memset(&rt, 0, sizeof(struct rtentry));
- memset(&sockaddr, 0, sizeof(struct sockaddr_in));
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = 0;
- if(inet_aton(ip,&sockaddr.sin_addr)<0)
- {
- perror("inet_aton error\n");
- close(sockFd);
- return FALSE;
- }
- memcpy ( &rt.rt_gateway,&sockaddr, sizeof(struct sockaddr_in));
- ((struct sockaddr_in*)&rt.rt_dst)->sin_family=AF_INET;
- ((struct sockaddr_in*)&rt.rt_genmask)->sin_family=AF_INET;
- rt.rt_flags = RTF_GATEWAY;
- if (ioctl(sockFd, SIOCADDRT,&rt)<0)
- {
- perror("ioctl(SIOCADDRT) error in set_default_route\n");
- close(sockFd);
- return FALSE;
- }
- return TRUE;
- }
1.获取IP地址,子网掩码,物理地址。
2.配置IP地址,子网掩码,网关等。
3.IP地址合法验证和子网掩码验证。
TIPS:部分代码摘自网上,代码已测试通过。
点击(此处)折叠或打开
- #include "stdio.h"
- #include "stdlib.h"
- #include "string.h"
- #include "net/if.h"
- #include "arpa/inet.h"
- #include "linux/sockios.h"
- int main(int argc,char*argv[])
- {
- struct sockaddr_in *addr;
- struct ifreq ifr;
- char*address;
- int sockfd;
- char *name = "eth0";
- if( strlen(name)>= IFNAMSIZ)
- printf("device name is error.\n"),exit(0);
-
- strcpy( ifr.ifr_name, name);
-
- sockfd = socket(AF_INET,SOCK_DGRAM,0);
- //get inet addr
- if( ioctl( sockfd, SIOCGIFADDR,&ifr) == -1)
- printf("ioctl error.\n"),exit(0);
- addr = (struct sockaddr_in*)&(ifr.ifr_addr);
- address = inet_ntoa(addr->sin_addr);
- printf("inet addr: %s\n",address);
- //get Mask
- if( ioctl( sockfd, SIOCGIFNETMASK,&ifr) == -1)
- printf("ioctl error.\n"),exit(0);
- addr = (struct sockaddr_in*)&ifr.ifr_addr;
- address = inet_ntoa(addr->sin_addr);
- printf("Mask: %s\n",address);
- //get HWaddr
- u_int8_t hd[6];
- if(ioctl(sockfd, SIOCGIFHWADDR,&ifr) == -1)
- printf("hwaddr error.\n"),exit(0);
- memcpy( hd, ifr.ifr_hwaddr.sa_data, sizeof(hd));
- printf("HWaddr: %02X:%02X:%02X:%02X:%02X:%02X\n", hd[0], hd[1], hd[2], hd[3], hd[4], hd[5]);
-
- exit(0);
- }
- #include "stdio.h"
- #include "stdlib.h"
- #include "string.h"
- #include "net/if.h"
- #include "arpa/inet.h"
- #include "linux/sockios.h"
- int main(int argc,char*argv[])
- {
- char *dev = "eth0";
- char *ip ="192.168.1.252";
-
- struct ifreq ifr;
- if( strlen(dev)>= IFNAMSIZ)
- printf("device name error.\n"),exit(0);
- else
- strcpy( ifr.ifr_name, dev);
-
- int sockfd = socket(AF_INET,SOCK_DGRAM,0);
- //get inet addr
- if( ioctl( sockfd, SIOCGIFADDR,&ifr) == -1)
- printf("ioctl error.\n"),exit(0);
-
- struct sockaddr_in *addr = (struct sockaddr_in *)&(ifr.ifr_addr);
- char * address = inet_ntoa(addr->sin_addr);
- printf("current inet addr: %s\n",address);
- //set inet addr
- struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);
- p->sin_family= AF_INET;
- inet_aton( ip,&(p->sin_addr));
- if( ioctl( sockfd, SIOCSIFADDR,&ifr) == -1)
- printf("ioctl error.\n"),exit(0);
- else
- printf("change inet addr to: %s\n", ip);
- //any OS need active dev.
- /*ifr.ifr_flags|= IFF_UP;
- if( ioctl( sockfd, SIOCSIFFLAGS,&ifr) == -1)
- printf("active fault.\n"),exit(0);
- else
- printf("%s[%s] is working...\n", dev, ip);
- */
-
- close(sockfd);
- exit(1);
- //end
- }
分类: LINUX
函数 : ioctl(int fd, int request, void * arg)
定义 : <sys/ioctl.h>
功能 : 控制I/O设备, 提供了一种获得设备信息和向设备发送控制参数的手段.
参数 : int fd 文件句柄. 用于socket时, 是socket套接字.
int request 函数定义的所有操作. 关于socket的操作, 定义在<linux/sockios.h>文件中.
void *arg 指针的类型依赖于request参数.
类别
Request
说明
数据类型
套
接
口
SIOCATMARK
SIOCSPGRP
SIOCGPGRP
是否位于带外标记
设置套接口的进程ID 或进程组ID
获取套接口的进程ID 或进程组ID
int
int
int
文
件
FIONBIN
FIOASYNC
FIONREAD
FIOSETOWN
FIOGETOWN
设置/清除非阻塞I/O 标志
设置/ 清除信号驱动异步I/O 标志
获取接收缓存区中的字节数
设置文件的进程ID 或进程组ID
获取文件的进程ID 或进程组ID
int
int
int
int
int
接
口
SIOCGIFCONF
SIOCSIFADDR
SIOCGIFADDR
SIOCSIFFLAGS
SIOCGIFFLAGS
SIOCSIFDSTADDR
SIOCGIFDSTADDR
SIOCGIFBRDADDR
SIOCSIFBRDADDR
SIOCGIFNETMASK
SIOCSIFNETMASK
SIOCGIFMETRIC
SIOCSIFMETRIC
SIOCGIFMTU
SIOCxxx
获取所有接口的清单
设置接口地址
获取接口地址
设置接口标志
获取接口标志
设置点到点地址
获取点到点地址
获取广播地址
设置广播地址
获取子网掩码
设置子网掩码
获取接口的测度
设置接口的测度
获取接口MTU
(还有很多取决于系统的实现)
struct ifconf
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
ARP
SIOCSARP
SIOCGARP
SIOCDARP
创建/修改ARP 表项
获取ARP 表项
删除ARP 表项
struct arpreq
struct arpreq
struct arpreq
路
由
SIOCADDRT
SIOCDELRT
增加路径
删除路径
struct rtentry
struct rtentry
流
I_xxx
socket最常用到的结构体: struct ifreq 定义在<net/if.h>.(包括struct ifconf/ifr_flags等的定义)
一、获取
以下例程通过ioctl获取设备"eth0"的IP/掩码/硬件址
二、设置
以下例程设置eth0的IP地址.
屏蔽的代码用于设置IP后, 激活新设置. 多数系统不需要这步操作.
而且这步仅作演示. 真实使用的时候, 至少应该
1. 获取当前ifr.ifr_flags
2. ifr.ifr_flags |= IFF_UP;
以上是ioctl的一些示例, 实战中灵活使用、举一反三.
- linux C获取网络信息
- linux获取网络信息
- linux编程获取网络信息
- linux获取网络信息函数
- linux c获取系统信息
- Linux编程获取网络信息总结
- Linux网络编程之"获取网络天气信息"
- Linux C 语言 获取系统时间信息
- linux c获取系统网卡信息
- Linux C 语言 获取系统时间信息
- Linux C 语言 获取系统时间信息
- Linux C 语言 获取系统时间信息
- linux C语言获取系统内存信息
- linux c 获取用户信息以及主机信息
- linux c 获取文件的时间信息
- Linux/C-网络信息传输:cURL-HTTP协议发送信息
- 获取linux系统的cup信息,内存信息c代码
- 获取网络配置信息
- 心灵鸡汤
- java enum(枚举)使用详解 + 总结
- SpringMVC返回json格式内容
- Cloudsim 3.0.3中Power系列类的解析——PowerDataCenter和PowerDCBroker
- humble numbers
- linux C获取网络信息
- 【剑指Offer】面试题15:链表中倒数第K个结点
- android 6.0(api 23) SDK,没有org.apache.http.包
- 在一台电脑上安装多个Tomcat并运行
- Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationEx
- RGB色盘
- PHP常用函数
- 日志记录模式(LOGGING 、FORCE LOGGING 、NOLOGGING)
- nodeJS之crypto加密