Exemple #1
0
int main(int argc, char *argv[]) {
	parse_arg_list(argc, argv);
	open_logfile(NULL);
	report_info("main()",
		"About Server:\nName: %s\nPID: %d\nAddress: %s\nPort: %d",
		server_name, getpid(), inet_ntoa(*(struct in_addr *)&server_address), server_port);
	
	start_server();
	return 0;
}
Exemple #2
0
int
userfw_cmd_dispatch(unsigned char *buf,
		struct socket *so,
		struct thread *td)
{
	int err = 0;
	userfw_module_id_t dst = 0;
	struct userfw_io_header *msg = (struct userfw_io_header *)buf;
	const userfw_modinfo *modinfo = NULL;
	const userfw_cmd_descr *cmdinfo = NULL;
	struct userfw_io_header *cmd, *opcode, *cookie = NULL, *mod_id;
	userfw_arg *parsed_args = NULL;
	int i, cookie_val;
	userfw_cmd_access_check access_checker = NULL;

	if (msg->type != T_CONTAINER || (msg->subtype != ST_MESSAGE && msg->subtype != ST_CMDCALL))
		return EOPNOTSUPP;
	if (msg->length < sizeof(*msg) + sizeof(*cmd))
		return EINVAL;

	if (msg->subtype == ST_CMDCALL)
		cmd = msg;
	else
	{
		cmd = userfw_io_find_block(buf + sizeof(*msg), msg->length - sizeof(*msg), T_CONTAINER, ST_CMDCALL);
		cookie = userfw_io_find_block(buf + sizeof(*msg), msg->length - sizeof(*msg), T_UINT32, ST_COOKIE);
	}

	if (cmd == NULL || (cmd != msg && !BLOCK_FITS_INTO_OUTER(cmd, msg)))
		return EINVAL;
	if (cookie != NULL && (!BLOCK_FITS_INTO_OUTER(cookie, msg) || cookie->length != sizeof(*cookie) + sizeof(uint32_t)))
		return EINVAL;

	mod_id = userfw_io_find_block((char*)cmd + sizeof(*cmd), cmd->length - sizeof(*cmd), T_UINT32, ST_MOD_ID);
	if (mod_id == NULL || ! BLOCK_FITS_INTO_OUTER(mod_id, cmd) ||
		mod_id->length != sizeof(*mod_id) + sizeof(uint32_t))
		return EINVAL;

	dst = *((uint32_t*)((char*)mod_id + sizeof(*mod_id)));
	modinfo = userfw_mod_find(dst);
	if (modinfo == NULL)
		return ECONNREFUSED;

	opcode = userfw_io_find_block((char*)cmd + sizeof(*cmd), cmd->length - sizeof(*cmd), T_UINT32, ST_OPCODE);
	if (opcode == NULL || ! BLOCK_FITS_INTO_OUTER(opcode, cmd) ||
		opcode->length != sizeof(*opcode) + sizeof(uint32_t))
		return EINVAL;

	cmdinfo = userfw_mod_find_cmd(dst, *((uint32_t*)((char*)opcode + sizeof(*opcode))));
	if (cmdinfo == NULL)
		return EINVAL;

	parsed_args = malloc(sizeof(userfw_arg)*(cmdinfo->nargs),
				M_USERFW, M_WAITOK | M_ZERO);

	err = parse_arg_list((unsigned char *)cmd + sizeof(*cmd), cmd->length - sizeof(*cmd),
				parsed_args, cmdinfo->nargs, cmdinfo->arg_types);

	access_checker = cmdinfo->is_allowed;
	if (access_checker == NULL)
		access_checker = userfw_cmd_access_only_root;

	if (err == 0)
		err = (*access_checker)(dst, cmdinfo, parsed_args, so, td) ? 0 : EPERM;

	cookie_val = cookie != NULL ? (*((uint32_t*)((char*)cookie + sizeof(*cookie)))) : 0;

	if (err != 0)
		userfw_msg_reply_error(so, cookie_val, err);

	if (err == 0)
		err = cmdinfo->do_cmd(*((uint32_t*)((char*)opcode + sizeof(*opcode))),
				cookie_val, parsed_args, so, td);

	for(i = 0; i < cmdinfo->nargs; i++)
	{
		if (parsed_args[i].type != T_INVAL)
			free_arg(&(parsed_args[i]), M_USERFW);
	}

	free(parsed_args, M_USERFW);

	return 0;
}
Exemple #3
0
int
parse_arg(unsigned char *buf, userfw_arg *dst)
{
	struct userfw_io_header *arg = (struct userfw_io_header *)buf;
	unsigned char *data = buf + sizeof(*arg);

	dst->type = arg->type;

	switch (arg->type)
	{
	case T_STRING:
	case T_HEXSTRING:
		dst->string.length = arg->length - sizeof(*arg);
		dst->string.data = malloc(arg->length - sizeof(*arg), M_USERFW, M_WAITOK);
		bcopy(buf + sizeof(*arg), dst->string.data, arg->length - sizeof(*arg));
		break;
	case T_UINT16:
		bcopy(data, &(dst->uint16.value), sizeof(uint16_t));
		break;
	case T_UINT32:
		bcopy(data, &(dst->uint32.value), sizeof(uint32_t));
		break;
	case T_UINT64:
		bcopy(data, &(dst->uint64.value), sizeof(uint64_t));
		break;
	case T_IPv4:
		bcopy(data, &(dst->ipv4.addr), sizeof(uint32_t));
		bcopy(data + sizeof(uint32_t), &(dst->ipv4.mask), sizeof(uint32_t));
		break;
	case T_IPv6:
		bcopy(data, &(dst->ipv6.addr), 4*sizeof(uint32_t));
		bcopy(data + 4*sizeof(uint32_t), &(dst->ipv6.addr), 4*sizeof(uint32_t));
		break;
	case T_MATCH:
	case T_ACTION:
		{
		userfw_match *match = NULL;
		userfw_action *action = NULL;
		struct userfw_io_header *opcode_p, *mod_id_p;
		const userfw_match_descr *matchdescr = NULL;
		const userfw_action_descr *actiondescr = NULL;
		opcode_t opcode;
		userfw_module_id_t mod_id;
		int err = 0;

		if (arg->length < sizeof(*arg) + sizeof(*opcode_p) + sizeof(*mod_id_p))
			return EINVAL;

		opcode_p = userfw_io_find_block(data, arg->length - sizeof(*arg), T_UINT32, ST_OPCODE);
		if (opcode_p == NULL || ! BLOCK_FITS_INTO_OUTER(opcode_p, arg) ||
			opcode_p->length != sizeof(*opcode_p) + sizeof(uint32_t))
			return EINVAL;
		opcode = *((uint32_t*)((char*)opcode_p + sizeof(*opcode_p)));

		mod_id_p = userfw_io_find_block(data, arg->length - sizeof(*arg), T_UINT32, ST_MOD_ID);
		if (mod_id_p == NULL || ! BLOCK_FITS_INTO_OUTER(mod_id_p, arg) ||
			mod_id_p->length != sizeof(*mod_id_p) + sizeof(uint32_t))
			return EINVAL;
		mod_id = *((uint32_t*)((char*)mod_id_p + sizeof(*mod_id_p)));

		switch(arg->type)
		{
		case T_MATCH:
			matchdescr = userfw_mod_find_match(mod_id, opcode);

			if (matchdescr == NULL)
				return EHOSTUNREACH;

			if (userfw_mod_inc_refcount(mod_id) == 0)
			{
				match = malloc(sizeof(userfw_match), M_USERFW, M_WAITOK | M_ZERO);

				match->mod = mod_id;
				match->op = opcode;
				match->nargs = matchdescr->nargs;
				match->do_match = matchdescr->do_match;
				match->dtor = matchdescr->dtor;

				err = parse_arg_list(data, arg->length - sizeof(*arg),
						match->args, match->nargs, matchdescr->arg_types);
				if (err == 0 && matchdescr->ctor != NULL)
					err = matchdescr->ctor(match);
				dst->match.p = match;
			}
			else
			{
				err = EHOSTUNREACH;
				dst->type = T_INVAL;
			}
			break;
		case T_ACTION:
			actiondescr = userfw_mod_find_action(mod_id, opcode);

			if (actiondescr == NULL)
				return EHOSTUNREACH;

			if (userfw_mod_inc_refcount(mod_id) == 0)
			{
				action = malloc(sizeof(userfw_action), M_USERFW, M_WAITOK | M_ZERO);

				action->mod = mod_id;
				action->op = opcode;
				action->nargs = actiondescr->nargs;
				action->do_action = actiondescr->do_action;
				action->dtor = actiondescr->dtor;

				err = parse_arg_list(data, arg->length - sizeof(*arg),
						action->args, action->nargs, actiondescr->arg_types);
				if (err == 0 && actiondescr->ctor != NULL)
					err = actiondescr->ctor(action);
				dst->action.p = action;
			}
			else
			{
				err = EHOSTUNREACH;
				dst->type = T_INVAL;
			}
			break;
		}
		if (err != 0)
			return err;
		}
		break;
	default:
		dst->type = T_INVAL;
		return EINVAL;
	}

	return 0;
}