#!/usr/local/bin/python3

import json
from scapy.all import *
from urllib.parse import urlparse, parse_qs

load_layer('http')
load_layer('tls')
load_layer('dns')

results = []

def packet_filter(packet):
    return (packet.haslayer('HTTP Request') | packet.haslayer('HTTP Response'))

def HTTP_Request_process(packet):
    if(packet['HTTP Request'].Method.decode() == "GET" or packet['HTTP Request'].Method.decode() == "POST"):
        dict_obj = {"type": "request"}
        dict_obj["host"] = packet['HTTP Request'].Host.decode()
        dict_obj["method"] = packet['HTTP Request'].Method.decode()
        dict_obj["path"] = packet['HTTP Request'].Path.decode()

        if((packet['HTTP Request'].Content_Type != None) and (packet['HTTP Request'].Content_Type.decode() == 'application/x-www-form-urlencoded')):
            dict_obj['body'] = packet['Raw'].load.decode()
            split = dict_obj['body'].split("&")
            username = split[0].split("=")[1]
            password = split[1].split("=")[1]
            dict_obj['form'] = [
                {
                    "key": split[0].split("=")[0],
                    "value": username
                },
                {
                    "key": split[1].split("=")[0],
                    "value": password
                }
            ]
        
        if(dict_obj['method'] == "GET"):
            if '?' in dict_obj['path']:
                find_params_split = dict_obj['path'].split("?")
                all_param = {}
                for i in range(1, len(find_params_split)):
                    further_split = find_params_split[i].split("=")
                    all_param[further_split[0]] = further_split[1]
                    dict_obj["query_args"] = all_param

            if packet['HTTP Request'].Cookie != None:
                if (len(packet['HTTP Request'].Cookie.decode().split(";")) > 1):
                    #Cookie    = 'session-id=eyJhbGciOiJIUzI1NiJ9.YWxpY2U.MHnFOEgp6Qm4GbdqyJfWeYdxnQqhZXw-kCEHw9AI--I; order-id=775230'
                    cookies_list = []
                    split_multiple = packet['HTTP Request'].Cookie.decode().split(";")
                    for i in range(0, len(split_multiple)):
                        all_cookies = {}
                        each_cookie = split_multiple[i].split("=")
                        all_cookies["key"] = each_cookie[0]
                        all_cookies["value"] = each_cookie[1]
                        cookies_list.append(all_cookies)
                    dict_obj['cookies'] = cookies_list
                    
                elif (len(packet['HTTP Request'].Cookie.decode().split(";")) == 1):
                    #Cookie    = 'session-id=eyJhbGciOiJIUzI1NiJ9.YWxpY2U.MHnFOEgp6Qm4GbdqyJfWeYdxnQqhZXw-kCEHw9AI--I'
                    cookie = packet['HTTP Request'].Cookie.decode().split("=")
                    cookie_dict = {}
                    cookie_dict["key"] = cookie[0]
                    cookie_dict["value"] = cookie[1]
                    dict_obj['cookies'] = [cookie_dict]


        results.append(dict_obj)


def HTTP_Response_process(packet):
    packet.show()
    dict_obj = {"type": "response"}
    dict_obj['status_code'] = packet['HTTP Response'].Status_Code.decode()

    if(packet['HTTP Response'].Set_Cookie != None):
        cookie_split = packet['HTTP Response'].Set_Cookie.decode().split(";")[0].split("=")
        if(cookie_split[0] == "session-id"):
            cookie_dict = {}
            cookie_dict["key"] = cookie_split[0]
            cookie_dict["value"] = cookie_split[1]
            dict_obj['cookie'] = cookie_dict
    
    dict_obj["body"] = packet['Raw'].load.decode()

    results.append(dict_obj)


def packet_process(packet):

    if(packet.haslayer('HTTP Request')):
        packet.show()
        HTTP_Request_process(packet)


    if (packet.haslayer('HTTP Response')):
        packet.show()
        HTTP_Response_process(packet)


def run(count, filepath):
    sniff(iface="eth0", lfilter=packet_filter, prn=packet_process, count=count)
    with open(filepath, "w") as file_stream:
        file_stream.write(json.dumps(results, indent=4))
    
if __name__ == "__main__":
    import os, sys, getopt
    def usage():
       print ('Usage:	' + os.path.basename(__file__) + ' filepath ')
       print ('\t -c count, --count=count')
       sys.exit(2)
    # extract parameters
    try:
         opts, args = getopt.getopt(sys.argv[1:],"hc:",["help", "count="])
    except getopt.GetoptError as err:
         print(err)
         usage()
         sys.exit(2)
    count = None
    filepath = args[0] if len(args) > 0 else None
    for opt, arg in opts:
        if opt in ("-h", "--help"):
           usage()
        elif opt in ("-c", "--count"):
           try:
                count = int(arg)
           except ValueError:
                print("count must be a natural number")
                sys.exit(2)
    if (count is None):
        print('count option is missing\n')
        usage()
    if (filepath is None):
        print('filepath is missing\n')
        usage()
    # run the command
    run(count, filepath)