网络link状态检测

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
简介: 网络link状态检测

Linux系统提供了两类ioctl系统调用SIOCETHTOOL和SIOCXMIIXXX,用于控制或者获取网卡PHY的状态。这两类系统调用的实现取决于PHY驱动中对应ioctl的实现,一般的PHY驱动都会实现至少其中的一类。下面以获取网卡的Link状态来说明这两类系统调用的使用。代码



#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <linux/mii.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <sys/ioctl.h>

#include <net/if.h>

#include <linux/sockios.h>

#include <linux/types.h>

#include <netinet/in.h>

 

static int detect_ethtool(int skfd, char *ifname);

static int detect_mii(int skfd, char *ifname);

#define MII_BMSR            0x01        /* Basic mode status register  */

#define BMSR_JCD                0x0002  /* Jabber detected             */

#define BMSR_LSTATUS            0x0004  /* Link status                 */

#define BMSR_RFAULT             0x0010  /* Remote fault detected       */

 

/*--------------------------------------------------------------------------*/

/**

@brief Detect eth link status from ETHTOOL API and MII reg.

@param ifname -- interface name.

@return Return true if link is up, return false if link is down,

or return -1 if errors occur.

This function will first try to get eth link status from ETHTOOL API.

If it fails, it will try to get eth link status from MII reg.

*/

/*--------------------------------------------------------------------------*/

static int get_netlink_status(char *ifname)

{

   int skfd = -1;

   int link_status;

 

   if (ifname == NULL) {

       ifname = "eth0";

   }

 

   if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {

       nl_err("socket error\n");

       return -1;

   }

 

   link_status = detect_ethtool(skfd, ifname);

   if (link_status < 0)

       link_status = detect_mii(skfd, ifname);

 

   close(skfd);

   return link_status;

}

 

 

/*--------------------------------------------------------------------------*/

/**

@brief Detect eth link status from ETHTOOL API.

@param skfd -- socket handler.

@param ifname -- interface name.

@return Return true if link is up, return false if link is down,

or return -1 if errors occur.

*/

/*--------------------------------------------------------------------------*/

int detect_ethtool(int skfd, char *ifname)

{

   struct ifreq ifr;

   struct ethtool_value edata;

 

   memset(&ifr, 0, sizeof(ifr));

   edata.cmd = ETHTOOL_GLINK;

 

   strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)-1);

   ifr.ifr_data = (char *) &edata;

 

   if (ioctl(skfd, SIOCETHTOOL, &ifr) == -1) {

       nl_err("ETHTOOL_GLINK failed: %s\n", strerror(errno));

       return -1;

   }

 

   return (edata.data ? 1 : 0);

}

 

/*--------------------------------------------------------------------------*/

/**

@brief Detect eth link status from MII status reg.

@param skfd -- socket handler.

@param ifname -- interface name.

@return Return true if link is up, return false if link is down,

or return -1 if errors occur.

*/

/*--------------------------------------------------------------------------*/

static int detect_mii(int skfd, char *ifname)

{

   struct ifreq ifr;

   struct mii_ioctl_data *mii_val;

 

 

   strncpy(ifr.ifr_name, ifname, IFNAMSIZ);

   if (ioctl(skfd, SIOCGMIIPHY, &ifr) < 0) {

       fprintf(stderr, "SIOCGMIIPHY on %s failed: %s\n", ifname,

       strerror(errno));

       (void) close(skfd);

       return -1;

   }

 

   mii_val = (struct mii_ioctl_data *)(&ifr.ifr_data);

   mii_val->reg_num = MII_BMSR;

 

   if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) {

       nl_err("SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name,

       strerror(errno));

       return -1;

   }

 

   if ((!(mii_val->val_out & BMSR_RFAULT)) &&

       (mii_val->val_out & BMSR_LSTATUS) &&

       (!(mii_val->val_out & BMSR_JCD))) {

       return 1;

   } else {

       return 0;

   }

}

int main(int argc, char* argv[])

{

   if(argc != 2)

   {

       fprintf(stderr, "usage: %s <ethname>", argv[0]);

       return -1;

   }

   if(getuid() != 0)

   {

       fprintf(stderr, "Netlink Status Check Need Root Power.\n");

       return 1;

   }

 

   printf("Net link status: %s\n", get_netlink_status(argv[1])==1?"up":"down");

   return 0;

}

SIOCETHTOOL相当于是对SIOCGMIIPHY的一个封装吧,其实最终调用的方式都是读取状态寄存器Link Status的值,测试程序中用到的三个寄存器如下图所示:







Remote Fault:远端错误指示位。Bit4=1代表连接对端(Link Partner)出错,至于出错的具体类型以及错误检测机制在规范中并没有定义,由PHY的制造商自由发挥,一般的厂商都会在其他的寄存器(Register16-31由厂商自行定义)指示比较详细的错误类型。在与端口相关的故障查证中,Remote Fault是一个重要的指示信息,通过互联双方的Remote Fault信息(可能要加上其他的具体错误指示),可以帮助定位故障原因。


Link Status:Link状态指示位。Bit2=1代表端口Link up,0则代表端口Link down。实际应用中一般都是通过Bit2来判断端口的状态。而且,一般的MAC芯片也是通过轮询PHY的这个寄存器值来判断端口的Link状态的(这个过程可能有不同的名称,比如BCM叫做Link Scan,而Marvell叫做PHY Polling。)如前所述,在AN Enable的情况下,Link Status的信息只有在Auto-Negotiation Complete指示已经完成的情况下才是正确可靠的,否则有可能出错。


Jabber Detect:Jabber 检测指示位。IEEE802.3对Jabber的解释是"A condition wherein a station transmits for a period of time longer than the maximum permissible packet length, usually due to a fault condition"。这一位指示的是Link Partner发送的时间超过了规定的最大长度。值得注意的是,Jabber Detect只有在10BASE-T模式下才有意义,100和1000M模式是没有定义Jabber这一功能的。


相关实践学习
基于Hologres轻松玩转一站式实时仓库
本场景介绍如何利用阿里云MaxCompute、实时计算Flink和交互式分析服务Hologres开发离线、实时数据融合分析的数据大屏应用。
Linux入门到精通
本套课程是从入门开始的Linux学习课程,适合初学者阅读。由浅入深案例丰富,通俗易懂。主要涉及基础的系统操作以及工作中常用的各种服务软件的应用、部署和优化。即使是零基础的学员,只要能够坚持把所有章节都学完,也一定会受益匪浅。
相关文章
|
10天前
|
机器学习/深度学习 计算机视觉 网络架构
【YOLO11改进 - C3k2融合】C3k2DWRSeg二次创新C3k2_DWR:扩张式残差分割网络,提高特征提取效率和多尺度信息获取能力,助力小目标检测
【YOLO11改进 - C3k2融合】C3k2DWRSeg二次创新C3k2_DWR:扩张式残差分割网络,提高特征提取效率和多尺度信息获取能力,助力小目DWRSeg是一种高效的实时语义分割网络,通过将多尺度特征提取分为区域残差化和语义残差化两步,提高了特征提取效率。它引入了Dilation-wise Residual (DWR) 和 Simple Inverted Residual (SIR) 模块,优化了不同网络阶段的感受野。在Cityscapes和CamVid数据集上的实验表明,DWRSeg在准确性和推理速度之间取得了最佳平衡,达到了72.7%的mIoU,每秒319.5帧。代码和模型已公开。
【YOLO11改进 - C3k2融合】C3k2DWRSeg二次创新C3k2_DWR:扩张式残差分割网络,提高特征提取效率和多尺度信息获取能力,助力小目标检测
|
13天前
|
机器学习/深度学习 搜索推荐 安全
深度学习之社交网络中的社区检测
在社交网络分析中,社区检测是一项核心任务,旨在将网络中的节点(用户)划分为具有高内部连接密度且相对独立的子群。基于深度学习的社区检测方法,通过捕获复杂的网络结构信息和节点特征,在传统方法基础上实现了更准确、更具鲁棒性的社区划分。
27 7
|
10天前
|
机器学习/深度学习 计算机视觉 网络架构
【YOLO11改进 - C3k2融合】C3k2融合DWRSeg二次创新C3k2_DWRSeg:扩张式残差分割网络,提高特征提取效率和多尺度信息获取能力,助力小目标检测
【YOLO11改进 - C3k2融合】C3k2融合DWRSDWRSeg是一种高效的实时语义分割网络,通过将多尺度特征提取方法分解为区域残差化和语义残差化两步,提高了多尺度信息获取的效率。网络设计了Dilation-wise Residual (DWR) 和 Simple Inverted Residual (SIR) 模块,分别用于高阶段和低阶段,以充分利用不同感受野的特征图。实验结果表明,DWRSeg在Cityscapes和CamVid数据集上表现出色,以每秒319.5帧的速度在NVIDIA GeForce GTX 1080 Ti上达到72.7%的mIoU,超越了现有方法。代码和模型已公开。
|
2月前
|
机器学习/深度学习 安全 网络安全
利用机器学习优化网络安全威胁检测
【9月更文挑战第20天】在数字时代,网络安全成为企业和个人面临的重大挑战。传统的安全措施往往无法有效应对日益复杂的网络攻击手段。本文将探讨如何通过机器学习技术来提升威胁检测的效率和准确性,旨在为读者提供一种创新的视角,以理解和实施机器学习在网络安全中的应用,从而更好地保护数据和系统免受侵害。
|
2月前
|
机器学习/深度学习 数据采集 网络安全
使用Python实现深度学习模型:智能网络安全威胁检测
使用Python实现深度学习模型:智能网络安全威胁检测
188 5
|
27天前
|
运维 安全 网络协议
Python 网络编程:端口检测与IP解析
本文介绍了使用Python进行网络编程的两个重要技能:检查端口状态和根据IP地址解析主机名。通过`socket`库实现端口扫描和主机名解析的功能,并提供了详细的示例代码。文章最后还展示了如何整合这两部分代码,实现一个简单的命令行端口扫描器,适用于网络故障排查和安全审计。
|
3月前
|
计算机视觉
在yolov5项目中如何使用自带摄像机不用网络摄像机进行实时检测?
这篇文章讨论了在yolov5项目中,如何避免使用网络摄像机而改用自带的本地摄像机进行实时目标检测,并提供了解决摄像头打开错误的具体步骤和代码示例。
在yolov5项目中如何使用自带摄像机不用网络摄像机进行实时检测?
|
3月前
|
机器学习/深度学习 监控 算法
基于深度学习网络的人员行为视频检测系统matlab仿真,带GUI界面
本仿真展示了基于GoogLeNet的人员行为检测系统在Matlab 2022a上的实现效果,无水印。GoogLeNet采用创新的Inception模块,高效地提取视频中人员行为特征并进行分类。核心程序循环读取视频帧,每十帧执行一次分类,最终输出最频繁的行为类别如“乐队”、“乒乓球”等。此技术适用于智能监控等多个领域。
69 4
|
3月前
|
机器学习/深度学习 数据采集 算法
基于深度学习网络的USB摄像头实时视频采集与火焰检测matlab仿真
本项目使用MATLAB2022a实现基于YOLOv2的火焰检测系统。通过USB摄像头捕捉火焰视频,系统实时识别并标出火焰位置。核心流程包括:视频采集、火焰检测及数据预处理(图像标准化与增强)。YOLOv2模型经特定火焰数据集训练,能快速准确地识别火焰。系统含详细中文注释与操作指南,助力快速上手。
|
3月前
|
机器学习/深度学习 运维 监控
下一篇
无影云桌面