Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/logger #48

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions tracevis.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
import utils.ripe_atlas
import utils.trace
import utils.vis
import textwrap
import logging

import json
from copy import deepcopy

logger = None

TIMEOUT = 1
MAX_TTL = 50
Expand Down Expand Up @@ -62,6 +69,7 @@ def process_input_args(args, parser):


def get_args():
global logger
parser = argparse.ArgumentParser(
description='Traceroute with any packet. \
Visualize the routes. Discover Middleboxes and Firewalls', formatter_class=argparse.RawTextHelpFormatter)
Expand Down Expand Up @@ -126,6 +134,8 @@ def get_args():
- 'new' : to change source port, sequence number, etc in each request (default)
- 'new,rexmit' : to begin with the 'new' option in each of the three steps for all destinations and then rexmit"""
)
parser.add_argument('--verbose', '-v', action='count', default=0,
help='Set log level: -v for WARNING, -vv for INFO, -vvv for DEBUG')
parser.add_argument('--iface', type=str,
help="set the target network interface")
parser.add_argument('--show-ifaces', action='store_true',
Expand All @@ -134,6 +144,9 @@ def get_args():
parser.print_help()
sys.exit(1)
args = parser.parse_args()
args.verbose = 40 - (10*args.verbose) if 0 <= args.verbose <= 3 else 40
logging.basicConfig(level=args.verbose, format='%(message)s')
logger = logging.getLogger(__name__)
args_dict = process_input_args(args, parser)
return args_dict

Expand Down Expand Up @@ -246,10 +259,10 @@ def main(args):
else:
raise RuntimeError("Bad input type")
except (utils.packet_input.BADPacketException, utils.packet_input.FirewallException) as e:
print(f"{e!s}")
logger.error(f"{e!s}")
exit(1)
except Exception as e:
print(f"Error!\n{e!s}")
logger.error(f"Error!\n{e!s}")
exit(2)
if do_tcph1 or do_tcph2:
name_prefix += "-tcph"
Expand Down Expand Up @@ -292,7 +305,7 @@ def main(args):
if utils.vis.vis(
measurement_path=measurement_path, attach_jscss=attach_jscss,
edge_lable=edge_lable):
print("finished.")
logger.info("finished.")


if __name__ == "__main__":
Expand Down
12 changes: 7 additions & 5 deletions utils/csv.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/usr/bin/env python3
import json
import os.path
import logging
logger = logging.getLogger(__name__)

csv_header_all = ""
csv_blank_row = ""
Expand All @@ -27,7 +29,7 @@ def parse_json(file_name: str) -> list:
try:
json_data = json.loads(json_str)
except:
print("JSON format is not valid!")
logger.error("JSON format is not valid!")
return ""
for measurement in json_data:
dst_addr = measurement["dst_addr"]
Expand Down Expand Up @@ -113,9 +115,9 @@ def json2csv(file_name: str, sort_it: bool = True):
if sort_it:
data = sorted(data, key=lambda d: d['hop'])
csv = data_to_csv(data, sort_it)
if csv != "": # todo (xhdix): it will never be empty. we shold do better
print("saving measurement in csv...")
if csv != "": # TODO (xhdix): it will never be empty. we should do better
logger.info("saving measurement in csv...")
csvfile.write(csv)
print("saved: " + new_file_name)
logger.info("saved: " + new_file_name)
else:
print("error: " + file_name + " does not exist!")
logger.error("error: " + file_name + " does not exist!")
53 changes: 25 additions & 28 deletions utils/packet_input.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
#!/usr/bin/env python3
import base64
import json
import json
import logging
logger = logging.getLogger(__name__)
import subprocess

from scapy.layers.inet import IP, TCP
from scapy.utils import hexdump, import_hexcap


FIREWALL_COMMANDS_HELP = "\r\n( · - · · · \r\n\
You may need to temporarily block RST output packets in your firewall.\r\n\
For example:\r\n\
Expand Down Expand Up @@ -128,9 +131,9 @@ def _read_pasted_packet(cls, show=False):
"it's not IPv4 or the hexdump is not started with IP layer")
p1[IP].src = '127.1.2.7'
if show:
print(" . . . - . developed view of this packet:")
logger.debug(" . . . - . developed view of this packet:")
p1.show()
print(" . . . - . . . . - . . . . - . . . . - . ")
logger.debug(" . . . - . . . . - . . . . - . . . . - . ")
return p1

@classmethod
Expand All @@ -154,17 +157,14 @@ def from_stdin(cls, os_name: str, trace_retransmission: bool):
# FIXME: WHAT IF NOT? FAIL?
raise FirewallException("No iptables!")
else:
do_tcph1 = cls._ask_yesno(
"Would you like to do a TCP Handshake before sending this packet?")
print(" · - · - · · - · - · · - · - · · - · - · ")

do_tcph1 = cls._ask_yesno("Would you like to do a TCP Handshake before sending this packet?")
logger.info(" · - · - · · - · - · · - · - · · - · - · ")
if cls._ask_yesno("Would you like to add a second packet"):
copy_packet_2 = cls._read_pasted_packet(True)
if copy_packet_2.haslayer(TCP):
if copy_packet_2[TCP].flags == "PA":
do_tcph2 = cls._ask_yesno(
"Would you like to do a TCP Handshake before sending this packet?")
print(" ********************************************************************** ")
do_tcph2 = cls._ask_yesno("Would you like to do a TCP Handshake before sending this packet?")
logger.info(" ********************************************************************** ")
return InputPacketInfo(copy_packet_1, copy_packet_2, do_tcph1, do_tcph2, add_firewall_rule)

@classmethod
Expand All @@ -173,14 +173,14 @@ def _read_json_packet(cls, json_config, k, show=False):
json_config[k]['hex'] = base64.b64decode(
json_config[k]['hex'][4:].strip()).decode()
packet = IP(import_hexcap(json_config[k]['hex']))
print(" . . . - . . . . - . . . . - . . . . - . ")
print(" . . . - . developed view of first packet:")
logger.info(" . . . - . . . . - . . . . - . . . . - . ")
logger.info(" . . . - . developed view of first packet:")
if not cls._supported_or_correct(packet):
BADPacketException(
f"{k} it's not IPv4 or the hexdump is not started with IP layer")
if show:
packet.show()
print(" . . . - . . . . - . . . . - . . . . - . ")
logger.info(" . . . - . . . . - . . . . - . . . . - . ")
return packet

@classmethod
Expand All @@ -204,13 +204,11 @@ def from_json(cls, os_name: str, trace_retransmission: bool, packet_data: json):
json_config, 'packet2', show=True)
if copy_packet_2.haslayer(TCP):
if copy_packet_2[TCP].flags == "PA":
do_tcph2 = json_config['packet2'].get(
'handshake', False)
add_firewall_rule = json_config.get('add_firewall_drop', False)
print(
" ********************************************************************** ")
do_tcph2 = json_config['packet2'].get('handshake', False)
add_firewall_rule = json_config.get('add_firewall_drop', False)
logger.info(" ********************************************************************** ")
except FileNotFoundError:
print(f" · · · · · · · · file '{file}' not found!.")
logger.error(f" · · · · · · · · file '{file}' not found!.")
raise BADPacketException("File Not Found")
return InputPacketInfo(copy_packet_1, copy_packet_2, do_tcph1, do_tcph2, add_firewall_rule)

Expand All @@ -234,10 +232,10 @@ def _read_interactive_packet(cls, show=False):
raise BADPacketException(
"it's not IPv4 or the hexdump is not started with IP layer")
if show:
print(" . . . - . . . . - . . . . - . . . . - . ")
print(" . . . - . developed view of first packet:")
logger.debug(" . . . - . . . . - . . . . - . . . . - . ")
logger.debug(" . . . - . developed view of first packet:")
packet.show()
print(" . . . - . . . . - . . . . - . . . . - . ")
logger.debug(" . . . - . . . . - . . . . - . . . . - . ")
return packet

@classmethod
Expand All @@ -260,13 +258,12 @@ def from_scapy(cls, os_name: str, trace_retransmission: bool):
# FIXME: WHAT IF NOT? FAIL?
raise FirewallException("No iptables!")
else:
do_tcph1 = cls._ask_yesno(
"Would you like to do a TCP Handshake before sending this packet?")
print(" · - · - · · - · - · · - · - · · - · - · ")
do_tcph1 = cls._ask_yesno("Would you like to do a TCP Handshake before sending this packet?")
logger.info(" · - · - · · - · - · · - · - · · - · - · ")

if cls._ask_yesno("Would you like to add a second packet"):
copy_packet_2 = cls._read_interactive_packet(show=True)
if copy_packet_2.haslayer(TCP) and copy_packet_2[TCP].flags == "PA":
do_tcph2 = cls._ask_yesno(
"Would you like to do a TCP Handshake before sending this packet?")
print(" ********************************************************************** ")
do_tcph2 = cls._ask_yesno("Would you like to do a TCP Handshake before sending this packet?")
logger.info(" ********************************************************************** ")
return InputPacketInfo(copy_packet_1, copy_packet_2, do_tcph1, do_tcph2, add_firewall_rule)
31 changes: 13 additions & 18 deletions utils/ripe_atlas.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import urllib.request
from datetime import datetime
from time import sleep
import logging
logger = logging.getLogger(__name__)

MEASUREMENT_IDS = [
5011, # c.root-servers.net
Expand Down Expand Up @@ -33,14 +35,11 @@ def download_from_atlas(
measurement_name = "ripe-atlas-" + str(probe_id) + "-tracevis-" \
+ datetime.utcnow().strftime("%Y%m%d-%H%M")
if probe_id != "":
print(
" ********************************************************************** ")
print(
"downloading data from probe ID: " + str(probe_id))
print(" · · · - - - · · · · · · - - - · · · · · · - - - · · · ")
logger.info(" ********************************************************************** ")
logger.info("downloading data from probe ID: " + str(probe_id))
logger.info(" · · · - - - · · · · · · - - - · · · · · · - - - · · · ")
for measurement_id in measurement_ids:
print(
"downloading measurement ID: " + str(measurement_id))
logger.info("downloading measurement ID: " + str(measurement_id))
requset_url = ("https://atlas.ripe.net/api/v2/measurements/"
+ str(measurement_id)
+ "/latest/?format=json&probe_ids="
Expand All @@ -50,24 +49,20 @@ def download_from_atlas(
downloaded_data = json.loads(url.read().decode())
if downloaded_data is not None:
all_measurements.append(downloaded_data[0])
print(
"downloading measurement ID " + str(measurement_id) + " finished.")
logger.info("downloading measurement ID " + str(measurement_id) + " finished.")
else:
print("failed to download measurement ID: "
+ str(measurement_id))
logger.error(f"failed to download measurement ID: {measurement_id!s}")
sleep(3)
print(" · · · - - - · · · · · · - - - · · · · · · - - - · · · ")
print(
" ********************************************************************** ")
logger.info(" · · · - - - · · · · · · - - - · · · · · · - - - · · · ")
logger.info(" ********************************************************************** ")
if len(all_measurements) < 1:
exit()
measurement_path = output_dir + measurement_name + ".json"
print("saving json file... to: " + measurement_path)
logger.info("saving json file... to: " + measurement_path)
with open((measurement_path), 'w', encoding='utf-8') as json_file:
json.dump(all_measurements, json_file,
ensure_ascii=False, indent=4)
print("saved: " + measurement_path)
logger.info("saved: " + measurement_path)
was_successful = True
print(
" ********************************************************************** ")
logger.info(" ********************************************************************** ")
return was_successful, measurement_path
Loading