⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipxfrm.c

📁 sloedgy open sip stack source code
💻 C
📖 第 1 页 / 共 2 页
字号:
		case 1:
			fprintf(fp, "espinudp-nonike ");
			break;
		case 2:
			fprintf(fp, "espinudp ");
			break;
		default:
			fprintf(fp, "%u ", e->encap_type);
			break;
		}
		fprintf(fp, "sport %u ", ntohs(e->encap_sport));
		fprintf(fp, "dport %u ", ntohs(e->encap_dport));

		memset(abuf, '\0', sizeof(abuf));
		fprintf(fp, "addr %s",
			rt_addr_n2a(family, sizeof(e->encap_oa),
				    &e->encap_oa, abuf, sizeof(abuf)));
		fprintf(fp, "%s", _SL_);
	}

	if (tb[XFRMA_TMPL]) {
		struct rtattr *rta = tb[XFRMA_TMPL];
		xfrm_tmpl_print((struct xfrm_user_tmpl *) RTA_DATA(rta),
				RTA_PAYLOAD(rta), family, fp, prefix);
	}

	if (tb[XFRMA_COADDR]) {
		char abuf[256];
		xfrm_address_t *coa;

		if (prefix)
			fprintf(fp, prefix);
		fprintf(fp, "coa ");

		coa = (xfrm_address_t *)RTA_DATA(tb[XFRMA_COADDR]);

		if (RTA_PAYLOAD(tb[XFRMA_COADDR]) < sizeof(*coa)) {
			fprintf(fp, "(ERROR truncated)");
			fprintf(fp, "%s", _SL_);
			return;
		}

		memset(abuf, '\0', sizeof(abuf));
		fprintf(fp, "%s",
			rt_addr_n2a(family, sizeof(*coa), coa,
				    abuf, sizeof(abuf)));
		fprintf(fp, "%s", _SL_);
	}

	if (tb[XFRMA_LASTUSED]) {
		__u64 lastused;

		if (prefix)
			fprintf(fp, prefix);
		fprintf(fp, "lastused ");

		if (RTA_PAYLOAD(tb[XFRMA_LASTUSED]) < sizeof(lastused)) {
			fprintf(fp, "(ERROR truncated)");
			fprintf(fp, "%s", _SL_);
			return;
		}

		lastused = *(__u64 *)RTA_DATA(tb[XFRMA_LASTUSED]);

		fprintf(fp, "%s", strxf_time(lastused));
		fprintf(fp, "%s", _SL_);
	}
}

static int xfrm_selector_iszero(struct xfrm_selector *s)
{
	struct xfrm_selector s0;

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

	return (memcmp(&s0, s, sizeof(s0)) == 0);
}

void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo,
			    struct rtattr *tb[], FILE *fp, const char *prefix,
			    const char *title)
{
	char buf[STRBUF_SIZE];
	int force_spi = xfrm_xfrmproto_is_ipsec(xsinfo->id.proto);

	memset(buf, '\0', sizeof(buf));

	xfrm_id_info_print(&xsinfo->saddr, &xsinfo->id, xsinfo->mode,
			   xsinfo->reqid, xsinfo->family, force_spi, fp,
			   prefix, title);

	if (prefix)
		STRBUF_CAT(buf, prefix);
	STRBUF_CAT(buf, "\t");

	fprintf(fp, buf);
	fprintf(fp, "replay-window %u ", xsinfo->replay_window);
	if (show_stats > 0)
		fprintf(fp, "seq 0x%08u ", xsinfo->seq);
	if (show_stats > 0 || xsinfo->flags) {
		__u8 flags = xsinfo->flags;

		fprintf(fp, "flag ");
		XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_NOECN, "noecn");
		XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_DECAP_DSCP, "decap-dscp");
		XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_WILDRECV, "wildrecv");
		if (flags)
			fprintf(fp, "%x", flags);
		if (show_stats > 0)
			fprintf(fp, " (0x%s)", strxf_mask8(flags));
	}
	fprintf(fp, "%s", _SL_);

	xfrm_xfrma_print(tb, xsinfo->family, fp, buf);

	if (!xfrm_selector_iszero(&xsinfo->sel)) {
		char sbuf[STRBUF_SIZE];

		memcpy(sbuf, buf, sizeof(sbuf));
		STRBUF_CAT(sbuf, "sel ");

		xfrm_selector_print(&xsinfo->sel, xsinfo->family, fp, sbuf);
	}

	if (show_stats > 0) {
		xfrm_lifetime_print(&xsinfo->lft, &xsinfo->curlft, fp, buf);
		xfrm_stats_print(&xsinfo->stats, fp, buf);
	}
}

void xfrm_policy_info_print(struct xfrm_userpolicy_info *xpinfo,
			    struct rtattr *tb[], FILE *fp, const char *prefix,
			    const char *title)
{
	char buf[STRBUF_SIZE];
	__u8 ptype = XFRM_POLICY_TYPE_MAIN;

	memset(buf, '\0', sizeof(buf));

	xfrm_selector_print(&xpinfo->sel, preferred_family, fp, title);

	if (prefix)
		STRBUF_CAT(buf, prefix);
	STRBUF_CAT(buf, "\t");

	fprintf(fp, buf);
	fprintf(fp, "dir ");
	switch (xpinfo->dir) {
	case XFRM_POLICY_IN:
		fprintf(fp, "in");
		break;
	case XFRM_POLICY_OUT:
		fprintf(fp, "out");
		break;
	case XFRM_POLICY_FWD:
		fprintf(fp, "fwd");
		break;
	default:
		fprintf(fp, "%u", xpinfo->dir);
		break;
	}
	fprintf(fp, " ");

	switch (xpinfo->action) {
	case XFRM_POLICY_ALLOW:
		if (show_stats > 0)
			fprintf(fp, "action allow ");
		break;
	case XFRM_POLICY_BLOCK:
		fprintf(fp, "action block ");
		break;
	default:
		fprintf(fp, "action %u ", xpinfo->action);
		break;
	}

	if (show_stats)
		fprintf(fp, "index %u ", xpinfo->index);
	fprintf(fp, "priority %u ", xpinfo->priority);

	fprintf(fp, "ptype ");

	if (tb[XFRMA_POLICY_TYPE]) {
		struct xfrm_userpolicy_type *upt;

		if (RTA_PAYLOAD(tb[XFRMA_POLICY_TYPE]) < sizeof(*upt))
			fprintf(fp, "(ERROR truncated)");

		upt = (struct xfrm_userpolicy_type *)RTA_DATA(tb[XFRMA_POLICY_TYPE]);
		ptype = upt->type;
	}

	switch (ptype) {
	case XFRM_POLICY_TYPE_MAIN:
		fprintf(fp, "main");
		break;
	case XFRM_POLICY_TYPE_SUB:
		fprintf(fp, "sub");
		break;
	default:
		fprintf(fp, "%u", ptype);
		break;
	}
	fprintf(fp, " ");

	if (show_stats > 0) {
		fprintf(fp, "share %s ", strxf_share(xpinfo->share));
		fprintf(fp, "flag 0x%s", strxf_mask8(xpinfo->flags));
	}
	fprintf(fp, "%s", _SL_);

	if (show_stats > 0)
		xfrm_lifetime_print(&xpinfo->lft, &xpinfo->curlft, fp, buf);

	xfrm_xfrma_print(tb, xpinfo->sel.family, fp, buf);
}

int xfrm_id_parse(xfrm_address_t *saddr, struct xfrm_id *id, __u16 *family,
		  int loose, int *argcp, char ***argvp)
{
	int argc = *argcp;
	char **argv = *argvp;
	inet_prefix dst;
	inet_prefix src;

	memset(&dst, 0, sizeof(dst));
	memset(&src, 0, sizeof(src));

	while (1) {
		if (strcmp(*argv, "src") == 0) {
			NEXT_ARG();

			get_prefix(&src, *argv, preferred_family);
			if (src.family == AF_UNSPEC)
				invarg("\"src\" address family is AF_UNSPEC", *argv);
			if (family)
				*family = src.family;

			memcpy(saddr, &src.data, sizeof(*saddr));

			filter.id_src_mask = src.bitlen;

		} else if (strcmp(*argv, "dst") == 0) {
			NEXT_ARG();

			get_prefix(&dst, *argv, preferred_family);
			if (dst.family == AF_UNSPEC)
				invarg("\"dst\" address family is AF_UNSPEC", *argv);
			if (family)
				*family = dst.family;

			memcpy(&id->daddr, &dst.data, sizeof(id->daddr));

			filter.id_dst_mask = dst.bitlen;

		} else if (strcmp(*argv, "proto") == 0) {
			int ret;

			NEXT_ARG();

			ret = xfrm_xfrmproto_getbyname(*argv);
			if (ret < 0)
				invarg("\"XFRM_PROTO\" is invalid", *argv);

			id->proto = (__u8)ret;

			filter.id_proto_mask = XFRM_FILTER_MASK_FULL;

		} else if (strcmp(*argv, "spi") == 0) {
			__u32 spi;

			NEXT_ARG();
			if (get_u32(&spi, *argv, 0))
				invarg("\"SPI\" is invalid", *argv);

			spi = htonl(spi);
			id->spi = spi;

			filter.id_spi_mask = XFRM_FILTER_MASK_FULL;

		} else {
			PREV_ARG(); /* back track */
			break;
		}

		if (!NEXT_ARG_OK())
			break;
		NEXT_ARG();
	}

	if (src.family && dst.family && (src.family != dst.family))
		invarg("the same address family is required between \"src\" and \"dst\"", *argv);

	if (loose == 0 && id->proto == 0)
		missarg("XFRM_PROTO");
	if (argc == *argcp)
		missarg("ID");

	*argcp = argc;
	*argvp = argv;

	return 0;
}

int xfrm_mode_parse(__u8 *mode, int *argcp, char ***argvp)
{
	int argc = *argcp;
	char **argv = *argvp;

	if (matches(*argv, "transport") == 0)
		*mode = XFRM_MODE_TRANSPORT;
	else if (matches(*argv, "tunnel") == 0)
		*mode = XFRM_MODE_TUNNEL;
	else if (matches(*argv, "ro") == 0)
		*mode = XFRM_MODE_ROUTEOPTIMIZATION;
	else if (matches(*argv, "in_trigger") == 0)
		*mode = XFRM_MODE_IN_TRIGGER;
	else if (matches(*argv, "beet") == 0)
		*mode = XFRM_MODE_BEET;
	else
		invarg("\"MODE\" is invalid", *argv);

	*argcp = argc;
	*argvp = argv;

	return 0;
}

int xfrm_encap_type_parse(__u16 *type, int *argcp, char ***argvp)
{
	int argc = *argcp;
	char **argv = *argvp;

	if (strcmp(*argv, "espinudp-nonike") == 0)
		*type = 1;
	else if (strcmp(*argv, "espinudp") == 0)
		*type = 2;
	else
		invarg("\"ENCAP-TYPE\" is invalid", *argv);

	*argcp = argc;
	*argvp = argv;

	return 0;
}

/* NOTE: reqid is used by host-byte order */
int xfrm_reqid_parse(__u32 *reqid, int *argcp, char ***argvp)
{
	int argc = *argcp;
	char **argv = *argvp;

	if (get_u32(reqid, *argv, 0))
		invarg("\"REQID\" is invalid", *argv);

	*argcp = argc;
	*argvp = argv;

	return 0;
}

static int xfrm_selector_upspec_parse(struct xfrm_selector *sel,
				      int *argcp, char ***argvp)
{
	int argc = *argcp;
	char **argv = *argvp;
	char *sportp = NULL;
	char *dportp = NULL;
	char *typep = NULL;
	char *codep = NULL;

	while (1) {
		if (strcmp(*argv, "proto") == 0) {
			__u8 upspec;

			NEXT_ARG();

			if (strcmp(*argv, "any") == 0)
				upspec = 0;
			else {
				struct protoent *pp;
				pp = getprotobyname(*argv);
				if (pp)
					upspec = pp->p_proto;
				else {
					if (get_u8(&upspec, *argv, 0))
						invarg("\"PROTO\" is invalid", *argv);
				}
			}
			sel->proto = upspec;

			filter.upspec_proto_mask = XFRM_FILTER_MASK_FULL;

		} else if (strcmp(*argv, "sport") == 0) {
			sportp = *argv;

			NEXT_ARG();

			if (get_u16(&sel->sport, *argv, 0))
				invarg("\"PORT\" is invalid", *argv);
			sel->sport = htons(sel->sport);
			if (sel->sport)
				sel->sport_mask = ~((__u16)0);

			filter.upspec_sport_mask = XFRM_FILTER_MASK_FULL;

		} else if (strcmp(*argv, "dport") == 0) {
			dportp = *argv;

			NEXT_ARG();

			if (get_u16(&sel->dport, *argv, 0))
				invarg("\"PORT\" is invalid", *argv);
			sel->dport = htons(sel->dport);
			if (sel->dport)
				sel->dport_mask = ~((__u16)0);

			filter.upspec_dport_mask = XFRM_FILTER_MASK_FULL;

		} else if (strcmp(*argv, "type") == 0) {
			typep = *argv;

			NEXT_ARG();

			if (get_u16(&sel->sport, *argv, 0) ||
			    (sel->sport & ~((__u16)0xff)))
				invarg("\"type\" value is invalid", *argv);
			sel->sport = htons(sel->sport);
			sel->sport_mask = ~((__u16)0);

			filter.upspec_sport_mask = XFRM_FILTER_MASK_FULL;


		} else if (strcmp(*argv, "code") == 0) {
			codep = *argv;

			NEXT_ARG();

			if (get_u16(&sel->dport, *argv, 0) ||
			    (sel->dport & ~((__u16)0xff)))
				invarg("\"code\" value is invalid", *argv);
			sel->dport = htons(sel->dport);
			sel->dport_mask = ~((__u16)0);

			filter.upspec_dport_mask = XFRM_FILTER_MASK_FULL;

		} else {
			PREV_ARG(); /* back track */
			break;
		}

		if (!NEXT_ARG_OK())
			break;
		NEXT_ARG();
	}
	if (argc == *argcp)
		missarg("UPSPEC");
	if (sportp || dportp) {
		switch (sel->proto) {
		case IPPROTO_TCP:
		case IPPROTO_UDP:
		case IPPROTO_SCTP:
		case IPPROTO_DCCP:
			break;
		default:
			fprintf(stderr, "\"sport\" and \"dport\" are invalid with proto=%s\n", strxf_proto(sel->proto));
			exit(1);
		}
	}
	if (typep || codep) {
		switch (sel->proto) {
		case IPPROTO_ICMP:
		case IPPROTO_ICMPV6:
		case IPPROTO_MH:
			break;
		default:
			fprintf(stderr, "\"type\" and \"code\" are invalid with proto=%s\n", strxf_proto(sel->proto));
			exit(1);
		}
	}

	*argcp = argc;
	*argvp = argv;

	return 0;
}

int xfrm_selector_parse(struct xfrm_selector *sel, int *argcp, char ***argvp)
{
	int argc = *argcp;
	char **argv = *argvp;
	inet_prefix dst;
	inet_prefix src;
	char *upspecp = NULL;

	memset(&dst, 0, sizeof(dst));
	memset(&src, 0, sizeof(src));

	while (1) {
		if (strcmp(*argv, "src") == 0) {
			NEXT_ARG();

			get_prefix(&src, *argv, preferred_family);
			if (src.family == AF_UNSPEC)
				invarg("\"src\" address family is AF_UNSPEC", *argv);
			sel->family = src.family;

			memcpy(&sel->saddr, &src.data, sizeof(sel->saddr));
			sel->prefixlen_s = src.bitlen;

			filter.sel_src_mask = src.bitlen;

		} else if (strcmp(*argv, "dst") == 0) {
			NEXT_ARG();

			get_prefix(&dst, *argv, preferred_family);
			if (dst.family == AF_UNSPEC)
				invarg("\"dst\" address family is AF_UNSPEC", *argv);
			sel->family = dst.family;

			memcpy(&sel->daddr, &dst.data, sizeof(sel->daddr));
			sel->prefixlen_d = dst.bitlen;

			filter.sel_dst_mask = dst.bitlen;

		} else if (strcmp(*argv, "dev") == 0) {
			int ifindex;

			NEXT_ARG();

			if (strcmp(*argv, "none") == 0)
				ifindex = 0;
			else {
				ifindex = if_nametoindex(*argv);
				if (ifindex <= 0)
					invarg("\"DEV\" is invalid", *argv);
			}
			sel->ifindex = ifindex;

			filter.sel_dev_mask = XFRM_FILTER_MASK_FULL;

		} else {
			if (upspecp) {
				PREV_ARG(); /* back track */
				break;
			} else {
				upspecp = *argv;
				xfrm_selector_upspec_parse(sel, &argc, &argv);
			}
		}

		if (!NEXT_ARG_OK())
			break;

		NEXT_ARG();
	}

	if (src.family && dst.family && (src.family != dst.family))
		invarg("the same address family is required between \"src\" and \"dst\"", *argv);

	if (argc == *argcp)
		missarg("SELECTOR");

	*argcp = argc;
	*argvp = argv;

	return 0;
}

int xfrm_lifetime_cfg_parse(struct xfrm_lifetime_cfg *lft,
			    int *argcp, char ***argvp)
{
	int argc = *argcp;
	char **argv = *argvp;
	int ret;

	if (strcmp(*argv, "time-soft") == 0) {
		NEXT_ARG();
		ret = get_u64(&lft->soft_add_expires_seconds, *argv, 0);
		if (ret)
			invarg("\"time-soft\" value is invalid", *argv);
	} else if (strcmp(*argv, "time-hard") == 0) {
		NEXT_ARG();
		ret = get_u64(&lft->hard_add_expires_seconds, *argv, 0);
		if (ret)
			invarg("\"time-hard\" value is invalid", *argv);
	} else if (strcmp(*argv, "time-use-soft") == 0) {
		NEXT_ARG();
		ret = get_u64(&lft->soft_use_expires_seconds, *argv, 0);
		if (ret)
			invarg("\"time-use-soft\" value is invalid", *argv);
	} else if (strcmp(*argv, "time-use-hard") == 0) {
		NEXT_ARG();
		ret = get_u64(&lft->hard_use_expires_seconds, *argv, 0);
		if (ret)
			invarg("\"time-use-hard\" value is invalid", *argv);
	} else if (strcmp(*argv, "byte-soft") == 0) {
		NEXT_ARG();
		ret = get_u64(&lft->soft_byte_limit, *argv, 0);
		if (ret)
			invarg("\"byte-soft\" value is invalid", *argv);
	} else if (strcmp(*argv, "byte-hard") == 0) {
		NEXT_ARG();
		ret = get_u64(&lft->hard_byte_limit, *argv, 0);
		if (ret)
			invarg("\"byte-hard\" value is invalid", *argv);
	} else if (strcmp(*argv, "packet-soft") == 0) {
		NEXT_ARG();
		ret = get_u64(&lft->soft_packet_limit, *argv, 0);
		if (ret)
			invarg("\"packet-soft\" value is invalid", *argv);
	} else if (strcmp(*argv, "packet-hard") == 0) {
		NEXT_ARG();
		ret = get_u64(&lft->hard_packet_limit, *argv, 0);
		if (ret)
			invarg("\"packet-hard\" value is invalid", *argv);
	} else
		invarg("\"LIMIT\" is invalid", *argv);

	*argcp = argc;
	*argvp = argv;

	return 0;
}

int do_xfrm(int argc, char **argv)
{
	memset(&filter, 0, sizeof(filter));

	if (argc < 1)
		usage();

	if (matches(*argv, "state") == 0 ||
	    matches(*argv, "sa") == 0)
		return do_xfrm_state(argc-1, argv+1);
	else if (matches(*argv, "policy") == 0)
		return do_xfrm_policy(argc-1, argv+1);
	else if (matches(*argv, "monitor") == 0)
		return do_xfrm_monitor(argc-1, argv+1);
	else if (matches(*argv, "help") == 0) {
		usage();
		fprintf(stderr, "xfrm Object \"%s\" is unknown.\n", *argv);
		exit(-1);
	}
	usage();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -