| o |
| from message import * |
| from error import * |
| from action import * |
| from action_list import action_list |
| from ofp import * |
| |
| """ |
| of_message.py |
| Contains wrapper functions and classes for the of_message namespace |
| that are generated by hand. It includes the rest of the wrapper |
| function information into the of_message namespace |
| """ |
| |
| # These message types are subclassed |
| msg_type_subclassed = [ |
| OFPT_STATS_REQUEST, |
| OFPT_STATS_REPLY, |
| OFPT_ERROR |
| ] |
| |
| # Maps from sub-types to classes |
| stats_reply_to_class_map = { |
| OFPST_DESC : desc_stats_reply, |
| OFPST_AGGREGATE : aggregate_stats_reply, |
| OFPST_FLOW : flow_stats_reply, |
| OFPST_TABLE : table_stats_reply, |
| OFPST_PORT : port_stats_reply, |
| OFPST_QUEUE : queue_stats_reply |
| } |
| |
| stats_request_to_class_map = { |
| OFPST_DESC : desc_stats_request, |
| OFPST_AGGREGATE : aggregate_stats_request, |
| OFPST_FLOW : flow_stats_request, |
| OFPST_TABLE : table_stats_request, |
| OFPST_PORT : port_stats_request, |
| OFPST_QUEUE : queue_stats_request |
| } |
| |
| error_to_class_map = { |
| OFPET_HELLO_FAILED : hello_failed_error_msg, |
| OFPET_BAD_REQUEST : bad_request_error_msg, |
| OFPET_BAD_ACTION : bad_action_error_msg, |
| OFPET_FLOW_MOD_FAILED : flow_mod_failed_error_msg, |
| OFPET_PORT_MOD_FAILED : port_mod_failed_error_msg, |
| OFPET_QUEUE_OP_FAILED : queue_op_failed_error_msg |
| } |
| |
| # Map from header type value to the underlieing message class |
| msg_type_to_class_map = { |
| OFPT_HELLO : hello, |
| OFPT_ERROR : error, |
| OFPT_ECHO_REQUEST : echo_request, |
| OFPT_ECHO_REPLY : echo_reply, |
| OFPT_VENDOR : vendor, |
| OFPT_FEATURES_REQUEST : features_request, |
| OFPT_FEATURES_REPLY : features_reply, |
| OFPT_GET_CONFIG_REQUEST : get_config_request, |
| OFPT_GET_CONFIG_REPLY : get_config_reply, |
| OFPT_SET_CONFIG : set_config, |
| OFPT_PACKET_IN : packet_in, |
| OFPT_FLOW_REMOVED : flow_removed, |
| OFPT_PORT_STATUS : port_status, |
| OFPT_PACKET_OUT : packet_out, |
| OFPT_FLOW_MOD : flow_mod, |
| OFPT_PORT_MOD : port_mod, |
| OFPT_STATS_REQUEST : stats_request, |
| OFPT_STATS_REPLY : stats_reply, |
| OFPT_BARRIER_REQUEST : barrier_request, |
| OFPT_BARRIER_REPLY : barrier_reply, |
| OFPT_QUEUE_GET_CONFIG_REQUEST : queue_get_config_request, |
| OFPT_QUEUE_GET_CONFIG_REPLY : queue_get_config_reply |
| } |
| |
| def _of_message_to_object(binary_string): |
| """ |
| Map a binary string to the corresponding class. |
| |
| Appropriately resolves subclasses |
| """ |
| hdr = ofp_header() |
| hdr.unpack(binary_string) |
| # FIXME: Add error detection |
| if not hdr.type in msg_type_subclassed: |
| return msg_type_to_class_map[hdr.type]() |
| if hdr.type == OFPT_STATS_REQUEST: |
| sub_hdr = ofp_stats_request() |
| sub_hdr.unpack(binary_string) |
| return stats_request_to_class_map[sub_hdr.type]() |
| elif hdr.type == OFPT_STATS_REPLY: |
| sub_hdr = ofp_stats_reply() |
| sub_hdr.unpack(binary_string) |
| return stats_reply_to_class_map[sub_hdr.type]() |
| elif hdr.type == OFPT_ERROR: |
| sub_hdr = ofp_error_msg() |
| sub_hdr.unpack(binary_string) |
| return error_to_class_map[sub_hdr.type]() |
| else: |
| print "ERROR parsing packet to object" |
| return None |
| |
| def of_message_parse(binary_string, raw=False): |
| """ |
| Parse an OpenFlow packet |
| |
| Parses a raw OpenFlow packet into a Python class, with class |
| members fully populated. |
| |
| @param binary_string The packet (string) to be parsed |
| @param raw If true, interpret the packet as an L2 packet. Not |
| yet supported. |
| @return An object of some message class or None if fails |
| |
| """ |
| |
| if raw: |
| print "raw packet message parsing not supported" |
| return None |
| |
| obj = _of_message_to_object(binary_string) |
| if obj != None: |
| obj.unpack(binary_string) |
| return obj |
| |
| |
| def of_header_parse(binary_string, raw=False): |
| """ |
| Parse only the header from an OpenFlow packet |
| |
| Parses the header from a raw OpenFlow packet into a |
| an ofp_header Python class. |
| |
| @param binary_string The packet (string) to be parsed |
| @param raw If true, interpret the packet as an L2 packet. Not |
| yet supported. |
| @return An ofp_header object |
| |
| """ |
| |
| if raw: |
| print "raw packet message parsing not supported" |
| return None |
| |
| hdr = ofp_header() |
| hdr.unpack(binary_string) |
| |
| return hdr |
| |
| def packet_to_flow(packet, wildcards=None, pkt_format="L2"): |
| """ |
| Create a flow that matches packet with the given wildcards |
| |
| @param packet The packet to use as a flow template |
| @param wildcards Wildcards to place in the flow (ignore those |
| fields from the packet) |
| @param pkt_format May be one string from: L2, L3, ? |
| Fields from unspecified layers are forced to be wildcards |
| |
| """ |
| |