Rich Lane | 972be33 | 2013-06-04 13:36:48 -0700 | [diff] [blame] | 1 | :: import of_g |
| 2 | :: ir = of_g.ir |
Rich Lane | 45dcae1 | 2013-06-04 13:07:41 -0700 | [diff] [blame] | 3 | -- TODO copyright (GPL) |
Rich Lane | 422d1b1 | 2013-06-04 13:09:17 -0700 | [diff] [blame] | 4 | |
Rich Lane | 872b95a | 2013-06-17 18:39:14 -0700 | [diff] [blame^] | 5 | :: include('_ofreader.lua') |
| 6 | |
Rich Lane | 422d1b1 | 2013-06-04 13:09:17 -0700 | [diff] [blame] | 7 | p_of = Proto ("of", "OpenFlow") |
| 8 | |
Rich Lane | 972be33 | 2013-06-04 13:36:48 -0700 | [diff] [blame] | 9 | local openflow_versions = { |
| 10 | :: for (version, name) in of_g.param_version_names.items(): |
| 11 | [${version}] = "${name}", |
| 12 | :: #endfor |
Rich Lane | 422d1b1 | 2013-06-04 13:09:17 -0700 | [diff] [blame] | 13 | } |
| 14 | |
Rich Lane | 972be33 | 2013-06-04 13:36:48 -0700 | [diff] [blame] | 15 | :: for version, ofproto in ir.items(): |
| 16 | :: for enum in ofproto.enums: |
| 17 | local enum_v${version}_${enum.name} = { |
| 18 | :: for (name, value) in enum.values: |
| 19 | [${value}] = "${name}", |
| 20 | :: #endfor |
| 21 | } |
| 22 | |
| 23 | :: #endfor |
| 24 | |
| 25 | :: #endfor |
| 26 | |
| 27 | local f_version = ProtoField.uint8("of.version", "Version", base.HEX, openflow_versions) |
| 28 | local f_type = ProtoField.uint8("of.type", "Type", base.HEX, enum_v1_ofp_type) |
| 29 | local f_length = ProtoField.uint16("of.length", "Length") |
Rich Lane | 422d1b1 | 2013-06-04 13:09:17 -0700 | [diff] [blame] | 30 | local f_xid = ProtoField.uint32("of.xid", "XID", base.HEX) |
| 31 | |
| 32 | p_of.fields = { |
| 33 | f_version, |
| 34 | f_type, |
| 35 | f_length, |
| 36 | f_xid, |
| 37 | } |
| 38 | |
Rich Lane | 96641df | 2013-06-10 13:36:35 -0700 | [diff] [blame] | 39 | :: for supercls in set(sorted(superclasses.values())): |
| 40 | local ${supercls}_dissectors = { |
| 41 | :: for version, ofproto in ir.items(): |
| 42 | [${version}] = {}, |
| 43 | :: #endfor |
| 44 | } |
| 45 | :: #endfor |
| 46 | |
| 47 | :: for version, ofproto in ir.items(): |
| 48 | :: for ofclass in ofproto.classes: |
| 49 | :: name = 'dissect_%s_v%d' % (ofclass.name, version) |
| 50 | :: typeval = 0 |
| 51 | :: include('_ofclass_dissector.lua', name=name, ofclass=ofclass) |
| 52 | :: if ofclass.name in superclasses: |
| 53 | ${superclasses[ofclass.name]}_dissectors[${version}][${typeval}] = ${name} |
| 54 | |
| 55 | :: #endif |
| 56 | :: #endfor |
| 57 | :: #endfor |
| 58 | |
| 59 | function dissect_of_message(buf, root) |
Rich Lane | 422d1b1 | 2013-06-04 13:09:17 -0700 | [diff] [blame] | 60 | -- create subtree for of |
| 61 | local subtree = root:add(p_of, buf(0)) |
| 62 | -- add protocol fields to subtree |
| 63 | subtree:add(f_version, buf(0,1)) |
| 64 | subtree:add(f_type, buf(1,1)) |
| 65 | subtree:add(f_length, buf(2,2)) |
| 66 | subtree:add(f_xid, buf(4,4)) |
| 67 | |
Rich Lane | 96641df | 2013-06-10 13:36:35 -0700 | [diff] [blame] | 68 | local version_val = buf(0,1):uint() |
Rich Lane | 422d1b1 | 2013-06-04 13:09:17 -0700 | [diff] [blame] | 69 | local type_val = buf(1,1):uint() |
Rich Lane | 96641df | 2013-06-10 13:36:35 -0700 | [diff] [blame] | 70 | if of_message_dissectors[version_val] and of_message_dissectors[version_val][type_val] then |
| 71 | of_message_dissectors[version_val][type_val](buf, root) |
| 72 | end |
Rich Lane | 422d1b1 | 2013-06-04 13:09:17 -0700 | [diff] [blame] | 73 | end |
| 74 | |
| 75 | -- of dissector function |
| 76 | function p_of.dissector (buf, pkt, root) |
| 77 | pkt.cols.protocol = p_of.name |
| 78 | |
| 79 | local offset = 0 |
| 80 | repeat |
| 81 | if buf:len() - offset >= 4 then |
| 82 | msg_len = buf(offset+2,2):uint() |
| 83 | if offset + msg_len > buf:len() then |
| 84 | -- we don't have all the data we need yet |
| 85 | pkt.desegment_len = offset + msg_len - buf:len() |
| 86 | return |
| 87 | end |
| 88 | |
Rich Lane | 96641df | 2013-06-10 13:36:35 -0700 | [diff] [blame] | 89 | dissect_of_message(buf(offset, msg_len), root) |
Rich Lane | 422d1b1 | 2013-06-04 13:09:17 -0700 | [diff] [blame] | 90 | offset = offset + msg_len |
| 91 | else |
| 92 | -- we don't have all of length field yet |
| 93 | pkt.desegment_len = DESEGMENT_ONE_MORE_SEGMENT |
| 94 | return |
| 95 | end |
| 96 | until offset >= buf:len() |
| 97 | end |
| 98 | |
| 99 | -- Initialization routine |
| 100 | function p_of.init() |
| 101 | end |
| 102 | |
| 103 | -- register a chained dissector for port 8002 |
| 104 | local tcp_dissector_table = DissectorTable.get("tcp.port") |
| 105 | tcp_dissector_table:add(6633, p_of) |