int analyzer_ppp_pap_finalize(struct analyzer_ppp_pap_priv *apriv, struct analyzer_ppp_pap_ce_priv *cpriv) {

    if (!cpriv->evt_request)
        return POM_OK;

    struct event *evt = NULL;
    struct data *evt_data = NULL;

    struct data *evt_req_data = event_get_data(cpriv->evt_request);

    evt = event_alloc(apriv->evt_auth);
    if (!evt)
        return POM_ERR;

    evt_data = event_get_data(evt);

    if (ptype_copy(evt_data[analyzer_ppp_pap_auth_peer_id].value, evt_req_data[evt_ppp_pap_request_peer_id].value) != POM_OK) {
        event_cleanup(evt);
        return POM_ERR;
    }
    data_set(evt_data[analyzer_ppp_pap_auth_peer_id]);

    if (ptype_copy(evt_data[analyzer_ppp_pap_auth_password].value, evt_req_data[evt_ppp_pap_request_password].value) != POM_OK) {
        event_cleanup(evt);
        return POM_ERR;
    }
    data_set(evt_data[analyzer_ppp_pap_auth_password]);


    if (cpriv->client) {
        evt_data[analyzer_ppp_pap_auth_client].value = cpriv->client;
        data_set(evt_data[analyzer_ppp_pap_auth_client]);
        data_do_clean(evt_data[analyzer_ppp_pap_auth_client]);
        cpriv->client = NULL;
    }

    if (cpriv->server) {
        evt_data[analyzer_ppp_pap_auth_server].value = cpriv->server;
        data_set(evt_data[analyzer_ppp_pap_auth_server]);
        data_do_clean(evt_data[analyzer_ppp_pap_auth_server]);
        cpriv->server = NULL;
    }

    if (cpriv->vlan) {
        evt_data[analyzer_ppp_pap_auth_vlan].value = cpriv->vlan;
        data_set(evt_data[analyzer_ppp_pap_auth_vlan]);
        data_do_clean(evt_data[analyzer_ppp_pap_auth_vlan]);
        cpriv->vlan = NULL;
    }

    if (cpriv->top_proto) {
        PTYPE_STRING_SETVAL(evt_data[analyzer_ppp_pap_auth_top_proto].value, cpriv->top_proto);
        data_set(evt_data[analyzer_ppp_pap_auth_top_proto]);
    }

    if (ptype_copy(evt_data[analyzer_ppp_pap_auth_identifier].value, evt_req_data[evt_ppp_pap_request_identifier].value) != POM_OK) {
        event_cleanup(evt);
        return POM_ERR;
    }
    data_set(evt_data[analyzer_ppp_pap_auth_identifier]);

    if (cpriv->evt_ack_nack) {
        struct data *evt_ack_data = event_get_data(cpriv->evt_ack_nack);
        uint8_t code = *PTYPE_UINT8_GETVAL(evt_ack_data[evt_ppp_pap_ack_nack_code].value);

        if (code == 2) {
            PTYPE_BOOL_SETVAL(evt_data[analyzer_ppp_pap_auth_success].value, 1);
        } else {
            PTYPE_BOOL_SETVAL(evt_data[analyzer_ppp_pap_auth_success].value, 0);
        }
        data_set(evt_data[analyzer_ppp_pap_auth_success]);

        event_refcount_dec(cpriv->evt_ack_nack);
        cpriv->evt_ack_nack = NULL;
    }

    ptime ts = event_get_timestamp(cpriv->evt_request);

    event_refcount_dec(cpriv->evt_request);
    cpriv->evt_request = NULL;

    return event_process(evt, NULL, 0, ts);
}
示例#2
0
static int analyzer_docsis_pkt_process(void *obj, struct packet *p, struct proto_process_stack *stack, unsigned int stack_index) {

	struct analyzer *analyzer = obj;
	struct analyzer_docsis_priv *priv = analyzer->priv;

	struct proto_process_stack *s = &stack[stack_index];

	uint8_t *type = PTYPE_UINT8_GETVAL(s->pkt_info->fields_value[proto_docsis_mgmt_field_type]);

	char *mac_dst = PTYPE_MAC_GETADDR(s->pkt_info->fields_value[proto_docsis_mgmt_field_dst]);

	// FIXME : improve this filtering at the source
	// Filter some useless messages we don't care about
	
	if (*type == MMT_UCD2 || *type == MMT_UCD3 || *type == MMT_MDD)
		return POM_OK;

	if (*type != MMT_RNG_RSP) {
		pomlog(POMLOG_DEBUG "Unhandled DOCSIS MGMT message type %u for destination mac %02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX", *type, mac_dst[0], mac_dst[1], mac_dst[2], mac_dst[3], mac_dst[4], mac_dst[5]);
		return POM_OK;
	}

	// Use the last bits for the modem ID
	uint16_t id = ntohs(*(uint16_t*) (mac_dst + 4)) & ANALYZER_DOCSIS_CM_MASK;

	pom_mutex_lock(&priv->lock);

	struct analyzer_docsis_cm *cm;
	for (cm = priv->cms[id]; cm; cm = cm->next) {
		if (!memcmp(cm->mac, mac_dst, sizeof(cm->mac)))
			break;
	}

	if (!cm) {
		// Cable modem not found !
		cm = malloc(sizeof(struct analyzer_docsis_cm));
		if (!cm) {
			pom_mutex_unlock(&priv->lock);
			pom_oom(sizeof(struct analyzer_docsis_cm));
			return POM_ERR;
		}
		memset(cm, 0, sizeof(struct analyzer_docsis_cm));

		cm->t = timer_alloc(cm, analyzer_docsis_cm_timeout);
		if (!cm->t) {
			pom_mutex_unlock(&priv->lock);
			free(cm);
			return POM_ERR;
		}
	
		cm->analyzer = analyzer;
		memcpy(cm->mac, mac_dst, sizeof(cm->mac));
		cm->t4_multiplier = 1;

		cm->next = priv->cms[id];
		if (cm->next)
			cm->next->prev = cm;

		priv->cms[id] = cm;

		// Announce the new CM
		if (event_has_listener(priv->evt_cm_new)) {
			struct event *evt = event_alloc(priv->evt_cm_new);
			if (!evt) {
				pom_mutex_unlock(&priv->lock);
				return POM_ERR;
			}

			struct data *evt_data = event_get_data(evt);
			PTYPE_MAC_SETADDR(evt_data[analyzer_docsis_cm_new_mac].value, cm->mac);
			data_set(evt_data[analyzer_docsis_cm_new_mac]);
			PTYPE_STRING_SETVAL(evt_data[analyzer_docsis_cm_new_input].value, p->input->name);
			data_set(evt_data[analyzer_docsis_cm_new_input]);

			if (event_process(evt, stack, stack_index, p->ts) != POM_OK) {
				pom_mutex_unlock(&priv->lock);
				return POM_ERR;
			}
		}
	}


	switch (*type) {

		case MMT_RNG_RSP:
			analyzer_docsis_pkt_parse_rng_rsp(priv, cm, p, stack, stack_index);
			break;

		// FIXME If ranging_status is 0 and we receive another msg, probably it's actually registered
		// and we need to call analyzer_docsis_reg_status_update();

	}

	timer_queue_now(cm->t, T4_TIMEOUT * cm->t4_multiplier, p->ts);

	pom_mutex_unlock(&priv->lock);

	return POM_OK;
}
示例#3
0
文件: registry.c 项目: k0a1a/pom-ng
int registry_config_load(char *config_name) {

	struct dataset_query *dsq_config_list = NULL, *dsq_config = NULL;
	
	struct datastore *sys_dstore = system_datastore();
	if (!sys_dstore) {
		pomlog(POMLOG_ERR "No system datastore declared");
		return POM_ERR;
	}


	// Find what is the id corresponding to the name given if any
	dsq_config_list = datastore_dataset_query_open(sys_dstore, REGISTRY_CONFIG_LIST, registry_config_list_dataset_template, NULL);
	if (!dsq_config_list)
		goto err;

	if (datastore_dataset_query_set_string_condition(dsq_config_list, 0, PTYPE_OP_EQ, config_name) != POM_OK)
		goto err;

	int res = datastore_dataset_read_single(dsq_config_list);

	if (res < 0)
		goto err;

	if (res == DATASET_QUERY_OK) {
		pomlog(POMLOG_ERR "Configuration \"%s\" not found in the database", config_name);
		goto err;
	}

	uint64_t config_id = dsq_config_list->data_id;

	datastore_dataset_query_cleanup(dsq_config_list);
	dsq_config_list = NULL;

	// Fetch the config
	dsq_config = datastore_dataset_query_open(sys_dstore, REGISTRY_CONFIG, registry_config_dataset_template, NULL);
	if (!dsq_config)
		goto err;

	if (datastore_dataset_query_set_uint64_condition(dsq_config, 0, PTYPE_OP_EQ, config_id) != POM_OK)
		goto err;

	// Fetch the config in a convenient way
	if (datastore_dataset_query_set_order(dsq_config, 3, DATASET_READ_ORDER_ASC) != POM_OK)
		goto err;

	registry_lock();

	// Reset the registry
	if (registry_config_reset() != POM_OK)
		goto err_locked;


	while ((res = datastore_dataset_read(dsq_config)) != DATASET_QUERY_OK) {
		if (res < 0)
			goto err_locked;

		if (dsq_config->values[1].is_null || dsq_config->values[3].is_null) {
			pomlog(POMLOG_ERR "Got NULL values while they were not supposed to be !");
			goto err_locked;
		}
		enum registry_config_entry_types type = *PTYPE_UINT8_GETVAL(dsq_config->values[3].value);
		char *entry = PTYPE_STRING_GETVAL(dsq_config->values[1].value);
		char *value = NULL;
		if (!dsq_config->values[2].is_null)
			value = PTYPE_STRING_GETVAL(dsq_config->values[2].value);

		// Parse the entry
		char *name1 = strdup(entry);
		if (!name1) {
			pom_oom(strlen(entry) + 1);
			goto err_locked;
		}
		char *name2 = strchr(name1, '.');
		if (!name2) {
			pomlog(POMLOG_ERR "Unparseable entry name \"%s\"", entry);
			free(name1);
			goto err_locked;
		}
		*name2 = 0;
		name2++;

		char *name3 = strchr(name2, '.');
		if (name3) {
			*name3 = 0;
			name3++;
		}

		switch (type) {

			case registry_config_instance: {

				if (!value) {
					pomlog(POMLOG_WARN "Instance type not provided for entry %s, skipping", entry);
					break;
				}

				struct registry_class *cls = registry_find_class(name1);
				if (!cls) {
					pomlog(POMLOG_WARN "Cannot add instance %s to class %s as this class doesn't exists. skipping", name2, name1);
					break;
				}

				struct registry_instance *inst;
				for (inst = cls->instances; inst && strcmp(inst->name, name2); inst = inst->next);
				if (inst) {
					pomlog(POMLOG_WARN "Cannot add instance %s as it's already in the registry, skipping", entry);
					break;
				}

				if (!cls->instance_add) {
					pomlog(POMLOG_WARN "Cannot add instances to class %s as it doesn't support it. skipping", name1);
					break;
				}

				if (cls->instance_add(value, name2) != POM_OK) {
					pomlog(POMLOG_WARN "Unable to add instance %s of type %s, skipping", entry, value);
					break;
				}

				break;

			}

			case registry_config_instance_param: {

				if (!value) {
					pomlog(POMLOG_WARN "Parameter value not provided for entry %s, skipping", entry);
					break;
				}

				if (!name3) {
					pomlog(POMLOG_WARN "Parameter name not provided for entry %s, skipping", entry);
					break;
				}

				struct registry_instance *inst = registry_find_instance(name1, name2);
				if (!inst) {
					pomlog(POMLOG_WARN "Cannot find instance %s.%s to set parameter, skipping", name1, name2);
					break;
				}


				if (!strcmp(name3, "uid")) {
					// Special handling for uids
					if (registry_uid_assign(inst, value) != POM_OK) {
						pomlog(POMLOG_WARN "Error while setting the uid, skipping");
						break;
					}

				} else if (!strcmp(name3, "running")) {
					// For now don't do anything for running

				} else {
					registry_set_param(inst, name3, value);
				}

				break;
			}
				
			
			default:
				pomlog(POMLOG_WARN "Unhandled configuration entry type %u for item %s", entry);

		}

		free(name1);
		

	}

	registry_classes_serial_inc();
	registry_unlock();

	datastore_dataset_query_cleanup(dsq_config);

	pomlog("Registry configuration \"%s\" loaded", config_name);

	return POM_OK;

err_locked:
	registry_unlock();
err:

	if (dsq_config_list)
		datastore_dataset_query_cleanup(dsq_config_list);

	if (dsq_config)
		datastore_dataset_query_cleanup(dsq_config);

	return POM_ERR;
}
示例#4
0
int analyzer_eap_event_process_begin(struct event *evt, void *obj, struct proto_process_stack *stack, unsigned int stack_index) {

	struct analyzer *analyzer = obj;

	struct analyzer_eap_priv *apriv = analyzer->priv;

	struct proto_process_stack *s = &stack[stack_index];
	if (!s->ce)
		return PROTO_ERR;

	conntrack_lock(s->ce);

	struct ptype *src = NULL, *dst = NULL;

	struct analyzer_eap_ce_priv *cpriv = conntrack_get_priv(s->ce, analyzer);
	if (!cpriv) {
		cpriv = malloc(sizeof(struct analyzer_eap_ce_priv));
		if (!cpriv) {
			pom_oom(sizeof(struct analyzer_eap_ce_priv));
			goto err;
		}
		memset(cpriv, 0, sizeof(struct analyzer_eap_ce_priv));


		if (conntrack_add_priv(s->ce, analyzer, cpriv, analyzer_eap_ce_priv_cleanup) != POM_OK) {
			free(cpriv);
			goto err;
		}

		// Try to find the source and destination
		
		unsigned int i = 0;
		for (i = 1; i <= 4; i++) {
			struct proto_process_stack *prev_stack = &stack[stack_index - i];
			if (!prev_stack->proto)
				break;

			struct proto_reg_info *info = proto_get_info(prev_stack->proto);
			if (!strcmp(info->name, "vlan")) {
				cpriv->vlan = ptype_alloc_from(prev_stack->pkt_info->fields_value[proto_vlan_field_vid]);
				if (!cpriv->vlan)
					return POM_ERR;
			}

			unsigned int j;
			for (j = 0; !src || !dst; j++) {
				struct proto_reg_info *prev_info = proto_get_info(prev_stack->proto);
				if (!prev_info->pkt_fields)
					break;
				char *name = prev_info->pkt_fields[j].name;
				if (!name)
					break;

				if (!src && !strcmp(name, "src"))
					src = prev_stack->pkt_info->fields_value[j];
				else if (!dst && !strcmp(name, "dst"))
					dst = prev_stack->pkt_info->fields_value[j];
			}

			if (src || dst)
				break;
		}

		struct proto_process_stack *prev_stack = &stack[stack_index - 2];
		if (prev_stack->proto) {
			struct proto_reg_info *info = proto_get_info(prev_stack->proto);
			cpriv->top_proto = info->name;
		}
	}

	struct event_reg *evt_reg = event_get_reg(evt);
	struct data *evt_data = event_get_data(evt);

	int dir = POM_DIR_UNK;

	if (evt_reg == apriv->evt_md5_challenge) {
		uint8_t code = *PTYPE_UINT8_GETVAL(evt_data[evt_eap_common_code].value);

		if (code == 1) {
			if (!cpriv->evt_request) {
				event_refcount_inc(evt);
				cpriv->evt_request = evt;
			}
			dir = POM_DIR_REV;
		} else if (code == 2) {
			if (!cpriv->evt_response) {
				event_refcount_inc(evt);
				cpriv->evt_response = evt;
			}
			dir = POM_DIR_FWD;
		}


	} else {
		if (!cpriv->evt_result) {
			event_refcount_inc(evt);
			cpriv->evt_result = evt;
		}
		dir = POM_DIR_REV;
	}

	if (src && dst && dir != POM_DIR_UNK) {
		if (dir == POM_DIR_FWD) {
			cpriv->client = ptype_alloc_from(src);
			cpriv->server = ptype_alloc_from(dst);
		} else {
			cpriv->client = ptype_alloc_from(dst);
			cpriv->server = ptype_alloc_from(src);
		}
	}

	int res = POM_OK;

	if (cpriv->evt_request && cpriv->evt_response && cpriv->evt_result)
		res = analyzer_eap_finalize(apriv, cpriv);

	conntrack_unlock(s->ce);

	return res;

err:
	conntrack_unlock(s->ce);
	return POM_ERR;

}