nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | #!/usr/bin/env python |
2 | # |
||
3 | # Parses the CSV version of the IANA Service Name and Transport Protocol Port Number Registry |
||
4 | # and generates a services(5) file. |
||
5 | # |
||
6 | # Wireshark - Network traffic analyzer |
||
7 | # By Gerald Combs <gerald@wireshark.org> |
||
8 | # Copyright 2013 Gerald Combs |
||
9 | # |
||
10 | # This program is free software; you can redistribute it and/or |
||
11 | # modify it under the terms of the GNU General Public License |
||
12 | # as published by the Free Software Foundation; either version 2 |
||
13 | # of the License, or (at your option) any later version. |
||
14 | # |
||
15 | # This program is distributed in the hope that it will be useful, |
||
16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
18 | # GNU General Public License for more details. |
||
19 | # |
||
20 | # You should have received a copy of the GNU General Public License |
||
21 | # along with this program; if not, write to the Free Software |
||
22 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
||
23 | |||
24 | iana_svc_url = 'http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.csv' |
||
25 | |||
26 | __doc__ = '''\ |
||
27 | Usage: make-services.py [url] |
||
28 | |||
29 | url defaults to |
||
30 | %s |
||
31 | ''' % (iana_svc_url) |
||
32 | |||
33 | import sys |
||
34 | import getopt |
||
35 | import csv |
||
36 | import re |
||
37 | |||
38 | python_version = sys.hexversion >> 16 |
||
39 | if python_version < 0x300: |
||
40 | import urllib |
||
41 | else: |
||
42 | import urllib.request, urllib.error, urllib.parse |
||
43 | import codecs |
||
44 | |||
45 | services_file = 'services' |
||
46 | |||
47 | exclude_services = [ |
||
48 | '^spr-itunes', |
||
49 | '^spl-itunes', |
||
50 | '^shilp', |
||
51 | ] |
||
52 | |||
53 | exclude_comments = [ |
||
54 | 'should not be used for discovery purposes', |
||
55 | 'NOTE Conflict', |
||
56 | ] |
||
57 | |||
58 | min_body_size = 900000 # Size was ~ 922000 on 2013-08-06 |
||
59 | |||
60 | def parse_rows(svc_fd): |
||
61 | lines = [] |
||
62 | port_reader = csv.reader(svc_fd) |
||
63 | |||
64 | # Header positions as of 2013-08-06 |
||
65 | if python_version < 0x206: |
||
66 | headers = port_reader.next() |
||
67 | else: |
||
68 | headers = next(port_reader) |
||
69 | |||
70 | try: |
||
71 | sn_pos = headers.index('Service Name') |
||
72 | except: |
||
73 | sn_pos = 0 |
||
74 | try: |
||
75 | pn_pos = headers.index('Port Number') |
||
76 | except: |
||
77 | pn_pos = 1 |
||
78 | try: |
||
79 | tp_pos = headers.index('Transport Protocol') |
||
80 | except: |
||
81 | tp_pos = 2 |
||
82 | |||
83 | positions = [sn_pos, pn_pos, tp_pos] |
||
84 | positions.sort() |
||
85 | positions.reverse() |
||
86 | |||
87 | for row in port_reader: |
||
88 | service = row[sn_pos] |
||
89 | port = row[pn_pos] |
||
90 | proto = row[tp_pos] |
||
91 | |||
92 | if len(service) < 1 or len(port) < 1 or len(proto) < 1: |
||
93 | continue |
||
94 | |||
95 | for pos in positions: |
||
96 | del row[pos] |
||
97 | row = filter(None, row) |
||
98 | comment = ' '.join(row) |
||
99 | comment = re.sub('[\n]', '', comment) |
||
100 | |||
101 | if re.search('|'.join(exclude_services), service): |
||
102 | continue |
||
103 | if re.search('|'.join(exclude_comments), comment): |
||
104 | continue |
||
105 | |||
106 | lines.append('%-15s %5s/%s # %s' % ( |
||
107 | service, |
||
108 | port, |
||
109 | proto, |
||
110 | comment |
||
111 | )) |
||
112 | |||
113 | return '\n'.join(lines) |
||
114 | |||
115 | def exit_msg(msg=None, status=1): |
||
116 | if msg is not None: |
||
117 | sys.stderr.write(msg + '\n\n') |
||
118 | sys.stderr.write(__doc__ + '\n') |
||
119 | sys.exit(status) |
||
120 | |||
121 | def main(argv): |
||
122 | try: |
||
123 | opts, args = getopt.getopt(argv, "h", ["help"]) |
||
124 | except getopt.GetoptError: |
||
125 | exit_msg() |
||
126 | for opt, arg in opts: |
||
127 | if opt in ("-h", "--help"): |
||
128 | exit_msg(None, 0) |
||
129 | |||
130 | if (len(argv) > 0): |
||
131 | svc_url = argv[0] |
||
132 | else: |
||
133 | svc_url = iana_svc_url |
||
134 | |||
135 | try: |
||
136 | if python_version < 0x300: |
||
137 | svc_fd = urllib.urlopen(svc_url) |
||
138 | else: |
||
139 | req = urllib.request.urlopen(svc_url) |
||
140 | svc_fd = codecs.getreader('utf8')(req) |
||
141 | except: |
||
142 | exit_msg('Error opening ' + svc_url) |
||
143 | |||
144 | body = parse_rows(svc_fd) |
||
145 | if len(body) < min_body_size: |
||
146 | exit_msg('Not enough parsed data') |
||
147 | |||
148 | out = open(services_file, 'w') |
||
149 | out.write('''\ |
||
150 | # This is a local copy of the IANA port-numbers file. |
||
151 | # |
||
152 | # Wireshark uses it to resolve port numbers into human readable |
||
153 | # service names, e.g. TCP port 80 -> http. |
||
154 | # |
||
155 | # It is subject to copyright and being used with IANA's permission: |
||
156 | # http://www.wireshark.org/lists/wireshark-dev/200708/msg00160.html |
||
157 | # |
||
158 | # The original file can be found at: |
||
159 | # %s |
||
160 | # |
||
161 | |||
162 | %s |
||
163 | ''' % (iana_svc_url, body)) |
||
164 | |||
165 | if __name__ == "__main__": |
||
166 | sys.exit(main(sys.argv[1:])) |