首页 > 编程语言 >自己实现一个自动检测网卡状态,并设置ip地址,源码见文章底部

自己实现一个自动检测网卡状态,并设置ip地址,源码见文章底部

时间:2023-11-07 20:34:32浏览次数:65  
标签:overruns errors 自动检测 bytes packets 网卡 源码 dropped RX

阅读本文前,请先学习下面几篇文章

搞懂进程组、会话、控制终端关系,才能明白守护进程干嘛的?

简简单单教你如何用C语言列举当前所有网口!

《Linux下C语言操作网卡的几个代码实例!特别实用》

《安卓如何设置开机自动启动某个程序?ramdisk + init.rc给你搞定》

一、usb网卡应该如何实现?

前文讲了如何利用开源软件ifplugd实现监测网口状态变化,

ifplugd的确可以实现监测网卡的状态,并执行相应脚本,

但是有个前提,就是网口已经注册到系统中,即用ifconfig -a能查看到

如何是usb网卡这种设备,在插入usb口之后网口设备才会注册

使用过程中可能随时会拔掉usb网卡,

那么这种情况下,要想设置usb网卡,那么就就需要修改ifplugd程序。

为了方便大家理解,本文给大家讲解如何自己实现一个简化的程序ethcheck

可以实现自动监测网卡是否存在

rk3568所有网口:

rk3568_r:/system # ifconfig -a                                                
lo        Link encap:Local Loopback                                           
          inet addr:127.0.0.1  Mask:255.0.0.0                                 
          inet6 addr: ::1/128 Scope: Host                                     
          UP LOOPBACK RUNNING  MTU:65536  Metric:1                            
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0                  
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0                
          collisions:0 txqueuelen:1000                                        
          RX bytes:0 TX bytes:0                                               
                                                                              
dummy0    Link encap:Ethernet  HWaddr fa:85:6c:74:1b:7d                       
          inet6 addr: fe80::f885:6cff:fe74:1b7d/64 Scope: Link                
          UP BROADCAST RUNNING NOARP  MTU:1500  Metric:1                      
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0                  
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0                
          collisions:0 txqueuelen:1000                                        
          RX bytes:0 TX bytes:560                                             
                                                                              
sit0      Link encap:IPv6-in-IPv4                                             
          NOARP  MTU:1480  Metric:1                                           
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0                  
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0                
          collisions:0 txqueuelen:1000                                        
          RX bytes:0 TX bytes:0                                               
                                                                              
ip6tnl0   Link encap:UNSPEC                                                   
          NOARP  MTU:1452  Metric:1                                           
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0                  
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0                
          collisions:0 txqueuelen:1000                                        
          RX bytes:0 TX bytes:0                                               
                                                                              
eth1      Link encap:Ethernet  HWaddr 5a:53:63:cf:dd:0b  Driver rk_gmac-dwmac 
          UP BROADCAST MULTICAST  MTU:1500  Metric:1                          
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0                  
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0                
          collisions:0 txqueuelen:1000                                        
          RX bytes:0 TX bytes:0                                               
          Interrupt:51                                                        
                                                                              
ip_vti0   Link encap:UNSPEC                                                   
          NOARP  MTU:1480  Metric:1                                           
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0                  
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0                
          collisions:0 txqueuelen:1000                                        
          RX bytes:0 TX bytes:0                                               
                                                                              
eth0      Link encap:Ethernet  HWaddr 5e:53:63:cf:dd:0b  Driver rk_gmac-dwmac 
          UP BROADCAST MULTICAST  MTU:1500  Metric:1                          
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0                  
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0                
          collisions:0 txqueuelen:1000                                        
          RX bytes:0 TX bytes:0                                               
          Interrupt:38                                                        
                                                                              
ip6_vti0  Link encap:UNSPEC                                                   
          NOARP  MTU:1364  Metric:1                                           
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0                  
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0                
          collisions:0 txqueuelen:1000                                        
          RX bytes:0 TX bytes:0                                               

二、程序设计

0.程序框图

1. 设置程序为守护进程

因为该程序最终要在后台执行,并且常驻内存,所以必须将该进程设置为守护进程

关于守护进程的内容,请参考下面文章:

搞懂进程组、会话、控制终端关系,才能明白守护进程干嘛的?

参考代码如下:

void init_daemon(void)
{
	int pid;
	int i;
	
	if(pid=fork())
		exit(0);//是父进程,结束父进程?
	
	else if(pid< 0)
		exit(1);//fork失败,退出?
	
//是第一子进程,后台继续执行?
	setsid();//第一子进程成为新的会话组长和进程组长?
//并与控制终端分离?
	chdir("/tmp");//改变工作目录到/tmp?
	umask(0);//重设文件创建掩模?
	
	for(i=0;i< NOFILE;++i)//关闭打开的文件描述符?
		close(i);

	return;
}

2. 确认制定网口是否存在?

要确认指定网口是否存在,主要通过/proc/net/dev 目录下是否有该网口信息:

peng@ubuntu:~$ cat /proc/net/dev
Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo:   26163     292    0    0    0     0          0         0    26163     292    0    0    0     0       0          0
  eth0: 285444708  243273    0    0    0     0          0         0 91828270   88660    0    0    0     0       0          0

如何用C语言实现检测指定网口,可以参考下面文章:

简简单单教你如何用C语言列举当前所有网口!

参考代码:

static char * interface_name_cut (char *buf, char **name)
{
  char *stat;
  /* Skip white space.  Line will include header spaces. */
  while (*buf == ' ')
    buf++;
  *name = buf;
  /* Cut interface name. */
  stat = strrchr (buf, ':');
  *stat++ = '\0';
  return stat;
}
/*
return value:1 exist 0:no
*/ 
int check_interface_fromproc(char *interface)
{
  FILE *fp;
  char buf[PROCBUFSIZ];
  struct interface *ifp;
  char *name;
 
  /* Open /proc/net/dev. */
  fp = fopen (_PATH_PROC_NET_DEV, "r");
  if (fp == NULL)
    {   
        printf("open proc file error\n");
      return -1; 
    }   
 
  /* Drop header lines. */
  fgets (buf, PROCBUFSIZ, fp);
  fgets (buf, PROCBUFSIZ, fp);
 
  /* Only allocate interface structure.  Other jobs will be done in
     if_ioctl.c. */
  while (fgets (buf, PROCBUFSIZ, fp) != NULL)
    {   
      interface_name_cut (buf, &name);
      if(strcmp(interface,name)==0)
          return 1;
    }   
  fclose(fp);
  return 0;
}

3. 指定网口不存在

如果检测网口不存在,则需要休眠,然后继续监测/proc/net/dev文件。

4. 如果指定网口存在

则获取该网口的IP地址,然后比较是否是指定的IP地址

网卡IP地址的获取,主要通过系统调用ioctl()SIOCGIFADDR命令实现

关于如何用c语言操作网卡,擦靠下面文章

《Linux下C语言操作网卡的几个代码实例!特别实用》

参考代码如下:

int getLocalIp(const char *eth, char *ip) {
    struct ifreq ifr;
    struct sockaddr_in sin;
    int fd;
    bzero(&ifr, sizeof(ifr));
    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        return -1;
    }
    strcpy(ifr.ifr_name, eth);
    if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
        close(fd);
        return -1;
    }
    memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
    snprintf(ip, IP_SIZE, "%s", inet_ntoa(sin.sin_addr));
    close(fd);
    return 0;
}

读取的ip地址存放在参数ip指向的内存中。

5. ip地址相同

如果网卡地址与指定的ip地址相同,那么不需要修改地址,休眠一段时间(根据实际操作的频率设置时间),
然后再监测网口是否存在

6. IP地址不相同

如果ip地址不相同,则需要修改ip地址,

执行我们提前设置好的脚本if.sh即可

#!/bin/bash

IPADDR=192.168.40.8
ETHPORT=eth1
echo "ethcheck set" $ETHPORT $IPADDR
echo $#
echo $0
echo $1
echo $2
if [ $# -eq 2 ];then
	if [ $1 = $ETHPORT ];then 
	echo $ETHPORT
	if [ $2 = "up" ];then
	ifconfig $ETHPORT $IPADDR
	sleep 1
	ip rule add from all lookup main pref 9000 
	sleep 1
	echo 1 > /proc/sys/net/ipv4/ip_forward 
	iptables -F
	echo "set" $ETHPORT "done"
	elif [ $2 = "down" ];then
	echo "down"
	elif [ $2 = "disable" ];then
	echo "disable"
	elif [ $2 = "error" ];then
	echo "error"
	fi
	fi
fi

7. 设置为开机启动

要实现开机就自动运行ifplugd,可以参考下面文章:

《安卓如何设置开机自动启动某个程序?ramdisk + init.rc给你搞定》

资料获取

完整代码,点赞留言,后台回复:eth

更多嵌入式Linux知识,请关注up主,添加我的vx!

标签:overruns,errors,自动检测,bytes,packets,网卡,源码,dropped,RX
From: https://www.cnblogs.com/yikoulinux/p/17815862.html

相关文章

  • 电脑软件开发常见源码与误区分享!
    随着科技的不断发展,电脑软件已经深入到各个领域,为人们的生活和工作带来了极大的便利,然而,电脑软件开发的历程中,常常会遇到一些问题和误区,本文将分享一些常见的源码和误区,帮助开发者更好地规避风险,提高软件的质量和效率。一、常见的源码1、开源源码开源源码是指那些公开源代码的软件,......
  • 开发直播带货系统源码的技术要点
    直播带货系统是一个复杂的技术项目,通常包括前端应用、后端服务器、数据库、支付集成、实时通信以及直播流处理等多个关键组件。以下是开发直播带货系统源码的技术要点:1. 实时视频流处理一个成功的直播带货系统需要支持实时视频流的传输和处理。可以使用开源的流媒体服务器或使用云......
  • 情侣飞行棋小程序游戏系统源码小程序搭建
      情侣飞行棋小程序一款适合情侣之间互动的游戏软件,小程序平台实现线上对战,双方在游戏中增进感情。下面就是关于游戏软件的系统搭建,开发功能的过程。  一、情侣飞行棋需求  1.游戏规则:两人游戏,多人游戏,轮流掷骰子,按照骰子点数前进,达到游戏的终点者胜利。  2.界......
  • Java智慧工地管理平台可视化大数据建造工地APP源码
    一、智慧工地概述智慧工地将更多人工智能、传感技术、虚拟现实等高科技技术融入到建筑、机械、人员穿戴设施、场地进出关口等各类物体中,围绕人、机、料、法、环等各方面关键因素,彻底改变传统建筑施工现场参建各方现场管理的交互方式、工作方式和管理模式,智慧工地主要以物联网、移......
  • huatuo示例项目源码分析与启发
    上一节我们安装huatuo的开发环境,然后运行示例项目,体验了huatuo做热更新,这节课我们来分析示例项目的源码,掌握huatuo做热更新的主要的步骤,让你自己的项目很好的基于huatuo来组织热更新。有几个huatuo的原则要清楚:(1)UnityADF机制来分项目,可以分成若干项目,避免大量代码长时间的编......
  • 电脑连接外置网卡共享网络
    方法电脑外置网卡网线连接路由器LAN口路由器设置界面设置LAN口的为192.168.137.2,之后通过此可以访问路由器设置界面电视端DNS设置为192.168.137.1或:路由器中的DNS设置为8.8.8.8114.114.114.114......
  • Vue源码学习(十五):diff算法(二)交叉比对(双指针)
    好家伙, 本节来解决我们上一章留下来的问题,新旧节点同时有儿子的情况本章继续解决 1.要做什么?本章将解决,1.在相同tag下子元素的替换问题2.使用双指针进行元素替换,实现效果如下: letvm1=newVue({data:{name:'张三'}})letrender1=compileToFunc......
  • AQS源码分析-Condition
    在生产者消费者模型这篇文章中我们使用了ReentrantLock结合Condition实现生产者消费者模型,但我们对于ReentrantLock和Condition的工作原理并不了解,其内部的结构和源码级别实现就更加不了解了。比如在使用await方法的时候,为什么一定要用while判断条件,用if为什么不行呢?使用Condition......
  • ReentrantLock源码笔记 - 获取锁(JDK 1.8)
    ReentrantLock学习-获取锁(JDK1.8)ReentrantLock提供非公平锁与公平锁两种加锁方式,默认加锁方式为非公平锁。ReentrantLock类的结构为:从图中可以看出,ReentrantLock类包含三个静态内部类:SyncNonfairSyncFairSync其中Sync类继承AbstractQueuedSynchronize(AQS),Nonf......
  • ReentrantLock源码笔记 - 释放锁(JDK 1.8)
    ReentrantLock源码学习-释放锁(unlock)上次谈到了利用ReentrantLock的非公平和公平加锁方式,那么接下来看看释放锁的流程首先调用ReentrantLock的unlock方法publicvoidunlock(){sync.release(1);}然后会调用AbstractQueuedSynchronizer(AQS)的release方法,在这个方法......