Skip to content

Commit 4766a5e

Browse files
authored
Merge pull request #1755 from gpotter2/manuffix
DADict: improvement + fix Manuf format
2 parents 03f4176 + 49aeec8 commit 4766a5e

File tree

3 files changed

+84
-10
lines changed

3 files changed

+84
-10
lines changed

scapy/dadict.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@
2121
def fixname(x):
2222
if x and str(x[0]) in "0123456789":
2323
x = "n_" + x
24-
return x.translate("________________________________________________0123456789_______ABCDEFGHIJKLMNOPQRSTUVWXYZ______abcdefghijklmnopqrstuvwxyz_____________________________________________________________________________________________________________________________________") # noqa: E501
24+
return x.translate(
25+
"________________________________________________"
26+
"0123456789_______ABCDEFGHIJKLMNOPQRSTUVWXYZ______"
27+
"abcdefghijklmnopqrstuvwxyz____________________________"
28+
"______________________________________________________"
29+
"___________________________________________________"
30+
)
2531

2632

2733
class DADict_Exception(Scapy_Exception):
@@ -55,7 +61,7 @@ def _show(self):
5561
print("%10s = %r" % (k, getattr(self, k)))
5662

5763
def __repr__(self):
58-
return "<%s/ %s>" % (self._name, " ".join(x for x in self.__dict__ if x and x[0] != "_")) # noqa: E501
64+
return "<%s - %s elements>" % (self._name, len(self.__dict__))
5965

6066
def _branch(self, br, uniq=0):
6167
if uniq and br._name in self:

scapy/data.py

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from scapy.consts import FREEBSD, NETBSD, OPENBSD, WINDOWS
1818
from scapy.error import log_loading
1919
from scapy.compat import plain_str
20+
import scapy.modules.six as six
2021

2122

2223
############
@@ -194,6 +195,9 @@ class ManufDA(DADict):
194195
def fixname(self, val):
195196
return plain_str(val)
196197

198+
def __dir__(self):
199+
return ["lookup", "reverse_lookup"]
200+
197201
def _get_manuf_couple(self, mac):
198202
oui = ":".join(mac.split(":")[:3]).upper()
199203
return self.__dict__.get(oui, (mac, mac))
@@ -210,24 +214,42 @@ def _resolve_MAC(self, mac):
210214
return ":".join([self[oui][0]] + mac.split(":")[3:])
211215
return mac
212216

213-
def __repr__(self):
214-
return "\n".join("<%s %s, %s>" % (i[0], i[1][0], i[1][1]) for i in self.__dict__.items()) # noqa: E501
217+
def lookup(self, mac):
218+
"""Find OUI name matching to a MAC"""
219+
oui = ":".join(mac.split(":")[:3]).upper()
220+
return self[oui]
221+
222+
def reverse_lookup(self, name, case_sensitive=False):
223+
"""Find all MACs registered to a OUI
224+
params:
225+
- name: the OUI name
226+
- case_sensitive: default to False
227+
returns: a dict of mac:tuples (Name, Extended Name)
228+
"""
229+
if case_sensitive:
230+
filtr = lambda x, l: any(x == z for z in l)
231+
else:
232+
name = name.lower()
233+
filtr = lambda x, l: any(x == z.lower() for z in l)
234+
return {k: v for k, v in six.iteritems(self.__dict__)
235+
if filtr(name, v)}
215236

216237

217238
def load_manuf(filename):
239+
"""Load manuf file from Wireshark.
240+
param:
241+
- filename: the file to load the manuf file from"""
218242
manufdb = ManufDA(_name=filename)
219243
with open(filename, "rb") as fdesc:
220244
for line in fdesc:
221245
try:
222246
line = line.strip()
223247
if not line or line.startswith(b"#"):
224248
continue
225-
oui, shrt = line.split()[:2]
226-
i = line.find(b"#")
227-
if i < 0:
228-
lng = shrt
229-
else:
230-
lng = line[i + 2:]
249+
parts = line.split(None, 2)
250+
oui, shrt = parts[:2]
251+
lng = parts[2].lstrip(b"#").strip() if len(parts) > 2 else ""
252+
lng = lng or shrt
231253
manufdb[oui] = plain_str(shrt), plain_str(lng)
232254
except Exception:
233255
log_loading.warning("Couldn't parse one line from [%s] [%r]",

test/regression.uts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,52 @@ assert(conf.manufdb._resolve_MAC("00:00:0F:01:02:03") == "Next:01:02:03")
517517
assert(conf.manufdb._get_short_manuf("00:00:0F:01:02:03") == "Next")
518518
assert(in6_addrtovendor("fe80::0200:0fff:fe01:0203").lower().startswith("next"))
519519

520+
assert conf.manufdb.lookup("00:00:0F:01:02:03") == ('Next', 'Next, Inc.')
521+
assert "00:00:0F" in conf.manufdb.reverse_lookup("Next")
522+
523+
= Test multiple wireshark's manuf formats
524+
~ manufdb
525+
526+
new_format = """
527+
# comment
528+
00:00:00 JokyIsland Joky Insland Corp SA
529+
00:01:12 SecdevCorp Secdev Corporation SA LLC
530+
EE:05:01 Scapy Scapy CO LTD & CIE
531+
FF:00:11 NoName
532+
"""
533+
old_format = """
534+
# comment
535+
00:00:00 JokyIsland # Joky Insland Corp SA
536+
00:01:12 SecdevCorp # Secdev Corporation SA LLC
537+
EE:05:01 Scapy # Scapy CO LTD & CIE
538+
FF:00:11 NoName
539+
"""
540+
541+
manuf1 = get_temp_file()
542+
manuf2 = get_temp_file()
543+
544+
with open(manuf1, "w") as w:
545+
w.write(old_format)
546+
547+
with open(manuf2, "w") as w:
548+
w.write(new_format)
549+
550+
a = load_manuf(manuf1)
551+
b = load_manuf(manuf2)
552+
553+
a.lookup("00:00:00") == ('JokyIsland', 'Joky Insland Corp SA'),
554+
a.lookup("FF:00:11:00:00:00") == ('NoName', 'NoName')
555+
a.reverse_lookup("Scapy") == {'EE:05:01': ('Scapy', 'Scapy CO LTD & CIE')}
556+
a.reverse_lookup("Secdevcorp") == {'00:01:12': ('SecdevCorp', 'Secdev Corporation SA LLC')}
557+
558+
559+
b.lookup("00:00:00") == ('JokyIsland', 'Joky Insland Corp SA'),
560+
b.lookup("FF:00:11:00:00:00") == ('NoName', 'NoName')
561+
b.reverse_lookup("Scapy") == {'EE:05:01': ('Scapy', 'Scapy CO LTD & CIE')}
562+
b.reverse_lookup("Secdevcorp") == {'00:01:12': ('SecdevCorp', 'Secdev Corporation SA LLC')}
563+
564+
scapy_delete_temp_files()
565+
520566
= Test utility functions - network related
521567
~ netaccess
522568

0 commit comments

Comments
 (0)