]>
Commit | Line | Data |
---|---|---|
29089a54 RL |
1 | #!/usr/bin/python |
2 | # | |
3 | # Copyright (C) 2012 Nicira, Inc. | |
4 | # | |
5 | # Copying and distribution of this file, with or without modification, | |
6 | # are permitted in any medium without royalty provided the copyright | |
7 | # notice and this notice are preserved. This file is offered as-is, | |
8 | # without warranty of any kind. | |
9 | ||
10 | import getopt | |
11 | import re | |
12 | import sys | |
13 | import xml.sax | |
14 | import xml.sax.handler | |
15 | ||
16 | class IpfixEntityHandler(xml.sax.handler.ContentHandler): | |
17 | ||
18 | RECORD_FIELDS = ['name', 'dataType', 'elementId', 'status'] | |
19 | ||
20 | # Cf. RFC 5101, Section 6. | |
21 | DATA_TYPE_SIZE = { | |
22 | 'unsigned8': 1, | |
23 | 'unsigned16': 2, | |
24 | 'unsigned32': 4, | |
25 | 'unsigned64': 8, | |
26 | 'signed8': 1, | |
27 | 'signed16': 2, | |
28 | 'signed32': 4, | |
29 | 'signed64': 8, | |
30 | 'float32': 4, | |
31 | 'float64': 8, | |
32 | 'boolean': 1, # Not clear. | |
33 | 'macAddress': 6, | |
34 | 'octetArray': 0, # Not clear. | |
35 | 'string': 0, # Not clear. | |
36 | 'dateTimeSeconds': 4, | |
37 | 'dateTimeMilliseconds': 8, | |
38 | 'dateTimeMicroseconds': 8, | |
39 | 'dateTimeNanoseconds': 8, | |
40 | 'ipv4Address': 4, | |
41 | 'ipv6Address': 16, | |
42 | } | |
43 | ||
44 | def __init__(self): | |
45 | self.current_field_name = None | |
46 | self.current_field_value = [] | |
47 | self.current_record = dict() | |
48 | ||
49 | def startDocument(self): | |
50 | print """\ | |
51 | /* IPFIX entities. */ | |
52 | #ifndef IPFIX_ENTITY | |
53 | #define IPFIX_ENTITY(ENUM, ID, SIZE, NAME) | |
54 | #endif | |
55 | """ | |
56 | ||
57 | def endDocument(self): | |
58 | print """ | |
59 | #undef IPFIX_ENTITY""" | |
60 | ||
61 | def startElement(self, name, attrs): | |
62 | if name in self.RECORD_FIELDS: | |
63 | self.current_field_name = name | |
64 | else: | |
65 | self.current_field_name = None | |
66 | self.current_field_value = [] | |
67 | ||
68 | @staticmethod | |
69 | def camelcase_to_uppercase(s): | |
70 | return re.sub('(.)([A-Z]+)', r'\1_\2', s).upper() | |
71 | ||
72 | def endElement(self, name): | |
73 | if self.current_field_name is not None: | |
74 | self.current_record[self.current_field_name] = ''.join( | |
75 | self.current_field_value).strip() | |
76 | elif (name == 'record' | |
77 | and self.current_record.get('status') == 'current' | |
78 | and 'dataType' in self.current_record): | |
79 | ||
80 | self.current_record['enumName'] = self.camelcase_to_uppercase( | |
81 | self.current_record['name']) | |
82 | self.current_record['dataTypeSize'] = self.DATA_TYPE_SIZE.get( | |
83 | self.current_record['dataType'], 0) | |
84 | ||
85 | print 'IPFIX_ENTITY(%(enumName)s, %(elementId)s, ' \ | |
86 | '%(dataTypeSize)i, %(name)s)' % self.current_record | |
87 | self.current_record.clear() | |
88 | ||
89 | def characters(self, content): | |
90 | if self.current_field_name is not None: | |
91 | self.current_field_value.append(content) | |
92 | ||
93 | def print_ipfix_entity_macros(xml_file): | |
94 | xml.sax.parse(xml_file, IpfixEntityHandler()) | |
95 | ||
96 | def usage(name): | |
97 | print """\ | |
98 | %(name)s: IPFIX entity definition generator | |
99 | Prints C macros defining IPFIX entities from the standard IANA file at | |
100 | <http://www.iana.org/assignments/ipfix/ipfix.xml> | |
101 | usage: %(name)s [OPTIONS] XML | |
102 | where XML is the standard IANA XML file defining IPFIX entities | |
103 | ||
104 | The following options are also available: | |
105 | -h, --help display this help message | |
106 | -V, --version display version information\ | |
107 | """ % {'name': name} | |
108 | sys.exit(0) | |
109 | ||
110 | if __name__ == '__main__': | |
111 | # try: | |
112 | try: | |
113 | options, args = getopt.gnu_getopt(sys.argv[1:], 'hV', | |
114 | ['help', 'version']) | |
115 | except getopt.GetoptError, geo: | |
116 | sys.stderr.write('%s: %s\n' % (sys.argv[0], geo.msg)) | |
117 | sys.exit(1) | |
118 | ||
119 | for key, value in options: | |
120 | if key in ['-h', '--help']: | |
121 | usage() | |
122 | elif key in ['-V', '--version']: | |
123 | print 'ipfix-gen-entities (Open vSwitch)' | |
124 | else: | |
125 | sys.exit(0) | |
126 | ||
127 | if len(args) != 1: | |
128 | sys.stderr.write('%s: exactly 1 non-option arguments required ' | |
129 | '(use --help for help)\n' % sys.argv[0]) | |
130 | sys.exit(1) | |
131 | ||
132 | print_ipfix_entity_macros(args[0]) | |
133 | ||
134 | # except Exception, e: | |
135 | # sys.stderr.write('%s: %s\n' % (sys.argv[0], e)) | |
136 | # sys.exit(1) | |
137 | ||
138 | # Local variables: | |
139 | # mode: python | |
140 | # End: |