Skip to content

Instantly share code, notes, and snippets.

@diraol
Last active February 15, 2021 11:34
Show Gist options
  • Save diraol/223ef5e5b6a9bbaae3d710226f419af6 to your computer and use it in GitHub Desktop.
Save diraol/223ef5e5b6a9bbaae3d710226f419af6 to your computer and use it in GitHub Desktop.
Python code to parse PCAP files with openflow (1.0) messages
"""Small script to parse pcap openflow files with python-openflow library.
######################################################################
Copyright (C) 2016, Diego Rabatone Oliveira <diraol AT diraol DOT eng DOT br>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
######################################################################
"""
from pyof.v0x01.common.header import Header
from pyof.v0x01.common.utils import new_message_from_header
from pcapfile import savefile
def parse_raw_of(raw_of_message):
"""Return a new OpenFlow Message from a binary OF message.
Args:
raw_of_message (bytes): The binary openflow message to be instantiated.
Return:
OpenFlow message: object from python-openflow library
"""
header = Header()
header.unpack(raw_of_message[:8])
message = new_message_from_header(header)
if header.length > 8:
message.unpack(raw_of_message[8:header.length.value])
return message
def get_raw_of(raw_eth):
"""Remove the Ethernet+IP+TCP.
Arg:
raw_eth (bytes): A binary object with a full ethernet packet.
Returns:
the binary payload from the given packet, without Ethernet, IP and TCP frames.
"""
return raw_eth[66:]
def load_pcap(filename='/tmp/of.pcap'):
"""Load and parse a pcap file.
This method will load a pcap file and parse it with the
pcapfile.savefile method, returning a new pcap/capfile object.
"""
raw_data = open(filename, 'rb')
capfile = savefile.load_savefile(raw_data, verbose=True)
return capfile
def get_pcap_packets(filename='/tmp/of.pcap'):
"""Return all packets from a pcap file.
Args:
filename (str): The name/location of the pcap file to be read.
Returns:
a list with "packets" objects from pcapfile library.
"""
capfile = load_pcap(filename)
return capfile.packets
def of_from_pcap_packet(pcap_packet):
"""Return a python-openflow message from a pcapfile packet file.
Arg:
pcap_packet an instance of a pcapfile packet file.
Returns:
An OpenFlow message as an instance of a python-openflow class.
"""
return parse_raw_of(get_raw_of(pcap_packet.raw()))
def main():
"""Return a list of python-openflow messages from a pcap file.
By default it will look for the '/tmp/of.pcap' file, read and parse it,
loop over all packets from this file and return the openflow parsed messages.
"""
packets = get_pcap_packets()
messages = [of_from_pcap_packet(packet) for packet in packets]
return messages
if __name__ == '__main__':
main()
"""Small script to parse pcap openflow files with python-openflow library.
License: GNU GPL v3
"""
from pyof.v0x01.common.header import Header
from pyof.v0x01.common.utils import new_message_from_header
from pcapfile import savefile
capfile = savefile.load_savefile(open('of.pcap', 'rb'))
messages = {}
exceptions = {}
for i, packet in enumerate(capfile.packets):
bin_data = packet.raw()[66:]
header = Header()
header.unpack(bin_data[:8])
message = new_message_from_header(header)
try:
message.unpack(bin_data[8:header.length.value])
messages[i+1] = message
except Exception as excp:
exceptions[i+1] = (str(header.message_type), str(excp))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment