mirror of https://github.com/secdev/scapy.git
commit
0a29b17b5b
|
@ -1434,8 +1434,8 @@ class IP6PrefixField(_IPPrefixFieldBase):
|
|||
_IPPrefixFieldBase.__init__(self, name, default, wordbytes, 16, lambda a: inet_pton(socket.AF_INET6, a), lambda n: inet_ntop(socket.AF_INET6, n), length_from)
|
||||
|
||||
class UTCTimeField(IntField):
|
||||
__slots__ = ["epoch", "delta", "strf"]
|
||||
def __init__(self, name, default, epoch=None, strf="%a, %d %b %Y %H:%M:%S +0000"):
|
||||
__slots__ = ["epoch", "delta", "strf", "use_nano"]
|
||||
def __init__(self, name, default, epoch=None, use_nano=False, strf="%a, %d %b %Y %H:%M:%S +0000"):
|
||||
IntField.__init__(self, name, default)
|
||||
if epoch is None:
|
||||
mk_epoch = EPOCH
|
||||
|
@ -1444,9 +1444,12 @@ class UTCTimeField(IntField):
|
|||
self.epoch = mk_epoch
|
||||
self.delta = mk_epoch - EPOCH
|
||||
self.strf = strf
|
||||
self.use_nano = use_nano
|
||||
def i2repr(self, pkt, x):
|
||||
if x is None:
|
||||
x = 0
|
||||
elif self.use_nano:
|
||||
x = x/1e9
|
||||
x = int(x) + self.delta
|
||||
t = time.strftime(self.strf, time.gmtime(x))
|
||||
return "%s (%d)" % (t, x)
|
||||
|
|
|
@ -3,15 +3,47 @@
|
|||
## Copyright (C) Philippe Biondi <phil@secdev.org>
|
||||
## This program is published under a GPLv2 license
|
||||
## Netflow V5 appended by spaceB0x and Guillaume Valadon
|
||||
## Netflow V9 appended ny Gabriel Potter
|
||||
|
||||
"""
|
||||
Cisco NetFlow protocol v1 and v5
|
||||
Cisco NetFlow protocol v1, v5 and v9
|
||||
|
||||
|
||||
|
||||
- NetflowV9 build example:
|
||||
|
||||
pkt = NetflowHeader()/\
|
||||
NetflowHeaderV9()/\
|
||||
NetflowFlowsetV9(templates=[
|
||||
NetflowTemplateV9(templateID=258, template_fields=[
|
||||
NetflowTemplateFieldV9(fieldType=1),
|
||||
NetflowTemplateFieldV9(fieldType=62),
|
||||
]),
|
||||
NetflowTemplateV9(templateID=257, template_fields=[
|
||||
NetflowTemplateFieldV9(fieldType=1),
|
||||
NetflowTemplateFieldV9(fieldType=62),
|
||||
]),
|
||||
])/NetflowDataflowsetV9(templateID=258, records=[
|
||||
NetflowRecordV9(fieldValue=b"\x01\x02\x03\x05"),
|
||||
NetflowRecordV9(fieldValue=b"\x05\x03\x02\x01\x04\x03\x02\x01\x04\x03\x02\x01\x04\x03\x02\x01"),
|
||||
])/NetflowDataflowsetV9(templateID=257, records=[
|
||||
NetflowRecordV9(fieldValue=b"\x01\x02\x03\x04"),
|
||||
NetflowRecordV9(fieldValue=b"\x04\x03\x02\x01\x04\x03\x02\x01\x04\x03\x02\x01\x04\x03\x02\x01"),
|
||||
])/NetflowOptionsFlowsetV9(templateID=256, scopes=[NetflowOptionsFlowsetScopeV9(scopeFieldType=1, scopeFieldlength=4),
|
||||
NetflowOptionsFlowsetScopeV9(scopeFieldType=1, scopeFieldlength=3)],
|
||||
options=[NetflowOptionsFlowsetOptionV9(optionFieldType=1, optionFieldlength=2),
|
||||
NetflowOptionsFlowsetOptionV9(optionFieldType=1, optionFieldlength=1)])/\
|
||||
NetflowOptionsDataRecordV9(templateID=256, records=[NetflowOptionsRecordScopeV9(fieldValue=b"\x01\x02\x03\x04"),
|
||||
NetflowOptionsRecordScopeV9(fieldValue=b"\x01\x02\x03"),
|
||||
NetflowOptionsRecordOptionV9(fieldValue=b"\x01\x02"),
|
||||
NetflowOptionsRecordOptionV9(fieldValue=b"\x01")])
|
||||
"""
|
||||
|
||||
|
||||
from scapy.fields import *
|
||||
from scapy.packet import *
|
||||
from scapy.data import IP_PROTOS
|
||||
from scapy.layers.inet import UDP
|
||||
|
||||
|
||||
class NetflowHeader(Packet):
|
||||
|
@ -28,8 +60,8 @@ class NetflowHeaderV1(Packet):
|
|||
name = "Netflow Header v1"
|
||||
fields_desc = [ ShortField("count", 0),
|
||||
IntField("sysUptime", 0),
|
||||
IntField("unixSecs", 0),
|
||||
IntField("unixNanoSeconds", 0) ]
|
||||
UTCTimeField("unixSecs", 0),
|
||||
UTCTimeField("unixNanoSeconds", 0, use_nano=True) ]
|
||||
|
||||
|
||||
class NetflowRecordV1(Packet):
|
||||
|
@ -66,8 +98,8 @@ class NetflowHeaderV5(Packet):
|
|||
name = "Netflow Header v5"
|
||||
fields_desc = [ ShortField("count", 0),
|
||||
IntField("sysUptime", 0),
|
||||
IntField("unixSecs", 0),
|
||||
IntField("unixNanoSeconds", 0),
|
||||
UTCTimeField("unixSecs", 0),
|
||||
UTCTimeField("unixNanoSeconds", 0, use_nano=True),
|
||||
IntField("flowSequence",0),
|
||||
ByteField("engineType", 0),
|
||||
ByteField("engineID", 0),
|
||||
|
@ -101,3 +133,316 @@ class NetflowRecordV5(Packet):
|
|||
bind_layers( NetflowHeader, NetflowHeaderV5, version=5)
|
||||
bind_layers( NetflowHeaderV5, NetflowRecordV5 )
|
||||
bind_layers( NetflowRecordV5, NetflowRecordV5 )
|
||||
|
||||
#########################################
|
||||
### Netflow Version 9
|
||||
#########################################
|
||||
|
||||
# https://www.ietf.org/rfc/rfc3954.txt
|
||||
|
||||
NetflowV9TemplateFieldTypes = {
|
||||
1: "IN_BYTES",
|
||||
2: "IN_PKTS",
|
||||
3: "FLOWS",
|
||||
4: "PROTOCOL",
|
||||
5: "TOS",
|
||||
6: "TCP_FLAGS",
|
||||
7: "L4_SRC_PORT",
|
||||
8: "IPV4_SRC_ADDR",
|
||||
9: "SRC_MASK",
|
||||
10: "INPUT_SNMP",
|
||||
11: "L4_DST_PORT",
|
||||
12: "IPV4_DST_ADDR",
|
||||
13: "DST_MASK",
|
||||
14: "OUTPUT_SNMP",
|
||||
15: "IPV4_NEXT_HOP",
|
||||
16: "SRC_AS",
|
||||
17: "DST_AS",
|
||||
18: "BGP_IPV4_NEXT_HOP",
|
||||
19: "MUL_DST_PKTS",
|
||||
20: "MUL_DST_BYTES",
|
||||
21: "LAST_SWITCHED",
|
||||
22: "FIRST_SWITCHED",
|
||||
23: "OUT_BYTES",
|
||||
24: "OUT_PKTS",
|
||||
27: "IPV6_SRC_ADDR",
|
||||
28: "IPV6_DST_ADDR",
|
||||
29: "IPV6_SRC_MASK",
|
||||
30: "IPV6_DST_MASK",
|
||||
31: "IPV6_FLOW_LABEL",
|
||||
32: "ICMP_TYPE",
|
||||
33: "MUL_IGMP_TYPE",
|
||||
34: "SAMPLING_INTERVAL",
|
||||
35: "SAMPLING_ALGORITHM",
|
||||
36: "FLOW_ACTIVE_TIMEOUT",
|
||||
37: "FLOW_INACTIVE_TIMEOUT",
|
||||
38: "ENGINE_TYPE",
|
||||
39: "ENGINE_ID",
|
||||
40: "TOTAL_BYTES_EXP",
|
||||
41: "TOTAL_PKTS_EXP",
|
||||
42: "TOTAL_FLOWS_EXP",
|
||||
46: "MPLS_TOP_LABEL_TYPE",
|
||||
47: "MPLS_TOP_LABEL_IP_ADDR",
|
||||
48: "FLOW_SAMPLER_ID",
|
||||
49: "FLOW_SAMPLER_MODE",
|
||||
50: "FLOW_SAMPLER_RANDOM_INTERVAL",
|
||||
55: "DST_TOS",
|
||||
56: "SRC_MAC",
|
||||
57: "DST_MAC",
|
||||
58: "SRC_VLAN",
|
||||
59: "DST_VLAN",
|
||||
60: "IP_PROTOCOL_VERSION",
|
||||
61: "DIRECTION",
|
||||
62: "IPV6_NEXT_HOP",
|
||||
63: "BGP_IPV6_NEXT_HOP",
|
||||
64: "IPV6_OPTION_HEADERS",
|
||||
70: "MPLS_LABEL_1",
|
||||
71: "MPLS_LABEL_2",
|
||||
72: "MPLS_LABEL_3",
|
||||
73: "MPLS_LABEL_4",
|
||||
74: "MPLS_LABEL_5",
|
||||
75: "MPLS_LABEL_6",
|
||||
76: "MPLS_LABEL_7",
|
||||
77: "MPLS_LABEL_8",
|
||||
78: "MPLS_LABEL_9",
|
||||
79: "MPLS_LABEL_10",
|
||||
}
|
||||
|
||||
ScopeFieldTypes = {
|
||||
1: "System",
|
||||
2: "Interface",
|
||||
3: "Line card",
|
||||
4: "Cache",
|
||||
5: "Template",
|
||||
}
|
||||
|
||||
NetflowV9TemplateFieldDefaultLengths = {
|
||||
1: 4,
|
||||
2: 4,
|
||||
3: 4,
|
||||
4: 1,
|
||||
5: 1,
|
||||
6: 1,
|
||||
7: 2,
|
||||
8: 4,
|
||||
9: 1,
|
||||
10: 2,
|
||||
11: 2,
|
||||
12: 4,
|
||||
13: 1,
|
||||
14: 2,
|
||||
15: 4,
|
||||
16: 2,
|
||||
17: 2,
|
||||
18: 4,
|
||||
19: 4,
|
||||
20: 4,
|
||||
21: 4,
|
||||
22: 4,
|
||||
23: 4,
|
||||
24: 4,
|
||||
27: 16,
|
||||
28: 16,
|
||||
29: 1,
|
||||
30: 1,
|
||||
31: 3,
|
||||
32: 2,
|
||||
33: 1,
|
||||
34: 4,
|
||||
35: 1,
|
||||
36: 2,
|
||||
37: 2,
|
||||
38: 1,
|
||||
39: 1,
|
||||
40: 4,
|
||||
41: 4,
|
||||
42: 4,
|
||||
46: 1,
|
||||
47: 4,
|
||||
48: 1,
|
||||
49: 1,
|
||||
50: 4,
|
||||
55: 1,
|
||||
56: 6,
|
||||
57: 6,
|
||||
58: 2,
|
||||
59: 2,
|
||||
60: 1,
|
||||
61: 1,
|
||||
62: 16,
|
||||
63: 16,
|
||||
64: 4,
|
||||
70: 3,
|
||||
71: 3,
|
||||
72: 3,
|
||||
73: 3,
|
||||
74: 3,
|
||||
75: 3,
|
||||
76: 3,
|
||||
77: 3,
|
||||
78: 3,
|
||||
79: 3,
|
||||
}
|
||||
|
||||
class NetflowHeaderV9(Packet):
|
||||
name = "Netflow Header V9"
|
||||
fields_desc = [ ShortField("count", 0),
|
||||
IntField("sysUptime", 0),
|
||||
UTCTimeField("unixSecs", 0),
|
||||
IntField("packageSequence",0),
|
||||
IntField("SourceID", 0) ]
|
||||
|
||||
class NetflowTemplateFieldV9(Packet):
|
||||
name = "Netflow Flowset Template Field V9"
|
||||
fields_desc = [ ShortEnumField("fieldType", None, NetflowV9TemplateFieldTypes),
|
||||
ShortField("fieldLength", 0) ]
|
||||
def __init__(self, *args, **kwargs):
|
||||
Packet.__init__(self, *args, **kwargs)
|
||||
if self.fieldType != None:
|
||||
self.fieldLength = NetflowV9TemplateFieldDefaultLengths[self.fieldType]
|
||||
|
||||
def default_payload_class(self, p):
|
||||
return conf.padding_layer
|
||||
|
||||
class NetflowTemplateV9(Packet):
|
||||
name = "Netflow Flowset Template V9"
|
||||
fields_desc = [ ShortField("templateID", 255),
|
||||
FieldLenField("fieldCount", None, count_of="template_fields"),
|
||||
PacketListField("template_fields", [], NetflowTemplateFieldV9,
|
||||
count_from = lambda pkt: pkt.fieldCount) ]
|
||||
|
||||
def default_payload_class(self, p):
|
||||
return conf.padding_layer
|
||||
|
||||
class NetflowFlowsetV9(Packet):
|
||||
name = "Netflow FlowSet V9"
|
||||
fields_desc = [ ShortField("flowSetID", 0),
|
||||
FieldLenField("length", None, length_of="templates", adjust=lambda pkt,x:x+4),
|
||||
PacketListField("templates", [], NetflowTemplateV9,
|
||||
length_from = lambda pkt: pkt.length-4) ]
|
||||
|
||||
class NetflowRecordV9(Packet):
|
||||
name = "Netflow DataFlowset Record V9"
|
||||
fields_desc = [ StrField("fieldValue", "") ]
|
||||
|
||||
def default_payload_class(self, p):
|
||||
return conf.padding_layer
|
||||
|
||||
class NetflowDataflowsetV9(Packet):
|
||||
name = "Netflow DataFlowSet V9"
|
||||
fields_desc = [ ShortField("templateID", 255),
|
||||
FieldLenField("length", None, length_of="records", adjust = lambda pkt,x:x+4),
|
||||
PadField(PacketListField("records", [], NetflowRecordV9,
|
||||
length_from = lambda pkt: pkt.length-4),
|
||||
4, padwith=b"\x00") ]
|
||||
|
||||
@classmethod
|
||||
def dispatch_hook(cls, _pkt=None, *args, **kargs):
|
||||
if _pkt:
|
||||
if _pkt[:2] == b"\x00\x01":
|
||||
return NetflowOptionsFlowsetV9
|
||||
return cls
|
||||
|
||||
def post_dissection(self, pkt):
|
||||
# We need the whole packet to be dissected to access field def in NetflowFlowsetV9
|
||||
root = pkt.firstlayer()
|
||||
current = root
|
||||
# Get all linked NetflowFlowsetV9
|
||||
while current.payload.haslayer(NetflowFlowsetV9):
|
||||
current = current.payload[NetflowFlowsetV9]
|
||||
for ntv9 in current.templates:
|
||||
current_ftl = root.getlayer(NetflowDataflowsetV9, templateID=ntv9.templateID)
|
||||
if current_ftl:
|
||||
# Matched
|
||||
if len(current_ftl.records) > 1:
|
||||
# post_dissection is not necessary
|
||||
return
|
||||
# All data is stored in one record, awaiting to be splitted
|
||||
data = current_ftl.records.pop(0).fieldValue
|
||||
res = []
|
||||
# Now, according to the NetflowFlowsetV9 data, re-dissect NetflowDataflowsetV9
|
||||
for template in ntv9.template_fields:
|
||||
_l = template.fieldLength
|
||||
if _l:
|
||||
res.append(NetflowRecordV9(data[:_l]))
|
||||
data = data[_l:]
|
||||
if data:
|
||||
res.append(Raw(data))
|
||||
# Inject dissected data
|
||||
current_ftl.records = res
|
||||
else:
|
||||
warning("[NetflowFlowsetV9 templateID=%s]: No matching NetflowDataflowsetV9 !" % ntv9.templateID)
|
||||
|
||||
class NetflowOptionsFlowsetScopeV9(Packet):
|
||||
name = "Netflow Options Template FlowSet V9 - Scope"
|
||||
fields_desc = [ ShortEnumField("scopeFieldType", None, ScopeFieldTypes),
|
||||
ShortField("scopeFieldlength", 0) ]
|
||||
|
||||
def default_payload_class(self, p):
|
||||
return conf.padding_layer
|
||||
|
||||
class NetflowOptionsRecordScopeV9(NetflowRecordV9):
|
||||
name = "Netflow Options Template Record V9 - Scope"
|
||||
|
||||
class NetflowOptionsRecordOptionV9(NetflowRecordV9):
|
||||
name = "Netflow Options Template Record V9 - Option"
|
||||
|
||||
class NetflowOptionsFlowsetOptionV9(Packet):
|
||||
name = "Netflow Options Template FlowSet V9 - Option"
|
||||
fields_desc = [ ShortEnumField("optionFieldType", None, NetflowV9TemplateFieldTypes),
|
||||
ShortField("optionFieldlength", 0) ]
|
||||
|
||||
def default_payload_class(self, p):
|
||||
return conf.padding_layer
|
||||
|
||||
class NetflowOptionsFlowsetV9(Packet):
|
||||
name = "Netflow Options Template FlowSet V9"
|
||||
fields_desc = [ ShortField("flowSetID", 1),
|
||||
LenField("length", None),
|
||||
ShortField("templateID", 255),
|
||||
FieldLenField("option_scope_length", None, length_of="scopes"),
|
||||
FieldLenField("option_field_length", None, length_of="options"),
|
||||
PacketListField("scopes", [], NetflowOptionsFlowsetScopeV9,
|
||||
length_from = lambda pkt: pkt.option_scope_length),
|
||||
PadField(PacketListField("options", [], NetflowOptionsFlowsetOptionV9,
|
||||
length_from = lambda pkt: pkt.option_field_length),
|
||||
4, padwith=b"\x00") ]
|
||||
|
||||
class NetflowOptionsDataRecordV9(NetflowDataflowsetV9):
|
||||
name = "Netflow Options Data Record V9"
|
||||
fields_desc = [ ShortField("templateID", 255),
|
||||
FieldLenField("length", None, length_of="records", adjust = lambda pkt,x:x+4),
|
||||
PadField(PacketListField("records", [], NetflowRecordV9,
|
||||
length_from = lambda pkt: pkt.length-4),
|
||||
4, padwith=b"\x00") ]
|
||||
|
||||
def post_dissection(self, pkt):
|
||||
options_data_record = pkt[NetflowOptionsDataRecordV9]
|
||||
if pkt.haslayer(NetflowOptionsFlowsetV9):
|
||||
options_flowset = pkt[NetflowOptionsFlowsetV9]
|
||||
data = options_data_record.records.pop(0).fieldValue
|
||||
res = []
|
||||
# Now, according to the NetflowOptionsFlowsetV9 data, re-dissect NetflowOptionsDataRecordV9
|
||||
for scope in options_flowset.scopes:
|
||||
_l = scope.scopeFieldlength
|
||||
if _l:
|
||||
res.append(NetflowOptionsRecordScopeV9(data[:_l]))
|
||||
data = data[_l:]
|
||||
|
||||
# Now, according to the NetflowOptionsFlowsetV9 data, re-dissect NetflowOptionsDataRecordV9
|
||||
for option in options_flowset.options:
|
||||
_l = option.optionFieldlength
|
||||
if _l:
|
||||
res.append(NetflowOptionsRecordOptionV9(data[:_l]))
|
||||
data = data[_l:]
|
||||
if data:
|
||||
res.append(Raw(data))
|
||||
# Inject dissected data
|
||||
options_data_record.records = res
|
||||
|
||||
bind_layers( NetflowHeader, NetflowHeaderV9, version=9 )
|
||||
bind_layers( NetflowHeaderV9, NetflowFlowsetV9 )
|
||||
bind_layers( NetflowFlowsetV9, NetflowDataflowsetV9 )
|
||||
bind_layers( NetflowDataflowsetV9, NetflowDataflowsetV9 )
|
||||
|
||||
bind_layers( NetflowOptionsFlowsetV9, NetflowOptionsDataRecordV9 )
|
||||
|
|
|
@ -5254,6 +5254,57 @@ raw(NetflowHeader()/NetflowHeaderV5(count=1)/NetflowRecordV5(dst="192.168.0.1"))
|
|||
nf5 = NetflowHeader(b'\x00\x05\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x01\x7f\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00<\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x01\x7f\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00<\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00')
|
||||
nf5.version == 5 and nf5[NetflowHeaderV5].count == 2 and isinstance(nf5[NetflowRecordV5].payload, NetflowRecordV5)
|
||||
|
||||
############
|
||||
############
|
||||
+ Netflow v9
|
||||
|
||||
= NetflowHeaderV9 - advanced building
|
||||
|
||||
import time
|
||||
|
||||
pkt = NetflowHeader()/\
|
||||
NetflowHeaderV9(unixSecs=int(time.time()))/\
|
||||
NetflowFlowsetV9(templates=[
|
||||
NetflowTemplateV9(templateID=258, template_fields=[
|
||||
NetflowTemplateFieldV9(fieldType=1),
|
||||
NetflowTemplateFieldV9(fieldType=62),
|
||||
]),
|
||||
NetflowTemplateV9(templateID=257, template_fields=[
|
||||
NetflowTemplateFieldV9(fieldType=1),
|
||||
NetflowTemplateFieldV9(fieldType=62),
|
||||
]),
|
||||
])/NetflowDataflowsetV9(templateID=258, records=[
|
||||
NetflowRecordV9(fieldValue=b"\x01\x02\x03\x05"),
|
||||
NetflowRecordV9(fieldValue=b"\x05\x03\x02\x01\x04\x03\x02\x01\x04\x03\x02\x01\x04\x03\x02\x01"),
|
||||
])/NetflowDataflowsetV9(templateID=257, records=[
|
||||
NetflowRecordV9(fieldValue=b"\x01\x02\x03\x04"),
|
||||
NetflowRecordV9(fieldValue=b"\x04\x03\x02\x01\x04\x03\x02\x01\x04\x03\x02\x01\x04\x03\x02\x01"),
|
||||
])/NetflowOptionsFlowsetV9(templateID=256, scopes=[NetflowOptionsFlowsetScopeV9(scopeFieldType=1, scopeFieldlength=4),
|
||||
NetflowOptionsFlowsetScopeV9(scopeFieldType=1, scopeFieldlength=3)],
|
||||
options=[NetflowOptionsFlowsetOptionV9(optionFieldType=1, optionFieldlength=2),
|
||||
NetflowOptionsFlowsetOptionV9(optionFieldType=1, optionFieldlength=1)])/\
|
||||
NetflowOptionsDataRecordV9(templateID=256, records=[NetflowOptionsRecordScopeV9(fieldValue=b"\x01\x02\x03\x04"),
|
||||
NetflowOptionsRecordScopeV9(fieldValue=b"\x01\x02\x03"),
|
||||
NetflowOptionsRecordOptionV9(fieldValue=b"\x01\x02"),
|
||||
NetflowOptionsRecordOptionV9(fieldValue=b"\x01")])
|
||||
|
||||
assert pkt[NetflowFlowsetV9].templates[0].template_fields[0].fieldLength == 4
|
||||
assert pkt[NetflowFlowsetV9].templates[0].template_fields[1].fieldLength == 16
|
||||
|
||||
= NetflowHeaderV9 - advanced dissection
|
||||
|
||||
d = NetflowHeader(raw(pkt))
|
||||
d.show()
|
||||
assert len(d[NetflowDataflowsetV9].records) == 2
|
||||
assert d.getlayer(NetflowDataflowsetV9, templateID=257).records[0].fieldValue == b"\x01\x02\x03\x04"
|
||||
assert d.getlayer(NetflowDataflowsetV9, templateID=257).records[1].fieldValue == b"\x04\x03\x02\x01\x04\x03\x02\x01\x04\x03\x02\x01\x04\x03\x02\x01"
|
||||
|
||||
assert d.getlayer(NetflowDataflowsetV9, templateID=258).records[0].fieldValue == b"\x01\x02\x03\x05"
|
||||
assert d.getlayer(NetflowDataflowsetV9, templateID=258).records[1].fieldValue == b"\x05\x03\x02\x01\x04\x03\x02\x01\x04\x03\x02\x01\x04\x03\x02\x01"
|
||||
|
||||
assert d[NetflowOptionsFlowsetV9].scopes[0].scopeFieldType == 1
|
||||
assert d[NetflowOptionsDataRecordV9].records[1].fieldValue == b"\x01\x02\x03"
|
||||
assert d[NetflowOptionsDataRecordV9].records[3].fieldValue == b"\x01"
|
||||
|
||||
############
|
||||
############
|
||||
|
|
Loading…
Reference in New Issue