def test_check_static(): """ Test check_static method """ #*** Test DPIDs and in ports: DPID1 = 123456 INPORT1 = 1 DPID2 = 1 INPORT2 = 6 DPID3 = 255 INPORT3 = 3 #*** Instantiate match object: classifier_result = policy_module.TCClassifierResult("", "") #*** Instantiate class object: flow = flow_class.Flow(config) #*** Test Flow 1 Packet 1 (Client TCP SYN): flow.ingest_packet(DPID1, INPORT1, pkts.RAW[0], datetime.datetime.now()) #*** Should match, even though dpid/port don't, as default match is unknown: classifier_result.policy_attr = 'location_src' classifier_result.policy_value = 'unknown' tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == True #*** Test Flow 1 Packet 1 (Client TCP SYN) with DPID/port set to external: flow.ingest_packet(DPID2, INPORT2, pkts.RAW[0], datetime.datetime.now()) #*** Should match as DPID/port belong to location external: classifier_result.policy_attr = 'location_src' classifier_result.policy_value = 'external' tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == True #*** Test Flow 1 Packet 1 (Client TCP SYN) with DPID/port set to internal: flow.ingest_packet(DPID3, INPORT3, pkts.RAW[0], datetime.datetime.now()) #*** Should not match as DPID/port belong to location internal: classifier_result.policy_attr = 'location_src' classifier_result.policy_value = 'external' tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == False #*** Should match as DPID/port belong to location internal: classifier_result.policy_attr = 'location_src' classifier_result.policy_value = 'internal' tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == True #*** Test Flow 1 Packet 1 (Client TCP SYN): flow.ingest_packet(DPID1, INPORT1, pkts.RAW[0], datetime.datetime.now()) classifier_result.policy_attr = 'eth_src' classifier_result.policy_value = pkts.ETH_SRC[0] tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == True classifier_result.policy_attr = 'eth_src' classifier_result.policy_value = pkts.ETH_DST[0] tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == False classifier_result.policy_attr = 'eth_dst' classifier_result.policy_value = pkts.ETH_DST[0] tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == True classifier_result.policy_attr = 'eth_dst' classifier_result.policy_value = pkts.ETH_SRC[0] tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == False #*** Eth type tests: classifier_result.policy_attr = 'eth_type' classifier_result.policy_value = pkts.ETH_TYPE[0] tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == True classifier_result.policy_attr = 'eth_type' classifier_result.policy_value = 2054 tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == False #*** Eth type Hex tests: classifier_result.policy_attr = 'eth_type' classifier_result.policy_value = 0x800 tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == True classifier_result.policy_attr = 'eth_type' classifier_result.policy_value = 0x808 tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == False #*** Simple IP src tests: classifier_result.policy_attr = 'ip_src' classifier_result.policy_value = pkts.IP_SRC[0] tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == True classifier_result.policy_attr = 'ip_src' classifier_result.policy_value = pkts.IP_DST[0] tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == False #*** Test IP src space matching: classifier_result.policy_attr = 'ip_src' classifier_result.policy_value = '10.1.0.0/24' tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == True classifier_result.policy_attr = 'ip_src' classifier_result.policy_value = '10.2.0.0/24' tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == False classifier_result.policy_attr = 'ip_src' classifier_result.policy_value = '10.1.0.1-10.1.0.15' tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == True classifier_result.policy_attr = 'ip_src' classifier_result.policy_value = '10.1.0.2-10.1.0.15' tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == False #*** Simple IP dst tests: classifier_result.policy_attr = 'ip_dst' classifier_result.policy_value = pkts.IP_DST[0] tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == True classifier_result.policy_attr = 'ip_dst' classifier_result.policy_value = pkts.IP_SRC[0] tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == False #*** Test IP dst space matching: classifier_result.policy_attr = 'ip_dst' classifier_result.policy_value = '10.1.0.0/24' tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == True classifier_result.policy_attr = 'ip_dst' classifier_result.policy_value = '10.2.0.0/24' tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == False classifier_result.policy_attr = 'ip_dst' classifier_result.policy_value = '10.1.0.1-10.1.0.15' tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == True classifier_result.policy_attr = 'ip_dst' classifier_result.policy_value = '10.1.0.3-10.1.0.15' tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == False classifier_result.policy_attr = 'tcp_src' classifier_result.policy_value = pkts.TP_SRC[0] tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == True classifier_result.policy_attr = 'tcp_src' classifier_result.policy_value = pkts.TP_DST[0] tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == False classifier_result.policy_attr = 'tcp_dst' classifier_result.policy_value = pkts.TP_DST[0] tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == True classifier_result.policy_attr = 'tcp_dst' classifier_result.policy_value = pkts.TP_SRC[0] tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == False #*** Ingest UDP: flow.ingest_packet(DPID1, INPORT1, pkts_udp.RAW[0], datetime.datetime.now()) classifier_result.policy_attr = 'udp_src' classifier_result.policy_value = pkts_udp.TP_SRC[0] tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == True classifier_result.policy_attr = 'udp_src' classifier_result.policy_value = pkts_udp.TP_DST[0] tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == False classifier_result.policy_attr = 'udp_dst' classifier_result.policy_value = pkts_udp.TP_DST[0] tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == True classifier_result.policy_attr = 'udp_dst' classifier_result.policy_value = pkts_udp.TP_SRC[0] tc_static.check_static(classifier_result, flow.packet) assert classifier_result.match == False
def test_LLDP_identity(): """ Test harvesting identity metadata from LLDP packets and then using this to validate an identity """ #*** Instantiate class objects: flow = flows_module.Flow(config) policy = policy_module.Policy(config) identities = identities_module.Identities(config, policy) tc_ident = tc_identity.IdentityInspect(config) #*** LLDP packet 0: flow.ingest_packet(DPID1, INPORT1, pkts_lldp.RAW[0], datetime.datetime.now()) identities.harvest(pkts_lldp.RAW[0], flow.packet) result_identity = identities.findbynode(pkts_lldp.LLDP_SYSTEM_NAME[0]) assert result_identity['host_name'] == pkts_lldp.LLDP_SYSTEM_NAME[0] assert result_identity['host_desc'] == pkts_lldp.LLDP_SYSTEM_DESC[0] assert result_identity['dpid'] == DPID1 assert result_identity['in_port'] == INPORT1 assert result_identity['mac_address'] == pkts_lldp.ETH_SRC[0] assert result_identity['harvest_type'] == 'LLDP' #*** Test tc_identity (foo should fail) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_lldp_systemname' classifier_result.policy_value = 'foo' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == False #*** Test tc_identity (pc1.example.com should match) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_lldp_systemname' classifier_result.policy_value = 'pc1.example.com' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == True #*** Test tc_identity regular expression (*.example.com should match) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_lldp_systemname_re' classifier_result.policy_value = '^.*\.example\.com' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == True #*** Test tc_identity regular expression (pc1.* should match) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_lldp_systemname_re' classifier_result.policy_value = '^pc1\.*' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == True #*** Test tc_identity regular expression (*.example.org should fail) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_lldp_systemname_re' classifier_result.policy_value = '^.*\.example\.org' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == False #*** LLDP packet 1 - test time-based invalidity of stale data flow.ingest_packet( DPID1, INPORT1, pkts_lldp.RAW[1], datetime.datetime.now() - datetime.timedelta(seconds=125)) identities.harvest(pkts_lldp.RAW[1], flow.packet) #*** Test tc_identity (sw1.example.com shouldn't match as data is stale as past LLDP TTL) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_lldp_systemname' classifier_result.policy_value = 'sw1.example.com' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == False #*** Reingest with current time to check it does work flow.ingest_packet(DPID1, INPORT1, pkts_lldp.RAW[1], datetime.datetime.now()) identities.harvest(pkts_lldp.RAW[1], flow.packet) #*** Test tc_identity (sw1.example.com should match as data is no longer stale) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_lldp_systemname' classifier_result.policy_value = 'sw1.example.com' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == True
def test_DHCP_identity(): """ Test harvesting identity metadata from DHCP packets and then using this to validate an identities against the learnt DHCP hostname """ #*** Instantiate class objects: flow = flows_module.Flow(config) policy = policy_module.Policy(config) identities = identities_module.Identities(config, policy) tc_ident = tc_identity.IdentityInspect(config) #*** Ingest packet from pc1: flow.ingest_packet(DPID1, INPORT1, pkts_http_pc1.RAW[0], datetime.datetime.now()) #*** Test tc_identity (pc1 should fail as haven't harvested DHCP yet) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_dhcp_hostname' classifier_result.policy_value = 'pc1' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == False #*** Harvesting DHCP host name for pc1 against IP 10.1.0.1 #*** Client to Server DHCP Request (DHCP Option 12 host name is pc1): flow.ingest_packet(DPID1, INPORT1, pkts_dhcp.RAW[2], datetime.datetime.now()) identities.harvest(pkts_dhcp.RAW[2], flow.packet) #*** Server to Client DHCP ACK: flow.ingest_packet(DPID1, INPORT2, pkts_dhcp.RAW[3], datetime.datetime.now()) identities.harvest(pkts_dhcp.RAW[3], flow.packet) #*** Ingest packet from pc1: flow.ingest_packet(DPID1, INPORT1, pkts_http_pc1.RAW[0], datetime.datetime.now()) #*** Test tc_identity (pc1 should pass) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_dhcp_hostname' classifier_result.policy_value = 'pc1' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == True #*** Ingest packet *to* pc1: flow.ingest_packet(DPID1, INPORT2, pkts_http_pc1.RAW[1], datetime.datetime.now()) #*** Test tc_identity (pc1 should pass) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_dhcp_hostname' classifier_result.policy_value = 'pc1' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == True #*** Ingest packet from lg1: flow.ingest_packet(DPID1, INPORT1, pkts_http_lg1.RAW[0], datetime.datetime.now()) #*** Test tc_identity (pc1 should fail, as packet is from lg1) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_dhcp_hostname' classifier_result.policy_value = 'pc1' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == False #*** Ingest packet from pc1: flow.ingest_packet(DPID1, INPORT1, pkts_http_pc1.RAW[0], datetime.datetime.now()) #*** Test tc_identity (Regex pc.* should pass) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_dhcp_hostname_re' classifier_result.policy_value = 'pc.*' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == True #*** Test tc_identity (Regex ac.* should fail) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_dhcp_hostname_re' classifier_result.policy_value = 'ac.*' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == False
def test_DNS_identity(): """ Test harvesting identity metadata from DNS packets and then using this to validate an identity """ #*** Instantiate class objects: flow = flows_module.Flow(config) policy = policy_module.Policy(config) identities = identities_module.Identities(config, policy) tc_ident = tc_identity.IdentityInspect(config) #*** DNS packet 1 (NAME to CNAME, then second answer with IP for CNAME): flow.ingest_packet(DPID1, INPORT1, pkts_dns.RAW[1], datetime.datetime.now()) identities.harvest(pkts_dns.RAW[1], flow.packet) result_identity = identities.findbyservice(pkts_dns.DNS_NAME[1]) assert result_identity['service_name'] == pkts_dns.DNS_NAME[1] assert result_identity['service_alias'] == pkts_dns.DNS_CNAME[1] result_identity = identities.findbyservice(pkts_dns.DNS_CNAME[1]) assert result_identity['service_name'] == pkts_dns.DNS_CNAME[1] assert result_identity['ip_address'] == pkts_dns.DNS_IP[1] #*** Ingest TCP SYN to www.facebook.com (CNAME star-mini.c10r.facebook.com, #*** IP 179.60.193.36) flow.ingest_packet(DPID1, INPORT1, pkts_facebook.RAW[0], datetime.datetime.now()) #*** Test tc_identity (foo should fail) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_service_dns' classifier_result.policy_value = 'foo' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == False #*** Test tc_identity (www.facebook.com should pass) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_service_dns' classifier_result.policy_value = 'www.facebook.com' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == True #*** Now, harvest another DNS packet with different A record for #*** www.facebook.com (CNAME star-mini.c10r.facebook.com A 31.13.95.36): flow.ingest_packet(DPID1, INPORT1, pkts_dns4.RAW[1], datetime.datetime.now()) identities.harvest(pkts_dns4.RAW[1], flow.packet) #*** Ingest TCP SYN to www.facebook.com (CNAME star-mini.c10r.facebook.com, #*** IP 179.60.193.36) flow.ingest_packet(DPID1, INPORT1, pkts_facebook.RAW[0], datetime.datetime.now()) #*** Test tc_identity (www.facebook.com, should pass even though there's #*** another A record against the CNAME, i.e. should handle one to many) #*** Test tc_identity (www.facebook.com should pass) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_service_dns' classifier_result.policy_value = 'www.facebook.com' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == True #*** Test regular expression match of previous test: #*** Test tc_identity (www.facebook.com should pass) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_service_dns_re' classifier_result.policy_value = '^.*\.facebook\.com' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == True #*** Test regular expression that shouldn't match: classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_service_dns_re' classifier_result.policy_value = '^.*\.facebook\.org' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == False #*** Ingest TCP SYN+ACK from www.facebook.com (CNAME star-mini.c10r.facebook.com, #*** IP 179.60.193.36) to test matching on source IP address: flow.ingest_packet(DPID1, INPORT1, pkts_facebook.RAW[1], datetime.datetime.now()) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'identity_service_dns' classifier_result.policy_value = 'www.facebook.com' tc_ident.check_identity(classifier_result, flow.packet, identities) assert classifier_result.match == True
def test_statistical_classifier(): """ Test instantiating custom classifiers and use of supplied sample statistical classifier """ #*** Test DPIDs and in ports: DPID1 = 1 INPORT1 = 1 #*** Instantiate class object: flow = flows_module.Flow(config) #*** Test DPIDs and in ports: DPID1 = 1 INPORT1 = 1 #*** Instantiate class objects: flow = flows_module.Flow(config) policy = policy_module.Policy(config) ident = identities_module.Identities(config, policy) #*** Instantiate custom classifiers tc_cust = tc_custom.CustomInspect(config) tc_cust.instantiate_classifiers(['statistical_qos_bandwidth_1']) #*** Instantiate match object: classifier_result = policy_module.TCClassifierResult("", "") #*** Ingest sufficient packets to complete statistical classification (7): #*** Ingest packet 10.1.0.1 10.1.0.2 TCP 38435 80 [SYN] flow.ingest_packet(DPID1, INPORT1, pkts2.RAW[0], datetime.datetime.now()) classifier_result.policy_attr = 'custom' classifier_result.policy_value = 'statistical_qos_bandwidth_1' tc_cust.check_custom(classifier_result, flow, ident) assert classifier_result.match == True assert classifier_result.continue_to_inspect == True assert classifier_result.classification_tag == "" assert classifier_result.actions == {} #*** Ingest packet 10.1.0.2 10.1.0.1 TCP 80 38435 [SYN, ACK] flow.ingest_packet(DPID1, INPORT1, pkts2.RAW[1], datetime.datetime.now()) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'custom' classifier_result.policy_value = 'statistical_qos_bandwidth_1' tc_cust.check_custom(classifier_result, flow, ident) assert classifier_result.match == True assert classifier_result.continue_to_inspect == True assert classifier_result.classification_tag == "" assert classifier_result.actions == {} #*** Ingest packet flow.ingest_packet(DPID1, INPORT1, pkts2.RAW[2], datetime.datetime.now()) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'custom' classifier_result.policy_value = 'statistical_qos_bandwidth_1' tc_cust.check_custom(classifier_result, flow, ident) assert classifier_result.match == True assert classifier_result.continue_to_inspect == True assert classifier_result.classification_tag == "" assert classifier_result.actions == {} #*** Ingest packet flow.ingest_packet(DPID1, INPORT1, pkts2.RAW[3], datetime.datetime.now()) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'custom' classifier_result.policy_value = 'statistical_qos_bandwidth_1' tc_cust.check_custom(classifier_result, flow, ident) assert classifier_result.match == True assert classifier_result.continue_to_inspect == True assert classifier_result.classification_tag == "" assert classifier_result.actions == {} #*** Ingest packet flow.ingest_packet(DPID1, INPORT1, pkts2.RAW[4], datetime.datetime.now()) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'custom' classifier_result.policy_value = 'statistical_qos_bandwidth_1' tc_cust.check_custom(classifier_result, flow, ident) assert classifier_result.match == True assert classifier_result.continue_to_inspect == True assert classifier_result.classification_tag == "" assert classifier_result.actions == {} #*** Ingest packet flow.ingest_packet(DPID1, INPORT1, pkts2.RAW[5], datetime.datetime.now()) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'custom' classifier_result.policy_value = 'statistical_qos_bandwidth_1' tc_cust.check_custom(classifier_result, flow, ident) assert classifier_result.match == True assert classifier_result.continue_to_inspect == True assert classifier_result.classification_tag == "" assert classifier_result.actions == {} #*** Ingest packet #*** This should conclude the statistical classification for this flow #*** and conclude action is default priority flow.ingest_packet(DPID1, INPORT1, pkts2.RAW[6], datetime.datetime.now()) classifier_result = policy_module.TCClassifierResult("", "") classifier_result.policy_attr = 'custom' classifier_result.policy_value = 'statistical_qos_bandwidth_1' tc_cust.check_custom(classifier_result, flow, ident) assert classifier_result.match == True assert classifier_result.continue_to_inspect == False assert classifier_result.classification_tag == "Normal flow" assert classifier_result.actions == {'qos_treatment': 'default_priority'}