1. ethernetPacket::HasProtocolError
方法
语法
capl
word ethernetPacket.HasProtocolError();
功能
若以太网报文的IP协议包含协议错误(如校验和错误、长度字段错误等),返回1。可使用ethernetPacket::GetProtocolErrorText获取错误描述。
参数
无
返回值
- 0:未检测到协议错误
- 1:检测到协议错误
可用性
- 版本:11.0 SP3
- 适用对象:Ethernet
- 支持场景:测量设置 ✓,仿真/测试设置 ✓
示例
capl
on ethernetPacket *
{
if (this.hasProtocolError())
{
char text[100];
this.GetProtocolErrorText(text);
write("Protocol error on Eth %d: %s", this.msgChannel, text);
}
}
2. ethernetPacket::HasVlan
方法
语法
capl
long ethernetPacket.HasVlan(); // 形式1
功能
返回VLAN标签的数量。
参数
无
返回值
VLAN标签的数量。
可用性
- 版本:10.0
- 适用对象:Ethernet
- 支持场景:测量设置 ✓,仿真/测试设置 ✓
示例
capl
on ethernetPacket *
{
if (this.hasVlan())
{
word vlanId;
vlanId = this.GetVlanId();
write("Received Ethernet packet with VLAN ID %d", vlanId);
}
}
3. ethernetPacket::PDUCount
方法
语法
capl
long ethernetPacket.PDUCount();
功能
返回报文包含的所有PDU(协议数据单元)数量。
参数
无
返回值
- ≥0:报文的PDU数量
- -1:总线类型错误
- -2:帧不支持访问PDU
- -3:PDU对象无效
- -4:PDU非接收类型
- -5:参数过小(如数组字节数不足)
- -6:报文或PDU不可用
- -7:PDU索引越界(使用PDUCount()确定数量)
可用性
- 版本:9.0
- 适用对象:Ethernet
- 支持场景:测量设置 ✓,仿真/测试设置 ✓
示例
无
4. ethernetPacket::PDUOffset
方法
语法
capl
long ethernetPacket.PDUOffset(long n);
功能
返回索引为n的PDU在报文数据载荷中的起始字节偏移量。
参数
- n:请求的PDU索引。第一个PDU索引为0,最后一个为PDUCount()-1
返回值
- ≥0:请求PDU的偏移量
- -1:总线类型错误
- -2:帧不支持访问PDU
- -3:PDU对象无效
- -4:PDU非接收类型
- -5:参数过小(如数组字节数不足)
- -6:报文或PDU不可用
- -7:PDU索引越界(使用PDUCount()确定数量)
可用性
- 版本:9.0
- 适用对象:Ethernet
- 支持场景:测量设置 ✓,仿真/测试设置 ✓
示例
无
5. ethernetPacket::protocol::field::GetData
方法
语法
capl
word ethernetPacket.<protocol>.<field>.GetData(word offset, char[] dest, word length);
word ethernetPacket.<protocol>.<field>.GetData(word offset, byte[] dest, word length);
word ethernetPacket.<protocol>.<field>.GetData(word offset, struct *dest);
word ethernetPacket.<protocol>.<field>.GetData(word offset, sysvarStruct dest);
功能
获取以太网报文中协议字段的数据,并复制到指定类型的目标缓冲区。若缓冲区过小,数据将被截断;若指定长度大于可用数据,仅复制可用数据并返回字节数。若<protocol>.<field>不可用,返回0。仅适用于非整数类型的协议字段。
参数
- dest:目标缓冲区(数据复制到此处)
- length:复制的字节数
- offset:载荷中开始复制数据的字节偏移量
返回值
复制到目标缓冲区的字节数。
可用性
- 版本:11.0 SP3
- 适用对象:Ethernet
- 支持场景:测量设置 ✓,仿真/测试设置 ✓
示例
capl
on ethernetPacket *
{
if (this.ipv6.IsAvailable())
{
byte ipv6AddrData[16];
long ipv6AddrDataLength;
char ipv6AddrStr[40];
ipv6AddrDataLength = this.ipv6.source.GetData(0, ipv6AddrData, elcount(ipv6AddrData));
if (ipv6AddrDataLength == 16)
{
ipGetAddressAsString(ipv6AddrData, ipv6AddrStr, elcount(ipv6AddrStr));
writeLineEx(kWritSink, 0, "Received IPv6 packet from %s", ipv6AddrStr);
}
}
}
6. ethernetPacket::protocol::field::IsAvailable
方法
语法
capl
long ethernetPacket.<protocol>.<field>.IsAvailable();
功能
判断以太网报文中的协议字段是否可用(适用于含可选字段或选项的协议)。
参数
无
返回值
- 1:协议字段可用
- 0:协议字段不可用
可用性
- 版本:11.0 SP3
- 适用对象:Ethernet
- 支持场景:测量设置 ✓,仿真/测试设置 ✓
示例
capl
on ethernetPacket *
{
if (this.udp.checksum.IsAvailable())
{
Write("Protocol field udp.checksum is available and has value 0x%X", this.udp.checksum);
}
}
7. ethernetPacket::protocol::field::ParseAddress
方法
语法
long ethernetPacket.<protocol>.<field>.ParseAddress( char addressAsString[] );
功能
设置协议字段(IPv4或IPv6地址类型)。地址必须按以下格式提供:
- IPv4地址:IPv4格式(如
192.168.1.1) - IPv6地址:IPv6格式(如
FC00::0001:0002)
仅适用于IPv4或IPv6地址字段。
参数
addressAsString:IPv4或IPv6格式的文本地址。
返回值
0:成功-1:错误-2:字段或协议不在数据包中-4:地址格式无效
可用性
- 版本:11.0 SP3
- 适用场景:测量设置、仿真/测试设置
示例1
capl
ethernetPacket pkt;
pkt.udp.Init();
pkt.ipv4.source.ParseAddress("192.168.1.1");
pkt.ipv4.destination.ParseAddress("255.255.255.255");
示例2
capl
ethernetPacket pkt;
pkt.ipv6.Init();
pkt.udp.Init();
pkt.ipv6.source.ParseAddress("FC01::1");
pkt.ipv6.destination.ParseAddress("FF00::1");
8. ethernetPacket::protocol::field::SetData
方法
语法
capl
word ethernetPacket.<protocol>.<field>.SetData( word offset, char[] data, word length );
word ethernetPacket.<protocol>.<field>.SetData( word offset, byte[] data, word length );
word ethernetPacket.<protocol>.<field>.SetData( word offset, struct * data );
word ethernetPacket.<protocol>.<field>.SetData( word offset, sysvarStruct data );
功能
设置以太网数据包中协议的 payload 数据。协议字段长度不变,若源数据大于字段长度则截断。若协议或字段不存在,返回0且不设置数据。
参数
data:源数据缓冲区length:复制到协议字段的字节数offset:协议字段数据中开始复制的字节偏移量
返回值
复制到以太网数据包的字节数。
可用性
- 版本:11.0 SP3
- 适用场景:测量设置、仿真/测试设置
示例
capl
ethernetPacket pkt;
byte ipv6AddrData[16];
// 初始化IPv6和UDP协议
pkt.ipv6.Init();
pkt.udp.Init();
// 设置IPv6地址
ipGetAddressAsArray("FC00::01", ipv6AddrData);
pkt.ipv6.source.SetData(0, ipv6AddrData, elcount(ipv6AddrData));
ipGetAddressAsArray("FC00::02", ipv6AddrData);
pkt.ipv6.destination.SetData(0, ipv6AddrData, elcount(ipv6AddrData));
// 设置UDP端口
pkt.udp.source = 40001;
pkt.udp.destination = 40002;
// 设置UDP payload
pkt.udp.SetData(0, "Hello", 5);
// 计算校验和并发送
pkt.CompletePacket();
output(pkt);
9. ethernetPacket::protocol::GetData
方法
语法
capl
word ethernetPacket.<protocol>.GetData( word offset, char[] dest, word length );
word ethernetPacket.<protocol>.GetData( word offset, byte[] dest, word length );
word ethernetPacket.<protocol>.GetData( word offset, struct * dest );
word ethernetPacket.<protocol>.GetData( word offset, sysvarStruct dest );
功能
获取以太网数据包中协议的 payload 数据,复制到目标缓冲区。若缓冲区过小则截断,若长度超过可用数据则仅复制可用部分。若协议不存在,返回0。
参数
dest:目标数据缓冲区length:复制的字节数offset:payload 中开始复制的字节偏移量
返回值
复制到目标缓冲区的字节数。
可用性
- 版本:11.0 SP3
- 适用场景:测量设置、仿真/测试设置
示例
capl
on ethernetPacket *
{
_align(1) struct MyData { long value1; long value2; } buffer;
if ((this.udp.IsAvailable()) && (this.udp.destination == 0xF123))
{
if (this.GetData(0, buffer, bufferLength) > 0)
{
write("Value1=%d, Value2=%d", buffer.value1, buffer.value2);
}
}
}
10. ethernetPacket::protocol::Init
方法
语法
long ethernetPacket.<protocol>.Init();
功能
初始化以太网数据包中的协议。若协议未包含在数据包中,则追加并初始化为默认值。若协议依赖底层协议(如UDP默认依赖IPv4),会自动添加底层协议。如需特定协议栈(如UDP over IPv6),需从低层到高层依次初始化(先IPv6,再UDP)。初始化后,高层协议将被移除。
返回值
0:成功-1:错误
可用性
- 版本:11.0 SP3
- 适用场景:测量设置、仿真/测试设置
示例1(IPv4 + UDP)
capl
ethernetPacket pkt;
pkt.udp.Init(); // 自动添加IPv4
pkt.ipv4.source.ParseAddress("192.168.1.1");
pkt.ipv4.destination.ParseAddress("192.168.1.255");
pkt.udp.source = 40001;
pkt.udp.destination = 40002;
pkt.udp.SetData(0, "Hello", 5);
pkt.CompletePacket();
output(pkt);
示例2(IPv6 + UDP)
capl
ethernetPacket pkt;
pkt.ipv6.Init(); // 先初始化IPv6
pkt.udp.Init(); // 再初始化UDP
pkt.ipv6.source.ParseAddress("FC00::01");
pkt.ipv6.destination.ParseAddress("FC00::02");
pkt.udp.source = 40001;
pkt.udp.destination = 40002;
pkt.udp.SetData(0, "Hello", 5);
pkt.CompletePacket();
output(pkt);