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

📄 af_key.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
			default:				break;			}		}	}	hdr->sadb_msg_len = size / sizeof(uint64_t);	hdr->sadb_msg_reserved = atomic_read(&xp->refcnt);}static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs){	int err;	struct sadb_lifetime *lifetime;	struct sadb_address *sa;	struct sadb_x_policy *pol;	struct xfrm_policy *xp;	struct sk_buff *out_skb;	struct sadb_msg *out_hdr;	if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],				     ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||	    !ext_hdrs[SADB_X_EXT_POLICY-1])		return -EINVAL;	pol = ext_hdrs[SADB_X_EXT_POLICY-1];	if (pol->sadb_x_policy_type > IPSEC_POLICY_IPSEC)		return -EINVAL;	if (!pol->sadb_x_policy_dir || pol->sadb_x_policy_dir >= IPSEC_DIR_MAX)		return -EINVAL;	xp = xfrm_policy_alloc(GFP_KERNEL);	if (xp == NULL)		return -ENOBUFS;	xp->action = (pol->sadb_x_policy_type == IPSEC_POLICY_DISCARD ?		      XFRM_POLICY_BLOCK : XFRM_POLICY_ALLOW);	xp->priority = pol->sadb_x_policy_priority;	sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1], 	xp->family = pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.saddr);	if (!xp->family) {		err = -EINVAL;		goto out;	}	xp->selector.family = xp->family;	xp->selector.prefixlen_s = sa->sadb_address_prefixlen;	xp->selector.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);	xp->selector.sport = ((struct sockaddr_in *)(sa+1))->sin_port;	if (xp->selector.sport)		xp->selector.sport_mask = ~0;	sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1], 	pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.daddr);	xp->selector.prefixlen_d = sa->sadb_address_prefixlen;	/* Amusing, we set this twice.  KAME apps appear to set same value	 * in both addresses.	 */	xp->selector.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);	xp->selector.dport = ((struct sockaddr_in *)(sa+1))->sin_port;	if (xp->selector.dport)		xp->selector.dport_mask = ~0;	xp->lft.soft_byte_limit = XFRM_INF;	xp->lft.hard_byte_limit = XFRM_INF;	xp->lft.soft_packet_limit = XFRM_INF;	xp->lft.hard_packet_limit = XFRM_INF;	if ((lifetime = ext_hdrs[SADB_EXT_LIFETIME_HARD-1]) != NULL) {		xp->lft.hard_packet_limit = _KEY2X(lifetime->sadb_lifetime_allocations);		xp->lft.hard_byte_limit = _KEY2X(lifetime->sadb_lifetime_bytes);		xp->lft.hard_add_expires_seconds = lifetime->sadb_lifetime_addtime;		xp->lft.hard_use_expires_seconds = lifetime->sadb_lifetime_usetime;	}	if ((lifetime = ext_hdrs[SADB_EXT_LIFETIME_SOFT-1]) != NULL) {		xp->lft.soft_packet_limit = _KEY2X(lifetime->sadb_lifetime_allocations);		xp->lft.soft_byte_limit = _KEY2X(lifetime->sadb_lifetime_bytes);		xp->lft.soft_add_expires_seconds = lifetime->sadb_lifetime_addtime;		xp->lft.soft_use_expires_seconds = lifetime->sadb_lifetime_usetime;	}	xp->xfrm_nr = 0;	if (pol->sadb_x_policy_type == IPSEC_POLICY_IPSEC &&	    (err = parse_ipsecrequests(xp, pol)) < 0)		goto out;	out_skb = pfkey_xfrm_policy2msg_prep(xp);	if (IS_ERR(out_skb)) {		err =  PTR_ERR(out_skb);		goto out;	}	err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp,				 hdr->sadb_msg_type != SADB_X_SPDUPDATE);	if (err) {		kfree_skb(out_skb);		goto out;	}	pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1);	xfrm_pol_put(xp);	out_hdr = (struct sadb_msg *) out_skb->data;	out_hdr->sadb_msg_version = hdr->sadb_msg_version;	out_hdr->sadb_msg_type = hdr->sadb_msg_type;	out_hdr->sadb_msg_satype = 0;	out_hdr->sadb_msg_errno = 0;	out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;	out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk);	return 0;out:	kfree(xp);	return err;}static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs){	int err;	struct sadb_address *sa;	struct sadb_x_policy *pol;	struct xfrm_policy *xp;	struct sk_buff *out_skb;	struct sadb_msg *out_hdr;	struct xfrm_selector sel;	if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],				     ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||	    !ext_hdrs[SADB_X_EXT_POLICY-1])		return -EINVAL;	pol = ext_hdrs[SADB_X_EXT_POLICY-1];	if (!pol->sadb_x_policy_dir || pol->sadb_x_policy_dir >= IPSEC_DIR_MAX)		return -EINVAL;	memset(&sel, 0, sizeof(sel));	sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1], 	sel.family = pfkey_sadb_addr2xfrm_addr(sa, &sel.saddr);	sel.prefixlen_s = sa->sadb_address_prefixlen;	sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);	sel.sport = ((struct sockaddr_in *)(sa+1))->sin_port;	if (sel.sport)		sel.sport_mask = ~0;	sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1], 	pfkey_sadb_addr2xfrm_addr(sa, &sel.daddr);	sel.prefixlen_d = sa->sadb_address_prefixlen;	sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);	sel.dport = ((struct sockaddr_in *)(sa+1))->sin_port;	if (sel.dport)		sel.dport_mask = ~0;	xp = xfrm_policy_bysel(pol->sadb_x_policy_dir-1, &sel, 1);	if (xp == NULL)		return -ENOENT;	err = 0;	out_skb = pfkey_xfrm_policy2msg_prep(xp);	if (IS_ERR(out_skb)) {		err =  PTR_ERR(out_skb);		goto out;	}	pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1);	out_hdr = (struct sadb_msg *) out_skb->data;	out_hdr->sadb_msg_version = hdr->sadb_msg_version;	out_hdr->sadb_msg_type = SADB_X_SPDDELETE;	out_hdr->sadb_msg_satype = 0;	out_hdr->sadb_msg_errno = 0;	out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;	out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk);	err = 0;out:	xfrm_pol_put(xp);	return err;}static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs){	int err;	struct sadb_x_policy *pol;	struct xfrm_policy *xp;	struct sk_buff *out_skb;	struct sadb_msg *out_hdr;	if ((pol = ext_hdrs[SADB_X_EXT_POLICY-1]) == NULL)		return -EINVAL;	xp = xfrm_policy_byid(0, pol->sadb_x_policy_id,			      hdr->sadb_msg_type == SADB_X_SPDDELETE2);	if (xp == NULL)		return -ENOENT;	err = 0;	out_skb = pfkey_xfrm_policy2msg_prep(xp);	if (IS_ERR(out_skb)) {		err =  PTR_ERR(out_skb);		goto out;	}	pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1);	out_hdr = (struct sadb_msg *) out_skb->data;	out_hdr->sadb_msg_version = hdr->sadb_msg_version;	out_hdr->sadb_msg_type = hdr->sadb_msg_type;	out_hdr->sadb_msg_satype = 0;	out_hdr->sadb_msg_errno = 0;	out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;	out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk);	err = 0;out:	xfrm_pol_put(xp);	return err;}static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr){	struct pfkey_dump_data *data = ptr;	struct sk_buff *out_skb;	struct sadb_msg *out_hdr;	out_skb = pfkey_xfrm_policy2msg_prep(xp);	if (IS_ERR(out_skb))		return PTR_ERR(out_skb);	pfkey_xfrm_policy2msg(out_skb, xp, dir);	out_hdr = (struct sadb_msg *) out_skb->data;	out_hdr->sadb_msg_version = data->hdr->sadb_msg_version;	out_hdr->sadb_msg_type = SADB_X_SPDDUMP;	out_hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC;	out_hdr->sadb_msg_errno = 0;	out_hdr->sadb_msg_seq = count;	out_hdr->sadb_msg_pid = data->hdr->sadb_msg_pid;	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, data->sk);	return 0;}static int pfkey_spddump(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs){	struct pfkey_dump_data data = { .skb = skb, .hdr = hdr, .sk = sk };	return xfrm_policy_walk(dump_sp, &data);}static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs){	struct sk_buff *skb_out;	struct sadb_msg *hdr_out;	skb_out = alloc_skb(sizeof(struct sadb_msg) + 16, GFP_KERNEL);	if (!skb_out)		return -ENOBUFS;	xfrm_policy_flush();	hdr_out = (struct sadb_msg *) skb_put(skb_out, sizeof(struct sadb_msg));	pfkey_hdr_dup(hdr_out, hdr);	hdr_out->sadb_msg_errno = (uint8_t) 0;	hdr_out->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));	pfkey_broadcast(skb_out, GFP_KERNEL, BROADCAST_ALL, NULL);	return 0;}typedef int (*pfkey_handler)(struct sock *sk, struct sk_buff *skb,			     struct sadb_msg *hdr, void **ext_hdrs);static pfkey_handler pfkey_funcs[SADB_MAX + 1] = {	[SADB_RESERVED]		= pfkey_reserved,	[SADB_GETSPI]		= pfkey_getspi,	[SADB_UPDATE]		= pfkey_add,	[SADB_ADD]		= pfkey_add,	[SADB_DELETE]		= pfkey_delete,	[SADB_GET]		= pfkey_get,	[SADB_ACQUIRE]		= pfkey_acquire,	[SADB_REGISTER]		= pfkey_register,	[SADB_EXPIRE]		= NULL,	[SADB_FLUSH]		= pfkey_flush,	[SADB_DUMP]		= pfkey_dump,	[SADB_X_PROMISC]	= pfkey_promisc,	[SADB_X_PCHANGE]	= NULL,	[SADB_X_SPDUPDATE]	= pfkey_spdadd,	[SADB_X_SPDADD]		= pfkey_spdadd,	[SADB_X_SPDDELETE]	= pfkey_spddelete,	[SADB_X_SPDGET]		= pfkey_spdget,	[SADB_X_SPDACQUIRE]	= NULL,	[SADB_X_SPDDUMP]	= pfkey_spddump,	[SADB_X_SPDFLUSH]	= pfkey_spdflush,	[SADB_X_SPDSETIDX]	= pfkey_spdadd,	[SADB_X_SPDDELETE2]	= pfkey_spdget,};static int pfkey_process(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr){	void *ext_hdrs[SADB_EXT_MAX];	int err;	pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL,			BROADCAST_PROMISC_ONLY, NULL);	memset(ext_hdrs, 0, sizeof(ext_hdrs));	err = parse_exthdrs(skb, hdr, ext_hdrs);	if (!err) {		err = -EOPNOTSUPP;		if (pfkey_funcs[hdr->sadb_msg_type])			err = pfkey_funcs[hdr->sadb_msg_type](sk, skb, hdr, ext_hdrs);	}	return err;}static struct sadb_msg *pfkey_get_base_msg(struct sk_buff *skb, int *errp){	struct sadb_msg *hdr = NULL;	if (skb->len < sizeof(*hdr)) {		*errp = -EMSGSIZE;	} else {		hdr = (struct sadb_msg *) skb->data;		if (hdr->sadb_msg_version != PF_KEY_V2 ||		    hdr->sadb_msg_reserved != 0 ||		    (hdr->sadb_msg_type <= SADB_RESERVED ||		     hdr->sadb_msg_type > SADB_MAX)) {			hdr = NULL;			*errp = -EINVAL;		} else if (hdr->sadb_msg_len != (skb->len /						 sizeof(uint64_t)) ||			   hdr->sadb_msg_len < (sizeof(struct sadb_msg) /						sizeof(uint64_t))) {			hdr = NULL;			*errp = -EMSGSIZE;		} else {			*errp = 0;		}	}	return hdr;}static inline int aalg_tmpl_set(struct xfrm_tmpl *t, struct xfrm_algo_desc *d){	return t->aalgos & (1 << d->desc.sadb_alg_id);}static inline int ealg_tmpl_set(struct xfrm_tmpl *t, struct xfrm_algo_desc *d){	return t->ealgos & (1 << d->desc.sadb_alg_id);}static int count_ah_combs(struct xfrm_tmpl *t){	int i, sz = 0;	for (i = 0; ; i++) {		struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(i);		if (!aalg)			break;		if (aalg_tmpl_set(t, aalg) && aalg->available)			sz += sizeof(struct sadb_comb);	}	return sz + sizeof(struct sadb_prop);}static int count_esp_combs(struct xfrm_tmpl *t){	int i, k, sz = 0;	for (i = 0; ; i++) {		struct xfrm_algo_desc *ealg = xfrm_ealg_get_byidx(i);		if (!ealg)			break;					if (!(ealg_tmpl_set(t, ealg) && ealg->available))			continue;					for (k = 1; ; k++) {			struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(k);			if (!aalg)				break;							if (aalg_tmpl_set(t, aalg) && aalg->available)				sz += sizeof(struct sadb_comb);		}	}	return sz + sizeof(struct sadb_prop);}static void dump_ah_combs(struct sk_buff *skb, struct xfrm_tmpl *t){	struct sadb_prop *p;	int i;	p = (struct sadb_prop*)skb_put(skb, sizeof(struct sadb_prop));	p->sadb_prop_len = sizeof(struct sadb_prop)/8;	p->sadb_prop_exttype = SADB_EXT_PROPOSAL;	p->sadb_prop_replay = 32;	memset(p->sadb_prop_reserved, 0, sizeof(p->sadb_prop_reserved));	for (i = 0; ; i++) {		struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(i);		if (!aalg)			break;		if (aalg_tmpl_set(t, aalg) && aalg->available) {			struct sadb_comb *c;			c = (struct sadb_comb*)skb_put(skb, sizeof(struct sadb_comb));			memset(c, 0, sizeof(*c));			p->sadb_prop_len += sizeof(struct sadb_comb)/8;			c->sadb_comb_auth = aalg->desc.sadb_alg_id;			c->sadb_comb_auth_minbits = aalg->desc.sadb_alg_minbits;			c->sadb_comb_auth_maxbits = aalg->desc.sadb_alg_maxbits;			c->sadb_comb_hard_addtime = 24*60*60;			c->sadb_comb_soft_addtime = 20*60*60;			c->sadb_comb_hard_usetime = 8*60*60;			c->sadb_comb_soft_usetime = 7*60*60;		}	}}static void dump_esp_combs(struct sk_buff *skb, struct xfrm_tmpl *t){	struct sadb_prop *p;	int i, k;	p = (struct sadb_prop*)skb_put(skb, sizeof(struct sadb_prop));	p->sadb_prop_len = sizeof(struct sadb_prop)/8;	p->sadb_prop_exttype = SADB_EXT_PROPOSAL;	p->sadb_prop_replay = 32;	memset(p->sadb_prop_reserved, 0, sizeof(p->sadb_prop_reserved));	for (i=0; ; i++) {		struct xfrm_algo_desc *ealg = xfrm_ealg_get_byidx(i);		if (!ealg)			break;			if (!(ealg_tmpl_set(t, ealg) && ealg->available))			continue;					for (k = 1; ; k++) {			struct sadb_comb *c;			struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(k);			if (!aalg)				break;			if (!(aalg_tmpl_set(t, aalg) && aalg->available))				continue;			c = (struct sadb_comb*)skb_put(skb, sizeof(struct sadb_comb));			memset(c, 0, sizeof(*c));			p->sadb_prop_len += sizeof(struct sadb_comb)/8;			c->sadb_comb_auth = aalg->desc.sadb_alg_id;			c->sadb_comb_auth_minbits = aalg->desc.sadb_alg_minbits;			c->sadb_comb_auth_maxbits = aalg->desc.sadb_alg_maxbits;			c->sadb_comb_encrypt = ealg->desc.sadb_alg_id;			c->sadb_comb_encrypt_minbits = ealg->desc.sadb_alg_minbits;			c->sadb_comb_encrypt_maxbits = ealg->desc.sadb_alg_maxbits;			c->sadb_comb_hard_addtime = 24*60*60;			c->sadb_comb_soft_addtime = 20*60*60;			c->sadb_comb_hard_usetime = 8*60*60;			c->sadb_comb_soft_usetim

⌨️ 快捷键说明

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