以太网基础 -- LLDP使用案例

LLDP使用技术报告

背景

链路层发现协议(Link Layer Discovery Protocol,LLDP)是一种网络协议,主要用于在以太网网络中发现相邻设备并与其交换信息。LLDP是一种开放的标准,由IEEE 802.1AB定义,能够跨多个厂商的设备进行互操作。它的主要功能是帮助网络管理员识别网络拓扑结构,便于管理和故障排除。

LLDP在网络设备之间周期性地发送和接收LLDP数据单元(LLDPDU),这些数据单元包含设备的配置信息和能力。每个LLDPDU由多个TLV(Type-Length-Value)字段组成,每个字段包含特定类型的信息。

最常用的字段

LLDPDU中的常用TLV字段包括:

  1. Chassis ID TLV:识别设备底盘的唯一标识符,通常是设备的MAC地址。
  2. Port ID TLV:标识发送LLDPDU的端口,可以是端口的MAC地址或端口号。
  3. Time to Live (TTL) TLV:指定LLDP信息的生存时间,单位为秒。
  4. Port Description TLV:描述端口的信息,如端口名称或类型。
  5. System Name TLV:设备的主机名。
  6. System Description TLV:设备的详细描述,包括制造商、型号和操作系统版本等信息。
  7. System Capabilities TLV:设备的功能和当前启用的功能,如交换机、路由器等。
  8. Management Address TLV:设备的管理地址,可以是IPv4或IPv6地址。

自定义字段

除了标准的TLV字段外,LLDP还允许使用自定义TLV字段。这些字段可以携带特定的厂商信息或特定应用的配置信息。定义自定义TLV字段时,需要确保Type值在特定范围内,以避免与标准字段冲突。

实验设备

实验设备包括一台PC和一台嵌入式Linux设备。在本次实验中,我们将演示如何在PC端使用Python Qt实现设备发现功能,并在嵌入式Linux设备上使用C语言发送设备信息。

PC端代码 (Python Qt)

import sys
import threading
from PyQt5.QtCore import pyqtSignal, QObject
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QTextEdit
from scapy.all import *
from scapy.layers.l2 import Ether# Define LLDP layer
class LLDPDU(Packet):name = "LLDPDU"fields_desc = [ByteField("type", 0),ByteField("length", 0),StrLenField("value", "", length_from=lambda pkt:pkt.length)]class SnifferThread(QObject):packet_received = pyqtSignal(str)def start_sniffing(self):thread = threading.Thread(target=self.sniff_packets)thread.daemon = Truethread.start()def sniff_packets(self):print("Starting packet sniffing...")sniff(filter="ether proto 0x88cc", prn=self.process_packet, store=0)print("Packet sniffing stopped.")def process_packet(self, packet):if packet.haslayer(Ether) and packet[Ether].type == 0x88cc:info = f"LLDP packet received from {packet.src}\n"payload = bytes(packet.payload)i = 14  # skip Ethernet headerwhile i < len(payload):tlv_type = (payload[i] >> 1) & 0x7Ftlv_len = (payload[i] & 0x01) << 8 | payload[i + 1]tlv_value = payload[i + 2: i + 2 + tlv_len]info += f"TLV Type: {tlv_type}, Length: {tlv_len}, Value: {tlv_value}\n"i += 2 + tlv_lenself.packet_received.emit(info)class LLDPDiscoveryApp(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("LLDP Discovery")self.setGeometry(100, 100, 600, 400)self.textEdit = QTextEdit(self)self.setCentralWidget(self.textEdit)self.sniffer_thread = SnifferThread()self.sniffer_thread.packet_received.connect(self.display_packet_info)self.sniffer_thread.start_sniffing()def display_packet_info(self, info):self.textEdit.append(info)def main():app = QApplication(sys.argv)window = LLDPDiscoveryApp()window.show()sys.exit(app.exec_())if __name__ == "__main__":main()

嵌入式Linux设备端代码 (C语言)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
//#include <netinet/if_ether.h>
//#include <netpacket/packet.h>
#include <net/if.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <sys/ioctl.h>#define MAX_TLV_SIZE 512
#define LLDP_MULTICAST_ADDR "01:80:C2:00:00:0E"typedef struct {uint8_t type;uint8_t length;uint8_t value[MAX_TLV_SIZE];
} TLV;void addTLV(uint8_t *buffer, size_t *offset, uint8_t type, uint8_t length, uint8_t *value) {buffer[*offset] = (type << 1) | ((length >> 8) & 0x01);buffer[*offset + 1] = length & 0xFF;memcpy(&buffer[*offset + 2], value, length);*offset += length + 2;
}void sendLLDPDU(char *interface) {int sockfd;struct ifreq ifr;struct sockaddr_ll sa;uint8_t lldpdu[MAX_TLV_SIZE];uint8_t ether_frame[MAX_TLV_SIZE + ETH_HLEN];size_t offset = 0;// Create a raw socketif ((sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {perror("socket");exit(EXIT_FAILURE);}// Get the interface indexmemset(&ifr, 0, sizeof(ifr));strncpy(ifr.ifr_name, interface, IFNAMSIZ - 1);if (ioctl(sockfd, SIOCGIFINDEX, &ifr) < 0) {perror("ioctl");close(sockfd);exit(EXIT_FAILURE);}int ifindex = ifr.ifr_ifindex;// Get the MAC address of the interfaceif (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0) {perror("ioctl");close(sockfd);exit(EXIT_FAILURE);}uint8_t *src_mac = (uint8_t *)ifr.ifr_hwaddr.sa_data;// Set up destination MAC addressuint8_t dst_mac[6];sscanf(LLDP_MULTICAST_ADDR, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",&dst_mac[0], &dst_mac[1], &dst_mac[2],&dst_mac[3], &dst_mac[4], &dst_mac[5]);// Construct LLDPDU// Add Chassis ID TLVuint8_t chassisID[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };addTLV(lldpdu, &offset, 1, sizeof(chassisID), chassisID);// Add Port ID TLVuint8_t portID[] = { 'E', 't', 'h', '0' };addTLV(lldpdu, &offset, 2, sizeof(portID), portID);// Add TTL TLVuint8_t ttl[] = { 0x00, 0x78 };  // 120 secondsaddTLV(lldpdu, &offset, 3, sizeof(ttl), ttl);// Add End TLVaddTLV(lldpdu, &offset, 0, 0, NULL);// Construct Ethernet framememcpy(ether_frame, dst_mac, 6);memcpy(ether_frame + 6, src_mac, 6);ether_frame[12] = 0x88;ether_frame[13] = 0xcc;memcpy(ether_frame + ETH_HLEN, lldpdu, offset);// Set up sockaddr_llmemset(&sa, 0, sizeof(sa));sa.sll_family = AF_PACKET;sa.sll_ifindex = ifindex;sa.sll_protocol = htons(ETH_P_ALL);sa.sll_halen = ETH_ALEN;memcpy(sa.sll_addr, dst_mac, 6);// Send the packetif (sendto(sockfd, ether_frame, offset + ETH_HLEN, 0, (struct sockaddr *)&sa, sizeof(sa)) < 0) {perror("sendto");close(sockfd);exit(EXIT_FAILURE);}close(sockfd);
}int main() {char *interface = "eth0";sendLLDPDU(interface);return 0;
}

总结

通过使用LLDP协议,可以有效地发现网络中的相邻设备并交换信息,这对于网络管理和故障排除具有重要意义。本次实验展示了如何在PC和嵌入式设备上实现LLDP功能,希望对相关技术的学习和应用有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/23408.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

dubbo服务引用

spring刷新容器的时候&#xff0c;ReferrenceBean只有被调用的情况下才会在createBean回调afterPropertiesSet的时候引入服务。 ReferrenceBean实现了FacotryBean的接口&#xff0c;当对任意服务Interface进行自动注入或者getBean获取&#xff0c;会触发getObject过程 本地服…

TensorBoard在pytorch训练过程中如何使用,及数据读取问题解决方法

TensorBoard 模块导入日志记录文件的创建训练中如何写入数据如何提取保存的数据调用TensorBoard面板可能会遇到的问题 模块导入 首先从torch中导入tensorboard的SummaryWriter日志记录模块 from torch.utils.tensorboard import SummaryWriter然后导入要用到的os库&#xff0…

通过一个例子,说明Python的责任链设计模式有什么优缺点

责任链设计模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为设计模式&#xff0c;它允许将一个请求沿着处理者链进行传递&#xff0c;直到有一个处理者处理它为止。在Python中&#xff0c;这种模式可以通过多种方式实现&#xff0c;通常涉及到一系列对象…

方案设计|汽车轮胎数显胎压计方案

一、引言 数显轮胎胎压计是一个专门测量车辆轮胎气压的工具&#xff0c;它具有高精度测量的功能&#xff0c;能够帮助快速准确获取轮胎气压正确数值&#xff0c;保证轮胎使用安全。本文将对数显轮胎胎压计的方案技术进行分析&#xff0c;包括其基本原理、硬件构成、软件设计等方…

架构学习:什么是业务架构图?如何画业务架构图?

6.1~6.18&#xff0c;艾威618年中大促&#xff0c;钜惠来袭&#xff01;想报课但还没下手的小伙伴&#xff0c;都可以行动起来啦&#xff01;活动规则还是一如既往的简单、粗暴——直接立减、返现、抽奖以及送礼品&#xff01;了解活动详情&#xff0c;请点击这里》》 业务架构…

ActiViz中的vtkVolumeMapper

文章目录 一、简介二、工作原理三、核心功能四、使用步骤五、配置与优化六、案例与应用七、扩展与集成八、结论一、简介 vtkVolumeMapper是 ActiViz库中专为处理和渲染三维体积数据设计的核心组件。在诸如医学成像、地质科学、气象模型及工程仿真等多个领域,它扮演着至关重要…

【源码】SpringBoot事务注册原理

前言 对于数据库的操作&#xff0c;可能存在脏读、不可重复读、幻读等问题&#xff0c;从而引入了事务的概念。 事务 1.1 事务的定义 事务是指在数据库管理系统中&#xff0c;一系列紧密相关的操作序列&#xff0c;这些操作作为一个单一的工作单元执行。事务的特点是要么全…

实验9 浮动静态路由配置

--名称-- 一、 原理描述二、 实验目的三、 实验内容四、 实验配置五、 实验步骤 一、 原理描述 浮动静态路由也是一种特殊的静态路由&#xff0c;主要考虑链路冗余。浮动静态路由通过配置一条比主路由优先级低的静态路由&#xff0c;用于保证在主路由失效的情况下&#xff0c;…

代码随想录 day27|day28|day29

回溯2 切割问题&#xff1a;是在每个节点判断是否是要剪枝收割元素。 startidx 是切割起点&#xff0c;i是本次切割终点 分割回文串 复原ip地址 非递减子序列 都是在树的节点依照题意判断&#xff0c;之后决定是否剪枝。 也就是都有if判断来剪枝 。 下面是非递减子序列。 下…

Python | 虚拟环境的增删改查

mkvirtualenv创建虚拟环境 mkvirtualenv是用于在Pyhon中创建虚拟环境的命令。它通过使用vitualenv库来创建一个隔离的Python环境&#xff0c;以便您可以安装特定版本的Python包&#xff0c;而不会影响全局Python环境。 使用方法: 安装virtualenv&#xff1a;pip install vir…

前端将xlsx转成json

第一种方式&#xff0c;用js方式 1.1先安装插件 万事都离不开插件的支持首先要安装两个插件 1.2. 安装xlsx cnpm install xlsx --save注&#xff1a;这块我用的cnpm&#xff0c;原生的是npm&#xff0c;因为镜像的问题安装了cnpm&#xff0c;至于怎么装网上一搜一大堆 1.3安…

用langchain搭配最新模型ollama打造属于自己的gpt

langchain 前段时间去玩了一下langchain,熟悉了一下大模型的基本概念&#xff0c;使用等。前段时间meta的ollama模型发布了3.0,感觉还是比较强大的&#xff0c;在了解过后&#xff0c;自己去用前后端代码&#xff0c;调用ollama模型搭建了一个本地的gpt应用。 核心逻辑 开始搭…

Vue 封装elementUI的el-popover

1.封装公共组件 <template><div class"confirm-popover disInlineBlock ml10"><el-popover placement"bottom" v-model"visible" :trigger"triggerType"><div class"confirm-popover-popover"><…

vue3中进度条上加高亮圆点

实现效果 小圆点基于进度条定位&#xff08;left&#xff09;。 实现代码 <template><!-- 这块代码实现的功能&#xff1a;progressData遍历的年份进度数组&#xff0c;展示每年完成的进度--><ul><li v-for"(item, index) in progressData" :k…

Unity VR 零基础开发之 Pico4 MR

一、新建Unity2021.3.37 3D工程 二、切换到Android安卓平台 1、点击Unity编辑器左上角的Flie后&#xff0c;选择Build Setting选项。 2、弹出弹窗后&#xff0c;点击Android选项&#xff0c;然后再点击Switch Platform按钮切换成安卓平台。 3、切换完成后Android选项后面会显示…

Centos7下安装sqlplus并连接远程数据库

已经不用Oracle好多年了&#xff0c;然而近期有项目居然需要用到Oracle&#xff0c;并且是在内网的&#xff0c;所以没办法直接安装数据库连接工具来测试连接&#xff0c;只能在Linux的服务器上面安装sqlplus工具来连接&#xff0c;找资料完成了安装和连接&#xff0c;遂记录。…

3. QGis二次开发项目实践一之解决“无法定位程序输入点“

前言 本章讲述实现本项目实现过程中遇到的QGis二次开发库版本和Qt以及其他动态库的版本匹配问题问题复现 本项目是要作为一个子模块集成到用户的项目中本项目最初的开发环境为QGis3.28+Qt5.15.2,而当时并未问清楚用户开发环境所以交付给用户之后,出现了类似下图的问题 出现该…

uniapp利用canvas绘制ECG网格图附带心电图显示------代码

之前是一个关于如何绘制心电图的代码&#xff0c;后续需求是添加ECG的网格背景图也是利用canvas绘制的 先看代码&#xff1a; <template><view><page-head :title"title"></page-head><!-- 心电图显示区 --><view class"disp…

AI论文:一键生成论文的高效工具

说到这个问题&#xff0c;那真的得看你对“靠谱”的定义是怎样的啦&#xff1f; 众所周知&#xff0c;写论文是一项极其耗时间的事情&#xff0c;从开始的选题到文献资料搜索查阅&#xff0c;大纲整理等等一大堆的繁杂工作是极艰辛的。用AI写论文就不一样了&#xff0c;自动化…

深入QML:现代用户界面开发的强大工具20240606

深入QML&#xff1a;现代用户界面开发的强大工具 引言 在数字化时代&#xff0c;用户界面 (UI) 是任何应用程序不可或缺的一部分。为了提供流畅、直观且具有吸引力的用户体验&#xff0c;开发者需要一种强大且灵活的开发工具。QML&#xff08;Qt Modeling Language&#xff0…