wireshark: dissect OpenFlow payload of error messages
diff --git a/wireshark_gen/field_info.py b/wireshark_gen/field_info.py
index b2e9a82..6c35d99 100644
--- a/wireshark_gen/field_info.py
+++ b/wireshark_gen/field_info.py
@@ -179,4 +179,19 @@
     ("of_packet_out", "data"): "read_ethernet",
     ("of_bsn_pdu_tx_request", "data"): "read_ethernet",
     ("of_bsn_pdu_rx_request", "data"): "read_ethernet",
+    ("of_error_msg", "data"): "read_openflow",
+    ("of_hello_failed_error_msg", "data"): "read_openflow",
+    ("of_bad_request_error_msg", "data"): "read_openflow",
+    ("of_bad_action_error_msg", "data"): "read_openflow",
+    ("of_bad_instruction_error_msg", "data"): "read_openflow",
+    ("of_bad_match_error_msg", "data"): "read_openflow",
+    ("of_flow_mod_failed_error_msg", "data"): "read_openflow",
+    ("of_group_mod_failed_error_msg", "data"): "read_openflow",
+    ("of_port_mod_failed_error_msg", "data"): "read_openflow",
+    ("of_table_mod_failed_error_msg", "data"): "read_openflow",
+    ("of_queue_op_failed_error_msg", "data"): "read_openflow",
+    ("of_switch_config_failed_error_msg", "data"): "read_openflow",
+    ("of_role_request_failed_error_msg", "data"): "read_openflow",
+    ("of_meter_mod_failed_error_msg", "data"): "read_openflow",
+    ("of_table_features_failed_error_msg", "data"): "read_openflow",
 }
diff --git a/wireshark_gen/templates/_oftype_readers.lua b/wireshark_gen/templates/_oftype_readers.lua
index f1de7ec..f7eb79c 100644
--- a/wireshark_gen/templates/_oftype_readers.lua
+++ b/wireshark_gen/templates/_oftype_readers.lua
@@ -173,3 +173,14 @@
     local info = of_bsn_vport_q_in_q_dissectors[version](reader, child_subtree)
     child_subtree:set_text(info)
 end
+
+function read_openflow(reader, version, subtree, field_name)
+    if reader.is_empty() then
+        return
+    end
+    local child_subtree = subtree:add(fields[field_name], reader.peek_all(0))
+    child_subtree:set_text("OpenFlow message")
+    pcall(function () -- Message may be truncated, ignore errors dissecting
+        p_of.dissector:call(reader.read_all():tvb(), current_pkt, child_subtree)
+    end)
+end