def vm_arp_reply(compute_bridge=None, Vlan_ID=None, Network=None, Mask=None, host_IP=None, vm_ipaddr=None,
                 competition_id=None, step_flag=None, command_scene=None, commands_type=None):
    # 得到网关及IP地址的16进制字符串
    result = net_dhcp_start_end_gw(Network, Mask)
    gateway_mac_hex = '0x' + ConfigParameter.VMGatewayMAC.replace(':', '')
    gateway_ip_hex = IP(result['dhcp_gateway']).strHex()
    command_scene = command_scene if command_scene else rule_normal
    commands_type = commands_type if commands_type else 'None'
    try:
        add_commands = [
            "\"ovs-ofctl add-flow %s 'arp,arp_op=0x01,arp_spa=%s,arp_tpa=%s,"
            "dl_dst=ff:ff:ff:ff:ff:ff,actions=move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],"
            "mod_dl_src:%s,load:0x2->NXM_OF_ARP_OP[],move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],"
            "move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],load:%s#x->NXM_NX_ARP_SHA[],"
            "load:%s#x->NXM_OF_ARP_SPA[],in_port'\"" %
            (compute_bridge, vm_ipaddr, result['dhcp_gateway'],
             ConfigParameter.VMGatewayMAC, gateway_mac_hex, gateway_ip_hex)
        ]
        del_commands = [
            "\"ovs-ofctl --strict del-flows %s 'arp,arp_op=0x01,arp_spa=%s,"
            "arp_tpa=%s,dl_dst=ff:ff:ff:ff:ff:ff'\"" % (
                compute_bridge, vm_ipaddr, result['dhcp_gateway'])
        ]
    except Exception, e:
        print str(e)
        LogExceptionHelp.logException("generate the cmd of making the ARP active fail: %s" % e)
        return None
def rule_scp_parent_ip(VMName, action, vlan_ID=None, mod_card=None, vm_ip_addr=None, vm_ipaddr_Mask=None,
                       dhcp_listening_ipadd=None, dhcp_gateway_ipadd=None):
    # 得到虚拟机的所有vnet及mac
    if vm_ip_addr and vm_ipaddr_Mask:
        result = net_dhcp_start_end_gw(vm_ip_addr, vm_ipaddr_Mask)
    vm_cards = getOVSPort_MAC(VMName)  # 返回[['vnet0', '52:54:00:96:5a:d3'], ['vnet1', 'fa:fd:1c:e4:b4:6e']]
    if not vm_cards or not mod_card:
        return False
    vm_vnet = vm_cards[mod_card][0]
    vm_mac = vm_cards[mod_card][1]
    try:
        if action == '1' or action == 'add':
            CMD = ['ip netns add VLAN%d' % vlan_ID,
                   'ip link add vlan%d-out type veth peer name vlan%d-in' % (vlan_ID, vlan_ID),
                   'ip link set vlan%d-in netns VLAN%d' % (vlan_ID, vlan_ID),
                   'ovs-vsctl add-port %s vlan%d-out' % (compute_bridge, vlan_ID),
                   'ovs-vsctl set port vlan%d-out tag=%d' % (vlan_ID, vlan_ID),
                   'ip link set vlan%d-out up' % vlan_ID,
                   'ip netns exec VLAN%d ip link set vlan%d-in up' % (vlan_ID, vlan_ID),
                   'ip netns exec VLAN%d ip add add %s/%d dev vlan%d-in' % (
                       vlan_ID, result['dhcp_gateway'], vm_ipaddr_Mask, vlan_ID),
                   "echo '%d %s %s * 01:%s' > /tmp/%d.leases" % (0, vm_mac, vm_ip_addr, vm_mac, vlan_ID),
                   '[ -e /tmp/%d.pid ] && kill -9 `cat /tmp/%d.pid`' % (vlan_ID, vlan_ID),
                   'ip netns exec VLAN%d dnsmasq --strict-order --interface vlan%d-in --except-interface lo'
                   ' --bind-interfaces --dhcp-range=%s,%s,infinite --dhcp-option=3,%s --dhcp-no-override'
                   ' --dhcp-leasefile=/tmp/%d.leases --pid-file=/tmp/%d.pid' % (
                       vlan_ID, vlan_ID, vm_ip_addr, vm_ip_addr, result['dhcp_gateway'], vlan_ID, vlan_ID),
                   'virsh domif-setlink %s %s down' % (VMName, vm_vnet),
                   'sleep 1',
                   'virsh domif-setlink %s %s up' % (VMName, vm_vnet)
                   ]
        if action == '2' or action == 'mod':
            CMD = ['[ -e /tmp/%d.pid ] && kill -9 `cat /tmp/%d.pid`' % (vlan_ID, vlan_ID),
                   "echo '%d %s %s * 01:%s' > /tmp/%d.leases" % (0, vm_mac, vm_ip_addr, vm_mac, vlan_ID),
                   'ip netns exec VLAN%d dnsmasq --strict-order --interface vlan%d-in --except-interface lo'
                   ' --bind-interfaces --dhcp-range=%s,%s,infinite --dhcp-option=3,%s --dhcp-no-override'
                   ' --dhcp-leasefile=/tmp/%d.leases --pid-file=/tmp/%d.pid' % (
                       vlan_ID, vlan_ID, vm_ip_addr, vm_ip_addr, result['dhcp_gateway'], vlan_ID, vlan_ID),
                   'virsh domif-setlink %s %s down' % (VMName, vm_vnet),
                   'sleep 1',
                   'virsh domif-setlink %s %s up' % (VMName, vm_vnet)
                   ]
        if action == '3' or action == 'del':
            CMD = ['ip netns del VLAN%d' % vlan_ID,
                   'ip link del vlan%d-out type veth peer name vlan%d-in' % (vlan_ID, vlan_ID),
                   'ovs-vsctl del-port %s vlan%d-out' % (compute_bridge, vlan_ID),
                   '[ -e /tmp/%d.pid ] && kill -9 `cat /tmp/%d.pid`' % (vlan_ID, vlan_ID),
                   '[ -e /tmp/%d.pid ] && rm -rf /tmp/%d.pid' % (vlan_ID, vlan_ID),
                   '[ -e /tmp/%d.leases ] && rm -rf /tmp/%d.leases' % (vlan_ID, vlan_ID)
                   ]
    except Exception, e:
        print str(e)
        LogExceptionHelp.logException("the cmd of generating dhcp for parent network is failure: %s" % e)
        return None
def client_dhcp_init(client_dhcp_network, client_Mask):
    leases_file = '/tmp/client_dhcp.leases'
    pid_file = '/tmp/client_dhcp.pid'
    last_gateway_file = '/tmp/client_last_gateway.txt'  # 保存DHCP上一次的网关信息
    command_scene = 1
    try:
        result = net_dhcp_start_end_gw(client_dhcp_network, client_Mask, 'student')
    except Exception, e:
        print str(e)
        LogExceptionHelp.logException("initialize adding dhcp to student's vm fail: %s" % e)
        return None
def Conn():
    try:
        conn = mysql.connector.connect(user=ConfigParameter.DBUser,
                                       password=ConfigParameter.DBPasswd,
                                       host=ConfigParameter.DBHost,
                                       database=ConfigParameter.DBName,
                                       port=ConfigParameter.DBPort)
        return conn
    except Exception as ex:
        LogExceptionHelp.logException(str(ex))
        return None
def vm_dhcp_init(compute_bridge, step_flag, competition_id, vlan_ID, host_ip, vm_dhcp_network, vm_ipaddr_Mask,
                 times=None, dhcp_listening_ipadd=None, vm_mac_address=None, vm_ip_addr=None, dhcp_gateway_ipadd=None):
    # 计算起始、结束ip、网关(dnsmasq命令必须加此参数,否则不分配)。
    result = net_dhcp_start_end_gw(vm_dhcp_network, vm_ipaddr_Mask, step_flag)
    dhcp_lease_time = result['dhcp_lease_time']
    # dhcp_start = vm_ip_addr if vm_ip_addr else result['dhcp_start']
    dhcp_start = result['dhcp_start']
    # dhcp_end = vm_ip_addr if vm_ip_addr else result['dhcp_end']
    dhcp_end = result['dhcp_end']
    dhcp_gateway = dhcp_gateway_ipadd if dhcp_gateway_ipadd else result['dhcp_gateway']
    # dhcp_listen_add = dhcp_listening_ipadd if dhcp_listening_ipadd else result['dhcp_ipaddr']
    dhcp_listen_add = result['dhcp_ipaddr']
    step4_dhcp_leases_file = '/tmp/%s.leases' % competition_id
    # 如果是场景3的话,保存所有虚拟机的leases信息
    if step_flag == ConfigParameter.scene_attack1:
        with open(step4_dhcp_leases_file, 'a+') as f:
            f.write('%d %s %s * 01:%s\n' % (dhcp_lease_time, vm_mac_address, vm_ip_addr, vm_mac_address))
    # DHCP添加命令
    try:
        # DHCP通用命令(所有场景通用)
        dhcp_init_commands = ['ip netns add VLAN%d' % vlan_ID,
                              'ip link add vlan%d-out type veth peer name vlan%d-in' % (vlan_ID, vlan_ID),
                              '[ -e /var/run/netns/VLAN%d ] && [ -e /sys/devices/virtual/net/vlan%d-in ]'
                              ' && [ -e /sys/devices/virtual/net/vlan%d-out ]' % (
                                  vlan_ID, vlan_ID, vlan_ID),
                              'ip link set vlan%d-in netns VLAN%d' % (vlan_ID, vlan_ID),
                              'ovs-vsctl add-port %s vlan%d-out' % (compute_bridge, vlan_ID),
                              'ovs-vsctl set port vlan%d-out tag=%d' % (vlan_ID, vlan_ID),
                              'ip link set vlan%d-out up' % vlan_ID,
                              'ip netns exec VLAN%d ip link set vlan%d-in up' % (vlan_ID, vlan_ID),
                              'ip netns exec VLAN%d ip add add %s/%d dev vlan%d-in' % (
                                  vlan_ID, dhcp_listen_add, vm_ipaddr_Mask, vlan_ID),
                              ]
        # 正常场景(非场景4)的dhcp命令
        normal_dhcp_commands = ["echo '%d %s %s * 01:%s' >> /tmp/%d.leases" % (
            dhcp_lease_time, vm_mac_address, vm_ip_addr, vm_mac_address, vlan_ID),
                                '[ -e /tmp/%d.pid ] && kill -9 `cat /tmp/%d.pid`' % (vlan_ID, vlan_ID),
                                'ip netns exec VLAN%d dnsmasq --strict-order --interface vlan%d-in'
                                ' --except-interface lo --bind-interfaces --dhcp-range=%s,%s,infinite'
                                ' --dhcp-option=3,%s --dhcp-no-override --dhcp-leasefile=/tmp/%d.leases'
                                ' --pid-file=/tmp/%d.pid' % (
                                    vlan_ID, vlan_ID, dhcp_start, dhcp_end, dhcp_gateway, vlan_ID, vlan_ID)
                                ]
        # 互攻阶段(场景4)的dhcp命令
        scene_attack2_dhcp_commands = [
            'ip netns exec VLAN%d dnsmasq --strict-order --interface vlan%d-in --except-interface lo'
            ' --bind-interfaces --dhcp-range=%s,%s,infinite --dhcp-option=3,%s --dhcp-no-override'
            ' --dhcp-leasefile=%s --pid-file=/tmp/%d.pid' % (
                vlan_ID, vlan_ID, dhcp_start, dhcp_end, dhcp_gateway, step4_dhcp_leases_file, vlan_ID)]
    except Exception, e:
        print str(e)
        LogExceptionHelp.logException("generate the cmd of making dhcp for scene %s fail: %s" % (step_flag, e))
        return None
def rule_compute(competition_id, step_flag, host_ip, vm_interface_name, new_vlan_ID,
                 vmname):  # 场景3的时候调用,循环每个虚拟机,阶段ID填4,host_ip填计算节点的IP,new_vlan_ID传新vlan
    try:
        compute_add_commands = ['ovs-vsctl set port %s tag=%d' % (vm_interface_name, new_vlan_ID),
                                r"sed -i 's/<tag id='.*'\\/>/<tag id='\\''%d'\\''\\/>/g' /etc/libvirt/qemu/%s.xml" % (
                                    new_vlan_ID, vmname)
                                ]
    except Exception, e:
        print str(e)
        LogExceptionHelp.logException('competition %s scene %d, '
                                      'generate the cmd of compute node fail: %s' %
                                      (competition_id, step_flag, e))
def vm_clear_dhcp(compute_bridge, vlan_ID, competition_id, step_flag, host_ip):
    # DHCP拆除命令
    step4_dhcp_leases_file = '/tmp/%s.leases' % competition_id
    try:
        clear_commands = ['ip netns del VLAN%d' % vlan_ID,
                          'ip link del vlan%d-out type veth peer name vlan%d-in' % (vlan_ID, vlan_ID),
                          'ovs-vsctl del-port %s vlan%d-out' % (compute_bridge, vlan_ID),
                          '[ -e /tmp/%d.pid ] && kill -9 `cat /tmp/%d.pid`' % (vlan_ID, vlan_ID),
                          '[ -e /tmp/%d.pid ] && rm -rf /tmp/%d.pid' % (vlan_ID, vlan_ID),
                          '[ -e /tmp/%d.leases ] && rm -rf /tmp/%d.leases' % (vlan_ID, vlan_ID)
                          ]
    except Exception, e:
        print str(e)
        LogExceptionHelp.logException("generate the cmd of clean up dhcp for scene %s fail: %s" % (step_flag, e))
        return None
def sql_insert(SQL_command):
    try:
        dbconn = sql_conn()
        cursor = dbconn.cursor()
        cursor.execute(SQL_command)
        dbconn.commit()
        cursor.close()
        dbconn.close()
    except mysql.connector.Error as e:
        print('mysql.connector.Error:{}'.format(e))
        LogExceptionHelp.logException('add rule to database error: %s' % e)
    finally:
        if cursor:
            cursor.close()
        dbconn.close()
def rule_student(competition_id, step_flag, student_ip, vm_mac, host_ip, vlan_ID, vm_ipaddr):  # 针对每个学生进行策略创建(循环每个虚拟机多次)
    try:
        add_commands = [
            'ovs-ofctl add-flow %s dl_type=0x0800,nw_src=%s,nw_dst=%s,actions=mod_dl_src:%s,mod_dl_dst:%s,'
            'mod_vlan_vid:%d,output:%d' % (
                router_bridge, student_ip, vm_ipaddr, ConfigParameter.VMGatewayMAC, vm_mac, vlan_ID,
                ConfigParameter.OvsServer_up_port_ID)
        ]
        del_commands = ['ovs-ofctl --strict del-flows %s dl_type=0x0800,nw_src=%s,nw_dst=%s' % (
            router_bridge, student_ip, vm_ipaddr)
                        ]
    except Exception, e:
        print str(e)
        LogExceptionHelp.logException('competition %s scene %d, '
                                      'generate the cmd for adding rules of student fail: %s' %
                                      (competition_id, step_flag, e))
        return None
def search_commands(student_ip=None, competition_id=None, step_flag=None, action=None, dhcp_for=None,
                    command_scene=None, command_type=None):
    SQL_Field = ''
    if step_flag == ConfigParameter.scene_attack1 or step_flag == ConfigParameter.scene_attack2:
        command_scene = None
    Argvs = {'student_ip': student_ip, 'competition_id': competition_id, 'step_flag': step_flag, 'action': action,
             'dhcp_for': dhcp_for, 'command_scene': command_scene, 'command_type': command_type}
    times = 0
    for k, v in Argvs.iteritems():
        if v == None:
            continue
        else:
            if times == 0:
                SQL_Field += "%s = '%s'" % (k, str(v))
                times += 1
            else:
                SQL_Field += " and %s = '%s'" % (k, str(v))
    SQL_command = "select host_ip,commands from %s where %s;" % (rule_tableName, SQL_Field)

    # 连接数据库
    try:
        dbconn = sql_conn()
        cursor = dbconn.cursor()
        cursor.execute(SQL_command)
        # 得到host_ip和command
        host_commands = {}
        for (HOST, CMD) in cursor:
            if host_commands.has_key(HOST):
                host_commands[HOST].append(CMD)
            else:
                host_commands[HOST] = [CMD]
    except mysql.connector.Error as e:
        print('mysql.connector.Error:{}'.format(e))
        LogExceptionHelp.logException("query the cmd %s of scene %d "
                                      "from database fail: %s" % (step_flag, action, e))
    finally:
        if cursor:
            cursor.close()
        dbconn.close()
    return host_commands
def init_flow_table(competition_id):
    dbconn = sql_conn()
    cursor = dbconn.cursor()
    # 检查大赛和流表号是否已经在数据库,如果流量号存在则重新随机生成,如果大赛存在则不做任何事
    while 1:
        flow_table = random.randint(1, 255)
        check_CMD = "select flow_table from %s WHERE flow_table = %d;" % (db_flow_table, flow_table)
        cursor.execute(check_CMD)
        result = cursor.fetchall()
        if not result:
            break

    try:
        insert_CMD = "insert into %s (uid,competition_id,flow_table) VALUES ('%s','%s',%d);" % (
            db_flow_table, str(uuid.uuid1()), competition_id, flow_table)
        cursor.execute(insert_CMD)
        dbconn.commit()
        ovs_cmd = 'ovs-ofctl add-flow %s priority=1,table=%d,actions=normal' % (router_bridge, flow_table)
        commands.getstatusoutput(ovs_cmd)
    except Exception, e:
        print str(e)
        LogExceptionHelp.logException("generate competition %s 's flow table failure: %s" % (competition_id, str(e)))
def rule_scene_attack2(competition_id, step_flag, student_ip, vm_mac, host_ip, vlan_ID,
                       vm_ipaddr):  # 针对每个学生进行策略创建(循环每个虚拟机多次)
    # 互攻阶段时,不同大赛的相同阶段使用不同的流表
    flow_table = search_flow_table(competition_id)
    try:
        add_commands = ['ovs-ofctl add-flow %s \'dl_type=0x0800,nw_src=%s,actions=resubmit(,%d)\'' % (
            router_bridge, student_ip, flow_table),
                        'ovs-ofctl add-flow %s table=%d,dl_type=0x0800,nw_dst=%s,actions=mod_dl_src:%s,'
                        'mod_dl_dst:%s,mod_vlan_vid:%d,output:%d' % (
                            router_bridge, flow_table, vm_ipaddr, ConfigParameter.VMGatewayMAC, vm_mac, vlan_ID,
                            ConfigParameter.OvsServer_up_port_ID),
                        ]
        del_commands = ['ovs-ofctl --strict del-flows %s dl_type=0x0800,nw_src=%s' % (router_bridge, student_ip),
                        'ovs-ofctl --strict del-flows %s table=%d,dl_type=0x0800,nw_dst=%s' % (
                            router_bridge, flow_table, vm_ipaddr),
                        ]
    except Exception, e:
        print str(e)
        LogExceptionHelp.logException('competition %s scene %d, '
                                      'generate the cmd for adding rules of student fail: %s' %
                                      (competition_id, step_flag, e))
        return None
def Data_Mirror(compute_bridge, Mirror_out_port,
                host_ip, competition_id, step_flag):
    """
    数据镜像(数据镜像,每个计算节点需要执行的命令)
    (每个br0的往返流量全部镜像到某一端口,端口在配置文件中指定),
    添加镜像
    :param compute_bridge:
    :param Mirror_out_port:
    :param host_ip:
    :param competition_id:
    :param step_flag:
    :return:
    """
    try:
        Mirror_add_commands = [
            'ovs-vsctl -- add bridge %s mirrors @m -- '
            '--id=@m create mirror name=mymirror' % compute_bridge,
            'ovs-vsctl set mirror mymirror select_all=1',
            'ovs-vsctl set mirror mymirror output_vlan=4093'
        ]
    except Exception, e:
        print str(e)
        LogExceptionHelp.logException("generate the cmd for adding data mirror fail: %s" % e)
        print str(e)
        LogExceptionHelp.logException("generate the cmd for adding data mirror fail: %s" % e)
    Action = 'add'
    Commands = ' && '.join(Mirror_add_commands)
    SQL_command = "insert into %s (uid,commands,competition_id,step_flag,host_ip,action)" \
                  " values ('%s',\"%s\",'%s',%d,'%s','%s');" % (
                      rule_tableName, str(uuid.uuid1()), Commands, competition_id, step_flag, host_ip, Action)
    sql_insert(SQL_command)

    # 移除镜像(每个计算节点都需要执行)
    try:
        Mirror_del_commands = ['ovs-vsctl clear Bridge %s mirrors' % compute_bridge
                               ]
    except Exception, e:
        print str(e)
        LogExceptionHelp.logException("generate the cmd for deleting data mirror fail: %s" % e)
        return None
    Action = 'del'
    Commands = ' ; '.join(Mirror_del_commands)
    SQL_command = "insert into %s (uid,commands,competition_id,step_flag,host_ip,action) " \
                  "values ('%s',\"%s\",'%s',%d,'%s','%s');" % (
                      rule_tableName, str(uuid.uuid1()), Commands, competition_id, step_flag, host_ip, Action)
    sql_insert(SQL_command)


# 学生端DHCP
# 初始化(学生端DHCP,OVS服务器侧)
def client_dhcp_init(client_dhcp_network, client_Mask):
    leases_file = '/tmp/client_dhcp.leases'
    pid_file = '/tmp/client_dhcp.pid'
    last_gateway_file = '/tmp/client_last_gateway.txt'  # 保存DHCP上一次的网关信息