Пример #1
0
static int xfrm_accept_msg(const struct sockaddr_nl *who,
			   struct rtnl_ctrl_data *ctrl,
			   struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE *)arg;

	if (timestamp)
		print_timestamp(fp);

	if (listen_all_nsid) {
		if (ctrl == NULL || ctrl->nsid < 0)
			fprintf(fp, "[nsid current]");
		else
			fprintf(fp, "[nsid %d]", ctrl->nsid);
	}

	switch (n->nlmsg_type) {
	case XFRM_MSG_NEWSA:
	case XFRM_MSG_DELSA:
	case XFRM_MSG_UPDSA:
	case XFRM_MSG_EXPIRE:
		xfrm_state_print(who, n, arg);
		return 0;
	case XFRM_MSG_NEWPOLICY:
	case XFRM_MSG_DELPOLICY:
	case XFRM_MSG_UPDPOLICY:
	case XFRM_MSG_POLEXPIRE:
		xfrm_policy_print(who, n, arg);
		return 0;
	case XFRM_MSG_ACQUIRE:
		xfrm_acquire_print(who, n, arg);
		return 0;
	case XFRM_MSG_FLUSHSA:
		xfrm_state_flush_print(who, n, arg);
		return 0;
	case XFRM_MSG_FLUSHPOLICY:
		xfrm_policy_flush_print(who, n, arg);
		return 0;
	case XFRM_MSG_REPORT:
		xfrm_report_print(who, n, arg);
		return 0;
	case XFRM_MSG_NEWAE:
		xfrm_ae_print(who, n, arg);
		return 0;
	case XFRM_MSG_MAPPING:
		xfrm_mapping_print(who, n, arg);
		return 0;
	default:
		break;
	}

	if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP &&
	    n->nlmsg_type != NLMSG_DONE) {
		fprintf(fp, "Unknown message: %08d 0x%08x 0x%08x\n",
			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
	}
	return 0;
}
Пример #2
0
static int xfrm_accept_msg(const struct sockaddr_nl *who,
			   struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE*)arg;

	if (timestamp)
		print_timestamp(fp);

	if (n->nlmsg_type == XFRM_MSG_NEWSA ||
	    n->nlmsg_type == XFRM_MSG_DELSA ||
	    n->nlmsg_type == XFRM_MSG_UPDSA ||
	    n->nlmsg_type == XFRM_MSG_EXPIRE) {
		xfrm_state_print(who, n, arg);
		return 0;
	}
	if (n->nlmsg_type == XFRM_MSG_NEWPOLICY ||
	    n->nlmsg_type == XFRM_MSG_DELPOLICY ||
	    n->nlmsg_type == XFRM_MSG_UPDPOLICY ||
	    n->nlmsg_type == XFRM_MSG_POLEXPIRE) {
		xfrm_policy_print(who, n, arg);
		return 0;
	}

	if (n->nlmsg_type == XFRM_MSG_ACQUIRE) {
		xfrm_acquire_print(who, n, arg);
		return 0;
	}
	if (n->nlmsg_type == XFRM_MSG_FLUSHSA) {
		/* XXX: Todo: show proto in xfrm_usersa_flush */
		fprintf(fp, "Flushed state\n");
		return 0;
	}
	if (n->nlmsg_type == XFRM_MSG_FLUSHPOLICY) {
		fprintf(fp, "Flushed policy\n");
		return 0;
	}
	if (n->nlmsg_type == XFRM_MSG_REPORT) {
		xfrm_report_print(who, n, arg);
		return 0;
	}
	if (n->nlmsg_type == XFRM_MSG_NEWAE) {
		xfrm_ae_print(who, n, arg);
		return 0;
	}
	if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP &&
	    n->nlmsg_type != NLMSG_DONE) {
		fprintf(fp, "Unknown message: %08d 0x%08x 0x%08x\n",
			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
	}
	return 0;
}
static int xfrm_accept_msg(const struct sockaddr_nl *who,
			   struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE*)arg;

	if (timestamp)
		print_timestamp(fp);

	switch (n->nlmsg_type) {
	case XFRM_MSG_NEWSA:
	case XFRM_MSG_DELSA:
	case XFRM_MSG_UPDSA:
	case XFRM_MSG_EXPIRE:
		xfrm_state_print(who, n, arg);
		return 0;
	case XFRM_MSG_NEWPOLICY:
	case XFRM_MSG_DELPOLICY:
	case XFRM_MSG_UPDPOLICY:
	case XFRM_MSG_POLEXPIRE:
		xfrm_policy_print(who, n, arg);
		return 0;
	case XFRM_MSG_ACQUIRE:
		xfrm_acquire_print(who, n, arg);
		return 0;
	case XFRM_MSG_FLUSHSA:
		xfrm_state_flush_print(who, n, arg);
		return 0;
	case XFRM_MSG_FLUSHPOLICY:
		xfrm_policy_flush_print(who, n, arg);
		return 0;
	case XFRM_MSG_REPORT:
		xfrm_report_print(who, n, arg);
		return 0;
	case XFRM_MSG_NEWAE:
		xfrm_ae_print(who, n, arg);
		return 0;
	default:
		break;
	}

	if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP &&
	    n->nlmsg_type != NLMSG_DONE) {
		fprintf(fp, "Unknown message: %08d 0x%08x 0x%08x\n",
			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
	}
	return 0;
}
Пример #4
0
static int xfrm_state_allocspi(int argc, char **argv)
{
	struct rtnl_handle rth;
	struct {
		struct nlmsghdr 	n;
		struct xfrm_userspi_info xspi;
		char   			buf[RTA_BUF_SIZE];
	} req;
	char *idp = NULL;
	char *minp = NULL;
	char *maxp = NULL;
	struct xfrm_mark mark = {0, 0};
	char res_buf[NLMSG_BUF_SIZE];
	struct nlmsghdr *res_n = (struct nlmsghdr *)res_buf;

	memset(res_buf, 0, sizeof(res_buf));

	memset(&req, 0, sizeof(req));

	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xspi));
	req.n.nlmsg_flags = NLM_F_REQUEST;
	req.n.nlmsg_type = XFRM_MSG_ALLOCSPI;
	req.xspi.info.family = preferred_family;

#if 0
	req.xsinfo.lft.soft_byte_limit = XFRM_INF;
	req.xsinfo.lft.hard_byte_limit = XFRM_INF;
	req.xsinfo.lft.soft_packet_limit = XFRM_INF;
	req.xsinfo.lft.hard_packet_limit = XFRM_INF;
#endif

	while (argc > 0) {
		if (strcmp(*argv, "mode") == 0) {
			NEXT_ARG();
			xfrm_mode_parse(&req.xspi.info.mode, &argc, &argv);
		} else if (strcmp(*argv, "mark") == 0) {
			xfrm_parse_mark(&mark, &argc, &argv);
		} else if (strcmp(*argv, "reqid") == 0) {
			NEXT_ARG();
			xfrm_reqid_parse(&req.xspi.info.reqid, &argc, &argv);
		} else if (strcmp(*argv, "seq") == 0) {
			NEXT_ARG();
			xfrm_seq_parse(&req.xspi.info.seq, &argc, &argv);
		} else if (strcmp(*argv, "min") == 0) {
			if (minp)
				duparg("min", *argv);
			minp = *argv;

			NEXT_ARG();

			if (get_u32(&req.xspi.min, *argv, 0))
				invarg("\"min\" value is invalid", *argv);
		} else if (strcmp(*argv, "max") == 0) {
			if (maxp)
				duparg("max", *argv);
			maxp = *argv;

			NEXT_ARG();

			if (get_u32(&req.xspi.max, *argv, 0))
				invarg("\"max\" value is invalid", *argv);
		} else {
			/* try to assume ID */
			if (idp)
				invarg("unknown", *argv);
			idp = *argv;

			/* ID */
			xfrm_id_parse(&req.xspi.info.saddr, &req.xspi.info.id,
				      &req.xspi.info.family, 0, &argc, &argv);
			if (req.xspi.info.id.spi) {
				fprintf(stderr, "\"SPI\" must be zero\n");
				exit(1);
			}
			if (preferred_family == AF_UNSPEC)
				preferred_family = req.xspi.info.family;
		}
		argc--; argv++;
	}

	if (!idp) {
		fprintf(stderr, "Not enough information: \"ID\" is required\n");
		exit(1);
	}

	if (minp) {
		if (!maxp) {
			fprintf(stderr, "\"max\" is missing\n");
			exit(1);
		}
		if (req.xspi.min > req.xspi.max) {
			fprintf(stderr, "\"min\" value is larger than \"max\" value\n");
			exit(1);
		}
	} else {
		if (maxp) {
			fprintf(stderr, "\"min\" is missing\n");
			exit(1);
		}

		/* XXX: Default value defined in PF_KEY;
		 * See kernel's net/key/af_key.c(pfkey_getspi).
		 */
		req.xspi.min = 0x100;
		req.xspi.max = 0x0fffffff;

		/* XXX: IPCOMP spi is 16-bits;
		 * See kernel's net/xfrm/xfrm_user(verify_userspi_info).
		 */
		if (req.xspi.info.id.proto == IPPROTO_COMP)
			req.xspi.max = 0xffff;
	}

	if (mark.m & mark.v) {
		int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
				  (void *)&mark, sizeof(mark));
		if (r < 0) {
			fprintf(stderr, "XFRMA_MARK failed\n");
			exit(1);
		}
	}

	if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
		exit(1);

	if (req.xspi.info.family == AF_UNSPEC)
		req.xspi.info.family = AF_INET;


	if (rtnl_talk(&rth, &req.n, 0, 0, res_n) < 0)
		exit(2);

	if (xfrm_state_print(NULL, res_n, (void*)stdout) < 0) {
		fprintf(stderr, "An error :-)\n");
		exit(1);
	}

	rtnl_close(&rth);

	return 0;
}