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

📄 pfkey.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	int len;
	if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi,
			reqid, wsize,
			keymat, e_type, e_keylen, a_type, a_keylen, flags,
			l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0)
		return -1;

	return len;
}

/*
 * sending SADB_DELETE message to the kernel.
 * OUT:
 *	positive: success and return length sent.
 *	-1	: error occured, and set errno.
 */
int
pfkey_send_delete(so, satype, mode, src, dst, spi)
	int so;
	u_int satype, mode;
	struct sockaddr *src, *dst;
	u_int32_t spi;
{
	int len;
	if ((len = pfkey_send_x2(so, SADB_DELETE, satype, mode, src, dst, spi)) < 0)
		return -1;

	return len;
}

/*
 * sending SADB_DELETE without spi to the kernel.  This is
 * the "delete all" request (an extension also present in
 * Solaris).
 *
 * OUT:
 *	positive: success and return length sent
 *	-1	: error occured, and set errno
 */
int
pfkey_send_delete_all(so, satype, mode, src, dst)
	int so;
	u_int satype, mode;
	struct sockaddr *src, *dst;
{
	struct sadb_msg *newmsg;
	int len;
	caddr_t p;
	int plen;
	caddr_t ep;

	/* validity check */
	if (src == NULL || dst == NULL) {
		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
		return -1;
	}
	if (src->sa_family != dst->sa_family) {
		__ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
		return -1;
	}
	switch (src->sa_family) {
	case AF_INET:
		plen = sizeof(struct in_addr) << 3;
		break;
	case AF_INET6:
		plen = sizeof(struct in6_addr) << 3;
		break;
	default:
		__ipsec_errcode = EIPSEC_INVAL_FAMILY;
		return -1;
	}

	/* create new sadb_msg to reply. */
	len = sizeof(struct sadb_msg)
		+ sizeof(struct sadb_address)
		+ PFKEY_ALIGN8(src->sa_len)
		+ sizeof(struct sadb_address)
		+ PFKEY_ALIGN8(dst->sa_len);

	if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
		__ipsec_set_strerror(strerror(errno));
		return -1;
	}
	ep = ((caddr_t)newmsg) + len;

	p = pfkey_setsadbmsg((caddr_t)newmsg, ep, SADB_DELETE, len, satype, 0,
	    getpid());
	if (!p) {
		free(newmsg);
		return -1;
	}
	p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
	    IPSEC_ULPROTO_ANY);
	if (!p) {
		free(newmsg);
		return -1;
	}
	p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
	    IPSEC_ULPROTO_ANY);
	if (!p || p != ep) {
		free(newmsg);
		return -1;
	}

	/* send message */
	len = pfkey_send(so, newmsg, len);
	free(newmsg);

	if (len < 0)
		return -1;

	__ipsec_errcode = EIPSEC_NO_ERROR;
	return len;
}

/*
 * sending SADB_GET message to the kernel.
 * OUT:
 *	positive: success and return length sent.
 *	-1	: error occured, and set errno.
 */
int
pfkey_send_get(so, satype, mode, src, dst, spi)
	int so;
	u_int satype, mode;
	struct sockaddr *src, *dst;
	u_int32_t spi;
{
	int len;
	if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0)
		return -1;

	return len;
}

/*
 * sending SADB_REGISTER message to the kernel.
 * OUT:
 *	positive: success and return length sent.
 *	-1	: error occured, and set errno.
 */
int
pfkey_send_register(so, satype)
	int so;
	u_int satype;
{
	int len, algno;

	if (satype == PF_UNSPEC) {
		for (algno = 0;
		     algno < sizeof(supported_map)/sizeof(supported_map[0]);
		     algno++) {
			if (ipsec_supported[algno]) {
				free(ipsec_supported[algno]);
				ipsec_supported[algno] = NULL;
			}
		}
	} else {
		algno = findsupportedmap(satype);
		if (algno == -1) {
			__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
			return -1;
		}

		if (ipsec_supported[algno]) {
			free(ipsec_supported[algno]);
			ipsec_supported[algno] = NULL;
		}
	}

	if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0)
		return -1;

	return len;
}

/*
 * receiving SADB_REGISTER message from the kernel, and copy buffer for
 * sadb_supported returned into ipsec_supported.
 * OUT:
 *	 0: success and return length sent.
 *	-1: error occured, and set errno.
 */
int
pfkey_recv_register(so)
	int so;
{
	pid_t pid = getpid();
	struct sadb_msg *newmsg;
	int error = -1;

	/* receive message */
	for (;;) {
		if ((newmsg = pfkey_recv(so)) == NULL)
			return -1;
		if (newmsg->sadb_msg_type == SADB_REGISTER &&
		    newmsg->sadb_msg_pid == pid)
			break;
		free(newmsg);
	}

	/* check and fix */
	newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len);

	error = pfkey_set_supported(newmsg, newmsg->sadb_msg_len);
	free(newmsg);

	if (error == 0)
		__ipsec_errcode = EIPSEC_NO_ERROR;

	return error;
}

/*
 * receiving SADB_REGISTER message from the kernel, and copy buffer for
 * sadb_supported returned into ipsec_supported.
 * NOTE: sadb_msg_len must be host order.
 * IN:
 *	tlen: msg length, it's to makeing sure.
 * OUT:
 *	 0: success and return length sent.
 *	-1: error occured, and set errno.
 */
int
pfkey_set_supported(msg, tlen)
	struct sadb_msg *msg;
	int tlen;
{
	struct sadb_supported *sup;
	caddr_t p;
	caddr_t ep;

	/* validity */
	if (msg->sadb_msg_len != tlen) {
		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
		return -1;
	}

	p = (caddr_t)msg;
	ep = p + tlen;

	p += sizeof(struct sadb_msg);

	while (p < ep) {
		sup = (struct sadb_supported *)p;
		if (ep < p + sizeof(*sup) ||
		    PFKEY_EXTLEN(sup) < sizeof(*sup) ||
		    ep < p + sup->sadb_supported_len) {
			/* invalid format */
			break;
		}

		switch (sup->sadb_supported_exttype) {
		case SADB_EXT_SUPPORTED_AUTH:
		case SADB_EXT_SUPPORTED_ENCRYPT:
			break;
		default:
			__ipsec_errcode = EIPSEC_INVAL_SATYPE;
			return -1;
		}

		/* fixed length */
		sup->sadb_supported_len = PFKEY_EXTLEN(sup);

		/* set supported map */
		if (setsupportedmap(sup) != 0)
			return -1;

		p += sup->sadb_supported_len;
	}

	if (p != ep) {
		__ipsec_errcode = EIPSEC_INVAL_SATYPE;
		return -1;
	}

	__ipsec_errcode = EIPSEC_NO_ERROR;

	return 0;
}

/*
 * sending SADB_FLUSH message to the kernel.
 * OUT:
 *	positive: success and return length sent.
 *	-1	: error occured, and set errno.
 */
int
pfkey_send_flush(so, satype)
	int so;
	u_int satype;
{
	int len;

	if ((len = pfkey_send_x3(so, SADB_FLUSH, satype)) < 0)
		return -1;

	return len;
}

/*
 * sending SADB_DUMP message to the kernel.
 * OUT:
 *	positive: success and return length sent.
 *	-1	: error occured, and set errno.
 */
int
pfkey_send_dump(so, satype)
	int so;
	u_int satype;
{
	int len;

	if ((len = pfkey_send_x3(so, SADB_DUMP, satype)) < 0)
		return -1;

	return len;
}

/*
 * sending SADB_X_PROMISC message to the kernel.
 * NOTE that this function handles promisc mode toggle only.
 * IN:
 *	flag:	set promisc off if zero, set promisc on if non-zero.
 * OUT:
 *	positive: success and return length sent.
 *	-1	: error occured, and set errno.
 *	0     : error occured, and set errno.
 *	others: a pointer to new allocated buffer in which supported
 *	        algorithms is.
 */
int
pfkey_send_promisc_toggle(so, flag)
	int so;
	int flag;
{
	int len;

	if ((len = pfkey_send_x3(so, SADB_X_PROMISC, (flag ? 1 : 0))) < 0)
		return -1;

	return len;
}

/*
 * sending SADB_X_SPDADD message to the kernel.
 * OUT:
 *	positive: success and return length sent.
 *	-1	: error occured, and set errno.
 */
int
pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
	int so;
	struct sockaddr *src, *dst;
	u_int prefs, prefd, proto;
	caddr_t policy;
	int policylen;
	u_int32_t seq;
{
	int len;

	if ((len = pfkey_send_x4(so, SADB_X_SPDADD,
				src, prefs, dst, prefd, proto,
				0, 0,
				policy, policylen, seq)) < 0)
		return -1;

	return len;
}

/*
 * sending SADB_X_SPDADD message to the kernel.
 * OUT:
 *	positive: success and return length sent.
 *	-1	: error occured, and set errno.
 */
int
pfkey_send_spdadd2(so, src, prefs, dst, prefd, proto, ltime, vtime,
		policy, policylen, seq)
	int so;
	struct sockaddr *src, *dst;
	u_int prefs, prefd, proto;
	u_int64_t ltime, vtime;
	caddr_t policy;
	int policylen;
	u_int32_t seq;
{
	int len;

	if ((len = pfkey_send_x4(so, SADB_X_SPDADD,
				src, prefs, dst, prefd, proto,
				ltime, vtime,
				policy, policylen, seq)) < 0)
		return -1;

	return len;
}

/*
 * sending SADB_X_SPDUPDATE message to the kernel.
 * OUT:
 *	positive: success and return length sent.
 *	-1	: error occured, and set errno.
 */
int
pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
	int so;
	struct sockaddr *src, *dst;
	u_int prefs, prefd, proto;
	caddr_t policy;
	int policylen;
	u_int32_t seq;
{
	int len;

	if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE,
				src, prefs, dst, prefd, proto,
				0, 0,
				policy, policylen, seq)) < 0)
		return -1;

	return len;
}

/*
 * sending SADB_X_SPDUPDATE message to the kernel.
 * OUT:
 *	positive: success and return length sent.
 *	-1	: error occured, and set errno.
 */
int
pfkey_send_spdupdate2(so, src, prefs, dst, prefd, proto, ltime, vtime,
		policy, policylen, seq)
	int so;
	struct sockaddr *src, *dst;
	u_int prefs, prefd, proto;
	u_int64_t ltime, vtime;
	caddr_t policy;
	int policylen;
	u_int32_t seq;
{
	int len;

	if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE,
				src, prefs, dst, prefd, proto,
				ltime, vtime,
				policy, policylen, seq)) < 0)
		return -1;

	return len;
}

/*
 * sending SADB_X_SPDDELETE message to the kernel.
 * OUT:
 *	positive: success and return length sent.
 *	-1	: error occured, and set errno.
 */
int
pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
	int so;
	struct sockaddr *src, *dst;
	u_int prefs, prefd, proto;
	caddr_t policy;
	int policylen;
	u_int32_t seq;
{
	int len;

	if (policylen != sizeof(struct sadb_x_policy)) {
		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
		return -1;
	}

	if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE,
				src, prefs, dst, prefd, proto,
				0, 0,
				policy, policylen, seq)) < 0)
		return -1;

	return len;
}

/*
 * sending SADB_X_SPDDELETE message to the kernel.
 * OUT:
 *	positive: success and return length sent.
 *	-1	: error occured, and set errno.
 */
int
pfkey_send_spddelete2(so, spid)
	int so;
	u_int32_t spid;
{
	int len;

	if ((len = pfkey_send_x5(so, SADB_X_SPDDELETE2, spid)) < 0)
		return -1;

	return len;
}

/*
 * sending SADB_X_SPDGET message to the kernel.
 * OUT:
 *	positive: success and return length sent.
 *	-1	: error occured, and set errno.
 */
int
pfkey_send_spdget(so, spid)
	int so;
	u_int32_t spid;
{
	int len;

	if ((len = pfkey_send_x5(so, SADB_X_SPDGET, spid)) < 0)
		return -1;

	return len;
}

/*
 * sending SADB_X_SPDSETIDX message to the kernel.
 * OUT:
 *	positive: success and return length sent.
 *	-1	: error occured, and set errno.
 */
int
pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
	int so;
	struct sockaddr *src, *dst;
	u_int prefs, prefd, proto;
	caddr_t policy;
	int policylen;

⌨️ 快捷键说明

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