kylin-nm/kylin-network-interface.c

967 lines
23 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/&gt;.
*
*/
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <linux/route.h>
#include <netinet/ether.h>
#include <net/ethernet.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include "kylin-network-interface.h"
//获取网络接口名
ifname *kylin_network_get_ifacename()
{
int i = 0;
int sockfd;
struct ifconf ifconf;
struct ifreq *ifreq;
unsigned char buf[1024];
//初始化ifconf
ifconf.ifc_len = 1024;
//字符串指针ifconf.ifc_buf指向buf
ifconf.ifc_buf = buf;
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("socket error");
return 0;
}
//获取所有接口信息
ioctl(sockfd, SIOCGIFCONF, &ifconf);
// printf("%s\n",ifconf.ifc_buf);
//逐个获取Ip地址
//结构体指针ifreq指向buf即ifconf.ifc_buf
ifreq = (struct ifreq*)buf;
int number=ifconf.ifc_len/sizeof(struct ifreq);
// printf("%d\n",number);
ifname *ifn=(ifname *)malloc(sizeof(ifname)*(number+1));
for(i = number; i>0; i--)
{
// printf("name = [%s] \n",ifreq->ifr_name);
int j=number-i;
ifn[j].if_name=(char *)malloc(sizeof(char)*10);
strcpy(ifn[j].if_name,ifreq->ifr_name);
// ifn[j].if_name=ifreq->ifr_name;
// printf("if_name[%d]:%s\n",j,if_name[j]);
ifreq++;
}
ifn[number].if_name=NULL;
return ifn;
}
//获取所有网络连接
conlist *kylin_network_get_conlist_info()
{
system("nmcli connection show > /tmp/conlist.txt");
char *filename="/tmp/conlist.txt";
FILE *confp;
int connum=0;
char ConStrLine[1024];
if((confp=fopen(filename,"r"))==NULL)
{
printf("error!");
}
fgets(ConStrLine,1024,confp);
while(!feof(confp))
{
fgets(ConStrLine,1024,confp);
connum++;
}
// printf("%d\n",connum);
fclose(confp);
conlist *clist=(conlist *)malloc(sizeof(conlist)*connum);
int count=0;
FILE *fp;
char StrLine[1024];
if((fp=fopen(filename,"r"))==NULL)
{
printf("error!");
}
fgets(StrLine,1024,fp);
while(!feof(fp))
{
if(count==connum-1)break;
fgets(StrLine,1024,fp);
char *index=StrLine;
char conname[100];
//截取连接名称
int num=0;
for(index;*index!='\n';index++)
{
if(*index==' ')
{
if(*(index+1)==' ')
break;
}
num++;
}
// printf("连接名称长度:%d\n",num);
clist[count].con_name=(char *)malloc(sizeof(char)*(num+1));
strncpy(conname,StrLine,num+1);
conname[num]='\0';
strncpy(clist[count].con_name,conname,num+1);
// printf("%s\n",clist[count].con_name);
//截取连接类型
char type[100];
for(index;*index!='\n';index++)
{
if(*index==' ')
{
if(*(index+1)=' ')
if(*(index+2)!=' ')
break;
}
}
char *index1=index+2;
for(index1;*index1!='\n';index1++)
{
if(*index1==' ')
{
if(*(index1+1)==' ')
break;
}
}
int num1=0;
char *index2=index1+2;
for(index2;*index2!='\n';index2++)
{
if(*index2==' ')break;
num1++;
}
clist[count].type=(char *)malloc(sizeof(char)*(num1+1));
strncpy(type,index1+2,num1+1);
type[num1]='\0';
strncpy(clist[count].type,type,num1+1);
// printf("%s\n",clist[count].type);
count++;
}
fclose(fp);
clist[count].con_name=NULL;
clist[count].type=NULL;
return clist;
}
//获取当前活动网络连接
activecon *kylin_network_get_activecon_info()
{
system("nmcli connection show -active > /tmp/activecon.txt");
char *filename="/tmp/activecon.txt";
FILE *activefp;
int activenum=0;
char activeStrLine[1024];
if((activefp=fopen(filename,"r"))==NULL)
{
printf("error!");
}
fgets(activeStrLine,1024,activefp);
while(!feof(activefp))
{
fgets(activeStrLine,1024,activefp);
activenum++;
}
// printf("%d\n",activenum);
fclose(activefp);
activecon *activelist=(activecon *)malloc(sizeof(activecon)*activenum);
int count=0;
FILE *fp;
char StrLine[1024];
if((fp=fopen(filename,"r"))==NULL)
{
printf("error!");
}
fgets(StrLine,1024,fp);
while(!feof(fp))
{
if(count==activenum-1)break;
fgets(StrLine,1024,fp);
char *index=StrLine;
char conname[100];
//截取连接名称
int num=0;
for(index;*index!='\n';index++)
{
if(*index==' ')
{
if(*(index+1)==' ')
break;
}
num++;
}
// printf("连接名称长度:%d\n",num);
activelist[count].con_name=(char *)malloc(sizeof(char)*(num+1));
strncpy(conname,StrLine,num+1);
conname[num]='\0';
strncpy(activelist[count].con_name,conname,num+1);
// printf("%s\n",activelist[count].con_name);
//截取连接类型
char type[100];
for(index;*index!='\n';index++)
{
if(*index==' ')
{
if(*(index+1)=' ')
if(*(index+2)!=' ')
break;
}
}
char *index1=index+2;
for(index1;*index1!='\n';index1++)
{
if(*index1==' ')
{
if(*(index1+1)==' ')
break;
}
}
int num1=0;
char *index2=index1+2;
for(index2;*index2!='\n';index2++)
{
if(*index2==' ')break;
num1++;
}
activelist[count].type=(char *)malloc(sizeof(char)*(num1+1));
strncpy(type,index1+2,num1+1);
type[num1]='\0';
strncpy(activelist[count].type,type,num1+1);
// printf("%s\n",activelist[count].type);
//截取连接所属设备
char *index3=index2;
char dev[100];
for(index3;*index3!='\n';index3++)
{
if(*index3==' ')
{
if(*(index3+1)!=' ')
break;
}
}
int num2=0;
char *index4=index3+1;
for(index4;*index4!='\n';index4++)
{
if(*index4==' ')break;
num2++;
}
activelist[count].dev=(char *)malloc(sizeof(char)*(num2+1));
strncpy(dev,index3+1,num2+1);
dev[num2]='\0';
strncpy(activelist[count].dev,dev,num2+1);
// printf("%s\n",activelist[count].dev);
count++;
}
fclose(fp);
activelist[count].con_name=NULL;
activelist[count].type=NULL;
activelist[count].dev=NULL;
return activelist;
}
//创建新的以太网连接
void kylin_network_create_new_ethernet(char *con_name,char *if_name)
{
char str[100];
char *net_type="ethernet";
sprintf(str,"nmcli connection add con-name %s ifname %s type %s",con_name,if_name,net_type);
system(str);
}
// 创建新的wifi连接配置
void kylin_network_create_new_wifi(char *con_name, char *if_name)
{
char str[200];
sprintf(str, "nmcli connection add con-name '%s' ifname '%s' type wifi ssid '%s'",
con_name, if_name, con_name);
system(str);
}
//删除以太网连接
void kylin_network_del_ethernet_con(char *con_name)
{
char str[100];
sprintf(str,"nmcli connection delete %s",con_name);
system(str);
}
//设置动态分配ip
void kylin_network_set_automethod(char *con_name)
{
char str[100];
char *automethod="auto";
sprintf(str,"nmcli connection modify '%s' ipv4.method %s",con_name,automethod);
system(str);
}
//设置手动分配ip
void kylin_network_set_manualmethod(char *con_name,char *ip)
{
char str[100];
char *method="manual";
sprintf(str,"nmcli connection modify '%s' ipv4.method %s ipv4.address %s",con_name,method,ip);
system(str);
}
// 设置手动分配all
void kylin_network_set_manualall(char *con_name, char *addr, char *mask, char *gateway, char *dns){
char str[200];
sprintf(str, "nmcli connection modify '%s' ipv4.method manual ipv4.address %s/%s ipv4.gateway %s ipv4.dns %s",
con_name, addr, mask, gateway, dns);
system(str);
}
//设置是否自动连接
void kylin_network_set_autoconnect(char *con_name,bool autocon)
{
char str[100];
if(autocon==false)
{
char *ac="no";
sprintf(str,"nmcli connection modify %s connection.autoconnect %s",con_name,ac);
}
else{
char *ac="yes";
sprintf(str,"nmcli connection modify %s connection.autoconnect %s",con_name,ac);
}
system(str);
}
//修改ip
void kylin_network_mod_ip(char *con_name,char *ip)
{
char str[100];
sprintf(str,"nmcli connection modify %s ipv4.address %s",con_name,ip);
system(str);
}
//修改网关
void kylin_network_mod_gateway(char *con_name,char *gw)
{
char str[100];
sprintf(str,"nmcli connection modify %s ipv4.gateway %s",con_name,gw);
system(str);
}
//修改dns
void kylin_network_mod_dns(char *con_name,char *dns)
{
char str[100];
sprintf(str,"nmcli connection modify %s ipv4.dns %s",con_name,dns);
system(str);
}
//连接以太网
void kylin_network_set_con_up(char *con_name)
{
char str[100];
sprintf(str,"nmcli connection up '%s'",con_name);
system(str);
}
//断开以太网
void kylin_network_set_con_down(char *con_name)
{
char str[100];
sprintf(str,"nmcli connection down '%s'",con_name);
system(str);
}
//连接wifi
void kylin_network_set_wifi_up(char *con_name,char *passwd)
{
char str[100];
sprintf(str,"export LANG='en_US.UTF-8';export LANGUAGE='en_US';nmcli device wifi connect '%s' password '%s'", con_name,passwd);
system(str);
}
//断开wifi连接
void kylin_network_set_wifi_down(char *if_name)
{
char str[100];
sprintf(str,"nmcli device disconnect '%s'",if_name);
system(str);
}
//获取wifi列表信息
wifilist *kylin_network_get_wifilist_info()
{
system("nmcli device wifi > /tmp/wflist.txt");
char *filename="/tmp/wflist.txt";
FILE *wffp;
int wfnum=0;
char WfStrLine[1024];
if((wffp=fopen(filename,"r"))==NULL)
{
printf("error!");
}
fgets(WfStrLine,1024,wffp);
while(!feof(wffp))
{
fgets(WfStrLine,1024,wffp);
wfnum++;
}
// printf("wifi数量%d\n",wfnum);
fclose(wffp);
//wifi实际数量是wfnum-1
wifilist *wflist=(wifilist *)malloc(sizeof(wifilist)*wfnum);
int count=0;
FILE *fp;
char StrLine[1024];
if((fp=fopen(filename,"r"))==NULL)
{
printf("error!");
}
fgets(StrLine,1024,fp);
while(!feof(fp))
{
if(count==wfnum-1)break;
fgets(StrLine,1024,fp);
// printf("%s\n",StrLine+3);
char *index=StrLine+3;
//截取ssid
char *str1="Infra";
int num=0;
for(index;strcmp(index+5,"\n")!=0;index++)
{
int result=strncmp(index,str1,5);
if(result==0)
{
// printf("%s\n",index);
break;
}
num++;
}
char ssid[100];
char *ssidindex=index-1;
int ssidnum=0;
for(ssidindex;*ssidindex==' ';ssidindex--)ssidnum++;
// printf("空格数量:%d\n",ssidnum);
// if(ssidnum==1)
strncpy(ssid,StrLine+3,num-1);
ssid[num-ssidnum]='\0';
// printf("-6666--%s---\n",ssid);
wflist[count].ssid=(char *)malloc(sizeof(char)*(num-ssidnum));
strncpy(wflist[count].ssid,ssid,num-ssidnum+1);
// printf("第%d个%s ",count,wflist[count].ssid);
//截取信号强度
char *str2="Mbit/s";
for(index;strcmp(index+6,"\n")!=0;index++)
{
int result=strncmp(index,str2,6);
if(result==0)
{
// printf("%s\n",index);
break;
}
}
char signal[10];
char *signalindex=index+8;
int signalnum=0;
for(signalindex;*signalindex!=' ';signalindex++)signalnum++;
strncpy(signal,index+8,signalnum);
signal[signalnum]='\0';
// printf("-7777--%s---\n",signal);
wflist[count].signal=atoi(signal);
// printf("%d ",wflist[count].signal);
//截取安全性
char *str3="WPA";
for(index;strcmp(index+3,"\n")!=0;index++)
{
int result=strncmp(index,str3,3);
if(result==0)
{
// printf("%s\n",index);
break;
}
}
char safety[20];
char *safetyindex=index;
int safetynum=0;
for(safetyindex;strcmp(safetyindex+2,"\n")!=0;safetyindex++)
{
int result=strncmp(safetyindex," ",2);
if(result==0)break;
safetynum++;
}
strncpy(safety,index,safetynum+1);
safety[safetynum+1]='\0';
// printf("-8888--%s---\n",safety);
wflist[count].safety=(char *)malloc(sizeof(char)*(safetynum+1));
strncpy(wflist[count].safety,safety,safetynum+2);
// printf("%s\n",wflist[count].safety);
count++;
}
fclose(fp);
wflist[count].ssid=NULL;
wflist[count].signal=0;
wflist[count].safety=NULL;
return wflist;
}
//启用联网
void kylin_network_enable_networking()
{
system("nmcli networking on");
}
//禁用联网
void kylin_network_disable_networking()
{
system("nmcli networking off");
}
//启用wifi
void kylin_network_enable_wifi()
{
system("nmcli radio wifi on;sleep 3");
}
//禁用wifi
void kylin_network_disable_wifi()
{
system("nmcli radio wifi off;sleep 2");
}
//获取ip地址
int kylin_network_get_ipaddr(char *if_name,char *ipaddr)
{
int sock_ip;
struct sockaddr_in sin_ip;
struct ifreq ifr_ip;
if((sock_ip=socket(AF_INET,SOCK_STREAM,0))<0)
{
perror("sockket error");
return -1;
}
strcpy(ifr_ip.ifr_name,if_name);
if(ioctl(sock_ip,SIOCGIFADDR,&ifr_ip)<0)//直接获取ip地址
{
perror("Not setup interface\n");
return -1;
}
memcpy(&sin_ip,&ifr_ip.ifr_addr,sizeof(sin_ip));
strcpy(ipaddr,inet_ntoa(sin_ip.sin_addr));//#include <arpa/inet.h>
close(sock_ip);
return 0;
}
//获取广播地址
int kylin_network_get_brdaddr(char *if_name,char *brdaddr)
{
int sock_brdaddr;
struct sockaddr_in sin_brd;
struct ifreq ifr_brd;
if((sock_brdaddr=socket(AF_INET,SOCK_STREAM,0))<0)
{
perror("sockket error");
return -1;
}
strcpy(ifr_brd.ifr_name,if_name);
if(ioctl(sock_brdaddr,SIOCGIFBRDADDR,&ifr_brd)<0)//直接获取广播地址
{
perror("Not setup interface\n");
return -1;
}
memcpy(&sin_brd,&ifr_brd.ifr_broadaddr,sizeof(sin_brd));
strcpy(brdaddr,inet_ntoa(sin_brd.sin_addr));
close(sock_brdaddr);
return 0;
}
//获取子网掩码
int kylin_network_get_netmask(char *if_name,char *netmask)
{
int sock_mask;
struct sockaddr_in sin_netmask;
struct ifreq ifr_mask;
if((sock_mask=socket(AF_INET,SOCK_STREAM,0))<0)
{
perror("sockket error");
return -1;
}
strcpy(ifr_mask.ifr_name,if_name);
if(ioctl(sock_mask,SIOCGIFNETMASK,&ifr_mask)<0)//直接获取子网掩码
{
perror("Not setup interface\n");
return -1;
}
memcpy(&sin_netmask,&ifr_mask.ifr_netmask,sizeof(sin_netmask));
strcpy(netmask,inet_ntoa(sin_netmask.sin_addr));
close(sock_mask);
return 0;
}
//获取MAC
int kylin_network_get_mac(char *if_name,char *macaddr)
{
int sock_mac;
struct ifreq ifr_mac;
struct sockaddr_in sin_mac;
struct ether_addr ethaddr;//#include <net/ethernet.h>
sock_mac=socket(AF_INET,SOCK_STREAM,0);
strcpy(ifr_mac.ifr_name,if_name);
if(-1==ioctl(sock_mac,SIOCGIFHWADDR,&ifr_mac))
{
perror("Not setup interface\n");
return -1;
}
memcpy(&ethaddr,&ifr_mac.ifr_hwaddr.sa_data,sizeof(ethaddr));
strcpy(macaddr,ether_ntoa(&ethaddr));//#include <netinet/ether.h>
// strcpy(macaddr,ether_ntoa((struct ether_addr*)ifr_mac.ifr_hwaddr.sa_data));
close(sock_mac);
return 0;
}
//获取MTU
int kylin_network_get_mtu(char *if_name)
{
int sock_mtu;
// struct sockaddr_in sin_ip;
struct ifreq ifr_MTU;
if((sock_mtu=socket(AF_INET,SOCK_STREAM,0))<0)
{
perror("sockket error");
return -1;
}
strcpy(ifr_MTU.ifr_name,if_name);
if(ioctl(sock_mtu,SIOCGIFMTU,&ifr_MTU))
{
perror("Not setup interface\n");
return -1;
}
int mtu=ifr_MTU.ifr_mtu;
// printf("%d\n",ifr_MTU.ifr_mtu);
// printf("%d\n",mtu);
close(sock_mtu);
return mtu;
}
static void getBuf(char *bufstr)
{
//O_RDONLY以只读方式打开文件
int fd=open("/proc/net/dev", O_RDONLY);
if(-1==fd)
{
printf("/proc/net/dev not exists!\n");
}
char buf[1024*2];
//将读写位置移到文件开头
lseek(fd,0,SEEK_SET);
int nBytes=read(fd,buf,sizeof(buf)-1);
if(-1==nBytes)
{
perror("read error");
close(fd);
}
buf[nBytes]='\0';
strcpy(bufstr,buf);
}
//总计上传下载数据量
long *kylin_network_get_bytes(char *if_name)
{
char buf[1024*2];
getBuf(buf);
//返回第一次指向if_name位置的指针
char *pDev=strstr(buf,if_name);
if(NULL==pDev)
{
printf("don't find dev %s\n",if_name);
return NULL;
}
char *p;
char *value;
int i=0;
static long rtbyt[2];
/*去除空格,制表符,换行符等不需要的字段*/
for (p = strtok(pDev, " \t\r\n"); p; p = strtok(NULL, " \t\r\n"))
{
i++;
value = (char*)malloc(20);
strcpy(value, p);
/*得到的字符串中的第二个字段是接收流量*/
if(i == 2)
{
rtbyt[0] = atol(value);
}
/*得到的字符串中的第十个字段是发送流量*/
if(i == 10)
{
rtbyt[1] = atol(value);
break;
}
free(value);
}
return rtbyt;
}
//总计上传下载数据包
long *kylin_network_get_packets(char *if_name)
{
char buf[1024*2];
getBuf(buf);
//返回第一次指向if_name位置的指针
char *pDev=strstr(buf,if_name);
if(NULL==pDev)
{
printf("don't find dev %s\n",if_name);
return NULL;
}
char *p;
char *value;
int i=0;
static long rtpkt[2];
/*去除空格,制表符,换行符等不需要的字段*/
for (p = strtok(pDev, " \t\r\n"); p; p = strtok(NULL, " \t\r\n"))
{
i++;
value = (char*)malloc(20);
strcpy(value, p);
/*得到的字符串中的第三个字段是接收流量*/
if(i == 3)
{
rtpkt[0] = atol(value);
}
/*得到的字符串中的第十一个字段是发送流量*/
if(i == 11)
{
rtpkt[1] = atol(value);
break;
}
free(value);
}
return rtpkt;
}
//总计上传下载错误数据包数量
long *kylin_network_get_errs(char *if_name)
{
char buf[1024*2];
getBuf(buf);
//返回第一次指向if_name位置的指针
char *pDev=strstr(buf,if_name);
if(NULL==pDev)
{
printf("don't find dev %s\n",if_name);
return NULL;
}
char *p;
char *value;
int i=0;
static long rterrs[2];
/*去除空格,制表符,换行符等不需要的字段*/
for (p = strtok(pDev, " \t\r\n"); p; p = strtok(NULL, " \t\r\n"))
{
i++;
value = (char*)malloc(20);
strcpy(value, p);
/*得到的字符串中的第四个字段是接收流量*/
if(i == 4)
{
rterrs[0] = atol(value);
}
/*得到的字符串中的第十二个字段是发送流量*/
if(i == 12)
{
rterrs[1] = atol(value);
break;
}
free(value);
}
return rterrs;
}
//总计上传下载丢弃数据包数量
long *kylin_network_get_drop(char *if_name)
{
char buf[1024*2];
getBuf(buf);
//返回第一次指向if_name位置的指针
char *pDev=strstr(buf,if_name);
if(NULL==pDev)
{
printf("don't find dev %s\n",if_name);
return NULL;
}
char *p;
char *value;
int i=0;
static long rtdrop[2];
/*去除空格,制表符,换行符等不需要的字段*/
for (p = strtok(pDev, " \t\r\n"); p; p = strtok(NULL, " \t\r\n"))
{
i++;
value = (char*)malloc(20);
strcpy(value, p);
/*得到的字符串中的第五个字段是接收流量*/
if(i == 5)
{
rtdrop[0] = atol(value);
}
/*得到的字符串中的第十三个字段是发送流量*/
if(i == 13)
{
rtdrop[1] = atol(value);
break;
}
free(value);
}
return rtdrop;
}
//总计上传下载过载数据包数量
long *kylin_network_get_fifo(char *if_name)
{
char buf[1024*2];
getBuf(buf);
//返回第一次指向if_name位置的指针
char *pDev=strstr(buf,if_name);
if(NULL==pDev)
{
printf("don't find dev %s\n",if_name);
return NULL;
}
char *p;
char *value;
int i=0;
static long rtfifo[2];
/*去除空格,制表符,换行符等不需要的字段*/
for (p = strtok(pDev, " \t\r\n"); p; p = strtok(NULL, " \t\r\n"))
{
i++;
value = (char*)malloc(20);
strcpy(value, p);
/*得到的字符串中的第六个字段是接收流量*/
if(i == 6)
{
rtfifo[0] = atol(value);
}
/*得到的字符串中的第十四个字段是发送流量*/
if(i == 14)
{
rtfifo[1] = atol(value);
break;
}
free(value);
}
return rtfifo;
}