Rich Lane | 972be33 | 2013-06-04 13:36:48 -0700 | [diff] [blame] | 1 | :: import of_g |
| 2 | :: ir = of_g.ir |
Rich Lane | eb10d16 | 2013-10-01 21:15:35 -0700 | [diff] [blame^] | 3 | :: include('_copyright.lua') |
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 | |
Rich Lane | 364e029 | 2013-10-01 21:05:57 -0700 | [diff] [blame] | 27 | fields = {} |
Rich Lane | b014bcf | 2013-06-19 11:14:11 -0700 | [diff] [blame] | 28 | :: for field in fields: |
Rich Lane | 364e029 | 2013-10-01 21:05:57 -0700 | [diff] [blame] | 29 | fields[${repr(field.fullname)}] = ProtoField.new("${field.name}", "${field.fullname}", "FT_${field.type}", nil, "BASE_${field.base}") |
Rich Lane | b014bcf | 2013-06-19 11:14:11 -0700 | [diff] [blame] | 30 | :: #endfor |
Rich Lane | 422d1b1 | 2013-06-04 13:09:17 -0700 | [diff] [blame] | 31 | |
| 32 | p_of.fields = { |
Rich Lane | b014bcf | 2013-06-19 11:14:11 -0700 | [diff] [blame] | 33 | :: for field in fields: |
Rich Lane | 364e029 | 2013-10-01 21:05:57 -0700 | [diff] [blame] | 34 | fields[${repr(field.fullname)}], |
Rich Lane | b014bcf | 2013-06-19 11:14:11 -0700 | [diff] [blame] | 35 | :: #endfor |
Rich Lane | 422d1b1 | 2013-06-04 13:09:17 -0700 | [diff] [blame] | 36 | } |
| 37 | |
Rich Lane | 96641df | 2013-06-10 13:36:35 -0700 | [diff] [blame] | 38 | :: for supercls in set(sorted(superclasses.values())): |
| 39 | local ${supercls}_dissectors = { |
| 40 | :: for version, ofproto in ir.items(): |
| 41 | [${version}] = {}, |
| 42 | :: #endfor |
| 43 | } |
| 44 | :: #endfor |
| 45 | |
| 46 | :: for version, ofproto in ir.items(): |
| 47 | :: for ofclass in ofproto.classes: |
| 48 | :: name = 'dissect_%s_v%d' % (ofclass.name, version) |
| 49 | :: typeval = 0 |
| 50 | :: include('_ofclass_dissector.lua', name=name, ofclass=ofclass) |
| 51 | :: if ofclass.name in superclasses: |
| 52 | ${superclasses[ofclass.name]}_dissectors[${version}][${typeval}] = ${name} |
| 53 | |
| 54 | :: #endif |
| 55 | :: #endfor |
| 56 | :: #endfor |
| 57 | |
| 58 | function dissect_of_message(buf, root) |
Rich Lane | 422d1b1 | 2013-06-04 13:09:17 -0700 | [diff] [blame] | 59 | local subtree = root:add(p_of, buf(0)) |
Rich Lane | 364e029 | 2013-10-01 21:05:57 -0700 | [diff] [blame] | 60 | subtree:add(fields['of10.header.version'], buf(0,1)) |
| 61 | subtree:add(fields['of10.header.type'], buf(1,1)) |
| 62 | subtree:add(fields['of10.header.length'], buf(2,2)) |
| 63 | subtree:add(fields['of10.header.xid'], buf(4,4)) |
Rich Lane | 422d1b1 | 2013-06-04 13:09:17 -0700 | [diff] [blame] | 64 | |
Rich Lane | 96641df | 2013-06-10 13:36:35 -0700 | [diff] [blame] | 65 | local version_val = buf(0,1):uint() |
Rich Lane | 422d1b1 | 2013-06-04 13:09:17 -0700 | [diff] [blame] | 66 | local type_val = buf(1,1):uint() |
Rich Lane | 96641df | 2013-06-10 13:36:35 -0700 | [diff] [blame] | 67 | if of_message_dissectors[version_val] and of_message_dissectors[version_val][type_val] then |
Rich Lane | a08c93d | 2013-10-01 21:04:50 -0700 | [diff] [blame] | 68 | of_message_dissectors[version_val][type_val](buf, subtree) |
Rich Lane | 96641df | 2013-06-10 13:36:35 -0700 | [diff] [blame] | 69 | end |
Rich Lane | 422d1b1 | 2013-06-04 13:09:17 -0700 | [diff] [blame] | 70 | end |
| 71 | |
| 72 | -- of dissector function |
| 73 | function p_of.dissector (buf, pkt, root) |
| 74 | pkt.cols.protocol = p_of.name |
| 75 | |
| 76 | local offset = 0 |
| 77 | repeat |
| 78 | if buf:len() - offset >= 4 then |
| 79 | msg_len = buf(offset+2,2):uint() |
| 80 | if offset + msg_len > buf:len() then |
| 81 | -- we don't have all the data we need yet |
| 82 | pkt.desegment_len = offset + msg_len - buf:len() |
| 83 | return |
| 84 | end |
| 85 | |
Rich Lane | 96641df | 2013-06-10 13:36:35 -0700 | [diff] [blame] | 86 | dissect_of_message(buf(offset, msg_len), root) |
Rich Lane | 422d1b1 | 2013-06-04 13:09:17 -0700 | [diff] [blame] | 87 | offset = offset + msg_len |
| 88 | else |
| 89 | -- we don't have all of length field yet |
| 90 | pkt.desegment_len = DESEGMENT_ONE_MORE_SEGMENT |
| 91 | return |
| 92 | end |
| 93 | until offset >= buf:len() |
| 94 | end |
| 95 | |
| 96 | -- Initialization routine |
| 97 | function p_of.init() |
| 98 | end |
| 99 | |
Rich Lane | 88d3afc | 2013-10-01 21:07:22 -0700 | [diff] [blame] | 100 | -- register a chained dissector for OpenFlow port numbers |
Rich Lane | 422d1b1 | 2013-06-04 13:09:17 -0700 | [diff] [blame] | 101 | local tcp_dissector_table = DissectorTable.get("tcp.port") |
| 102 | tcp_dissector_table:add(6633, p_of) |
Rich Lane | 88d3afc | 2013-10-01 21:07:22 -0700 | [diff] [blame] | 103 | tcp_dissector_table:add(6653, p_of) |