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



    这部分代码包含:
    1.获取IP地址,子网掩码,物理地址。
    2.配置IP地址,子网掩码,网关等。
    3.IP地址合法验证和子网掩码验证。

    TIPS:部分代码摘自网上,代码已测试通过。

    点击(此处)折叠或打开
    1. #include <sys/socket.h>
    2. #include <arpa/inet.h>
    3. #include <net/if.h>
    4. #include <net/if_arp.h>
    5. #include <unistd.h>
    6. #include <errno.h>
    7. #include <sys/time.h>
    8. #include <sys/stat.h>
    9. #include <stdio.h>
    10. #include <netdb.h>
    11. #include <netinet/in.h>
    12. #include <sys/ioctl.h>
    13. #include <ctype.h>
    14. #include <net/route.h>
    15. #include <fcntl.h>
    16. #include <string.h>
    17. #include <pthread.h>
    18. #if defined(__GLIBC__)&& __GLIBC__>=2 && __GLIBC_MINOR__ >= 1
    19. #include <netpacket/packet.h>
    20. #include <net/ethernet.h>
    21. #else
    22. #include <sys/types.h>
    23. #include <netinet/if_ether.h>
    24. #endif

    25. #include "xxx_ip.h"

    26. static int set_addr(unsigned char ip[16],int flag);
    27. static int get_addr(unsigned char ip[16],int flag);

    28. int get_ip(unsigned char ip[16])
    29. {
    30.     return get_addr(ip, SIOCGIFADDR);
    31. }

    32. int get_ip_netmask(unsigned char ip[16])
    33. {
    34.     return get_addr(ip, SIOCGIFNETMASK);
    35. }

    36. int get_mac(unsigned char addr[6])
    37. {
    38.     return get_addr(addr, SIOCGIFHWADDR);
    39. }

    40. static int get_addr(unsigned char*addr, int flag)
    41. {
    42.     SINT32 sockfd = 0;
    43.     struct sockaddr_in *sin;
    44.     struct ifreq ifr;

    45.     if ((sockfd= socket(AF_INET, SOCK_STREAM, 0))< 0)
    46.     {
    47.         perror("socket error!\n");
    48.         return FALSE;
    49.     }

    50.     memset(&ifr, 0, sizeof(ifr));
    51.     snprintf(ifr.ifr_name,(sizeof(ifr.ifr_name)- 1),"%s", DEFAULT_ETH);

    52.     if(ioctl(sockfd, flag,&ifr) < 0 )
    53.     {
    54.         perror("ioctl error!\n");
    55.         close(sockfd);
    56.         return FALSE;
    57.     }
    58.     close(sockfd);

    59.     if (SIOCGIFHWADDR== flag){
    60.         memcpy((void*)addr,(const void*)&ifr.ifr_ifru.ifru_hwaddr.sa_data, 6);
    61.         /*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]);*/
    62.     }else{
    63.         sin =(struct sockaddr_in *)&ifr.ifr_addr;
    64.         snprintf((char*)addr, IP_LENGTH,"%s", inet_ntoa(sin->sin_addr));
    65.     }

    66.     return TRUE;
    67. }

    68. int is_valid_ip(unsigned char ipaddr[16])
    69. {
    70.     int ret = 0;
    71.     struct in_addr inp;
    72.     ret = inet_aton(ipaddr,&inp);
    73.     if (0== ret)
    74.     {
    75.         return FALSE;
    76.     }
    77.     else
    78.     {
    79.         printf("inet_aton:ip=%lu\n",ntohl(inp.s_addr));
    80.     }

    81.     return TRUE;
    82. }

    83. /*
    84.  * 先验证是否为合法IP,然后将掩码转化成32无符号整型,取反为000...00111...1,
    85.  * 然后再加1为00...01000...0,此时为2^n,如果满足就为合法掩码
    86.  *
    87.  * */
    88. int is_valid_netmask(unsigned char netmask[16])
    89. {
    90.     if(is_valid_ip(netmask)> 0)
    91.     {
    92.         unsigned int b = 0, i, n[4];
    93.         sscanf(netmask,"%u.%u.%u.%u",&n[3],&n[2],&n[1],&n[0]);
    94.         for(i= 0; i < 4; ++i)//将子网掩码存入32位无符号整型
    95.             b += n[i]<< (i * 8);
    96.         b = ~b+ 1;
    97.         if((b& (b - 1))== 0)//判断是否为2^n
    98.             return TRUE;
    99.     }

    100.     return FALSE;
    101. }


    102. int set_ip_netmask(unsigned char ip[16])
    103. {
    104.     return set_addr(ip, SIOCSIFNETMASK);
    105. }

    106. int set_ip(unsigned char ip[16])
    107. {
    108.     return set_addr(ip, SIOCSIFADDR);
    109. }

    110. static int set_addr(unsigned char ip[16],int flag)
    111. {
    112.     struct ifreq ifr;
    113.     struct sockaddr_in sin;
    114.     int sockfd;

    115.     if (is_valid_ip(ip)< 0)
    116.     {
    117.         printf("ip was invalid!\n");
    118.         return FALSE;
    119.     }

    120.     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    121.     if(sockfd== -1){
    122.         fprintf(stderr,"Could not get socket.\n");
    123.         perror("eth0\n");
    124.         return FALSE;
    125.     }

    126.     snprintf(ifr.ifr_name,(sizeof(ifr.ifr_name)- 1),"%s", DEFAULT_ETH);

    127.     /* Read interface flags*/
    128.     if (ioctl(sockfd, SIOCGIFFLAGS,&ifr) < 0) {
    129.         fprintf(stderr,"ifdown: shutdown ");
    130.         perror(ifr.ifr_name);
    131.         return FALSE;
    132.     }

    133.     memset(&sin, 0, sizeof(struct sockaddr));
    134.     sin.sin_family= AF_INET;
    135.     inet_aton(ip,&sin.sin_addr.s_addr);
    136.     memcpy(&ifr.ifr_addr,&sin, sizeof(struct sockaddr));
    137.     if (ioctl(sockfd, flag,&ifr) < 0){
    138.         fprintf(stderr,"Cannot set IP address. ");
    139.         perror(ifr.ifr_name);
    140.         return FALSE;
    141.     }

    142.     return TRUE;
    143. }


    144. int set_gateway(unsigned char ip[16])
    145. {
    146.     int sockFd;
    147.     struct sockaddr_in sockaddr;
    148.     struct rtentry rt;

    149.     if (is_valid_ip(ip)< 0)
    150.     {
    151.         printf("gateway was invalid!\n");
    152.         return FALSE;
    153.     }

    154.     sockFd = socket(AF_INET, SOCK_DGRAM, 0);
    155.     if (sockFd< 0)
    156.     {
    157.         perror("Socket create error.\n");
    158.         return FALSE;
    159.     }

    160.     memset(&rt, 0, sizeof(struct rtentry));
    161.     memset(&sockaddr, 0, sizeof(struct sockaddr_in));
    162.     sockaddr.sin_family = AF_INET;
    163.     sockaddr.sin_port = 0;
    164.     if(inet_aton(ip,&sockaddr.sin_addr)<0)
    165.     {
    166.         perror("inet_aton error\n");
    167.         close(sockFd);
    168.         return FALSE;
    169.     }

    170.     memcpy ( &rt.rt_gateway,&sockaddr, sizeof(struct sockaddr_in));
    171.     ((struct sockaddr_in*)&rt.rt_dst)->sin_family=AF_INET;
    172.     ((struct sockaddr_in*)&rt.rt_genmask)->sin_family=AF_INET;
    173.     rt.rt_flags = RTF_GATEWAY;
    174.     if (ioctl(sockFd, SIOCADDRT,&rt)<0)
    175.     {
    176.         perror("ioctl(SIOCADDRT) error in set_default_route\n");
    177.         close(sockFd);
    178.         return FALSE;
    179.     }

    180.     return TRUE;
    181. }

    分类: LINUX

    ioctl在socket中的一些用法及示例

    函数 : 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 - arg指针类型的对应关系

    类别

    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/掩码/硬件址

    1. #include "stdio.h"
    2. #include "stdlib.h"
    3. #include "string.h"

    4. #include "net/if.h"
    5. #include "arpa/inet.h"
    6. #include "linux/sockios.h"

    7. int main(int argc,char*argv[])
    8. {
    9.     struct sockaddr_in *addr;
    10.     struct ifreq ifr;
    11.     char*address;
    12.     int sockfd;

    13.     char *name = "eth0";
    14.     if( strlen(name)>= IFNAMSIZ)
    15.         printf("device name is error.\n"),exit(0);
    16.         
    17.     strcpy( ifr.ifr_name, name);
    18.         
    19.     sockfd = socket(AF_INET,SOCK_DGRAM,0);

    20.     //get inet addr
    21.     if( ioctl( sockfd, SIOCGIFADDR,&ifr) == -1)
    22.         printf("ioctl error.\n"),exit(0);

    23.     addr = (struct sockaddr_in*)&(ifr.ifr_addr);
    24.     address = inet_ntoa(addr->sin_addr);

    25.     printf("inet addr: %s\n",address);

    26.     //get Mask
    27.     if( ioctl( sockfd, SIOCGIFNETMASK,&ifr) == -1)
    28.         printf("ioctl error.\n"),exit(0);

    29.     addr = (struct sockaddr_in*)&ifr.ifr_addr;
    30.     address = inet_ntoa(addr->sin_addr);

    31.     printf("Mask: %s\n",address);

    32.     //get HWaddr
    33.     u_int8_t hd[6];
    34.     if(ioctl(sockfd, SIOCGIFHWADDR,&ifr) == -1)
    35.         printf("hwaddr error.\n"),exit(0);

    36.     memcpy( hd, ifr.ifr_hwaddr.sa_data, sizeof(hd));
    37.     printf("HWaddr: %02X:%02X:%02X:%02X:%02X:%02X\n", hd[0], hd[1], hd[2], hd[3], hd[4], hd[5]);
    38.     
    39.     exit(0);
    40. }


     二、设置

    以下例程设置eth0的IP地址.

    1. #include "stdio.h"
    2. #include "stdlib.h"
    3. #include "string.h"

    4. #include "net/if.h"
    5. #include "arpa/inet.h"
    6. #include "linux/sockios.h"

    7. int main(int argc,char*argv[])
    8. {
    9.     char *dev = "eth0";
    10.     char *ip ="192.168.1.252";
    11.     
    12.     struct ifreq ifr;
    13.     if( strlen(dev)>= IFNAMSIZ)
    14.         printf("device name error.\n"),exit(0);
    15.     else
    16.         strcpy( ifr.ifr_name, dev);
    17.     
    18.     int sockfd = socket(AF_INET,SOCK_DGRAM,0);

    19.     //get inet addr
    20.     if( ioctl( sockfd, SIOCGIFADDR,&ifr) == -1)
    21.         printf("ioctl error.\n"),exit(0);
    22.     
    23.     struct sockaddr_in *addr = (struct sockaddr_in *)&(ifr.ifr_addr);
    24.     char * address = inet_ntoa(addr->sin_addr);

    25.     printf("current inet addr: %s\n",address);

    26.     //set inet addr
    27.     struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);

    28.     p->sin_family= AF_INET;
    29.     inet_aton( ip,&(p->sin_addr));

    30.     if( ioctl( sockfd, SIOCSIFADDR,&ifr) == -1)
    31.      printf("ioctl error.\n"),exit(0);
    32.     else    
    33.         printf("change inet addr to: %s\n", ip);

    34.     //any OS need active dev.
    35.     /*ifr.ifr_flags|= IFF_UP;
    36.     if( ioctl( sockfd, SIOCSIFFLAGS,&ifr) == -1)
    37.         printf("active fault.\n"),exit(0);
    38.     else
    39.         printf("%s[%s] is working...\n", dev, ip);
    40.     */
    41.         
    42.     close(sockfd);
    43.     exit(1);
    44.     //end
    45. }

    屏蔽的代码用于设置IP后, 激活新设置. 多数系统不需要这步操作.
    而且这步仅作演示. 真实使用的时候, 至少应该
    1. 获取当前ifr.ifr_flags
    2. ifr.ifr_flags |= IFF_UP;

    以上是ioctl的一些示例, 实战中灵活使用、举一反三.

     

     

原创粉丝点击