本文主要是介绍【Linux 应用】网络相关开发---ip、网关、掩码、dns、mac的获取和设置,以及dhcp动态获取,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
最近开始调试Linux 的测试版,需要开发网络设置相关功能。其实这一块以前也做过,但是都忘记了,可见沉淀的重要性。
1、ip、掩码设置和获取
通过int ioctl(int d, int request, ...);这个函数可以获取到。
其中:
IP设置:SIOCGIFADDR
掩码设置:SIOCGIFNETMASK
mac设置:SIOCGIFHWADDR
其他具体如下:
2、DNS获取和设置
dns设置和获取时通过读写/etc/resolv.conf文件来实现的
# cat /etc/resolv.conf
nameserver 202.96.134.133
nameserver 202.96.128.166
nameserver 202.96.134.133 # eth0
nameserver 202.96.128.166 # eth0/tmp/resolv.conf文件也是可以的
# ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 18 Apr 22 2020 /etc/resolv.conf -> ../tmp/resolv.conf
3、网关获取
通过ip route 命令来获取route,以及字符串处理来获取默认网关(default)
4、dhcp动态获取
通过udhcpc 命令来实现dhcp动态获取的
5、代码实现
1、头文件
#ifndef __NET_MANAGER_H__
#define __NET_MANAGER_H__#define DEFAULT_ETH "eth0"
#define IP_ADDE_COUNT 16#define IP_SET_STATIC 1
#define IP_SET_AUTO 0int start_dhcp(char* net_name);
int end_dhcp();int is_valid_netmask(char* netmask);int get_ip(char* ip,int length);
int get_ip_netmask(char* ip,int length);int get_mac(char* addr,int length);int set_ip_netmask(char* ip,int length);
int set_ip(char* ip,int length);int set_gateway(char* gateway,int length);
int get_gateway(char* gateway, int length);
int get_dns(char* dns1, int length_dns1, char* dns2, int length_dns2);
int set_dns(const char *dns1,int length_dns1, const char *dns2, int length_dns2);
void set_net(char *ip_addr,int length_ip_addr,char *netmask,int length_netmask,char *gateway,int length_gateway,char *dns1,int length_dns1,char *dns2,int length_dns2);
int connect_check_real ();
int device_check_if_conn(char* ifname);
void net_init();
#endif
2、实现文件
#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <ctype.h>
#include <net/route.h>
#include <fcntl.h>
#include <string.h>
#include <pthread.h>
#include <sys/wait.h>
#if defined(__GLIBC__) && __GLIBC__ >=2 && __GLIBC_MINOR__ >= 1
#include <netpacket/packet.h>
#include <net/ethernet.h>
#else
#include <sys/types.h>
#include <netinet/if_ether.h>
#endif#include "netManager.h"
#include "userInfo.h"
#include "debugUtils.h"#define NET_MANAGER_FALSE -1
#define NET_MANAGER_TRUE 0static int set_addr(char* ip, int flag);
static int get_addr(char *addr, int length, int flag);/*
*检测ips是否合法
*/
static int is_valid_ip(const char* ipaddr)
{int ret = 0;struct in_addr inp;char buf[64] = {0};int ip1,ip2,ip3,ip4;if(ipaddr == NULL){printf("is_valid_ip error: ipaddr is NULL \n");return NET_MANAGER_FALSE;}sscanf(ipaddr, "%03d.%03d.%03d.%03d", &ip1,&ip2,&ip3,&ip4);snprintf((char *)buf, sizeof(buf), "%d.%d.%d.%d", ip1, ip2, ip3, ip4);ret = inet_aton(buf, &inp);if (0 == ret){return NET_MANAGER_FALSE;}return NET_MANAGER_TRUE;
}/** 先验证是否为合法IP,然后将掩码转化�?2无符号整型,取反�?00...00111...1�?* 然后再加1�?0...01000...0,此时为2^n,如果满足就为合法掩�?** */
int is_valid_netmask(char* netmask)
{if(netmask == NULL){printf("is_valid_ip error: ipaddr is NULL \n");return NET_MANAGER_FALSE;}if(is_valid_ip(netmask) == 0){unsigned long b = 0, i, n[4];sscanf(netmask, "%u.%u.%u.%u", &n[3], &n[2], &n[1], &n[0]);for(i = 0; i < 4; ++i) //将子网掩码存�?2位无符号整型{b += n[i] << (i * 8);}b = ~b + 1;if((b & (b - 1)) == 0) //判断是否�?^nreturn NET_MANAGER_TRUE;}GUI_DEBUG("============is_valid_netmask=======%s=============\n",netmask);return NET_MANAGER_FALSE;
}int end_dhcp()
{int ret = NET_MANAGER_FALSE;if(access("/var/run/udhcpc.pid",R_OK) == -1){return NET_MANAGER_TRUE;}ret = system("cat /var/run/udhcpc.pid|xargs kill -9");if(ret < 0){perror("end_dhcp error");return NET_MANAGER_FALSE;}return NET_MANAGER_TRUE;
}/*
*dhcp动态获取网络
*/
int start_dhcp(char* net_name)
{int ret = NET_MANAGER_FALSE;char cmd[IP_ADDE_COUNT+128] = {0};end_dhcp();if(NULL == net_name ||strlen(net_name) == 0){snprintf(cmd, sizeof(cmd),"busybox udhcpc -b -q -i %s -s /etc/simple.script -p /var/run/udhcpc.pid",DEFAULT_ETH);cmd[sizeof(cmd) -1] ='\0';}else{snprintf(cmd, sizeof(cmd),"busybox udhcpc -b -q -i %s -s /etc/simple.script -p /var/run/udhcpc.pid",net_name);cmd[sizeof(cmd) -1] ='\0';}ret = system(cmd);if(ret==-1){GUI_DEBUG("run system command error");}else{if(WIFEXITED(ret)){if(0==WEXITSTATUS(ret)){GUI_DEBUG("cmd: %s", cmd);ret=NET_MANAGER_TRUE;}else{//GLOG_DEBUG("%s connect to internet fail", ifname);}}else{GUI_DEBUG("exit Code status %d", WEXITSTATUS(ret));}}return ret;
}/*
*获取ip
*/
int get_ip(char* ip,int length)
{return get_addr(ip, length, SIOCGIFADDR);
}/*
*获取子网掩码
*/
int get_ip_netmask(char* ip,int length)
{return get_addr(ip, length, SIOCGIFNETMASK);
}/*
*获取mac
*/
int get_mac(char* addr,int length)
{return get_addr(addr, length, SIOCGIFHWADDR);
}/*
*根据参数获取�?
*/
static int get_addr(char *addr, int length, int flag)
{int sockfd = 0;struct sockaddr_in *sin;struct ifreq ifr;if(addr == NULL){printf("get_addr error:addr is NULL\n");return NET_MANAGER_FALSE;}if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){perror("socket error!\n");return NET_MANAGER_FALSE;}memset(&ifr, 0, sizeof(ifr));snprintf(ifr.ifr_name, (sizeof(ifr.ifr_name) - 1), "%s", DEFAULT_ETH);if(ioctl(sockfd, flag, &ifr) < 0 ){perror("ioctl error!\n");close(sockfd);return NET_MANAGER_FALSE;}close(sockfd);if (SIOCGIFHWADDR == flag){memcpy((void *)addr, (const void *)&ifr.ifr_ifru.ifru_hwaddr.sa_data, 6);GUI_DEBUG("mac address: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", addr[0],addr[1],addr[2],addr[3],addr[4],addr[5]);}else{sin = (struct sockaddr_in *)&ifr.ifr_addr;//snprintf((char *)addr, IP_ADDE_COUNT, "%s", inet_ntoa(sin->sin_addr));long ipaddr = inet_addr(inet_ntoa(sin->sin_addr));snprintf((char *)addr, length, "%03d.%03d.%03d.%03d", (ipaddr >> 0) & 0xFF, (ipaddr >> 8) & 0xFF, (ipaddr >> 16) & 0xFF, (ipaddr >> 24) & 0xFF);GUI_DEBUG("============get_addr======= %s =============\n", addr);if(is_valid_ip(addr) != 0){return NET_MANAGER_FALSE;}}return NET_MANAGER_TRUE;
}/*
*设置子网掩码
*/
int set_ip_netmask(char* ip,int length)
{int ip1,ip2,ip3,ip4;if(NULL == ip){printf("set_ip_netmask error: ip is NULL \n");return NET_MANAGER_FALSE;}sscanf(ip, "%03d.%03d.%03d.%03d", &ip1,&ip2,&ip3,&ip4);snprintf((char *)ip, length, "%d.%d.%d.%d", ip1, ip2, ip3, ip4);GUI_DEBUG("============set_ip_netmask======= %s =============\n", ip);return set_addr(ip, SIOCSIFNETMASK);
}/*
*设置ip
*/
int set_ip(char* ip,int length)
{int ip1,ip2,ip3,ip4;if(NULL == ip){printf("set_ip_netmask error: ip is NULL \n");return NET_MANAGER_FALSE;}sscanf(ip, "%03d.%03d.%03d.%03d", &ip1,&ip2,&ip3,&ip4);snprintf((char *)ip, length, "%d.%d.%d.%d", ip1, ip2, ip3, ip4);GUI_DEBUG("============set_ip======= %s =============\n", ip);return set_addr(ip, SIOCSIFADDR);
}/*
*根据参数设置
*/
static int set_addr(char* ip, int flag)
{struct ifreq ifr;struct sockaddr_in sin;int sockfd;if(ip == NULL){printf("set_addr error: ip is NULL\n");return NET_MANAGER_FALSE;}if (is_valid_ip(ip) != 0){printf("ip was invalid!\n");return NET_MANAGER_FALSE;}sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(sockfd == -1){fprintf(stderr, "Could not get socket.\n");perror("eth0\n");return NET_MANAGER_FALSE;}snprintf(ifr.ifr_name, (sizeof(ifr.ifr_name) - 1), "%s", DEFAULT_ETH);/* Read interface flags */if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {fprintf(stderr, "ifdown: shutdown ");perror(ifr.ifr_name);close(sockfd);return NET_MANAGER_FALSE;}memset(&sin, 0, sizeof(struct sockaddr));sin.sin_family = AF_INET;inet_aton(ip, &sin.sin_addr.s_addr);memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));if (ioctl(sockfd, flag, &ifr) < 0){fprintf(stderr, "Cannot set IP address. ");perror(ifr.ifr_name);close(sockfd);return NET_MANAGER_FALSE;}close(sockfd);return NET_MANAGER_TRUE;
} /*
*设置网关
*/
int set_gateway(char* gateway,int length)
{int s;struct rtentry rt;struct sockaddr_in sockaddr;int ip1,ip2,ip3,ip4;if((NULL == gateway) || (length == 0)){printf("set_gateway: gateway error.\n");return NET_MANAGER_FALSE;}sscanf(gateway, "%03d.%03d.%03d.%03d", &ip1,&ip2,&ip3,&ip4);snprintf((char *)gateway, length, "%d.%d.%d.%d", ip1, ip2, ip3, ip4);GUI_DEBUG("============set_gateway======= %s =============\n", gateway);s = socket(AF_INET, SOCK_DGRAM, 0);if (s < 0){perror("Socket create error.\n");return NET_MANAGER_FALSE;}memset(&rt, 0, sizeof(struct rtentry));memset(&sockaddr, 0, sizeof(struct sockaddr_in));sockaddr.sin_family = AF_INET;sockaddr.sin_port = 0;if(inet_aton(gateway, &sockaddr.sin_addr)<0){perror("inet_aton error\n" );close(s);return NET_MANAGER_FALSE;}memcpy ( &rt.rt_gateway, &sockaddr, sizeof(struct sockaddr_in));((struct sockaddr_in *)&rt.rt_dst)->sin_family=AF_INET;((struct sockaddr_in *)&rt.rt_genmask)->sin_family=AF_INET;rt.rt_flags = RTF_GATEWAY;if (ioctl(s, SIOCADDRT, &rt)<0){perror("ioctl(SIOCADDRT) error in set_default_route\n");close(s);return NET_MANAGER_FALSE;}close(s);return NET_MANAGER_TRUE;
}/*
*获取网关
*/
int get_gateway(char* gateway, int length)
{ FILE *fp;char buf[512];char cmd[128];char *tmp; if(gateway == NULL){printf("get_gateway error: gateway is NULL\n");return NET_MANAGER_FALSE;}strcpy(cmd, "busybox ip route"); fp = popen(cmd, "r"); if(NULL == fp) { perror("popen error"); return NET_MANAGER_FALSE; } while(fgets(buf, sizeof(buf), fp) != NULL) { tmp =buf; while(*tmp && isspace(*tmp)) ++ tmp; if(strncmp(tmp, "default", strlen("default")) == 0){GUI_DEBUG("default gateway:%s\n", buf);sscanf(buf, "%*s%*s%s", gateway);long ipaddr = inet_addr(gateway);snprintf((char *)gateway, length, "%03d.%03d.%03d.%03d", (ipaddr >> 0) & 0xFF, (ipaddr >> 8) & 0xFF, (ipaddr >> 16) & 0xFF, (ipaddr >> 24) & 0xFF);GUI_DEBUG("default gateway:%s\n", gateway);break; } }pclose(fp);return NET_MANAGER_TRUE;
}/*
*获取dns
*/
int get_dns(char* dns1, int length_dns1, char* dns2, int length_dns2)
{ FILE *fp;char buf[512];char cmd[128];int i = 0;if(dns1 == NULL || NULL == dns2){printf("get_dns error: dns is NULL \n");return NET_MANAGER_FALSE;}strcpy(cmd, "cat /tmp/resolv.conf");fp = popen(cmd, "r");if(NULL == fp){ perror("popen error");return NET_MANAGER_FALSE;}while(fgets(buf, sizeof(buf), fp) != NULL){if(strlen(buf) == 0 || strncmp(buf, "nameserver",strlen("nameserver")) != 0){continue;}if(i >= 2){i = 0;}if(i == 0){sscanf(buf, "%*s%s", dns1);long ipaddr = inet_addr(dns1);snprintf((char *)dns1, length_dns1, "%03d.%03d.%03d.%03d", (ipaddr >> 0) & 0xFF, (ipaddr >> 8) & 0xFF, (ipaddr >> 16) & 0xFF, (ipaddr >> 24) & 0xFF);}else{sscanf(buf, "%*s%s", dns2);long ipaddr = inet_addr(dns2);snprintf((char *)dns2, length_dns2, "%03d.%03d.%03d.%03d", (ipaddr >> 0) & 0xFF, (ipaddr >> 8) & 0xFF, (ipaddr >> 16) & 0xFF, (ipaddr >> 24) & 0xFF);}i++;}pclose(fp);return NET_MANAGER_TRUE;
} /*
*设置dns
*/
int set_dns(const char *dns1,int length_dns1, const char *dns2, int length_dns2)
{int ret = NET_MANAGER_TRUE;char cmd[128] = {0};int ip1,ip2,ip3,ip4;if(NULL == dns1 || NULL == dns2){printf("set_dns error: dns1 or dns2 is NULL \n");return NET_MANAGER_FALSE;}sscanf(dns1, "%03d.%03d.%03d.%03d", &ip1,&ip2,&ip3,&ip4);snprintf((char *)dns1, length_dns1,"%d.%d.%d.%d", ip1, ip2, ip3, ip4);sscanf(dns2, "%03d.%03d.%03d.%03d", &ip1,&ip2,&ip3,&ip4);snprintf((char *)dns2, length_dns2,"%d.%d.%d.%d", ip1, ip2, ip3, ip4);GUI_DEBUG("============set_dns====dns1=== %s =============\n", dns1);GUI_DEBUG("============set_dns====dns2=== %s =============\n", dns2);if(sizeof(dns1) == 0){return;}snprintf(cmd, sizeof(cmd),"echo \"nameserver %s\" > /tmp/resolv.conf",dns1);ret = system(cmd);if(ret < 0){perror("route error");return NET_MANAGER_FALSE;}snprintf(cmd, sizeof(cmd), "echo \"nameserver %s\" >> /tmp/resolv.conf",dns2);//strcpy(cmd, "route add default gw ");//strcat(cmd, szGateWay);ret = system(cmd); if(ret < 0) { perror("set_dns error"); return NET_MANAGER_FALSE; }return ret;
} /*
*设置静态IP网络
*/
void set_net(char *ip_addr,int length_ip_addr,char *netmask,int length_netmask,char *gateway,int length_gateway,char *dns1,int length_dns1,char *dns2,int length_dns2)
{if(ip_addr != NULL){set_ip(ip_addr,length_ip_addr);}if((netmask == NULL) && is_valid_netmask(netmask) == 0){set_ip_netmask(netmask, length_netmask);}else{GUI_DEBUG("g_mask_addr is error\n");}if(gateway != NULL){set_gateway(gateway, length_gateway);}if((dns1 != NULL) && (dns2 != NULL)){set_dns(dns1, length_dns1, dns2, length_dns2);}return;
}void net_init()
{IpInfo_S netInfo = getIpinfo();if(netInfo.m_netMode == IP_SET_STATIC){GUI_DEBUG("net_init is IP_SET_STATIC\n");set_net(netInfo.m_ipAddr, strlen(netInfo.m_ipAddr), netInfo.m_Netmask, strlen(netInfo.m_Netmask), netInfo.m_gateWay, strlen(netInfo.m_gateWay), netInfo.m_Dns1,strlen(netInfo.m_Dns1), netInfo.m_Dns2,strlen(netInfo.m_Dns2));}else{GUI_DEBUG("net_init is IP_SET_AUTO\n");start_dhcp(DEFAULT_ETH);}return;
}int connect_check_real ()
{ int ret = -1;int fp;char status[10];//一定要只读模式打开,读写模式打开不可以 fp = open ("/sys/class/net/eth0/operstate",O_RDONLY);if (fp<0) {printf("open file operstate failure%d\n",fp);return;}memset(status,0,sizeof(status));ret = read (fp,status,10);printf("status:%s\n",status);if (NULL != strstr(status,"up")){printf("on line now \n");ret = 0;}else if (NULL != strstr(status,"down")){printf("off off \n");}else{printf("unknow error\n");}close (fp);return ret;
}int device_check_if_conn(char* ifname)
{pid_t status;uint8_t ret=-1, i=0;char cmd[256];char serverip[3][32]={"114.114.114.114","8.8.8.8","223.5.5.5"};for(i=0;i<3;i++){snprintf(cmd, sizeof(cmd),"busybox ping -I %s -w 1 -c 1 %s 1>/dev/null 2>&1", ifname, serverip[i]);status=system(cmd);if(status==-1){GUI_DEBUG("run system command error");}else{if(WIFEXITED(status)){if(0==WEXITSTATUS(status)){GUI_DEBUG("%s connect to internet ok", ifname);GUI_DEBUG("cmd: %s", cmd);ret=0;break;}else{//GLOG_DEBUG("%s connect to internet fail", ifname);}}else{GUI_DEBUG("exit Code status %d", WEXITSTATUS(status));}}}return ret;
}int check_net()
{if(connect_check_real() != 0){return -1;}if(device_check_if_conn("eth0") != 0){return 0;}return 1;
}
3、测试代码
#include <stdio.h>
#include "netManager.h"void set_net();int main(int argc, char *argv[])
{set_net();get_dhcp(NULL);get_net_info();return 0;
}void set_net()
{char g_mask_addr[IP_ADDE_COUNT] = "255.255.0.0";char g_ip_addr[IP_ADDE_COUNT] = "172.30.16.68";char g_gateway_addr[IP_ADDE_COUNT] = "172.30.15.253";char g_dns_addr[2][IP_ADDE_COUNT] = {"8.8.8.8","114.114.114.144"};set_ip(g_ip_addr);if(is_valid_netmask(g_mask_addr) == 0){set_ip_netmask(g_mask_addr);}else{printf("g_mask_addr is error\n");}set_gateway(g_gateway_addr);set_dns(g_dns_addr[0],g_dns_addr[1]);return;
}void get_net_info()
{char s_ip_addr[IP_ADDE_COUNT] = {0},s_mask_addr[IP_ADDE_COUNT] = {0},s_mac_addr[6] = {0}, \s_gateway_addr[IP_ADDE_COUNT] = {0},s_dns_addr[2][IP_ADDE_COUNT] = {0};get_ip(s_ip_addr);get_mac(s_mac_addr);get_ip_netmask(s_mask_addr);get_gateway(s_gateway_addr);get_dns(s_dns_addr);printf("=========================%s=====================\n",s_ip_addr);printf("=========================%s=====================\n",s_mask_addr);printf("=========================%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x=====================\n", s_mac_addr[0],s_mac_addr[1],s_mac_addr[2],s_mac_addr[3],s_mac_addr[4],s_mac_addr[5]);printf("=========================%s=====================\n",s_gateway_addr);printf("=========================%s=====================\n",s_dns_addr[0]);printf("=========================%s=====================\n",s_dns_addr[1]);return;
}
结束语
这篇文章主要是记录一下,方便以后回忆和查阅,写的不尽详细,又不懂得欢迎留言交流。
这篇关于【Linux 应用】网络相关开发---ip、网关、掩码、dns、mac的获取和设置,以及dhcp动态获取的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!