MOD aaa-12 增加设置ipv6地址功能,增加获取接口物理属性功能

SOL    增加设置ipv6地址功能,增加获取接口物理属性功能
修改人:zhangliang
检视人:zhangliang
This commit is contained in:
zhanglianghy 2019-09-19 17:26:25 +08:00
parent 0bb5361a12
commit acb603cb9b
9 changed files with 1005 additions and 331 deletions

View File

@ -4,7 +4,7 @@
#include "config_manager.h" #include "config_manager.h"
/* error no, 32位前16位为模块ID后16位为模块错误码 */ /* error no, 32位前16位为模块ID后16位为模块错误码 */
typedef uint ret_code; typedef unsigned int ret_code;
/*0x00000000 ~ 0x0000ffff 为系统预留错误码,用于一般性系统错误, /*0x00000000 ~ 0x0000ffff 为系统预留错误码,用于一般性系统错误,
@ -28,43 +28,35 @@ typedef uint ret_code;
#define RET_SENDERR 13 #define RET_SENDERR 13
#define RET_NOCMID 14 #define RET_NOCMID 14
#define RET_SRCERR 15 #define RET_SRCERR 15
#define RET_JSONERR 16
/* NETCONFIG_MODULE 0x00010000 ~ 0x0001ffff*/ /* NETCONFIG_MODULE 0x00010000 ~ 0x0001ffff*/
#define RET_IPINVALID (uint)((uint)NETCONFIG_MODULE<<16|1) #define RET_IPINVALID (unsigned int)((unsigned int)NETCONFIG_MODULE<<16|1)
#define RET_BRNAMEERR (uint)((uint)NETCONFIG_MODULE<<16|2) #define RET_BRNAMEERR (unsigned int)((unsigned int)NETCONFIG_MODULE<<16|2)
/* VLANCONFIG_MODULE 0x00050000 ~ 0x0005ffff*/ /* VLANCONFIG_MODULE 0x00050000 ~ 0x0005ffff*/
#define RET_VIDNUM_INVALID (uint)((uint)VLAN_CONFIG_MODULE<<16|1) #define RET_VIDNUM_INVALID (unsigned int)((unsigned int)VLAN_CONFIG_MODULE<<16|1)
#define RET_VID_INVALID (uint)((uint)VLAN_CONFIG_MODULE<<16|2) #define RET_VID_INVALID (unsigned int)((unsigned int)VLAN_CONFIG_MODULE<<16|2)
#define RET_VID_EXIST (uint)((uint)VLAN_CONFIG_MODULE<<16|3) #define RET_VID_EXIST (unsigned int)((unsigned int)VLAN_CONFIG_MODULE<<16|3)
#define RET_VID_NOT_EXIST (uint)((uint)VLAN_CONFIG_MODULE<<16|4) #define RET_VID_NOT_EXIST (unsigned int)((unsigned int)VLAN_CONFIG_MODULE<<16|4)
#define RET_INTERFACE_NOT_EXIST (uint)((uint)VLAN_CONFIG_MODULE<<16|5) #define RET_INTERFACE_NOT_EXIST (unsigned int)((unsigned int)VLAN_CONFIG_MODULE<<16|5)
#define RET_ATTR_INVALID (uint)((uint)VLAN_CONFIG_MODULE<<16|6) #define RET_ATTR_INVALID (unsigned int)((unsigned int)VLAN_CONFIG_MODULE<<16|6)
#define RET_OPTYPE_ERR (uint)((uint)VLAN_CONFIG_MODULE<<16|7) #define RET_OPTYPE_ERR (unsigned int)((unsigned int)VLAN_CONFIG_MODULE<<16|7)
#define RET_SYS_VCONFIG_ERR (uint)((uint)VLAN_CONFIG_MODULE<<16|8) #define RET_SYS_VCONFIG_ERR (unsigned int)((unsigned int)VLAN_CONFIG_MODULE<<16|8)
#define RET_SYS_IFCONFIG_ERR (uint)((uint)VLAN_CONFIG_MODULE<<16|9) #define RET_SYS_IFCONFIG_ERR (unsigned int)((unsigned int)VLAN_CONFIG_MODULE<<16|9)
#define RET_SYS_FILEOP_ERR (uint)((uint)VLAN_CONFIG_MODULE<<16|10) #define RET_SYS_FILEOP_ERR (unsigned int)((unsigned int)VLAN_CONFIG_MODULE<<16|10)
/* STATIC_ROUTING_MODULE 0x00090000 ~ 0x0009ffff*/ /* STATIC_ROUTING_MODULE 0x00090000 ~ 0x0009ffff*/
#define RET_OPEN_FILE_ERR (uint)((uint)STATIC_ROUTING_CONFIG_MODULE<<16|1) #define RET_OPEN_FILE_ERR (unsigned int)((unsigned int)STATIC_ROUTING_CONFIG_MODULE<<16|1)
#define RET_EXEC_ERR (uint)((uint)STATIC_ROUTING_CONFIG_MODULE<<16|2) #define RET_EXEC_ERR (unsigned int)((unsigned int)STATIC_ROUTING_CONFIG_MODULE<<16|2)
#define RET_METRIC_ERR (uint)((uint)STATIC_ROUTING_CONFIG_MODULE<<16|3) #define RET_METRIC_ERR (unsigned int)((unsigned int)STATIC_ROUTING_CONFIG_MODULE<<16|3)
#define RET_NETMASK_ERR (uint)((uint)STATIC_ROUTING_CONFIG_MODULE<<16|4) #define RET_NETMASK_ERR (unsigned int)((unsigned int)STATIC_ROUTING_CONFIG_MODULE<<16|4)
#define RET_EMPTY_STRING (uint)((uint)STATIC_ROUTING_CONFIG_MODULE<<16|5) #define RET_EMPTY_STRING (unsigned int)((unsigned int)STATIC_ROUTING_CONFIG_MODULE<<16|5)
#define RET_WRONG_TYPE (uint)((uint)STATIC_ROUTING_CONFIG_MODULE<<16|6) #define RET_WRONG_TYPE (unsigned int)((unsigned int)STATIC_ROUTING_CONFIG_MODULE<<16|6)
#define RET_VERSION_ERR (uint)((uint)STATIC_ROUTING_CONFIG_MODULE<<16|7) #define RET_VERSION_ERR (unsigned int)((unsigned int)STATIC_ROUTING_CONFIG_MODULE<<16|7)
#define RET_DESTIP_ERR (uint)((uint)STATIC_ROUTING_CONFIG_MODULE<<16|8) #define RET_DESTIP_ERR (unsigned int)((unsigned int)STATIC_ROUTING_CONFIG_MODULE<<16|8)
#define RET_GATEWAY_ERR (uint)((uint)STATIC_ROUTING_CONFIG_MODULE<<16|9) #define RET_GATEWAY_ERR (unsigned int)((unsigned int)STATIC_ROUTING_CONFIG_MODULE<<16|9)
#define RET_GW_DEV_ERR (uint)((uint)STATIC_ROUTING_CONFIG_MODULE<<16|10) #define RET_GW_DEV_ERR (unsigned int)((unsigned int)STATIC_ROUTING_CONFIG_MODULE<<16|10)
#define ERR_STR_LEN 64 #define ERR_STR_LEN 64
@ -87,6 +79,7 @@ typedef uint ret_code;
{ RET_SENDERR, "SendErr"},\ { RET_SENDERR, "SendErr"},\
{ RET_NOCMID, "CanNotFindConfig"},\ { RET_NOCMID, "CanNotFindConfig"},\
{ RET_SRCERR, "ConfigSourceErr"},\ { RET_SRCERR, "ConfigSourceErr"},\
{ RET_JSONERR, "JsonFormatErr"},\
\ \
{ RET_IPINVALID, "IpInvalid"},\ { RET_IPINVALID, "IpInvalid"},\
{ RET_BRNAMEERR, "BrNameInvalid"},\ { RET_BRNAMEERR, "BrNameInvalid"},\

View File

@ -50,6 +50,7 @@ BEGIN_DECLS
typedef int boolean; typedef int boolean;
typedef unsigned int uint; typedef unsigned int uint;
typedef unsigned short uint16;
typedef unsigned long long uint64; typedef unsigned long long uint64;
typedef unsigned char uchar; typedef unsigned char uchar;

View File

@ -72,6 +72,15 @@ do { \
}\ }\
} while (0) } while (0)
#define ASSERT_COND(COND) \
do { \
if (COND) \
{\
rpc_log_error("cond errors\n");\
return RET_ERR;\
}\
} while (0)
#define ASSERT_RET(ret) \ #define ASSERT_RET(ret) \
do { \ do { \
if (ret != RET_OK) \ if (ret != RET_OK) \
@ -100,6 +109,15 @@ do { \
}\ }\
} while (0) } while (0)
#define ASSERT_CONTINUE(ret) \
do { \
if (ret != RET_OK) \
{\
rpc_log_error("ret error: %s\n", rpc_code_format(ret));\
continue;\
}\
} while (0)
#define ASSERT_RET_NO(ret) \ #define ASSERT_RET_NO(ret) \
do { \ do { \
if (ret != RET_OK) \ if (ret != RET_OK) \

View File

@ -11,9 +11,12 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <net/if.h> #include <net/if.h>
#include <linux/ethtool.h>
#include <linux/sockios.h>
#define MAX_IF_NUM 32 #define MAX_IF_NUM 32
#define DOT_IP_STR 32 #define DOT_IP_STR 32
#define IF_INFO_STR 32
#define INTERFACE_NAMSIZ 20 #define INTERFACE_NAMSIZ 20
/* Max bit/byte length of IPv4 address. */ /* Max bit/byte length of IPv4 address. */
@ -33,6 +36,9 @@
#define IPV4_MC_LINKLOCAL(a) ((((uint)(a)) & 0xffffff00) == 0xe0000000) #define IPV4_MC_LINKLOCAL(a) ((((uint)(a)) & 0xffffff00) == 0xe0000000)
#define IPV4_ADDR_SAME(A,B) ipv4_addr_same((A), (B)) #define IPV4_ADDR_SAME(A,B) ipv4_addr_same((A), (B))
#define IPV6_MAX_PREFIXLEN 128
#define IPV6_DEFAULT_PREFIXLEN 64
static inline boolean ipv4_addr_same(const struct in_addr *a, static inline boolean ipv4_addr_same(const struct in_addr *a,
const struct in_addr *b) const struct in_addr *b)
{ {
@ -59,6 +65,15 @@ static inline int ipv4_martian(struct in_addr *addr)
return FALSE; return FALSE;
} }
static inline int ipv6_martian(struct in6_addr *ip)
{
if (IN6_IS_ADDR_LOOPBACK(ip) || IN6_IS_ADDR_LINKLOCAL(ip) || IN6_IS_ADDR_MULTICAST(ip))
{
return TRUE;
}
return FALSE;
}
/* 配置消息 */ /* 配置消息 */
struct _ip_config_str { struct _ip_config_str {
@ -66,6 +81,7 @@ struct _ip_config_str {
uchar family; uchar family;
uchar prefixlen; uchar prefixlen;
struct in_addr prefix __attribute__((aligned(8))); struct in_addr prefix __attribute__((aligned(8)));
struct in6_addr prefix6 __attribute__((aligned(8)));
}; };
struct _ip_config_string { struct _ip_config_string {
@ -79,6 +95,38 @@ struct _ip_config_string {
typedef struct _ip_config_str ip_config_t; typedef struct _ip_config_str ip_config_t;
typedef struct _ip_config_string ip_config_string_t; typedef struct _ip_config_string ip_config_string_t;
struct _if_v4addr_str {
char addr[DOT_IP_STR];
int prefixlen;
};
typedef struct _if_v4addr_str if_v4addr_t;
struct _if_v6addr_str {
char addr[DOT_IP_STR];
int prefixlen;
};
typedef struct _if_v6addr_str if_v6addr_t;
struct _if_count_str {
char rcv_packets[IF_INFO_STR];
char snd_packets[IF_INFO_STR];
char rcv_bytes[IF_INFO_STR];
char snd_bytes[IF_INFO_STR];
};
typedef struct _if_count_str if_cnt_t;
struct _if_info_str {
char ifname[INTERFACE_NAMSIZ];
char maxspeed[IF_INFO_STR];
char hwaddr[IF_INFO_STR];
char state[IF_INFO_STR];
if_v4addr_t ipv4;
if_v6addr_t ipv6;
if_cnt_t stats;
};
typedef struct _if_info_str if_info_t;
/* 业务模块函数声明 */ /* 业务模块函数声明 */
/* ip config */ /* ip config */

View File

@ -4,7 +4,19 @@
#include "brconfig.h" #include "brconfig.h"
#define PORT_MAX_VLAN (10) #define PORT_MAX_VLAN (10)
/* CMDs currently supported */
#define ETHTOOL_GSET 0x00000001 /* DEPRECATED, Get settings.
* Please use ETHTOOL_GLINKSETTINGS*/
#define ETHTOOL_GLINK 0x0000000a
#define ETHTOOL_GLINKSETTINGS 0x0000004c /* Get ethtool_link_settings */
/*#ifndef SIOCETHTOOL
#define SIOCETHTOOL 0x8946
#endif*/
#define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32 (127)
#define ETHTOOL_DECLARE_LINK_MODE_MASK(name) \
uint name[ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32]
/* 事件通知数据结构 */ /* 事件通知数据结构 */
struct _net_ifnum { struct _net_ifnum {
int wan_num; int wan_num;
@ -12,14 +24,140 @@ struct _net_ifnum {
}; };
typedef struct _net_ifnum net_ifnum_t; typedef struct _net_ifnum net_ifnum_t;
ret_code if_ioctl(unsigned long request, caddr_t ifreq, int *ret);
#if 0
struct _ethtool_value {
uint cmd;
uint data;
};
typedef struct _ethtool_value ethtool_value_t;
struct ethtool_cmd {
uint cmd;
uint supported;
uint advertising;
uint16 speed;
uchar duplex;
uchar port;
uchar phy_address;
uchar transceiver;
uchar autoneg;
uchar mdio_support;
uint maxtxpkt;
uint maxrxpkt;
uint16 speed_hi;
uchar eth_tp_mdix;
uchar eth_tp_mdix_ctrl;
uint lp_advertising;
uint reserved[2];
};
struct ethtool_link_settings {
uint cmd;
uint speed;
uchar duplex;
uchar port;
uchar phy_address;
uchar autoneg;
uchar mdio_support;
uchar eth_tp_mdix;
uchar eth_tp_mdix_ctrl;
uchar link_mode_masks_nwords;
uchar transceiver;
uchar reserved1[3];
uint reserved[7];
uint link_mode_masks[0];
};
#endif
struct ethtool_link_data{
struct ethtool_link_settings req;
uint link_mode_data[3 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32];
};
struct user_net_device_stats {
unsigned long long rx_packets; /* total packets received */
unsigned long long tx_packets; /* total packets transmitted */
unsigned long long rx_bytes; /* total bytes received */
unsigned long long tx_bytes; /* total bytes transmitted */
unsigned long rx_errors; /* bad packets received */
unsigned long tx_errors; /* packet transmit problems */
unsigned long rx_dropped; /* no space in linux buffers */
unsigned long tx_dropped; /* no space available in linux */
unsigned long rx_multicast; /* multicast packets received */
unsigned long rx_compressed;
unsigned long tx_compressed;
unsigned long collisions;
/* detailed rx_errors: */
unsigned long rx_length_errors;
unsigned long rx_over_errors; /* receiver ring buff overflow */
unsigned long rx_crc_errors; /* recved pkt with crc error */
unsigned long rx_frame_errors; /* recv'd frame alignment error */
unsigned long rx_fifo_errors; /* recv'r fifo overrun */
unsigned long rx_missed_errors; /* receiver missed packet */
/* detailed tx_errors */
unsigned long tx_aborted_errors;
unsigned long tx_carrier_errors;
unsigned long tx_fifo_errors;
unsigned long tx_heartbeat_errors;
unsigned long tx_window_errors;
};
struct interface {
struct interface *next, *prev;
char name[IFNAMSIZ]; /* interface name */
short type; /* if type */
short flags; /* various flags */
int metric; /* routing metric */
int mtu; /* MTU value */
int tx_queue_len; /* transmit queue length */
struct ifmap map; /* hardware setup */
struct sockaddr addr; /* IP address */
struct sockaddr dstaddr; /* P-P IP address */
struct sockaddr broadaddr; /* IP broadcast address */
struct sockaddr netmask; /* IP network mask */
struct sockaddr ipxaddr_bb; /* IPX network address */
struct sockaddr ipxaddr_sn; /* IPX network address */
struct sockaddr ipxaddr_e3; /* IPX network address */
struct sockaddr ipxaddr_e2; /* IPX network address */
struct sockaddr ddpaddr; /* Appletalk DDP address */
struct sockaddr ecaddr; /* Econet address */
int has_ip;
int has_ipx_bb;
int has_ipx_sn;
int has_ipx_e3;
int has_ipx_e2;
int has_ax25;
int has_ddp;
int has_econet;
char hwaddr[32]; /* HW address */
int statistics_valid;
struct user_net_device_stats stats; /* statistics */
int keepalive; /* keepalive value for SLIP */
int outfill; /* outfill value for SLIP */
};
void masklen2ip(const int masklen, struct in_addr *netmask);
uchar ip_masklen(struct in_addr netmask);
ret_code if_ioctl(int af, unsigned long request, caddr_t ifreq, int *ret);
ret_code if_get_linkstat(if_info_t *if_info, int *code);
ret_code if_get_maxspeed(if_info_t *if_info, int *code);
ret_code if_get_hwaddr(if_info_t *if_info, int *code);
ret_code if_set_up(char *ifname, int *code); ret_code if_set_up(char *ifname, int *code);
ret_code if_set_down(char *ifname, int *code); ret_code if_set_down(char *ifname, int *code);
ret_code if_set_prefix(ip_config_t *ip_conf, int *code);
ret_code if_set_prefix6(uint config_type, ip_config_t *ip_conf, int *code);
ret_code if_get_prefix(if_info_t *if_conf, int *code);
ret_code if_num_init(); ret_code if_num_init();
ret_code net_main();
int if_lan_num(); int if_lan_num();
int if_wan_num(); int if_wan_num();
int if_wan_get(char ifname[MAX_IF_NUM][INTERFACE_NAMSIZ], int max_port); int if_wan_get(char ifname[MAX_IF_NUM][INTERFACE_NAMSIZ], int max_port);
int if_lan_get(char ifname[MAX_IF_NUM][INTERFACE_NAMSIZ], int max_port); int if_lan_get(char ifname[MAX_IF_NUM][INTERFACE_NAMSIZ], int max_port);
ret_code net_main(); int if_get_allport(struct ifreq *ifreq, int max_port);
#endif #endif

View File

@ -5,9 +5,11 @@
#include "rpc_common.h" #include "rpc_common.h"
#include "ipconfig.h"
#define PROC_NET_DEV "/proc/net/dev" #define PROC_NET_DEV "/proc/net/dev"
#define ETC_NETWORK_IFS "/etc/network/interfaces" #define ETC_NETWORK_IFS "/etc/network/interfaces"
#define ETC_PRODUCT "/etc/product.conf" #define ETC_PRODUCT "/etc/product.conf"
#define PROC_NET_IFINET6 "/proc/net/if_inet6"
#define IF_BUFF_LEN 128 #define IF_BUFF_LEN 128
@ -17,10 +19,14 @@ ret_code if_conf_file_set(char *if_name, char *conf_name, char *conf_buff);
ret_code if_conf_file_get(char *if_name, char *conf_name, char *conf_buff); ret_code if_conf_file_get(char *if_name, char *conf_name, char *conf_buff);
void ip_conf_file_set(char *if_name, char *conf_name, char *conf_buff); void ip_conf_file_set(char *if_name, char *conf_name, char *conf_buff);
void ipv6_conf_file_set(char *if_name, char *conf_name, char *conf_buff);
void ip_conf_file_del(char *if_name, char *conf_buff); void ip_conf_file_del(char *if_name, char *conf_buff);
void ipv6_conf_file_del(char *if_name, char *conf_buff);
ret_code del_sub_string(char *str_in,char *str_sub); ret_code del_sub_string(char *str_in,char *str_sub);
int if_read_dev_file(struct ifreq *ifcfg, int max_port); int if_read_dev_file(struct ifreq *ifcfg, int max_port);
int if_read_stats_file(if_info_t *if_info);
int if_read_conf_file(struct ifreq *ifcfg, int max_port); int if_read_conf_file(struct ifreq *ifcfg, int max_port);
ret_code if_role_file_get(char *if_name, char *conf_buff); ret_code if_role_file_get(char *if_name, char *conf_buff);

View File

@ -16,10 +16,38 @@
#include "netconfig.h" #include "netconfig.h"
#include "parsefile.h" #include "parsefile.h"
#ifndef _LINUX_IN6_H
/*
* This is in linux/include/net/ipv6.h.
*/
struct in6_ifreq {
struct in6_addr ifr6_addr;
uint ifr6_prefixlen;
unsigned int ifr6_ifindex;
};
#endif
net_ifnum_t g_if_num = {.wan_num = 2, .lan_num = 4}; net_ifnum_t g_if_num = {.wan_num = 2, .lan_num = 4};
/* Display an Ethernet address in readable format. */
static void print_ether(char *buff, unsigned char *ptr)
{
snprintf(buff, 32, "%02X:%02X:%02X:%02X:%02X:%02X",
(ptr[0] & 0377), (ptr[1] & 0377), (ptr[2] & 0377),
(ptr[3] & 0377), (ptr[4] & 0377), (ptr[5] & 0377)
);
}
#if 0
static uint ethtool_cmd_speed(const struct ethtool_cmd *ep)
{
return (ep->speed_hi << 16) | ep->speed;
}
#endif
/* call ioctl system call */ /* call ioctl system call */
ret_code if_ioctl(unsigned long request, caddr_t ifreq, int *ret) ret_code if_ioctl(int af, unsigned long request, caddr_t ifreq, int *ret)
{ {
int sock; int sock;
int err = 0; int err = 0;
@ -29,7 +57,7 @@ ret_code if_ioctl(unsigned long request, caddr_t ifreq, int *ret)
*ret = 0; *ret = 0;
} }
sock = socket(AF_INET, SOCK_DGRAM, 0); sock = socket(af, SOCK_DGRAM, 0);
if (sock < 0) if (sock < 0)
{ {
rpc_log_error("Cannot create UDP socket"); rpc_log_error("Cannot create UDP socket");
@ -55,6 +83,152 @@ ret_code if_ioctl(unsigned long request, caddr_t ifreq, int *ret)
return RET_OK; return RET_OK;
} }
/* call ioctl system call */
ret_code if_ethctl(char *name, void *cmd, int *ret)
{
struct ifreq ifr = {0};
int sock;
int err = 0;
if(ret)
{
*ret = 0;
}
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
{
rpc_log_error("Cannot create UDP socket");
return RET_SYSERR;
}
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1);
ifr.ifr_data = cmd;
if ((err = ioctl(sock, SIOCETHTOOL, &ifr)) < 0)
{
rpc_log_error("Ioctl error: %s\n", strerror(errno));
}
close(sock);
if (err < 0)
{
if(ret)
{
*ret = err;
}
return RET_SYSERR;
}
return RET_OK;
}
ret_code if_get_linksetting(if_info_t *if_info, int *code)
{
ret_code ret = RET_OK;
struct ethtool_link_data ecmd;
unsigned int u32_offs;
/* Handshake with kernel to determine number of words for link
* mode bitmaps. When requested number of bitmap words is not
* the one expected by kernel, the latter returns the integer
* opposite of what it is expecting. We request length 0 below
* (aka. invalid bitmap length) to get this info.
*/
memset(&ecmd, 0, sizeof(ecmd));
ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
ret = if_ethctl(if_info->ifname, &ecmd, code);
ASSERT_RET(ret);
/* see above: we expect a strictly negative value from kernel.
*/
ASSERT_COND(ecmd.req.link_mode_masks_nwords >= 0
|| ecmd.req.cmd != ETHTOOL_GLINKSETTINGS);
/* got the real ecmd.req.link_mode_masks_nwords,
* now send the real request
*/
ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords;
ret = if_ethctl(if_info->ifname, &ecmd, code);
ASSERT_RET(ret);
ASSERT_COND(ecmd.req.link_mode_masks_nwords <= 0
|| ecmd.req.cmd != ETHTOOL_GLINKSETTINGS);
sprintf(if_info->maxspeed, "%uMb/s", ecmd.req.speed);
return ret;
}
ret_code if_get_setting(if_info_t *if_info, int *code)
{
ret_code ret = RET_OK;
struct ethtool_cmd ecmd;
memset(&ecmd, 0, sizeof(ecmd));
ecmd.cmd = ETHTOOL_GSET;
ret = if_ethctl(if_info->ifname, &ecmd, code);
ASSERT_RET(ret);
sprintf(if_info->maxspeed, "%uMb/s", ethtool_cmd_speed(&ecmd));
return ret;
}
ret_code if_get_linkstat(if_info_t *if_info, int *code)
{
struct ethtool_value edata = {0};
ret_code ret = RET_OK;
edata.cmd = ETHTOOL_GLINK;
ret = if_ethctl(if_info->ifname, &edata, code);
ASSERT_RET(ret);
if(edata.data)
{
strcpy(if_info->state, "up");
}
else
{
strcpy(if_info->state, "down");
}
return ret;
}
ret_code if_get_maxspeed(if_info_t *if_info, int *code)
{
ret_code ret = RET_OK;
ret = if_get_linksetting(if_info, code);
if(ret != RET_OK)
{
ret = if_get_setting(if_info, code);
}
ASSERT_RET(ret);
return ret;
}
ret_code if_get_hwaddr(if_info_t *if_info, int *code)
{
struct ifreq ifr = {0};
ret_code ret = RET_OK;
strncpy(ifr.ifr_name, if_info->ifname, sizeof(ifr.ifr_name) - 1);
ret = if_ioctl(AF_INET, SIOCGIFHWADDR, (caddr_t)&ifr, code);
ASSERT_RET(ret);
print_ether(if_info->hwaddr, ifr.ifr_hwaddr.sa_data);
return ret;
}
/* Set a certain interface flag. */ /* Set a certain interface flag. */
static int if_set_flag(char *ifname, short flag, int *code) static int if_set_flag(char *ifname, short flag, int *code)
@ -64,13 +238,13 @@ static int if_set_flag(char *ifname, short flag, int *code)
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
ret = if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifr, code); ret = if_ioctl(AF_INET, SIOCGIFFLAGS, (caddr_t)&ifr, code);
ASSERT_RET(ret); ASSERT_RET(ret);
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
ifr.ifr_flags |= flag; ifr.ifr_flags |= flag;
ret = if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifr, code); ret = if_ioctl(AF_INET, SIOCSIFFLAGS, (caddr_t)&ifr, code);
ASSERT_RET(ret); ASSERT_RET(ret);
return ret; return ret;
@ -85,13 +259,13 @@ static int if_clear_flag(char *ifname, short flag, int *code)
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
ret = if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifr, code); ret = if_ioctl(AF_INET, SIOCGIFFLAGS, (caddr_t)&ifr, code);
ASSERT_RET(ret); ASSERT_RET(ret);
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
ifr.ifr_flags &= ~flag; ifr.ifr_flags &= ~flag;
ret = if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifr, code); ret = if_ioctl(AF_INET, SIOCSIFFLAGS, (caddr_t)&ifr, code);
ASSERT_RET(ret); ASSERT_RET(ret);
return ret; return ret;
@ -107,6 +281,170 @@ ret_code if_set_down(char *ifname, int *code)
return if_clear_flag(ifname, IFF_UP, code); return if_clear_flag(ifname, IFF_UP, code);
} }
int if_get_allport(struct ifreq *ifreq, int max_port)
{
ret_code ret = RET_OK;
struct ifconf ifc;
int if_count;
int code;
if_count = if_read_dev_file(ifreq, max_port);
if(if_count == 0)
{
memset(&ifc, 0, sizeof(struct ifconf));
ifc.ifc_len = max_port * sizeof(struct ifreq);
ifc.ifc_buf = (char *)ifreq;
ret = if_ioctl(AF_INET, SIOCGIFCONF, (caddr_t)&ifc, &code);
ASSERT_RET(ret);
if_count = ifc.ifc_len / (sizeof(struct ifreq));
}
return if_count;
}
ret_code if_set_prefix(ip_config_t *ip_conf, int *code)
{
ret_code ret;
struct ifreq ifreq = {0};
struct sockaddr_in addr;
struct sockaddr_in mask;
strncpy(ifreq.ifr_name, ip_conf->ifname, sizeof(ifreq.ifr_name) - 1);
addr.sin_addr = ip_conf->prefix;
addr.sin_family = ip_conf->family;
memcpy(&ifreq.ifr_addr, &addr, sizeof(struct sockaddr_in));
ret = if_ioctl(AF_INET, SIOCSIFADDR, (caddr_t)&ifreq, code);
ASSERT_RET(ret);
if(ip_conf->prefix.s_addr != 0)
{
masklen2ip(ip_conf->prefixlen, &mask.sin_addr);
mask.sin_family = ip_conf->family;
memcpy(&ifreq.ifr_netmask, &mask, sizeof(struct sockaddr_in));
ret = if_ioctl(AF_INET, SIOCSIFNETMASK, (caddr_t)&ifreq, code);
ASSERT_RET(ret);
}
return RET_OK;
}
ret_code if_set_prefix6(uint config_type, ip_config_t *ip_conf, int *code)
{
ret_code ret = RET_OK;
struct ifreq ifr = {0};
struct in6_ifreq ifr6 = {0};
strncpy(ifr.ifr_name, ip_conf->ifname, sizeof(ifr.ifr_name) - 1);
ret = if_ioctl(AF_INET, SIOGIFINDEX, (caddr_t)&ifr, code);
ASSERT_RET(ret);
ifr6.ifr6_ifindex = ifr.ifr_ifindex;
ifr6.ifr6_prefixlen = ip_conf->prefixlen;
memcpy((char *) &ifr6.ifr6_addr, &(ip_conf->prefix6), sizeof(struct in6_addr));
if(config_type == CM_CONFIG_SET)
{
ret = if_ioctl(AF_INET6, SIOCSIFADDR, (caddr_t)&ifr6, code);
}
else if(config_type == CM_CONFIG_DEL)
{
ret = if_ioctl(AF_INET6, SIOCDIFADDR, (caddr_t)&ifr6, code);
}
ASSERT_RET(ret);
return RET_OK;
}
ret_code if_get_prefix(if_info_t *if_conf, int *code)
{
struct sockaddr_in *addr;
struct ifreq ifreq;
ret_code ret = RET_OK;
int mask_ret;
memset(&ifreq, 0, sizeof(struct ifreq));
rpc_log_info("get interface %s info\n", if_conf->ifname);
strncpy(ifreq.ifr_name, if_conf->ifname, sizeof(ifreq.ifr_name) - 1);
ret = if_ioctl(AF_INET, SIOCGIFADDR, (caddr_t)&ifreq, code);
ASSERT_RET(ret);
strcpy(if_conf->ipv4.addr, inet_ntoa(((struct sockaddr_in *)&(ifreq.ifr_addr))->sin_addr));
memset(&ifreq, 0, sizeof(ifreq));
strncpy(ifreq.ifr_name, if_conf->ifname, sizeof(ifreq.ifr_name) - 1);
ret = if_ioctl(AF_INET, SIOCGIFNETMASK, (caddr_t)&ifreq, &mask_ret);
ASSERT_RET_NO(ret);
addr = ( struct sockaddr_in * )&(ifreq.ifr_netmask);
if_conf->ipv4.prefixlen = ip_masklen(addr->sin_addr);
return ret;
}
#if 0
ret_code if_get_prefix6(if_info_t *if_conf, int *code)
{
FILE *f;
char addr6[40], devname[20];
struct sockaddr_in6 sap;
int plen, scope, dad_status, if_idx;
char addr6p[8][5];
/* FIXME: should be integrated into interface.c. */
if ((f = fopen(PROC_NET_IFINET6, "r")) != NULL) {
while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
addr6p[0], addr6p[1], addr6p[2], addr6p[3],
addr6p[4], addr6p[5], addr6p[6], addr6p[7],
&if_idx, &plen, &scope, &dad_status, devname) != EOF) {
if (!strcmp(devname, if_conf->ifname)) {
sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
addr6p[0], addr6p[1], addr6p[2], addr6p[3],
addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
inet6_aftype.input(1, addr6, (struct sockaddr *) &sap);
printf(_(" inet6 addr: %s/%d"),
inet6_aftype.sprint((struct sockaddr *) &sap, 1), plen);
printf(_(" Scope:"));
switch (scope) {
case 0:
printf(_("Global"));
break;
case IPV6_ADDR_LINKLOCAL:
printf(_("Link"));
break;
case IPV6_ADDR_SITELOCAL:
printf(_("Site"));
break;
case IPV6_ADDR_COMPATv4:
printf(_("Compat"));
break;
case IPV6_ADDR_LOOPBACK:
printf(_("Host"));
break;
default:
printf(_("Unknown"));
}
printf("\n");
}
}
fclose(f);
}
}
#endif
int if_lan_num() int if_lan_num()
{ {
return g_if_num.lan_num; return g_if_num.lan_num;

View File

@ -36,6 +36,32 @@ void masklen2ip(const int masklen, struct in_addr *netmask)
htonl(masklen ? 0xffffffffU << (32 - masklen) : 0); htonl(masklen ? 0xffffffffU << (32 - masklen) : 0);
} }
static ret_code ip_inet6_pton(char *bufp, struct in6_addr *dst)
{
struct sockaddr_in6 sin6 = {0};
sin6.sin6_family = AF_INET6;
sin6.sin6_port = 0;
if (inet_pton(AF_INET6, bufp, sin6.sin6_addr.s6_addr) <= 0)
{
return RET_ERR;
}
memcpy((char *) dst, (char *) &sin6.sin6_addr, sizeof(struct in6_addr));
return RET_OK;
}
static char *ip_inet6_print(struct in6_addr *ptr)
{
static char name[80] = {0};
inet_ntop(AF_INET6, ptr, name, 80);
return name;
}
void ip_save_file(ip_config_t *ip_conf, uint config_type) void ip_save_file(ip_config_t *ip_conf, uint config_type)
{ {
char *addr_name = "address"; char *addr_name = "address";
@ -61,15 +87,37 @@ void ip_save_file(ip_config_t *ip_conf, uint config_type)
} }
} }
void ip6_save_file(ip_config_t *ip_conf, uint config_type)
{
char *addr_name = "address";
char *mask_name = "netmask";
char addr_buff[IF_BUFF_LEN] = {0};
char mask_buff[IF_BUFF_LEN] = {0};
if(config_type == CM_CONFIG_SET)
{
sprintf(addr_buff, "address %s\n", ip_inet6_print(&ip_conf->prefix6));
sprintf(mask_buff, "netmask %d\n", ip_conf->prefixlen);
rpc_log_info("%s %s",addr_buff, mask_buff);
ipv6_conf_file_set(ip_conf->ifname, addr_name, addr_buff);
ipv6_conf_file_set(ip_conf->ifname, mask_name, mask_buff);
}
else if(config_type == CM_CONFIG_DEL)
{
ipv6_conf_file_del(ip_conf->ifname, addr_name);
ipv6_conf_file_del(ip_conf->ifname, mask_name);
}
}
ret_code ip_config_json_parse(pointer input, uint *conf_type, ip_config_t *config_buff) ret_code ip_config_json_parse(pointer input, uint *conf_type, ip_config_t *config_buff)
{ {
//ip_config_string_t *ip_config;
cJSON *json_obj; cJSON *json_obj;
json_obj = cJSON_Parse(input); json_obj = cJSON_Parse(input);
if(!json_obj) if(!json_obj)
{ {
return RET_INPUTERR; return RET_JSONERR;
} }
rpc_json_print(json_obj); rpc_json_print(json_obj);
@ -92,7 +140,15 @@ ret_code ip_config_json_parse(pointer input, uint *conf_type, ip_config_t *confi
config_buff->family = (uchar)ip_config->family; config_buff->family = (uchar)ip_config->family;
config_buff->prefixlen = (uchar)ip_config->prefixlen; config_buff->prefixlen = (uchar)ip_config->prefixlen;
if(config_buff->family == AF_INET)
{
config_buff->prefix.s_addr = inet_addr(ip_config->ipaddr); config_buff->prefix.s_addr = inet_addr(ip_config->ipaddr);
}
else if(config_buff->family == AF_INET6)
{
ip_inet6_pton(ip_config->ipaddr, &(config_buff->prefix6));
}
if(ip_config->config_type) if(ip_config->config_type)
{ {
@ -105,265 +161,99 @@ ret_code ip_config_json_parse(pointer input, uint *conf_type, ip_config_t *confi
return RET_OK; return RET_OK;
} }
ret_code ip_config_json_parse_array(pointer input, uint *conf_type, cJSON * ip_config_format_json(if_info_t *config_buff)
ip_config_t *config_buff, int *cnt)
{ {
//ip_config_string_t *ip_config; if_v4addr_t *ipv4 = &config_buff->ipv4;
cJSON *json_obj; if_v6addr_t *ipv6 = &config_buff->ipv6;
cJSON* pArrayItem; if_cnt_t *stats = &config_buff->stats;
int iCount = 0, i = 0;
json_obj = cJSON_Parse(input);
if(!json_obj)
{
return RET_INPUTERR;
}
rpc_json_print(json_obj);
iCount = cJSON_GetArraySize(json_obj);
config_buff = rpc_new0(ip_config_t, iCount);
conf_type = rpc_new0(uint, iCount);
if(!config_buff || !conf_type)
{
return RET_NOMEM;
}
s2j_create_struct_obj(ip_config, ip_config_string_t);
if(ip_config == NULL)
{
cJSON_Delete(json_obj);
rpc_free(config_buff);
return RET_NOMEM;
}
*cnt = 0;
for(i = 0; i < iCount; i++)
{
pArrayItem = cJSON_GetArrayItem(json_obj, i);
if(pArrayItem)
{
memset(ip_config, 0, sizeof(ip_config_string_t));
s2j_struct_get_basic_element(ip_config, pArrayItem, int, config_type);
s2j_struct_get_string_element(ip_config, pArrayItem, ifname, INTERFACE_NAMSIZ);
s2j_struct_get_basic_element(ip_config, pArrayItem, int, family);
s2j_struct_get_string_element(ip_config, pArrayItem, ipaddr, DOT_IP_STR);
s2j_struct_get_basic_element(ip_config, pArrayItem, int, prefixlen);
strncpy(config_buff[*cnt].ifname, ip_config->ifname, INTERFACE_NAMSIZ - 1);
config_buff[*cnt].family = (uchar)ip_config->family;
config_buff[*cnt].prefixlen = (uchar)ip_config->prefixlen;
config_buff[*cnt].prefix.s_addr = inet_addr(ip_config->ipaddr);
conf_type[*cnt] = ip_config->config_type;
(*cnt)++;
}
}
s2j_delete_struct_obj(ip_config);
cJSON_Delete(json_obj);
return RET_OK;
}
ret_code ip_config_format_json(ip_config_t *config_buff,
pointer output, int *outlen)
{
ip_config_string_t tem_buff = {0};
ip_config_string_t *ip_config = &tem_buff;
ip_config->family = AF_INET;
ip_config->prefixlen = config_buff->prefixlen;
strncpy(ip_config->ifname, config_buff->ifname, INTERFACE_NAMSIZ - 1);
strncpy(ip_config->ipaddr, inet_ntoa(config_buff->prefix), DOT_IP_STR - 1);
s2j_create_json_obj(json_ipv4);
s2j_create_json_obj(json_ipv6);
s2j_create_json_obj(json_stats);
s2j_create_json_obj(json_obj); s2j_create_json_obj(json_obj);
if(json_obj == NULL)
{ s2j_json_set_basic_element(json_ipv4, ipv4, string, addr);
return RET_NOMEM; s2j_json_set_basic_element(json_ipv4, ipv4, int, prefixlen);
s2j_json_set_basic_element(json_ipv6, ipv6, string, addr);
s2j_json_set_basic_element(json_ipv6, ipv6, int, prefixlen);
s2j_json_set_basic_element(json_stats, stats, string, rcv_packets);
s2j_json_set_basic_element(json_stats, stats, string, rcv_bytes);
s2j_json_set_basic_element(json_stats, stats, string, snd_packets);
s2j_json_set_basic_element(json_stats, stats, string, snd_bytes);
s2j_json_set_basic_element(json_obj, config_buff, string, ifname);
s2j_json_set_basic_element(json_obj, config_buff, string, maxspeed);
s2j_json_set_basic_element(json_obj, config_buff, string, state);
s2j_json_set_basic_element(json_obj, config_buff, string, hwaddr);
cJSON_AddItemToObject(json_obj, "ipv4", json_ipv4);
cJSON_AddItemToObject(json_obj, "ipv6", json_ipv6);
cJSON_AddItemToObject(json_obj, "statistics", json_stats);
return json_obj;
} }
s2j_json_set_basic_element(json_obj, ip_config, string, ifname); ret_code if_get_info(if_info_t *if_info, int *code)
s2j_json_set_basic_element(json_obj, ip_config, int, family);
s2j_json_set_basic_element(json_obj, ip_config, string, ipaddr);
s2j_json_set_basic_element(json_obj, ip_config, int, prefixlen);
*outlen = cm_format_data(RET_OK, json_obj, output);
return RET_OK;
}
ret_code ip_config_format_json_array(ip_config_t *config_buff,
int count, pointer output,
int *outlen)
{ {
ip_config_string_t tem_buff = {0};
ip_config_string_t *ip_config = &tem_buff;
cJSON *json_array = NULL;
int i;
json_array = cJSON_CreateArray();
if(json_array == NULL)
{
return RET_NOMEM;
}
for(i = 0; i < count; i++)
{
memset(ip_config, 0, sizeof(ip_config_string_t));
ip_config->family = AF_INET;
ip_config->prefixlen = config_buff[i].prefixlen;
strncpy(ip_config->ifname, config_buff[i].ifname, INTERFACE_NAMSIZ - 1);
strncpy(ip_config->ipaddr, inet_ntoa(config_buff[i].prefix), DOT_IP_STR - 1);
s2j_create_json_obj(json_obj);
if(json_obj == NULL)
{
return RET_NOMEM;
}
s2j_json_set_basic_element(json_obj, ip_config, string, ifname);
s2j_json_set_basic_element(json_obj, ip_config, int, family);
s2j_json_set_basic_element(json_obj, ip_config, string, ipaddr);
s2j_json_set_basic_element(json_obj, ip_config, int, prefixlen);
cJSON_AddItemToArray(json_array, json_obj);
}
*outlen = cm_format_data(RET_OK, json_array, output);
return RET_OK;
}
ret_code if_set_prefix(ip_config_t *ip_conf, int *code)
{
ret_code ret;
struct ifreq ifreq = {0};
struct sockaddr_in addr;
struct sockaddr_in mask;
strncpy(ifreq.ifr_name, ip_conf->ifname, sizeof(ifreq.ifr_name) - 1);
addr.sin_addr = ip_conf->prefix;
addr.sin_family = ip_conf->family;
memcpy(&ifreq.ifr_addr, &addr, sizeof(struct sockaddr_in));
ret = if_ioctl(SIOCSIFADDR, (caddr_t)&ifreq, code);
ASSERT_RET(ret);
if(ip_conf->prefix.s_addr != 0)
{
masklen2ip(ip_conf->prefixlen, &mask.sin_addr);
mask.sin_family = ip_conf->family;
memcpy(&ifreq.ifr_netmask, &mask, sizeof(struct sockaddr_in));
ret = if_ioctl(SIOCSIFNETMASK, (caddr_t)&ifreq, code);
ASSERT_RET(ret);
}
return RET_OK;
}
ret_code if_get_prefix(ip_config_t *ip_conf, int *code)
{
struct sockaddr_in *addr;
struct ifreq ifreq;
ret_code ret = RET_OK; ret_code ret = RET_OK;
int mask_ret;
if(ip_conf->family != AF_INET)
{
ret = RET_INPUTERR;
}
ret = if_get_hwaddr(if_info, code);
ASSERT_RET(ret); ASSERT_RET(ret);
memset(&ifreq, 0, sizeof(struct ifreq)); ret = if_get_maxspeed(if_info, code);
//ASSERT_RET(ret);
rpc_log_info("get interface %s info\n", ip_conf->ifname); ret = if_get_linkstat(if_info, code);
strncpy(ifreq.ifr_name, ip_conf->ifname, sizeof(ifreq.ifr_name) - 1);
ret = if_ioctl(SIOCGIFADDR, (caddr_t)&ifreq, code);
ASSERT_RET(ret); ASSERT_RET(ret);
ret = if_get_prefix(if_info, code);
ASSERT_RET(ret);
ip_conf->prefix = ((struct sockaddr_in *)&(ifreq.ifr_addr))->sin_addr; ret = if_read_stats_file(if_info);
ASSERT_RET(ret);
memset(&ifreq, 0, sizeof(ifreq));
strncpy(ifreq.ifr_name, ip_conf->ifname, sizeof(ifreq.ifr_name) - 1);
ret = if_ioctl(SIOCGIFNETMASK, (caddr_t)&ifreq, &mask_ret);
ASSERT_RET_NO(ret);
addr = ( struct sockaddr_in * )&(ifreq.ifr_netmask);
ip_conf->prefixlen = ip_masklen(addr->sin_addr);
return ret; return ret;
} }
ret_code if_get_prefix_all(pointer output, int *output_len, int *code)
ret_code ip_config_v4chk(uint config_type, ip_config_t *ip_conf)
{ {
struct ifreq ifreq[MAX_IF_NUM]; ret_code ret = RET_OK;
ip_config_t *ip_conf;
struct ifconf ifc;
int if_count = 0;
ret_code ret;
int i;
memset(ifreq, 0, MAX_IF_NUM * sizeof(struct ifreq)); if (config_type != CM_CONFIG_DEL && ipv4_martian(&ip_conf->prefix))
if_count = if_read_dev_file(ifreq, MAX_IF_NUM);
if(if_count == 0)
{ {
memset(&ifc, 0, sizeof(struct ifconf)); ret = RET_IPINVALID;
ifc.ifc_len = MAX_IF_NUM * sizeof(struct ifreq); }
ifc.ifc_buf = (char *)ifreq;
ret = if_ioctl(SIOCGIFCONF, (caddr_t)&ifc, code);
ASSERT_RET(ret); ASSERT_RET(ret);
if_count = ifc.ifc_len / (sizeof(struct ifreq)); if(ip_conf->prefixlen == 0 || ip_conf->prefixlen > IPV4_MAX_PREFIXLEN)
{
ip_conf->prefixlen = IPV4_DEFAULT_PREFIXLEN;
} }
rpc_log_info("if num is %d\n", if_count); return ret;
}
if((if_count * sizeof(ip_config_t) > CM_BUFF_SIZE) ret_code ip_config_v6chk(uint config_type, ip_config_t *ip_conf)
|| (if_count == 0))
{ {
ret = RET_NOMEM; ret_code ret = RET_OK;
if (config_type != CM_CONFIG_DEL && ipv6_martian(&(ip_conf->prefix6)))
{
ret = RET_IPINVALID;
}
ASSERT_RET(ret); ASSERT_RET(ret);
}
ip_conf = rpc_new0(ip_config_t, MAX_IF_NUM); if(ip_conf->prefixlen == 0 || ip_conf->prefixlen > IPV6_MAX_PREFIXLEN)
if(ip_conf == NULL)
{ {
return RET_NOMEM; ip_conf->prefixlen = IPV6_DEFAULT_PREFIXLEN;
} }
for(i = 0; i < if_count; i++) return ret;
{
rpc_log_info("get interface %s info\n", ifreq[i].ifr_name);
strncpy(ip_conf[i].ifname, ifreq[i].ifr_name, INTERFACE_NAMSIZ - 1);
ip_conf[i].family = AF_INET;
if_get_prefix(&ip_conf[i], code);
}
ip_config_format_json_array(ip_conf, if_count, output, output_len);
rpc_free(ip_conf);
return RET_OK;
} }
@ -382,19 +272,17 @@ ret_code ip_config_set_chk(uint source,uint config_type,
ret = RET_INPUTERR; ret = RET_INPUTERR;
} }
if (config_type != CM_CONFIG_DEL && ipv4_martian(&ip_conf->prefix)) if(ip_conf->family == AF_INET)
{ {
ret = RET_IPINVALID; ret = ip_config_v4chk(config_type, ip_conf);
}
else if(ip_conf->family == AF_INET6)
{
ret = ip_config_v6chk(config_type, ip_conf);
} }
ASSERT_RET(ret); ASSERT_RET(ret);
if(ip_conf->prefixlen == 0 || ip_conf->prefixlen > IPV4_MAX_PREFIXLEN)
{
ip_conf->prefixlen = IPV4_DEFAULT_PREFIXLEN;
}
return RET_OK; return RET_OK;
} }
@ -403,15 +291,16 @@ ret_code ip_config_get_chk(uint source,uint config_type,
pointer output, int *output_len) pointer output, int *output_len)
{ {
ret_code ret = RET_OK; ret_code ret = RET_OK;
ip_config_t *ip_conf; ip_config_t *ip_config;
ip_conf = (ip_config_t *)input; ip_config = (ip_config_t *)input;
if(input_len < sizeof(ip_config_t) if(input_len < sizeof(ip_config_t)
|| strlen(ip_conf->ifname) == 0 ) || strlen(ip_config->ifname) == 0 )
{ {
ret = RET_INPUTERR; ret = RET_INPUTERR;
} }
ASSERT_RET(ret);
return ret; return ret;
} }
@ -426,6 +315,7 @@ ret_code ip_config_getall_chk(uint source,uint config_type,
{ {
ret = RET_INPUTERR; ret = RET_INPUTERR;
} }
ASSERT_RET(ret);
return ret; return ret;
} }
@ -442,7 +332,8 @@ ret_code ip_config_chk(uint source,uint *config_type,
ret_code ret = RET_OK; ret_code ret = RET_OK;
int code = 0; int code = 0;
ip_config_json_parse(input, &conf_type, &ip_config); ret = ip_config_json_parse(input, &conf_type, &ip_config);
ASSERT_RET(ret);
switch (conf_type) switch (conf_type)
{ {
@ -484,6 +375,16 @@ ret_code ip_config_chk(uint source,uint *config_type,
return ret; return ret;
} }
/*
ipv4地址
{"config_type":3,"ifname":"br0","family":2,"ipaddr":"192.168.3.1","prefixlen":16}
ipv6地址
{"config_type":3,"ifname":"br0","family":10,"ipaddr":"2001::1","prefixlen":64}
ipv4地址
{"config_type":2,"ifname":"br0","family":2,"ipaddr":"192.168.3.1","prefixlen":16}
ipv6地址
{"config_type":2,"ifname":"br0","family":10,"ipaddr":"2001::1","prefixlen":64}
*/
ret_code ip_config_proc(uint source, uint config_type, ret_code ip_config_proc(uint source, uint config_type,
pointer input, int input_len, pointer input, int input_len,
pointer output, int *output_len) pointer output, int *output_len)
@ -498,55 +399,131 @@ ret_code ip_config_proc(uint source, uint config_type,
if(conf_type == CM_CONFIG_DEL) if(conf_type == CM_CONFIG_DEL)
{ {
ip_conf->prefix.s_addr = 0; ip_conf->prefix.s_addr = 0;
ip_conf->prefixlen = IPV4_DEFAULT_PREFIXLEN;
} }
if(ip_conf->family == AF_INET)
{
rpc_log_info("config type is %d, if %s ip %s prefixlen %d\n", rpc_log_info("config type is %d, if %s ip %s prefixlen %d\n",
conf_type, ip_conf->ifname, conf_type, ip_conf->ifname,
inet_ntoa(ip_conf->prefix), inet_ntoa(ip_conf->prefix),
ip_conf->prefixlen); ip_conf->prefixlen);
ip_conf->prefixlen = IPV4_DEFAULT_PREFIXLEN;
ret = if_set_prefix(ip_conf, &code); ret = if_set_prefix(ip_conf, &code);
RET_ERR_FORMART(ret, code, output, *output_len); RET_ERR_FORMART(ret, code, output, *output_len);
ASSERT_RET(ret); ASSERT_RET(ret);
ip_save_file(ip_conf, conf_type); ip_save_file(ip_conf, conf_type);
}
else if(ip_conf->family == AF_INET6)
{
rpc_log_info("config type is %d, if %s ip %s prefixlen %d\n",
conf_type, ip_conf->ifname,
ip_inet6_print(&(ip_conf->prefix6)),
ip_conf->prefixlen);
ip_conf->prefixlen = IPV6_DEFAULT_PREFIXLEN;
ret = if_set_prefix6(conf_type, ip_conf, &code);
RET_ERR_FORMART(ret, code, output, *output_len);
ASSERT_RET(ret);
ip6_save_file(ip_conf, conf_type);
}
return RET_OK; return RET_OK;
} }
/*{"config_type":4,"ifname":"br0"}*/
ret_code ip_config_get(uint source, ret_code ip_config_get(uint source,
pointer input, int input_len, pointer input, int input_len,
pointer output, int *output_len) pointer output, int *output_len)
{ {
ip_config_t *ip_conf; if_info_t if_info = {0};
ret_code ret = RET_OK; ret_code ret = RET_OK;
ip_config_t *if_config;
cJSON *item_obj;
int code; int code;
ip_conf = (ip_config_t *)input; if_config = (ip_config_t *)input;
strncpy(if_info.ifname, if_config->ifname, INTERFACE_NAMSIZ - 1);
ret = if_get_prefix(ip_conf, &code); ret = if_get_info(&if_info, &code);
RET_ERR_FORMART(ret, code, output, *output_len);
ASSERT_RET(ret); ASSERT_RET(ret);
ip_config_format_json(ip_conf, output, output_len); item_obj = ip_config_format_json(&if_info);
*output_len = cm_format_data(RET_OK, item_obj, output);
return ret; return ret;
} }
/* {"config_type":5} */
ret_code ip_config_get_all(uint source, pointer output, int *output_len) ret_code ip_config_get_all(uint source, pointer output, int *output_len)
{ {
struct ifreq *ifreq;
ret_code ret = RET_OK; ret_code ret = RET_OK;
int if_count = 0;
if_info_t *if_info;
cJSON *json_array;
cJSON *item_obj;
int code = 0; int code = 0;
int i;
*output_len = 0; ifreq = rpc_new0(struct ifreq, MAX_IF_NUM);
ret = if_get_prefix_all(output, output_len, &code); ASSERT_PTR(ifreq, RET_NOMEM);
if_count = if_get_allport(ifreq, MAX_IF_NUM);
rpc_log_info("if num is %d\n", if_count);
if((if_count * sizeof(if_info_t) > CM_BUFF_SIZE)
|| (if_count == 0))
{
rpc_free(ifreq);
ret = RET_NOMEM;
}
ASSERT_RET(ret);
if_info = rpc_new0(if_info_t, if_count);
if(if_info == NULL)
{
rpc_free(ifreq);
return RET_NOMEM;
}
json_array = cJSON_CreateArray();
if(json_array == NULL)
{
rpc_free(ifreq);
rpc_free(if_info);
return RET_NOMEM;
}
for(i = 0; i < if_count; i++)
{
rpc_log_info("get interface %s info\n", ifreq[i].ifr_name);
strncpy(if_info[i].ifname, ifreq[i].ifr_name, INTERFACE_NAMSIZ - 1);
ret = if_get_info(&if_info[i], &code);
ASSERT_CONTINUE(ret);
item_obj = ip_config_format_json(&if_info[i]);
if(item_obj == NULL)
{
continue;
}
cJSON_AddItemToArray(json_array, item_obj);
}
rpc_free(ifreq);
rpc_free(if_info);
*output_len = cm_format_data(RET_OK, json_array, output);
rpc_log_info("ip_config_get_all: %s\n", (char *)output); rpc_log_info("ip_config_get_all: %s\n", (char *)output);
RET_ERR_FORMART(ret, code, output, *output_len); RET_ERR_FORMART(ret, code, output, *output_len);
ASSERT_RET(ret); ASSERT_RET(ret);
return RET_OK; return RET_OK;

View File

@ -6,11 +6,12 @@
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <ctype.h> #include <ctype.h>
#include <net/if.h>
#include "rpc.h" #include "rpc.h"
#include "parsefile.h"
#include "netconfig.h" #include "netconfig.h"
#include "parsefile.h"
static char *if_parse_name(char *name, char *p) static char *if_parse_name(char *name, char *p)
{ {
@ -39,6 +40,131 @@ static char *if_parse_name(char *name, char *p)
return p; return p;
} }
static int procnetdev_version(char *buf)
{
if (strstr(buf, "compressed"))
return 3;
if (strstr(buf, "bytes"))
return 2;
return 1;
}
static int get_dev_stats( int procnetdev_vsn, char *bp, struct interface *ife)
{
switch (procnetdev_vsn) {
case 3:
sscanf(bp,
"%llu %llu %lu %lu %lu %lu %lu %lu %llu %llu %lu %lu %lu %lu %lu %lu",
&ife->stats.rx_bytes,
&ife->stats.rx_packets,
&ife->stats.rx_errors,
&ife->stats.rx_dropped,
&ife->stats.rx_fifo_errors,
&ife->stats.rx_frame_errors,
&ife->stats.rx_compressed,
&ife->stats.rx_multicast,
&ife->stats.tx_bytes,
&ife->stats.tx_packets,
&ife->stats.tx_errors,
&ife->stats.tx_dropped,
&ife->stats.tx_fifo_errors,
&ife->stats.collisions,
&ife->stats.tx_carrier_errors,
&ife->stats.tx_compressed);
break;
case 2:
sscanf(bp, "%llu %llu %lu %lu %lu %lu %llu %llu %lu %lu %lu %lu %lu",
&ife->stats.rx_bytes,
&ife->stats.rx_packets,
&ife->stats.rx_errors,
&ife->stats.rx_dropped,
&ife->stats.rx_fifo_errors,
&ife->stats.rx_frame_errors,
&ife->stats.tx_bytes,
&ife->stats.tx_packets,
&ife->stats.tx_errors,
&ife->stats.tx_dropped,
&ife->stats.tx_fifo_errors,
&ife->stats.collisions,
&ife->stats.tx_carrier_errors);
ife->stats.rx_multicast = 0;
break;
case 1:
sscanf(bp, "%llu %lu %lu %lu %lu %llu %lu %lu %lu %lu %lu",
&ife->stats.rx_packets,
&ife->stats.rx_errors,
&ife->stats.rx_dropped,
&ife->stats.rx_fifo_errors,
&ife->stats.rx_frame_errors,
&ife->stats.tx_packets,
&ife->stats.tx_errors,
&ife->stats.tx_dropped,
&ife->stats.tx_fifo_errors,
&ife->stats.collisions,
&ife->stats.tx_carrier_errors);
ife->stats.rx_bytes = 0;
ife->stats.tx_bytes = 0;
ife->stats.rx_multicast = 0;
break;
}
return 0;
}
static int cpy_dev_stats( if_cnt_t *ifstats, struct interface *ife)
{
sprintf(ifstats->rcv_bytes, "%llu", ife->stats.rx_bytes);
sprintf(ifstats->rcv_packets, "%llu", ife->stats.rx_packets);
sprintf(ifstats->snd_bytes, "%llu", ife->stats.tx_bytes);
sprintf(ifstats->snd_packets, "%llu", ife->stats.tx_packets);
return 0;
}
int if_read_stats_file(if_info_t *if_info)
{
struct interface ife = {0};
char buf[512] = {0};
int file_ver = 1;
FILE *fh;
fh = fopen(PROC_NET_DEV, "r");
if (!fh) {
rpc_log_error("Warning: cannot open %s (%s). Limited output.\n",
PROC_NET_DEV, strerror(errno));
return RET_SYSERR;
}
fgets(buf, sizeof buf, fh); /* eat line */
fgets(buf, sizeof buf, fh);
file_ver = procnetdev_version(buf);
while (fgets(buf, sizeof buf, fh))
{
char *s, name[IFNAMSIZ];
s = if_parse_name(name, buf);
if(strcmp(if_info->ifname, name) != 0)
{
continue;
}
get_dev_stats(file_ver, s, &ife);
sprintf(if_info->stats.rcv_bytes, "%llu", ife.stats.rx_bytes);
sprintf(if_info->stats.rcv_packets, "%llu", ife.stats.rx_packets);
sprintf(if_info->stats.snd_bytes, "%llu", ife.stats.tx_bytes);
sprintf(if_info->stats.snd_packets, "%llu", ife.stats.tx_packets);
}
fclose(fh);
return RET_OK;
}
int if_read_dev_file(struct ifreq *ifcfg, int max_port) int if_read_dev_file(struct ifreq *ifcfg, int max_port)
{ {
struct ifreq *ifreq = (struct ifreq *)ifcfg; struct ifreq *ifreq = (struct ifreq *)ifcfg;
@ -461,7 +587,8 @@ int conf_value_in_block_set_add(char *conf_path,
} }
/* 配置块结束 */ /* 配置块结束 */
if(strstr(config_linebuf, end_str)) if(strstr(config_linebuf, end_str)
|| strstr(config_linebuf, "auto"))
{ {
if(config_line == NULL) if(config_line == NULL)
{ {
@ -842,7 +969,24 @@ void ip_conf_file_set(char *if_name, char *conf_name, char *conf_buff)
sprintf(static_name, "iface %s inet static\n", if_name); sprintf(static_name, "iface %s inet static\n", if_name);
conf_value_in_block_set_add(ETC_NETWORK_IFS, auto_str, "auto", iface_str, static_name); conf_value_in_block_set_add(ETC_NETWORK_IFS, auto_str, "auto", iface_str, static_name);
conf_value_in_block_set_add(ETC_NETWORK_IFS, auto_str, "auto", conf_name, conf_buff); conf_value_in_block_set_add(ETC_NETWORK_IFS, static_name, "iface", conf_name, conf_buff);
return;
}
void ipv6_conf_file_set(char *if_name, char *conf_name, char *conf_buff)
{
char auto_str[IF_BUFF_LEN] = {0};
char iface_str[IF_BUFF_LEN] = {0};
char static_name[IF_BUFF_LEN] = {0};
sprintf(auto_str, "auto %s", if_name);
sprintf(iface_str, "iface %s inet6", if_name);
sprintf(static_name, "iface %s inet6 static\n", if_name);
conf_value_in_block_set_add(ETC_NETWORK_IFS, auto_str, "auto", iface_str, static_name);
conf_value_in_block_set_add(ETC_NETWORK_IFS, static_name, "iface", conf_name, conf_buff);
return; return;
} }
@ -855,11 +999,22 @@ void ip_conf_file_set(char *if_name, char *conf_name, char *conf_buff)
*/ */
void ip_conf_file_del(char *if_name, char *conf_buff) void ip_conf_file_del(char *if_name, char *conf_buff)
{ {
char auto_str[IF_BUFF_LEN] = {0}; char iface_str[IF_BUFF_LEN] = {0};
sprintf(auto_str, "auto %s", if_name); sprintf(iface_str, "iface %s inet", if_name);
conf_value_in_block_del(ETC_NETWORK_IFS, auto_str, "auto", conf_buff); conf_value_in_block_del(ETC_NETWORK_IFS, iface_str, "iface", conf_buff);
return;
}
void ipv6_conf_file_del(char *if_name, char *conf_buff)
{
char iface_str[IF_BUFF_LEN] = {0};
sprintf(iface_str, "iface %s inet6", if_name);
conf_value_in_block_del(ETC_NETWORK_IFS, iface_str, "iface", conf_buff);
return; return;
} }