Scenario
I have a PCAP containing Netflow v10/ IPFIX data templates and data flows and would like to replay the PCAP. Before the packet is sent, I would like to update one of the flow data fields (i.e. startTime with the current time).
Current code
My current code is able to read the PCAP, grab the last layer (Netflowv10), create a socket and send the packet over the interface. The socket takes care of the Ethernet -> IP -> UDP layers, and the 'getlayer' function in Scapy preserves the Netflow v10 template & data flow layers as is from the donor PCAP.
Question
The issue I would like help with is, how do I update the startTime flow data field?.
Code
I have only provided the Python3 code relating to the issue in scope for this question, relating to Scapy
packets = sniff(session=NetflowSession, offline=open(pcap_file, "rb"))
for packet in packets:
if packet.haslayer(NetflowDataflowsetV9):
# This return the NetflowDateflowset Records key/value pairs
flowset = netflowv9_defragment(packet[NetflowDataflowsetV9].records)
Any pointers or suggestions would greatly be appreciated. Thank you in advance :)
First of, the netflowv9_defragment
should not be used here: it has the same effect as session=NetflowSession
and should be given a list of packets.
The main help page for flow set is https://scapy.readthedocs.io/en/latest/layers/netflow.html but there are also some test cases in https://github.com/secdev/scapy/blob/master/test/scapy/layers/netflow.uts that give info on how the module works.
You could do something like
for packet in packets:
if packet.haslayer(NetflowDataflowsetV9):
for rec in packet.records:
if 'startTime' in rec:
rec.startTime = 12345
The build example is in my opinion a great way of understanding how netflow packets are build:
header = Ether()/IP()/UDP()
netflow_header = NetflowHeader()/NetflowHeaderV9()
# Let's first build the template. Those need an ID > 255.
# The (full) list of possible fieldType is available in the
# NetflowV910TemplateFieldTypes list. You can also use the int value.
flowset = NetflowFlowsetV9(
templates=[NetflowTemplateV9(
template_fields=[
NetflowTemplateFieldV9(fieldType="IN_BYTES", fieldLength=1),
NetflowTemplateFieldV9(fieldType="IN_PKTS", fieldLength=4),
NetflowTemplateFieldV9(fieldType="PROTOCOL"),
NetflowTemplateFieldV9(fieldType="IPV4_SRC_ADDR"),
NetflowTemplateFieldV9(fieldType="IPV4_DST_ADDR"),
],
templateID=256,
fieldCount=5)
],
flowSetID=0
)
# Let's generate the record class. This will be a Packet class
# In case you provided several templates in ghe flowset, you will need
# to pass the template ID as second parameter
recordClass = GetNetflowRecordV9(flowset)
# Now lets build the data records
dataFS = NetflowDataflowsetV9(
templateID=256,
records=[ # Some random data.
recordClass(
IN_BYTES=b"\x12",
IN_PKTS=b"\0\0\0\0",
PROTOCOL=6,
IPV4_SRC_ADDR="192.168.0.10",
IPV4_DST_ADDR="192.168.0.11"
),
recordClass(
IN_BYTES=b"\x0c",
IN_PKTS=b"\1\1\1\1",
PROTOCOL=3,
IPV4_SRC_ADDR="172.0.0.10",
IPV4_DST_ADDR="172.0.0.11"
)
],
)
pkt = header / netflow_header / flowset / dataFS