diff --git a/config.py b/config.py
index 80b9c95..77679ff 100644
--- a/config.py
+++ b/config.py
@@ -12,7 +12,6 @@ VT_ATTRIBUTES_MAPPING = {
     'ip': 'str'
 }
 
-#DNS_QUERIES_TYPE = ('A', 'MX', 'TXT')
 DNS_QUERIES_TYPE = {
     'A': 'address',
     'MX': ['exchange', 'preference'],
diff --git a/dnsinformations.py b/dnsinformations.py
index 77a59e5..6921415 100644
--- a/dnsinformations.py
+++ b/dnsinformations.py
@@ -20,37 +20,35 @@ class DNSInformations:
         report['updated_date'] = w.updated_date
         report['ns'] = w.name_servers
         report['admin_name'] = w.admin_name
+        report['registrar'] = w.registrar
         return report
 
     def resolver(self):
         report = dict()
 
-        n = dns.name.from_text(self._fqdn)
-        s = self._fqdn.split(".")
-        l = len(s)
-        fqdn = f"{s[l - 2]}.{s[l - 1]}"
-        print(fqdn)
-        o = dns.name.from_text(fqdn)
-        if n.relativize(o):
-            print(True)
-        
-
         for t in DNS_QUERIES_TYPE.keys():
             report[t] = self._resolving(self._fqdn, t, DNS_QUERIES_TYPE[t])
         return report
 
     def _resolving(self, fqdn, t, attr):
         report = list()
-        res_query = dns.resolver.resolve(fqdn, t)
-        for rdata in res_query:
-            if isinstance(attr, list):
-                data = dict()
-                for a in attr:
-                    data[a] = getattr(rdata, a)
-                report.append(data)
-            else:
-                report.append({
-                    attr: getattr(rdata, attr)
-                })
+        try:
+            res_query = dns.resolver.resolve(fqdn, t)
+            for rdata in res_query:
+                if isinstance(attr, list):
+                    data = dict()
+                    for a in attr:
+                        data[a] = getattr(rdata, a)
+                    report.append(data)
+                else:
+                    report.append({
+                        attr: getattr(rdata, attr)
+                    })
+        except dns.resolver.NoAnswer:
+            pass
+        except dns.resolver.NXDOMAIN:
+            report.append({'error': 'Domain not exist'})
+        except dns.resolver.NoNameservers:
+            report.append({'error': 'Domain not exist'})
         return report
 
diff --git a/hashing.py b/hashing.py
new file mode 100644
index 0000000..efa5063
--- /dev/null
+++ b/hashing.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+
+import hashlib
+
+
+class Hash:
+    def __init__(self):
+        pass
+
+    def hashMd5(self, f):
+        md5 = hashlib.md5()
+        with open(f, "rb") as data:
+            md5.update(data.read())
+        return md5.hexdigest()
+
+    def hashSha1(self, f):
+        sha1 = hashlib.sha1()
+        with open(f, "rb") as data:
+            sha1.update(data.read())
+        return sha1.hexdigest()
+
+    def hashSha256(self, f):
+        sha256 = hashlib.sha256()
+        with open(f, "rb") as data:
+            sha256.update(data.read())
+        return sha256.hexdigest()
+
+    def hashSha384(self, f):
+        sha384 = hashlib.sha384()
+        with open(f, "rb") as data:
+            sha384.update(data.read())
+        return sha384.hexdigest()
+
+    def hashSha512(self, f):
+        sha512 = hashlib.sha512()
+        with open(f, "rb") as data:
+            sha512.update(data.read())
+        return sha512.hexdigest()
diff --git a/main.py b/main.py
index d1697b8..3dc046b 100644
--- a/main.py
+++ b/main.py
@@ -2,19 +2,33 @@
 # -*- coding: utf-8 -*-
 
 from argparse import ArgumentParser
-import requests
-import re
 from config import VT_ATTRIBUTES_MAPPING
 from vt import VT
 from dnsinformations import DNSInformations as DNS
+import ipaddress
+from datetime import datetime
+from hashing import Hash
+from os.path import exists
 
 
 def checkArguments():
     parser = ArgumentParser(description="baoSOC")
     parser.add_argument('-c', '--config', help='Config file')
-    parser.add_argument('--hash', help='Hash file', action='store_true')
-    parser.add_argument('--dns', help='Get domain name information')
+    parser.add_argument('--dns', help='Get domain name information', action="store_true")
+    # For dns command
     parser.add_argument('--dnsattacks', help='Parse DNS pcap file')
+    parser.add_argument('--domain', help='Get domain name information')
+    parser.add_argument('--host', help='Get domain name information')
+    parser.add_argument('--ip', help='Get IP information')
+    # For hash command
+    parser.add_argument('--hash', help='Hash file', action='store_true')
+    parser.add_argument('--scanvt', help='If specified, scan the hash with VirusTotal', action='store_true')
+    parser.add_argument('--md5', help='Hash file')
+    parser.add_argument('--sha1', help='Hash file')
+    parser.add_argument('--sha256', help='Hash file')
+    parser.add_argument('--sha384', help='Hash file')
+    parser.add_argument('--sha512', help='Hash file')
+
     return parser.parse_args()
 
 def usage():
@@ -25,8 +39,20 @@ def usage():
     print("Usage: main.py [COMMAND]")
     print("-c PATH, --config PATH\t\tConfig file - mandatory")
     print("--hash FILE\t\t\tHash the file and check in VirusTotal")
-    print("--dns FQDN\t\t\tGet information regarding the domain with whois and VirusTotal")
-    print("--dnsattacks FILE\t\t\tParse the DNS pcap file and identify some DNS attacks")
+    print("--dns \t\t\t\tGet information regarding the domain with whois and VirusTotal")
+    print("--dnsattacks FILE\t\tParse the DNS pcap file and identify some DNS attacks")
+
+    print("\n--dns command:")
+    print("\t --domain FQDN\t\tScan and get domain information")
+    print("\t --host HOST\t\tScan and get host information")
+    print("\t --ip IP\t\tScan and get IP information")
+
+    print("\n--hash command:")
+    print("\t --md5 FILE\t\tGet the MD5 hash of the file")
+    print("\t --sha1 FILE\t\tGet the SHA256 of the file")
+    print("\t --sha256 FILE\t\tGet the SHA256 of the file")
+    print("\t --sha384 FILE\t\tGet the SHA384 of the file")
+    print("\t --sha512 FILE\t\tGet the SHA512 of the file")
 
 def mainMenu():
     print("\n           baoSOC           ")
@@ -74,35 +100,151 @@ def main():
         print("Failed to read the config file")
         exit(0)
 
-    #vt = VT(config['api_key'])
-    #report = list()
-    #print(vt.getIPVirusTotal("1.1.1.1", report))
+    report = dict()
 
+    # Analyse DNS
     if args.dns:
-        dns = DNS(config['api_key'], args.dns)
+        if args.domain:
+            _parsingDomain(config, args.domain, report)
+        if args.host:
+            pass
+        if args.ip:
+            _parsingIP(config, args.ip, report)
+    # Analyse hash
+    if args.hash:
+        h = Hash()
+        dispatcher = {
+           "MD5": h.hashMd5,
+           "SHA1": h.hashSha1,
+           "SHA256": h.hashSha256,
+           "SHA384": h.hashSha384,
+           "SHA512": h.hashSha512,
+        }
+        if args.md5:
+            hashType = "MD5"
+            filename = args.md5
+        if args.sha1:
+            hashType = "SHA1"
+            filename = args.sha1
+        if args.sha256:
+            hashType = "SHA256"
+            filename = args.sha256
+        if args.sha384:
+            hashType = "SHA384"
+            filename = args.sha384
+        if args.sha512:
+            hashType = "SHA512"
+            filename = args.sha512
+        
+        if not exists(filename):
+            print(f"File {filename} do not exist")
+        else:
+            res = dispatcher[hashType](filename)
+            print(f"{hashType} hash: {res}")
 
-        print("IP Informations:\n")
-        report = dns.resolver()
-        for key in report.keys():
-            print(f"{key}: ")
-            for entry in report[key]:
-                for subkey in entry.keys():
-                    value = entry[subkey]
-                    if isinstance(value, bytes):
-                        value = value.decode()
-                    print(f"\t{subkey}: {value}")
+        res = "6548eec09f4d8bc6514bee3e5452541c"
+        if args.scanvt:
+            _parsingHash(config, res, report)
 
-        print("\nReport with Whois:\n")
-        report = dns.whois()
-        for key in report.keys():
-            if isinstance(report[key], list):
-                print(f"{key}:")
-                for value in report[key]:
-                    print(f"\t{value}")
-            else:
-                print(f"{key}: {report[key]}")
+def _parsingHash(config, h, report):
+    report = dict() 
+    vt = VT(config['api_key'])
+
+    vt.getRateFromHash(h, report)
+    print("\n----------------------")
+    print("|     VirusTotal     |")
+    print("----------------------")
+
+    if 'error' in report:
+        print("Error, can not find any informations")
+        return
+
+    # File
+    print("\nFile information:")
+    f = report['results']['file']
+    print(f"\tMD5: {f['md5']}")
+    print(f"\tSHA1: {f['sha1']}")
+    print(f"\tMagic: {f['magic']}")
+    print(f"\tFile type: {f['filetype']}")
+    print(f"\tSize: {f['size']}")
+    print(f"\tExtension: {f['extension']}")
+    print(f"\tFirst seen: {f['first_seen']}")
+    print(f"\tLast analysis: {f['last_analysis']}")
+
+    # Vendors
+    vendors = report['results']['vendors']
+    print("\nVendors:")
+    print(f"\tTotal vendors: {vendors['total_vendors']}")
+    print(f"\tCategorized as malicious: {vendors['total_malicious']}\n")
+    for key in vendors['result']:
+        print(f"\t{key}: {vendors['result'][key]}")
+
+def _parsingIP(config, ip, report):
+    # Check if it's an IP address
+    vt = VT(config['api_key'])
+    try:
+        ip_obj = ipaddress.ip_address(ip)
+    except ValueError:
+        print("The IP is not valid")
+        return
+
+    report['ip'] = dict()
+    report['ip'] = vt.getIPVirusTotal(ip)
+
+    if 'error' not in report['ip']:
+        print("----------------------------")
+        print("|      IP Informations     |")
+        print("----------------------------")
+        for vt in VT_ATTRIBUTES_MAPPING.keys():
+            try:
+                vtAttributes = VT_ATTRIBUTES_MAPPING[vt]
+                if 'date' in vtAttributes:
+                    value = datetime.fromtimestamp(int(report['ip'][vt]))
+                else:
+                    value = report['ip'][vt]
+                print(f"{vt}: {value}")
+            except KeyError:
+                print(f"Cannot find the key {vt}")
+
+def _parsingDomain(config, fqdn, report):
+    vt = VT(config['api_key'])
+    dns = DNS(config['api_key'], fqdn)
+
+    print("----------------------")
+    print("|     resolving      |")
+    print("----------------------")
+    report['resolving'] = dns.resolver()
+    for key in report['resolving'].keys():
+        print(f"{key}: ")
+        for entry in report['resolving'][key]:
+            for subkey in entry.keys():
+                value = entry[subkey]
+                if isinstance(value, bytes):
+                    value = value.decode()
+                print(f"\t{subkey}: {value}")
+
+    print("\n----------------------")
+    print("|        whois       |")
+    print("----------------------")
+    report['whois'] = dns.whois()
+    report_whois = report['whois']
+    for key in report_whois.keys():
+        if isinstance(report_whois[key], list):
+            print(f"{key}:")
+            for value in report_whois[key]:
+                print(f"\t{value}")
+        else:
+            print(f"{key}: {report_whois[key]}")
+
+    print("\n----------------------")
+    print("|     VirusTotal     |")
+    print("----------------------")
+    report['vt'] = dict()
+    vt.getDomainReport(fqdn, report['vt'])
+    report_vt = report['vt']
+    for key in report_vt:
+        print(f"{key}: {report_vt[key]}")
 
-        print("\nReport with VirusTotal:\n")
 
 if __name__ == "__main__":
     main()
diff --git a/vt.py b/vt.py
index 76b44e1..6514461 100644
--- a/vt.py
+++ b/vt.py
@@ -1,16 +1,18 @@
 #!/ur/bin/env python3
 
 import requests
+from config import VT_ATTRIBUTES_MAPPING
+from datetime import datetime
 
 
 class VT:
     def __init__(self, api_key):
         self._url = "https://www.virustotal.com/api/v3"
         self._headers = {
-            'x-apki-key': api_key,
+            'x-apikey': api_key,
         }
 
-    def getIPVirusTotal(self, ip, report):
+    def getIPVirusTotal(self, ip):
         res = requests.get(
             f"{self._url}/ip_addresses/{ip}",
             headers=self._headers
@@ -33,16 +35,76 @@ class VT:
                     data[entry] = vt[entry]
                 except KeyError:
                     data[entry] = 'Unknown'
+        return data
 
-        report.append(data)
+    def getDomainReport(self, fqdn, report):
+        res = requests.get(
+            f"{self._url}/domains/{fqdn}",
+            headers=self._headers
+        )
+
+        js = res.json()
+        report['reputation'] = js['data']['attributes']['reputation']
+        report['last_update'] = \
+            datetime.fromtimestamp(js['data']['attributes']['last_update_date'])
+
+        # Get number of security vendors
+        report['total_vendors'] = 0
+        report['clean'] = 0
+        report['unrated'] = 0
+        report['malicious'] = 0
+        vendors = js['data']['attributes']['last_analysis_results']
+
+        for entry in vendors:
+            report['total_vendors'] += 1
+            if vendors[entry]['result'] == 'clean':
+                report['clean'] += 1
+            elif vendors[entry]['result'] == 'unrated':
+                report['unrated'] += 1
+            elif vendors[entry]['result'] == 'malicious':
+                report['malicious'] += 1
 
     def getRateFromHash(self, h, report):
         headers = self._headers
-        headers['resource'] = h
 
         res = requests.get(
-            f"{self._url}/file/report",
-            headers=headers
+            f"{self._url}/files/{h}",
+            headers=self._headers
         ).json()
 
-        data = dict()
+        if 'error' in res:
+            report["error"] = "Can not find the result"
+            return
+
+        attributes = res['data']['attributes']
+        report['results'] = dict()
+        report['results']['file'] = dict()
+        report['results']['file']['magic'] = attributes['magic']
+        report['results']['file']['sha1'] = attributes['sha1']
+        report['results']['file']['md5'] = attributes['md5']
+        report['results']['file']['filetype'] = attributes['detectiteasy']['filetype']
+        report['results']['file']['size'] = attributes['size']
+        report['results']['file']['extension'] = attributes['type_extension']
+        report['results']['file']['first_seen'] = \
+            datetime.fromtimestamp(attributes['first_seen_itw_date'])
+        report['results']['file']['last_analysis'] = \
+            datetime.fromtimestamp(attributes['last_analysis_date'])
+
+        # Identify vendors 
+        report['results']['vendors'] = dict()
+        report['results']['vendors']['total_vendors'] = 0
+        report['results']['vendors']['total_malicious'] = 0
+        report['results']['vendors']['result'] = dict()
+        report['results']['vendors']['result']['undetected'] = 0
+        results = res['data']['attributes']['last_analysis_results']
+        for entry in results:
+            report['results']['vendors']['total_vendors'] += 1
+            if results[entry]['category'] == 'undetected':
+                report['results']['vendors']['result']['undetected'] += 1
+            else:
+                result = results[entry]['result']
+                if result not in report['results']['vendors']['result']:
+                    report['results']['vendors']['result'][result] = 0
+                report['results']['vendors']['result'][result] += 1
+                report['results']['vendors']['total_malicious'] += 1
+