]>
Commit | Line | Data |
---|---|---|
e0edde6f | 1 | # Copyright (c) 2011 Nicira, Inc. |
436f27dd AS |
2 | # Copyright (c) 2010 Citrix Systems, Inc. |
3 | # | |
4 | # Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | # you may not use this file except in compliance with the License. | |
6 | # You may obtain a copy of the License at: | |
7 | # | |
8 | # http://www.apache.org/licenses/LICENSE-2.0 | |
9 | # | |
10 | # Unless required by applicable law or agreed to in writing, software | |
11 | # distributed under the License is distributed on an "AS IS" BASIS, | |
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | # See the License for the specific language governing permissions and | |
14 | # limitations under the License. | |
15 | ||
16 | from OVEStandard import * | |
17 | ||
18 | from OVEConfig import * | |
a9806b56 | 19 | import re |
436f27dd AS |
20 | |
21 | class OVEUtil: | |
22 | UUID_RE = re.compile(r'([a-f0-9]{8}-[a-f0-9]{2})[a-f0-9]{2}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}') | |
23 | ||
24 | @classmethod | |
25 | def paramToLongString(cls, param): | |
26 | if isinstance(param, (types.ListType, types.TupleType)) and len(param) > 1: | |
27 | text = str(param[1]) | |
28 | else: | |
29 | text = str(param) | |
30 | ||
31 | return text.replace(', ', ',\n') | |
32 | ||
33 | @classmethod | |
34 | def paramToString(cls, param): | |
35 | if isinstance(param, (types.ListType, types.TupleType)) and len(param) > 1: | |
36 | text = str(param[1]) | |
37 | else: | |
38 | text = str(param) | |
39 | if OVEConfig.Inst().truncateUuids: | |
40 | text = cls.UUID_RE.sub('\\1...', text) | |
41 | ||
42 | return text.replace(', ', ',\n') | |
43 | ||
44 | @classmethod | |
45 | def flowDecodeHeadings(self): | |
46 | return [ | |
47 | 'Type', | |
48 | 'Proto', | |
49 | 'Inport', | |
50 | 'VLAN', | |
51 | 'Source MAC', | |
52 | 'Destination MAC', | |
53 | 'Source IP', | |
54 | 'Destination IP', | |
55 | 'Src port', | |
56 | 'Dest port', | |
57 | 'Packet count', | |
58 | 'Bytes', | |
59 | 'Used', | |
60 | 'Tos', | |
61 | 'PCP', | |
62 | 'Tunnel', | |
63 | 'Actions', | |
64 | ] | |
65 | ||
66 | @classmethod | |
67 | def getFlowColumn(cls, name): | |
68 | lowerName = name.lower() | |
69 | for i, columnName in enumerate(cls.flowDecodeHeadings()): | |
70 | if lowerName == columnName.lower(): | |
71 | return i | |
72 | return None | |
73 | ||
74 | ETHERTYPE_TRANS = { | |
75 | '05ff':'ESX probe', | |
76 | '0800':'IP', | |
77 | '0806':'ARP', | |
78 | '86dd':'IPv6', | |
79 | '88cc':'LLDP' | |
80 | } | |
81 | ||
82 | ETHERPROTO_TRANS = { | |
83 | '1':'ICMP', | |
84 | '6':'TCP', | |
85 | '17':'UDP' | |
86 | } | |
87 | ||
88 | # Parsing of ovs-dpctl dump-flows output should be localised in this method and flowDecodeHeadings | |
89 | @classmethod | |
90 | def decodeFlows(cls, srcLines): | |
91 | retVal = [] | |
436f27dd AS |
92 | for line in srcLines.split('\n'): |
93 | if line != '': | |
a9806b56 BP |
94 | fields = {} |
95 | for name, val in re.findall(r'([a-zA-Z0-9_+]+)\(([^)]+)\)', line): | |
96 | if '=' in val: | |
97 | for setting in val.split(','): | |
98 | k,v = setting.split('=') | |
99 | fields['%s.%s' % (name, k)] = v | |
100 | else: | |
101 | fields[name] = val | |
102 | for setting in re.split(', ', line)[1:]: | |
103 | if ':' in setting: | |
104 | k,v = setting.split(':') | |
105 | fields[k] = v | |
106 | ||
107 | tun_id = fields.get('tun_id', '') | |
108 | in_port = int(fields.get('in_port', 0)) | |
109 | eth_src = fields.get('eth.src', '') | |
110 | eth_dst = fields.get('eth.dst', '') | |
111 | vlan_vid = int(fields.get('vlan.vid', 0)) | |
112 | vlan_pcp = int(fields.get('vlan.pcp', 0)) | |
113 | eth_type = fields.get('eth_type', '') | |
114 | ip_src = fields.get('ipv4.src', fields.get('ipv6.src', '')) | |
115 | ip_dst = fields.get('ipv4.dst', fields.get('ipv6.dst', '')) | |
116 | ip_proto = fields.get('ipv4.proto', fields.get('ipv6.proto', '')) | |
117 | ip_tos = fields.get('ipv4.tos', fields.get('ipv6.tos', '')) | |
118 | tp_src = fields.get('tcp.src', fields.get('udp.src', fields.get('arp.sip', fields.get('icmp.type', fields.get('icmpv6.type', ''))))) | |
119 | tp_dst = fields.get('tcp.dst', fields.get('udp.dst', fields.get('arp.tip', fields.get('icmp.code', fields.get('icmpv6.code', ''))))) | |
120 | ||
121 | packets = fields.get('packets', '') | |
122 | bytes = fields.get('bytes', '') | |
123 | actions = fields.get('actions', '') | |
124 | used = fields.get('used', '') | |
125 | ||
126 | # Order below needs to match that in flowDecodeHeadings | |
127 | retVal.append((eth_type, ip_proto, in_port, vlan_vid, eth_src, eth_dst, ip_src, ip_dst, tp_src, tp_dst, packets, bytes, used, ip_tos, vlan_pcp, tun_id, actions)) | |
436f27dd AS |
128 | |
129 | return retVal | |
130 | ||
131 | COLOURS = [Qt.black, Qt.darkBlue, Qt.darkRed, Qt.darkGreen, Qt.darkMagenta, Qt.darkCyan, Qt.darkGray, Qt.darkYellow, Qt.blue, Qt.gray, Qt.magenta, Qt.red] | |
132 | ||
133 | @classmethod | |
134 | def intToColour(cls, value): | |
135 | return cls.COLOURS[value % len(cls.COLOURS)] |