LLDP报文格式

LLDP报文格式前面已经知道了FloodlightController是通过从SW发送LLDP帧来获得链路信息的,链路层发现协议(L2)是通过在本地网络中广播LLDP报文来通告自己的设备信息,从而服务于拓扑计算,(wikipedia:LLDPinformationissentbydevicesfromeachoftheirinterfacesatafixedinterval,i

大家好,又见面了,我是你们的朋友全栈君。


     前面已经知道了Floodlight Controller是通过从SW发送LLDP帧来获得链路信息的,链路层发现协议(L2)是通过在本地网络中广播LLDP报文来通告自己的设备信息,从而服务于拓扑计算,(wikipedia:LLDP information is sent by devices from each of their interfaces at a fixed interval, in the form of an Ethernet frame. Each frame contains one LLDP Data Unit (LLDPDU). Each LLDPDU is a sequence of type-length-value (TLV) structures.)报文格式如下:
LLDP报文格式

type-length-value 的设计很常见(比如netlink中attribute也是这种格式),这里的TLV结构是:
LLDP报文格式
LLDP报文格式

此时再看代码就很容易理解:
public 
class 
LLDPTLV {
     
protected 
byte 
type 
;
     
protected 
short 
length 
;
     
protected 
byte
[] 
value 
;

     
public 
byte 
getType() {
           
return 
type 
;
     }

     
public 
LLDPTLV setType( 
byte 
type) {
           
this
.
type 
= type;
           
return 
this 
;
     }

     
public 
short 
getLength() {
           
return 
length 
;
     }

     
public 
LLDPTLV setLength( 
short 
length) {
           
this
.
length 
= length;
           
return 
this 
;
     }

     
public 
byte
[] getValue() {
           
return 
value 
;
     }

     
public 
LLDPTLV setValue( 
byte
[] value) {
           
this
.
value 
= value;
           
return 
this 
;
     }

     
// serialization – Turn data into a stream of bytes
     
public 
byte
[] serialize() {
           
// type = 7 bits
           
// info string length 9 bits, each value == byte
           
// info string
           
short 
scratch = (
short
) (((0x7f & 
this
. 
type
) << 9) | (0x1ff & 
this 
.
length 
));
           
// 7+9 = 2B
           
byte
[] data = 
new 
byte
[2 + 
this
.
length 
];
          ByteBuffer bb = ByteBuffer. wrap(data);
          bb.putShort(scratch);
           
if 
(
this 
.
value 
!= 
null
)
              bb.put( 
this
.
value 
);
           
return 
data;
     }

     
// deserialization – Turn a stream of bytes back into a copy of the original
     
// object.
     
public 
LLDPTLV deserialize(ByteBuffer bb) {
           
short 
sscratch;
          sscratch = bb.getShort();
           
this
.
type 
= (
byte
) ((sscratch >> 9) & 0x7f);
           
this
.
length 
= (
short
) (sscratch & 0x1ff);
           
if 
(
this 
.
length 
> 0) {
               
this
.
value 
= 
new 
byte
[ 
this
.
length 
];

               
// if there is an underrun just toss the TLV
               
if 
(bb.remaining() < 
this
.
length
)
                    
return 
null 
;
              bb.get( 
this
.
value 
);
          }
           
return 
this 
;
     }
}

public 
class 
LLDP 
extends 
BasePacket {
     
protected 
LLDPTLV 
chassisId
;
     
protected 
LLDPTLV 
portId
;
     
protected 
LLDPTLV 
ttl
;
     
protected 
List<LLDPTLV> 
optionalTLVList
;
     
protected 
short 
ethType 
;
     
//上述几个字段都是LLDP协议规定的

     
public 
LLDP() {
           
this
.
optionalTLVList 
= 
new 
ArrayList<LLDPTLV>();
           
this
.
ethType 
= Ethernet.
TYPE_LLDP
; 
// 0x88cc
     }
     
public 
LLDPTLV getChassisId() {
           
return 
chassisId 
;
     }

     
public 
LLDP setChassisId(LLDPTLV chassisId) {
           
this
.
chassisId 
= chassisId;
           
return 
this 
;
     }

     
public 
LLDPTLV getPortId() {
           
return 
portId 
;
     }

     
public 
LLDP setPortId(LLDPTLV portId) {
           
this
.
portId 
= portId;
           
return 
this 
;
     }

     
public 
LLDPTLV getTtl() {
           
return 
ttl 
;
     }

     
public 
LLDP setTtl(LLDPTLV ttl) {
           
this
.
ttl 
= ttl;
           
return 
this 
;
     }

     
public 
List<LLDPTLV> getOptionalTLVList() {
           
return 
optionalTLVList 
;
     }

     
public 
LLDP setOptionalTLVList(List<LLDPTLV> optionalTLVList) {
           
this
.
optionalTLVList 
= optionalTLVList;
           
return 
this 
;
     }

     
@Override
     
public 
byte
[] serialize() {
           
int 
length = 2 + 
this
.
chassisId
.getLength() + 2
                   + 
this
.
portId 
.getLength() + 2 + 
this
.
ttl 
.getLength() + 2;
           
for 
(LLDPTLV tlv : 
this
.
optionalTLVList
) {
              length += 2 + tlv.getLength();
          }

           
byte
[] data = 
new 
byte
[length];
          ByteBuffer bb = ByteBuffer. wrap(data);
          bb.put( 
this
.
chassisId 
.serialize());
          bb.put( 
this
.
portId 
.serialize());
          bb.put( 
this
.
ttl 
.serialize());
           
for 
(LLDPTLV tlv : 
this
.
optionalTLVList
) {
              bb.put(tlv.serialize());
          }
          bb.putShort(( 
short
) 0); 
// End of LLDPDU

           
if 
(
this 
.
parent 
!= 
null 
&& 
this
. 
parent 
instanceof 
Ethernet)
              ((Ethernet) 
this
.
parent 
).setEtherType(
ethType
);

           
return 
data;
     }

     
@Override
     
public 
IPacket deserialize( 
byte
[] data, 
int 
offset, 
int 
length) {
          ByteBuffer bb = ByteBuffer. wrap(data, offset, length);
          LLDPTLV tlv;
           
do 
{
              tlv = 
new 
LLDPTLV().deserialize(bb);

               
// if there was a failure to deserialize stop processing TLVs
               
if 
(tlv == 
null 
)
                    
break
;
               
switch 
(tlv.getType()) {
               
case 
0x0:
                    
// can throw this one away, its just an end delimiter
                    
break
;
               
case 
0x1:
                    
this
.
chassisId 
= tlv;
                    
break
;
               
case 
0x2:
                    
this
.
portId 
= tlv;
                    
break
;
               
case 
0x3:
                    
this
.
ttl 
= tlv;
                    
break
;
               
default
:
                    
this
.
optionalTLVList 
.add(tlv);
                    
break
;
              }
          } 
while 
(tlv.getType() != 0 && bb.hasRemaining());
           
return 
this 
;
     }
}


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/140278.html原文链接:https://javaforall.net

(0)
上一篇 2022年5月28日 下午2:16
下一篇 2022年5月28日 下午2:16


相关推荐

  • mybatis实现原理,动态代理_jdk动态代理实现原理

    mybatis实现原理,动态代理_jdk动态代理实现原理前言一直以来都在使用MyBatis做持久化框架,也知道当我们定义XXXMapper接口类并利用它来做CRUD操作时,Mybatis是利用了动态代理的技术帮我们生成代理类。那么动态代理内部的实现细节到底是怎么的呀?XXXMapper.java类和XXXMapper.xml到底是如何关联起来的呀?本篇文章就来详细剖析下MyBatis的动态代理的具体实现机制。MyBatis的核心组件及应用在详细探究MyBatis中动态代理机制之前,先来补充一下基础知识,认识一下MyBatis的核心组件。SqlSessio

    2022年8月8日
    7
  • java sm9_一个支持国密SM2/SM3/SM4/SM9/ZUC/SSL的密码工具箱

    java sm9_一个支持国密SM2/SM3/SM4/SM9/ZUC/SSL的密码工具箱TheGmSSLProj 网址 http gmssl org docs quickstart html 在网上闲逛时发现一个工具 SSL 支持国密算法 看着比较高大上 还没有用呢 记下来 备用 快速上手指南介绍 GmSSL 的编译 安装和 gmssl 命令行工具的基本指令 下载源代码 zip 解压缩至当前工作目录 unzipGmSSL master zip 编译与安装 Linux 平台 其他平台

    2026年3月17日
    2
  • 10.10.10.1可以设置为网关吗_个人如何做跨境电商

    10.10.10.1可以设置为网关吗_个人如何做跨境电商【大型电商项目开发】商品服务-配置网关路由与路径重写-10

    2022年7月28日
    7
  • 电平转换方法_为什么低电平有效

    电平转换方法_为什么低电平有效咸鱼NOFASHION硬件开发过程中常常遇到电平不匹配的问题,就这个问题作简要说明与总结:电平匹配或者电平转换方法:直接选用转换芯片,此方案对于设计来说最简单、通信速率高、性能稳定、成本一般较高;但作为一个合格的硬件工程师,需要考虑成本、空间、结构等问…

    2022年8月10日
    8
  • VMware Ubuntu安装详细过程(详细图解)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!一.下载Ubuntu镜像文件下载地址:http://mirrors.aliyun.com/ubuntu-releases/16.04/进入下载页面,如下图选择版本点击即可下载二.下载及安装VMware下载地址:https://pan.baidu.com/s/1aEEI-DRa4oKeViddxW2CPA…

    2022年4月7日
    73
  • Python 颜色代码大全

    Python 颜色代码大全常用的 Python 颜色代码

    2026年3月19日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号