Last active
February 15, 2021 11:34
-
-
Save diraol/223ef5e5b6a9bbaae3d710226f419af6 to your computer and use it in GitHub Desktop.
Python code to parse PCAP files with openflow (1.0) messages
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""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