1. ip地址、子网掩码、网关设置和获取
net.h
/*
* =====================================================================================
*
* Filename: net.h
*
* Description:
*
* Version: 1.0
* Created: 07/22/17 16:13:58
* Revision: none
* Compiler: gcc
*
* Author: linsheng.pan (), life_is_legend@163.com
* Organization:
*
* =====================================================================================
*/
#ifndef INCLUDE_NET_H
#define INCLUDE_NET_H
#ifdef __cplusplus
extern "C" {
#endif
#include <net/if.h>
#define WV_NET_SUCCESS (0)
#define WV_NET_ERROR (-1)
/*
* function: 获取本机指定网卡的IP
*
* description: Net_GetIpAddr
*
* input: @eth_name: 网卡的名字
* @ip: ip的网络序号
* @buf_size: 字符串的长度
*
* output: @
*
* return:
*
* author: linsheng.pan
*/
int Net_GetIpAddr(const char *eth_name, unsigned int *ip, int ip_len);
/*
* function: 获取本机指定网卡的IP
*
* description: Net_SetIpAddr
*
* input: @eth_name: 网卡的名字
* @ip_addr: ip的网络序号
*
* output: @
*
* return:
*
* author: linsheng.pan
*/
int Net_SetIpAddr(const char *eth_name, const unsigned int ip_addr);
/*
* function: Net_SetIpAddrStr
*
* description: 设置网卡的IP
*
* input: @eth_name:网卡名
* @ip_buf:ip地址("192.168.1.1")
* @buf_size: ip地址的长度
*
* output: @
*
* return:
*
* author: linsheng.pan
*/
int Net_SetIpAddrStr(const char *eth_name, const char *ip_buf, int buf_size);
/*
* function: Net_SetIpAddrStr
*
* description: 设置网卡的IP
*
* input: @eth_name:网卡名
* @ip_buf:ip地址("192.168.1.1")
* @buf_size: ip地址的长度
*
* output: @
*
* return:
*
* author: linsheng.pan
*/
int Net_GetIpAddrStr(const char *eth_name, char *ip_buf, int buf_size);
/*
* function: Net_GetMacAddr
*
* description: 获取本机指定网卡的MAC地址
*
* input: @eth_name: 网卡名字
* @mac_buf: 存储mac地址
* @buf_size: mac地址的长度
*
* output: @
*
* return:
*
* author: linsheng.pan
*/
int Net_GetMacAddr(const char *eth_name, unsigned char *mac_buf, int buf_size);
/*
* function: Net_SetMacAddr
*
* description:给指定网卡设置mac地址
*
* input: @eth_name:网卡名
* @mac_buf:mac地址
* @buf_size:mac地址长度
*
* output: @
*
* return:
*
* author: linsheng.pan
*/
int Net_SetMacAddr(const char *eth_name, const unsigned char *mac_buf, int buf_size);
/*
* function: Net_BindInterface
*
* description: 将套接字绑定网卡
*
* input: @sockfd: 一个已经打开的套接字
* @eth_name: 网卡名字
*
* output: @
*
* return:
*
* author: linsheng.pan
*/
int Net_BindInterface(int *sockfd, const char *eth_name);
/*
* function: Net_GetIpAddrWithDHCP
*
* description: 动态获取ip
*
* input: @ip: ip的网络序
* @eth_name: 网卡名字
*
* output: @
*
* return:
*
* author: linsheng.pan
*/
int Net_GetIpAddrWithDHCP(const char * eth_name, unsigned int *ip, unsigned int ip_len);
/*
* function: Net_SetNetmask
*
* description: 设置子网掩码
*
* input: @eth_name: 网口名
* @net_mask: 网络序
*
* output: @
*
* return@
* success:
* fail:
*
* author: linsheng.pan
*/
int Net_SetNetmask(const char *eth_name, const unsigned int net_mask);
/*
* function: Net_GetNetmask
*
* description: 获取子网掩码
*
* input: @eth_name: 网口名
*
* output: @net_mask: 网络序存储
* @net_mask_len: 长度
*
* return@
* success:
* fail:
*
* author: linsheng.pan
*/
int Net_GetNetmask(const char *eth_name, unsigned int *net_mask, int net_mask_len);
/*
* function: Net_SetGateWay
*
* description: 设置网关
*
* input: @eth_name: 网口名
* @gw: 网络序
*
* output: @
*
* return@
* success:
* fail:
*
* author: linsheng.pan
*/
int Net_SetGateWay(char *eth_name, unsigned int gw);
/*
* function: Net_DelGateWay
*
* description: 删除网关
*
* input: @eth_name: 网口名
* @gw: 网络序
*
* output: @
*
* return@
* success:
* fail:
*
* author: linsheng.pan
*/
int Net_DelGateWay(char *eth_name, unsigned int gw);
/*
* function: Net_GetGateWay
*
* description: 获取网关
*
* input: @eth_name: 网口名
* @gateway: 网络序
* @buf_len: 缓存区长度
*
* output: @
*
* return@
* success:
* fail:
*
* author: linsheng.pan
*/
int Net_GetGateWay(const char *eth_name, unsigned int *gateway, int buf_len);
#ifdef __cplusplus
}
#endif
#endif /* ifndef INCLUDE_NET_H */
net.c
/*
* =====================================================================================
*
* Filename: net.c
*
* Description:
*
* Version: 1.0
* Created: 07/22/17 16:32:49
* Revision: none
* Compiler: gcc
*
* Author: linsheng.pan (), life_is_legend@163.com
* Organization:
*
* =====================================================================================
*/
#include "wv_net.h"
#include "wv_log.h"
#include <arpa/inet.h>
#include <ctype.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/route.h>
#include <net/if_arp.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <linux/rtnetlink.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/utsname.h>
#include <limits.h>
#include <linux/sockios.h>
#define BUFSIZE (8192)
#define MAX_NETWORK_NUM (16)
#define ERR_BUF_LEN (256)
#define ERR_STRING(err_buf) strerror_r(errno, err_buf, sizeof(err_buf))
#define CLOSE(fd) {\
if(fd > 0) \
{\
close(fd);\
fd = -1;\
}\
}
struct route_info {
u_int dstAddr;
u_int srcAddr;
u_int gateWay;
char ifName[IF_NAMESIZE];
};
static struct ifconf s_stIfconf;
static struct ifreq s_st_arrIfreq[MAX_NETWORK_NUM];
static int Net_FindInterface(const char *eth_name)
{
if(!eth_name)
{
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: param = NULL");
return WV_NET_ERROR;
}
int index = -1;
int interface_num = 0;
interface_num = s_stIfconf.ifc_len / sizeof(struct ifreq);
while(interface_num-- > 0)
{
if(!strcmp(s_st_arrIfreq[interface_num].ifr_name, eth_name))
{
index = interface_num;
break;
}
}
return index;
}
/*
* function: Net_GetInterfaceInfo
*
* description: 获取所有工作网卡的信息(网)
*
* input: @
*
* output: @
*
* return:
*
* author: linsheng.pan
*/
static int Net_GetInterfaceInfo(void)
{
char err_buf[ERR_BUF_LEN] = {0};
int sockfd = -1;
int interface_num = 0;
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
ERR_STRING(err_buf);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: %s", err_buf);
return WV_NET_ERROR;
}
s_stIfconf.ifc_len = sizeof(s_st_arrIfreq);
s_stIfconf.ifc_buf = (caddr_t)(s_st_arrIfreq);
if(!ioctl(sockfd, SIOCGIFCONF, &s_stIfconf))
{
interface_num = s_stIfconf.ifc_len / sizeof(struct ifreq);
while(interface_num-- > 0)
{
//get mac ip broatcast subnet mask
//if(!ioctl(sockfd, SIOCGIFFLAGS | SIOCGIFHWADDR | SIOCGIFADDR | SIOCGIFBRDADDR | SIOCGIFNETMASK, &s_st_arrIfreq[interface_num]))
if(!ioctl(sockfd, SIOCGIFADDR , &s_st_arrIfreq[interface_num]))
{
//LOG_PRINTF(LOG_LEVEL_DEBUG, LOG_MODULE_SYS, "Get Network[%d] Info Success!", interface_num);
}
else
{
ERR_STRING(err_buf);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: %s", err_buf);
CLOSE(sockfd);
return WV_NET_ERROR;
}
}
}
else
{
ERR_STRING(err_buf);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: %s", err_buf);
CLOSE(sockfd);
return WV_NET_ERROR;
}
CLOSE(sockfd);
return WV_NET_SUCCESS;
}
/*
* function: Net_SetIpAddrStr
*
* description: 设置网卡的IP
*
* input: @eth_name:网卡名
* @ip_buf:ip地址("192.168.1.1")
* @buf_size: ip地址的长度
*
* output: @
*
* return:
*
* author: linsheng.pan
*/
int Net_SetIpAddrStr(const char *eth_name, const char *ip_buf, int buf_size)
{
U32 u32IPAddr = 0;
inet_pton(AF_INET, ip_buf, &u32IPAddr);
return Net_SetIpAddr(eth_name, u32IPAddr);
}
/*
* function: 获取本机指定网卡的IP
*
* description: Net_GetIpAddr
*
* input: @eth_name: 网卡的名字
* @ip_buf: ip的字符串
* @buf_size: 字符串的长度
*
* output: @
*
* return:
*
* author: linsheng.pan
*/
int Net_GetIpAddrStr(const char *eth_name, char *ip_buf, int buf_size)
{
if((!eth_name) || (!ip_buf))
{
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: param = NULL");
return WV_NET_ERROR;
}
int index = -1;
//获取本地网卡信息
Net_GetInterfaceInfo();
//判断是否有指定网口的ip
if((index = Net_FindInterface(eth_name)) >= 0)
{
//将ip的网络序转换为点十制
inet_ntop(AF_INET, &(((struct sockaddr_in *)&(s_st_arrIfreq[index].ifr_addr))->sin_addr.s_addr), ip_buf, buf_size);
LOG_PRINTF(LOG_LEVEL_DEBUG, LOG_MODULE_SYS, "%s : %s", eth_name, ip_buf);
}
else
{
//解锁资源并推出
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: Can't find %s", eth_name);
return WV_NET_ERROR;
}
return WV_NET_SUCCESS;
}
/*
* function: 获取本机指定网卡的IP
*
* description: Net_GetIpAddr
*
* input: @eth_name: 网卡的名字
* @ip: 网络序
*
* output: @
*
* return:
*
* author: linsheng.pan
*/
int Net_GetIpAddr(const char *eth_name, unsigned int *ip, int ip_len)
{
if((!eth_name) || (!ip))
{
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: param = NULL");
return WV_NET_ERROR;
}
int index = -1;
char ip_buf[16] = {0};
unsigned int val = 0;
//获取本地网卡信息
Net_GetInterfaceInfo();
//判断是否有指定网口的ip
if((index = Net_FindInterface(eth_name)) >= 0)
{
//将ip的网络序转换为点十制
inet_ntop(AF_INET, &(((struct sockaddr_in *)&(s_st_arrIfreq[index].ifr_addr))->sin_addr.s_addr), ip_buf, sizeof(ip_buf));
memcpy(&val, &(((struct sockaddr_in *)&(s_st_arrIfreq[index].ifr_addr))->sin_addr.s_addr), sizeof(val));
*ip = val;
//LOG_PRINTF(LOG_LEVEL_DEBUG, LOG_MODULE_SYS, "Get ip[%s] : %s", eth_name, ip_buf);
}
else
{
//解锁资源并推出
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: Can't find %s", eth_name);
return WV_NET_ERROR;
}
return WV_NET_SUCCESS;
}
/*
* function: Net_SetIpAddr
*
* description: 设置ip
*
* input: @eth_name: 网口名(eth0, eth0:0),可以创建虚拟网口
* @ip_addr: 网络序
* @ip_len: 长度
*
* output: @
*
* return@
* success:
* fail:
*
* author: linsheng.pan
*/
int Net_SetIpAddr(const char *eth_name, const unsigned int ip_addr)
{
if((!eth_name))
{
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: param = NULL");
return WV_NET_ERROR;
}
int fd;
struct ifreq ifr;
struct sockaddr_in *sin;
char err_buff[ERR_BUF_LEN];
unsigned int ip_net = 0;
ip_net = ip_addr;
char *ip_str = NULL;
struct in_addr net_addr;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd < 0)
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: call socket failed[%s]", err_buff);
return WV_NET_ERROR;
}
memset(&ifr,0,sizeof(ifr));
strncpy(ifr.ifr_name, eth_name, strlen(eth_name));
sin = (struct sockaddr_in*)&ifr.ifr_addr;
sin->sin_family = AF_INET;
memcpy(&(sin->sin_addr), &ip_net, sizeof(ip_net));
if(ioctl(fd, SIOCSIFADDR, &ifr) < 0)
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: call ioctl failed[%s]", err_buff);
CLOSE(fd);
return WV_NET_ERROR;
}
CLOSE(fd);
return WV_NET_SUCCESS;
}
/*
* function: Net_GetMacAddr
*
* description: 输入网口名字,获取mac地址
*
* input: @eht_name: 网口名字("eth0")
*
* output: @mac_buf: 存储mac地址的buffer(6 字节以上)
* @mac_len: buffer 长度
*
* return@
* success:
* fail:
*
* author: linsheng.pan
*/
int Net_GetMacAddr(const char *eth_name, unsigned char *mac_buf, int mac_len)
{
if((!eth_name) || (!mac_buf))
{
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: param = NULL");
return WV_NET_ERROR;
}
struct ifreq temp;
struct sockaddr *addr;
int fd = -1;
char err_buff[ERR_BUF_LEN];
int err_code = WV_NET_SUCCESS;
int ret = 0;
if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: call socket failed[%s]", err_buff);
return WV_NET_ERROR;
}
strncpy(temp.ifr_name, eth_name, strlen(eth_name) + 1);
addr = (struct sockaddr *)(&temp.ifr_hwaddr);
addr->sa_family = ARPHRD_ETHER;
ret = ioctl(fd, SIOCGIFHWADDR, &temp);
if(ret < 0)
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: call ioctl failed[%s]", err_buff);
err_code = WV_NET_ERROR;
}
close(fd);
if(WV_NET_SUCCESS == err_code)
{
memcpy(mac_buf, addr->sa_data, 6);
//LOG_PRINTF(LOG_LEVEL_DEBUG, LOG_MODULE_SYS, "Get [%s], mac:%x:%x:%x:%x:%x:%x", eth_name, mac_buf[0],
// mac_buf[1], mac_buf[2], mac_buf[3], mac_buf[4], mac_buf[5]);
}
return err_code;
}
/*
* function: Net_SetMacAddr
*
* description: 设置mac地址
*
* input: @eth_name: 网口名
* @mac_buff: mac地址(0xa0,0x69,0x86,0x0, 0x0, 0x1)
* @mac_len: buffer 长度
*
*
* output: @
*
* return@
* success:
* fail:
*
* author: linsheng.pan
*/
int Net_SetMacAddr(const char *eth_name, const unsigned char *mac_buff, int mac_len)
{
if((!eth_name) || (!mac_buff))
{
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: param = NULL");
return WV_NET_ERROR;
}
struct ifreq temp;
struct sockaddr *addr;
int fd = -1;
char err_buff[ERR_BUF_LEN];
int err_code = WV_NET_SUCCESS;
int ret = 0;
strncpy(temp.ifr_name, eth_name, strlen(eth_name) + 1);
//ifconfig down
temp.ifr_flags &= ~IFF_UP;
if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: call socket failed[%s]", err_buff);
return WV_NET_ERROR;
}
ret = ioctl(fd, SIOCSIFFLAGS, &temp);
if(ret < 0)
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: call ioctl failed[%s]", err_buff);
CLOSE(fd);
return WV_NET_ERROR;
}
CLOSE(fd);
//set mac
if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: call socket failed[%s]", err_buff);
return WV_NET_ERROR;
}
addr = (struct sockaddr *)(&temp.ifr_hwaddr);
addr->sa_family = ARPHRD_ETHER;
memcpy(addr->sa_data, mac_buff, mac_len);
ret = ioctl(fd, SIOCSIFHWADDR, &temp);
if(ret < 0)
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: call ioctl failed[%s]", err_buff);
CLOSE(fd);
return WV_NET_ERROR;
}
CLOSE(fd);
//ifconfig up
temp.ifr_flags |= IFF_UP;
if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: call socket failed[%s]", err_buff);
return WV_NET_ERROR;
}
ret = ioctl(fd, SIOCSIFFLAGS, &temp);
if(ret < 0)
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: call ioctl failed[%s]", err_buff);
CLOSE(fd);
return WV_NET_ERROR;
}
CLOSE(fd);
LOG_PRINTF(LOG_LEVEL_DEBUG, LOG_MODULE_SYS, "Set [%s], mac:%x:%x:%x:%x:%x:%x", eth_name, mac_buff[0],
mac_buff[1], mac_buff[2], mac_buff[3], mac_buff[4], mac_buff[5]);
return err_code;
}
/*
* function: Net_GetNetmask
*
* description: 获取子网掩码
*
* input: @eth_name: 网口名
*
* output: @net_mask: 主机序存储
* @net_mask_len: 长度
*
* return@
* success:
* fail:
*
* author: linsheng.pan
*/
int Net_GetNetmask(const char *eth_name, unsigned int *net_mask, int net_mask_len)
{
if((!eth_name) || (!net_mask))
{
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: param = NULL");
return WV_NET_ERROR;
}
int fd;
struct ifreq ifr;
struct sockaddr_in *sin;
char err_buff[ERR_BUF_LEN];
unsigned int net_mask_tmp = 0;
char *ip_str = NULL;
struct in_addr net_addr;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd < 0)
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: call socket failed[%s]", err_buff);
return WV_NET_ERROR;
}
memset(&ifr,0,sizeof(ifr));
strncpy(ifr.ifr_name, eth_name, strlen(eth_name));
sin = (struct sockaddr_in*)&ifr.ifr_addr;
sin->sin_family = AF_INET;
if(ioctl(fd, SIOCGIFNETMASK, &ifr) < 0)
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: call ioctl failed[%s]", err_buff);
CLOSE(fd);
return WV_NET_ERROR;
}
memcpy(&net_mask_tmp, &(sin->sin_addr), net_mask_len);
*net_mask = net_mask_tmp;
CLOSE(fd);
return WV_NET_SUCCESS;
}
/*
* function: Net_SetNetmask
*
* description: 设置子网掩码
*
* input: @eth_name: 网口名
* @net_mask: 网络序
* @net_mask_len: 长度
*
* output: @
*
* return@
* success:
* fail:
*
* author: linsheng.pan
*/
int Net_SetNetmask(const char *eth_name, const unsigned int net_mask)
{
if((!eth_name))
{
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: param = NULL");
return WV_NET_ERROR;
}
int fd;
struct ifreq ifr;
struct sockaddr_in *sin;
char err_buff[ERR_BUF_LEN];
struct in_addr net_addr;
char *ip_str = NULL;
unsigned int net_mask_net= net_mask;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd < 0)
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: call socket failed[%s]", err_buff);
return WV_NET_ERROR;
}
memset(&ifr,0,sizeof(ifr));
strncpy(ifr.ifr_name, eth_name, strlen(eth_name));
sin = (struct sockaddr_in*)&ifr.ifr_addr;
sin->sin_family = AF_INET;
memcpy(&(sin->sin_addr), &net_mask_net, sizeof(net_mask_net));
if(ioctl(fd, SIOCSIFNETMASK, &ifr) < 0)
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: call ioctl failed[%s]", err_buff);
CLOSE(fd);
return WV_NET_ERROR;
}
CLOSE(fd);
return WV_NET_SUCCESS;
}
/*
* function: Net_BindInterface
*
* description: 将套接字绑定网卡
*
* input: @sockfd: 一个已经打开的套接字
* @eth_name: 网卡名字
*
* output: @
*
* return:
*
* author: linsheng.pan
*/
int Net_BindInterface(int *sockfd, const char *eth_name)
{
if((!eth_name) && (!sockfd))
{
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: param = NULL");
return WV_NET_ERROR;
}
int ret = 0;
char err_buf[ERR_BUF_LEN] = {0};
struct ifreq netdev;
memset(&netdev, 0, sizeof(netdev));
strncpy(netdev.ifr_name, eth_name, sizeof(netdev.ifr_name) - 1);
ret = setsockopt(*sockfd, SOL_SOCKET, SO_BINDTODEVICE, &netdev, sizeof(netdev));
if(ret)
{
ERR_STRING(err_buf);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: call setsockopt:%s", err_buf);
return WV_NET_ERROR;
}
return WV_NET_SUCCESS;
}
/*
* function: Net_GetIpAddrWithDHCP
*
* description: 动态获取IP
*
* input: @
*
* output: @
*
* return@
* success:
* fail:
*
* author: linsheng.pan
*/
int Net_GetIpAddrWithDHCP(const char * eth_name, unsigned int *ip, unsigned int ip_len)
{
if(!eth_name)
{
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: param = NULL");
return WV_NET_ERROR;
}
char cmd[128] = {0};
//尝试5次获取动态ip,失败后自动退出
snprintf(cmd, sizeof(cmd), "udhcpc -t 5 -n -i %s", eth_name);
system(cmd);
Net_GetIpAddr(eth_name, ip, ip_len);
return WV_NET_SUCCESS;
}
int Net_SetGateWay(char *eth_name, unsigned int gw)
{
if(!eth_name)
{
return WV_NET_ERROR;
}
int skfd;
struct rtentry rt;
int err;
char ip_str[16];
char err_buff[ERR_BUF_LEN] = {0};
skfd = socket(PF_INET, SOCK_DGRAM, 0);
if (skfd < 0)
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "ERROR[%s]: call socket", err_buff);
return WV_NET_ERROR;
}
/* Delete existing defalt gateway */
memset(&rt, 0, sizeof(rt));
rt.rt_dst.sa_family = AF_INET;
((struct sockaddr_in *)&rt.rt_dst)->sin_addr.s_addr = 0;
rt.rt_genmask.sa_family = AF_INET;
((struct sockaddr_in *)&rt.rt_genmask)->sin_addr.s_addr = 0;
rt.rt_flags = RTF_UP;
rt.rt_dev = eth_name;
err = ioctl(skfd, SIOCDELRT, &rt);
if ((err == 0 || errno == ESRCH) && gw)
{
/* Set default gateway */
memset(&rt, 0, sizeof(rt));
rt.rt_dst.sa_family = AF_INET;
((struct sockaddr_in *)&rt.rt_dst)->sin_addr.s_addr = 0;
rt.rt_gateway.sa_family = AF_INET;
((struct sockaddr_in *)&rt.rt_gateway)->sin_addr.s_addr = gw;
rt.rt_genmask.sa_family = AF_INET;
((struct sockaddr_in *)&rt.rt_genmask)->sin_addr.s_addr = 0;
rt.rt_flags = RTF_UP | RTF_GATEWAY;
rt.rt_dev = eth_name;
err = ioctl(skfd, SIOCADDRT, &rt);
}
inet_ntop(AF_INET, &gw, ip_str, sizeof(ip_str));
if(!(err == 0 || errno == ESRCH))
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error[%s]: Can't set %s:%s gate way",err_buff, eth_name, ip_str);
}
else
{
LOG_PRINTF(LOG_LEVEL_DEBUG, LOG_MODULE_SYS, "Set default gateway %s:%s ", eth_name, ip_str);
}
CLOSE(skfd);
return err;
}
int Net_DelGateWay(char *eth_name, unsigned int gw)
{
if(!eth_name)
{
return WV_NET_ERROR;
}
int skfd;
struct rtentry rt;
int err;
char ip_str[16];
char err_buff[ERR_BUF_LEN] = {0};
skfd = socket(PF_INET, SOCK_DGRAM, 0);
if (skfd < 0)
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "ERROR[%s]: call socket", err_buff);
return WV_NET_ERROR;
}
/* Delete existing defalt gateway */
memset(&rt, 0, sizeof(rt));
rt.rt_dst.sa_family = AF_INET;
((struct sockaddr_in *)&rt.rt_dst)->sin_addr.s_addr = 0;
rt.rt_gateway.sa_family = AF_INET;
((struct sockaddr_in *)&rt.rt_gateway)->sin_addr.s_addr = gw;
rt.rt_genmask.sa_family = AF_INET;
((struct sockaddr_in *)&rt.rt_genmask)->sin_addr.s_addr = 0;
rt.rt_flags = RTF_UP;
rt.rt_dev = eth_name;
err = ioctl(skfd, SIOCDELRT, &rt);
inet_ntop(AF_INET, &gw, ip_str, sizeof(ip_str));
if(!(err == 0 || errno == ESRCH))
{
ERR_STRING(err_buff);
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error[%s]: Can't del %s:%s gate way",err_buff, eth_name, ip_str);
}
else
{
LOG_PRINTF(LOG_LEVEL_DEBUG, LOG_MODULE_SYS, "Del default gateway %s:%s ", eth_name, ip_str);
}
CLOSE(skfd);
return err;
}
int readNlSock(int sockFd, char *bufPtr, int seqNum, int pId)
{
struct nlmsghdr *nlHdr;
int readLen = 0, msgLen = 0;
do{
if((readLen = recv(sockFd, bufPtr, BUFSIZE - msgLen, 0)) < 0)
{
perror("SOCK READ: ");
return WV_NET_ERROR;
}
nlHdr = (struct nlmsghdr *)bufPtr;
if((NLMSG_OK(nlHdr, readLen) == 0) || (nlHdr->nlmsg_type == NLMSG_ERROR))
{
perror("Error in recieved packet");
return WV_NET_ERROR;
}
if(nlHdr->nlmsg_type == NLMSG_DONE)
{
break;
}
else
{
bufPtr += readLen;
msgLen += readLen;
}
if((nlHdr->nlmsg_flags & NLM_F_MULTI) == 0)
{
break;
}
} while((nlHdr->nlmsg_seq != seqNum) || (nlHdr->nlmsg_pid != pId));
return msgLen;
}
int parseRoutes(struct nlmsghdr *nlHdr, struct route_info *rtInfo)
{
struct rtmsg *rtMsg;
struct rtattr *rtAttr;
int rtLen;
struct in_addr dst;
struct in_addr gate;
rtMsg = (struct rtmsg *)NLMSG_DATA(nlHdr);
// If the route is not for AF_INET or does not belong to main routing table
//then return.
if((rtMsg->rtm_family != AF_INET) || (rtMsg->rtm_table != RT_TABLE_MAIN))
{
return WV_NET_ERROR;
}
rtAttr = (struct rtattr *)RTM_RTA(rtMsg);
rtLen = RTM_PAYLOAD(nlHdr);
for(;RTA_OK(rtAttr,rtLen);rtAttr = RTA_NEXT(rtAttr,rtLen)){
switch(rtAttr->rta_type) {
case RTA_OIF:
if_indextoname(*(int *)RTA_DATA(rtAttr), rtInfo->ifName);
break;
case RTA_GATEWAY:
rtInfo->gateWay = *(u_int *)RTA_DATA(rtAttr);
break;
case RTA_PREFSRC:
rtInfo->srcAddr = *(u_int *)RTA_DATA(rtAttr);
break;
case RTA_DST:
rtInfo->dstAddr = *(u_int *)RTA_DATA(rtAttr);
break;
}
}
unsigned int ip_addr = 0;
char ip_str[16];
ip_addr = rtInfo->dstAddr;
inet_ntop(AF_INET, &ip_addr, ip_str, sizeof(ip_str));
if (strstr(ip_str, "0.0.0.0"))
{
return 0;
}
else
{
return WV_NET_ERROR;
}
}
int Net_GetGateWay(const char *eth_name, unsigned int *gateway, int buf_len)
{
if((!eth_name) || (!gateway) ||( buf_len < 4))
{
return WV_NET_ERROR;
}
struct nlmsghdr *nlMsg;
struct rtmsg *rtMsg;
struct route_info stRouteInfo;
char msgBuf[BUFSIZE];
int sock, len, msgSeq = 0;
int ret = 0;
if((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0)
{
perror("Socket Creation: ");
return WV_NET_ERROR;
}
memset(msgBuf, 0, BUFSIZE);
nlMsg = (struct nlmsghdr *)msgBuf;
rtMsg = (struct rtmsg *)NLMSG_DATA(nlMsg);
nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); // Length of message.
nlMsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table .
nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; // The message is a request for dump.
nlMsg->nlmsg_seq = msgSeq++; // Sequence of the message packet.
nlMsg->nlmsg_pid = getpid(); // PID of process sending the request.
if(send(sock, nlMsg, nlMsg->nlmsg_len, 0) < 0)
{
printf("Write To Socket Failed…\n");
return WV_NET_ERROR;
}
if((len = readNlSock(sock, msgBuf, msgSeq, getpid())) < 0)
{
printf("Read From Socket Failed…\n");
return WV_NET_ERROR;
}
for(;NLMSG_OK(nlMsg,len);nlMsg = NLMSG_NEXT(nlMsg,len))
{
memset(&stRouteInfo, 0, sizeof(struct route_info));
ret = parseRoutes(nlMsg, &stRouteInfo);
if(0 != ret)
{
continue;
}
//比较eth_name
if(0 == strcmp(eth_name, stRouteInfo.ifName))
{
*gateway = stRouteInfo.gateWay;
break;
}
else
{
ret = WV_NET_ERROR;
}
}
if(ret < 0)
{
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "Error: Can't get %s: gate way", eth_name);
}
close(sock);
return ret;
}