Skip to content

Commit ceb624c

Browse files
authored
Merge pull request #65 from cisagov/restore_mac_tab
Restored MAC to IP tab to development branch
2 parents 4a17e7b + a36d396 commit ceb624c

File tree

3 files changed

+74
-1
lines changed

3 files changed

+74
-1
lines changed

src/navv/bll.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,46 @@ def get_snmp_df(zeek_data: list):
159159
"community",
160160
],
161161
)
162+
163+
@timeit
164+
def get_mac_df(zeek_df: pd.DataFrame):
165+
smac_df = zeek_df[
166+
[
167+
"src_mac",
168+
"src_ip",
169+
]
170+
].reset_index(drop=True)
171+
172+
dmac_df = zeek_df[
173+
[
174+
"dst_mac",
175+
"dst_ip",
176+
]
177+
].reset_index(drop=True)
178+
179+
smac_df = smac_df.rename(columns={'src_mac': 'mac', 'src_ip': 'ip'})
180+
dmac_df = dmac_df.rename(columns={'dst_mac': 'mac', 'dst_ip': 'ip'})
181+
mac_df = smac_df._append(dmac_df, ignore_index=True)
182+
mac_df = mac_df.groupby('mac')['ip'].apply(list).reset_index(name='associated_ip')
183+
184+
for index, row in enumerate(mac_df.to_dict(orient="records"), start=0):
185+
# Source IPs - Need to get unique values
186+
ips = set(row["associated_ip"])
187+
list_ips = (list(ips))
188+
if len(list_ips) > 1:
189+
ip_list = ', '.join([str(item) for item in list_ips])
190+
191+
else:
192+
ip_list = list_ips[0]
193+
194+
mac_df.at[index, 'associated_ip'] = ip_list
195+
196+
# Source Manufacturer column
197+
mac_vendors = {}
198+
with open(MAC_VENDORS_JSON_FILE) as f:
199+
mac_vendors = json.load(f)
200+
mac_df["vendor"] = mac_df["mac"].apply(
201+
lambda mac: get_mac_vendor(mac_vendors, mac)
202+
)
203+
204+
return mac_df

src/navv/commands.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
# cisagov Libraries
1010
from navv.gui.app import app
11-
from navv.bll import get_inventory_report_df, get_snmp_df, get_zeek_df
11+
from navv.bll import get_inventory_report_df, get_snmp_df, get_zeek_df, get_mac_df
1212
from navv.message_handler import success_msg, warning_msg
1313
from navv.spreadsheet_tools import (
1414
auto_adjust_width,
@@ -24,6 +24,7 @@
2424
write_snmp_sheet,
2525
write_stats_sheet,
2626
write_unknown_internals_sheet,
27+
write_mac_sheet,
2728
)
2829
from navv.zeek import (
2930
get_conn_data,
@@ -90,6 +91,7 @@ def generate(customer_name, output_dir, pcap, zeek_logs):
9091

9192
# Get inventory report dataframe
9293
inventory_df = get_inventory_report_df(zeek_df)
94+
mac_df = get_mac_df(zeek_df)
9395

9496
# Turn zeekcut data into rows for spreadsheet
9597
rows = create_analysis_array(zeek_data, timer=timer_data)
@@ -118,6 +120,8 @@ def generate(customer_name, output_dir, pcap, zeek_logs):
118120

119121
write_snmp_sheet(snmp_df, wb)
120122

123+
write_mac_sheet(mac_df, wb)
124+
121125
auto_adjust_width(wb["Analysis"])
122126

123127
times = (

src/navv/spreadsheet_tools.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import openpyxl
1616
import openpyxl.styles
17+
from openpyxl.styles import Alignment
1718
from openpyxl.worksheet.table import Table
1819
import netaddr
1920
from tqdm import tqdm
@@ -478,6 +479,31 @@ def write_stats_sheet(wb, stats):
478479
stats_sheet[f"{string.ascii_uppercase[col_index]}2"].value = stats[stat]
479480
auto_adjust_width(stats_sheet)
480481

482+
def write_mac_sheet(mac_df, wb):
483+
"""Fill spreadsheet with MAC address -> IP address translation with manufacturer information"""
484+
sheet = make_sheet(wb, "MAC", idx=4)
485+
sheet.append(
486+
["MAC", "Manufacturer", "IPs"]
487+
)
488+
for index, row in enumerate(mac_df.to_dict(orient="records"), start=2):
489+
# Source MAC column
490+
sheet[f"A{index}"].value = row["mac"]
491+
492+
# Source Manufacturer column
493+
sheet[f"B{index}"].value = row["vendor"]
494+
495+
# Source IPs
496+
sheet[f"C{index}"].value = row["associated_ip"]
497+
if len(row["associated_ip"]) > 16:
498+
sel_cell = sheet[f"C{index}"]
499+
sel_cell.alignment = Alignment(wrap_text=True)
500+
est_row_hght = int(len(row["associated_ip"])/50)
501+
if est_row_hght < 1:
502+
est_row_hght = 1
503+
sheet.row_dimensions[index].height = est_row_hght * 15
504+
505+
auto_adjust_width(sheet)
506+
sheet.column_dimensions["C"].width = 39 * 1.2
481507

482508
def make_sheet(wb, sheet_name, idx=None):
483509
"""Create the sheet if it doesn't already exist otherwise remove it and recreate it"""

0 commit comments

Comments
 (0)