Linux中ifreq 结构体分析和使用 及其在项目中的简单应用

简介: [基础知识说明] 结构原型: /* * Interface request structure used for socket * ioctl's.  All interface ioctl's must have parameter * definitions which begin with ifr_name.

[基础知识说明]

结构原型:

/*
 * 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_INC


bool 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;
}
复制代码
目录
相关文章
|
4月前
|
Java 关系型数据库 MySQL
在Linux平台上进行JDK、Tomcat、MySQL的安装并部署后端项目
现在,你可以通过访问http://Your_IP:Tomcat_Port/Your_Project访问你的项目了。如果一切顺利,你将看到那绚烂的胜利之光照耀在你的项目之上!
288 41
|
6月前
|
监控 Linux
Linux基础:文件和目录类命令分析。
总的来说,这些基础命令,像是Linux中藏匿的小矮人,每一次我们使用他们,他们就把我们的指令准确的传递给Linux,让我们的指令变为现实。所以,现在就开始你的Linux之旅,挥动你的命令之剑,探索这个充满神秘而又奇妙的世界吧!
128 19
|
7月前
|
缓存 网络协议 Linux
PCIe 以太网芯片 RTL8125B 的 spec 和 Linux driver 分析备忘
本文详细介绍了 Realtek RTL8125B PCIe 以太网芯片的规格以及在 Linux 中的驱动安装和配置方法。通过深入分析驱动源码,可以更好地理解其工作原理和优化方法。在实际应用中,合理配置和优化驱动程序可以显著提升网络性能和稳定性。希望本文能帮助您更好地使用和管理 RTL8125B,以满足各种网络应用需求。
650 33
|
7月前
|
数据管理 Linux iOS开发
Splunk Enterprise 9.4.1 (macOS, Linux, Windows) 发布 - 机器数据管理和分析
Splunk Enterprise 9.4.1 (macOS, Linux, Windows) 发布 - 机器数据管理和分析
126 0
Splunk Enterprise 9.4.1 (macOS, Linux, Windows) 发布 - 机器数据管理和分析
|
7月前
|
机器学习/深度学习 安全 Linux
Linux 主要应用领域的归纳
服务器领域 Linux在服务器领域的应用是其最为广泛和成熟的领域之一。由于其开源、稳定、高效和安全的特性,Linux成为许多企业服务器的首选操作系统。 Web服务器:Linux是Web服务器的理想选择,因为它支持Apache、Nginx等流行的Web服务器软件,这些软件在Linux上运行稳定且性能卓越。Linux服务器可以高效地处理大量并发请求,提供快速、可靠的Web服务。 数据库服务器:Linux也广泛用于数据库服务器,如MySQL、PostgreSQL和Oracle等数据库管理系统在Linux上运行良好。Linux的稳定性和安全性使得它成为存储和管理敏感数据的理想平台。 邮件服务器:Lin
269 5
|
8月前
|
消息中间件 Linux
Linux:进程间通信(共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量)
通过上述讲解和代码示例,您可以理解和实现Linux系统中的进程间通信机制,包括共享内存、消息队列和信号量。这些机制在实际开发中非常重要,能够提高系统的并发处理能力和数据通信效率。希望本文能为您的学习和开发提供实用的指导和帮助。
600 20
|
9月前
|
存储 运维 监控
Linux--深入理与解linux文件系统与日志文件分析
深入理解 Linux 文件系统和日志文件分析,对于系统管理员和运维工程师来说至关重要。文件系统管理涉及到文件的组织、存储和检索,而日志文件则记录了系统和应用的运行状态,是排查故障和维护系统的重要依据。通过掌握文件系统和日志文件的管理和分析技能,可以有效提升系统的稳定性和安全性。
211 7
|
9月前
|
监控 安全 Linux
启用Linux防火墙日志记录和分析功能
为iptables启用日志记录对于监控进出流量至关重要
278 1
|
10月前
|
缓存 Linux 开发者
Linux内核中的并发控制机制:深入理解与应用####
【10月更文挑战第21天】 本文旨在为读者提供一个全面的指南,探讨Linux操作系统中用于实现多线程和进程间同步的关键技术——并发控制机制。通过剖析互斥锁、自旋锁、读写锁等核心概念及其在实际场景中的应用,本文将帮助开发者更好地理解和运用这些工具来构建高效且稳定的应用程序。 ####
176 5
|
10月前
|
存储 安全 关系型数据库
Linux系统在服务器领域的应用与优势###
本文深入探讨了Linux操作系统在服务器领域的广泛应用及其显著优势。通过分析其开源性、安全性、稳定性和高效性,揭示了为何Linux成为众多企业和开发者的首选服务器操作系统。文章还列举了Linux在服务器管理、性能优化和社区支持等方面的具体优势,为读者提供了全面而深入的理解。 ###