Esempio n. 1
0
errno_t
ipf_inject_input(
	mbuf_t data,
	ipfilter_t filter_ref)
{
	struct mbuf	*m = (struct mbuf*)data;
	struct m_tag *mtag = 0;
	struct ip *ip = mtod(m, struct ip *);
	u_int8_t	vers;
	int hlen;
	errno_t error = 0;
	protocol_family_t proto;

	vers = IP_VHL_V(ip->ip_vhl);
	
	switch (vers) {
		case 4:
			proto = PF_INET;
			break;
		case 6:
			proto = PF_INET6;
			break;
		default:
			error = ENOTSUP;
			goto done;
	}
	
	if (filter_ref == 0 && m->m_pkthdr.rcvif == 0) {
		m->m_pkthdr.rcvif = lo_ifp;
		m->m_pkthdr.csum_data = 0;
		m->m_pkthdr.csum_flags = 0;
		if (vers == 4) {
			hlen = IP_VHL_HL(ip->ip_vhl) << 2;
			ip->ip_sum = 0;
			ip->ip_sum = in_cksum(m, hlen);
		}
	}
	if (filter_ref != 0) {
		mtag = m_tag_create(KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_IPFILT,
					 	   sizeof (ipfilter_t), M_NOWAIT, m);
		if (mtag == NULL) {
			error = ENOMEM;
			goto done;
		}	
		*(ipfilter_t*)(mtag+1) = filter_ref;
		m_tag_prepend(m, mtag);
	}
	
	error = proto_inject(proto, data);

done:
	return error;
}
Esempio n. 2
0
static errno_t
ipf_injectv4_out(mbuf_t data, ipfilter_t filter_ref, ipf_pktopts_t options)
{
	struct route ro;
	struct ip	*ip;
	struct mbuf	*m = (struct mbuf*)data;
	errno_t error = 0;
	struct m_tag *mtag = NULL;
	struct ip_moptions *imo = NULL;
	struct ip_out_args ipoa = { IFSCOPE_NONE, { 0 }, 0, 0 };

	/* Make the IP header contiguous in the mbuf */
	if ((size_t)m->m_len < sizeof (struct ip)) {
		m = m_pullup(m, sizeof (struct ip));
		if (m == NULL)
			return (ENOMEM);
	}
	ip = (struct ip *)m_mtod(m);

	if (filter_ref != 0) {
		mtag = m_tag_create(KERNEL_MODULE_TAG_ID,
		    KERNEL_TAG_TYPE_IPFILT, sizeof (ipfilter_t), M_NOWAIT, m);
		if (mtag == NULL) {
			m_freem(m);
			return (ENOMEM);
		}
		*(ipfilter_t *)(mtag + 1) = filter_ref;
		m_tag_prepend(m, mtag);
	}

	if (options != NULL && (options->ippo_flags & IPPOF_MCAST_OPTS) &&
	    (imo = ip_allocmoptions(M_DONTWAIT)) != NULL) {
		imo->imo_multicast_ifp = options->ippo_mcast_ifnet;
		imo->imo_multicast_ttl = options->ippo_mcast_ttl;
		imo->imo_multicast_loop = options->ippo_mcast_loop;
	}

	if (options != NULL) {
		if (options->ippo_flags & IPPOF_SELECT_SRCIF)
			ipoa.ipoa_flags |= IPOAF_SELECT_SRCIF;
		if (options->ippo_flags & IPPOF_BOUND_IF) {
			ipoa.ipoa_flags |= IPOAF_BOUND_IF;
			ipoa.ipoa_boundif = options->ippo_flags >>
			    IPPOF_SHIFT_IFSCOPE;
		}
		if (options->ippo_flags & IPPOF_NO_IFT_CELLULAR)
			ipoa.ipoa_flags |= IPOAF_NO_CELLULAR;
		if (options->ippo_flags & IPPOF_BOUND_SRCADDR)
			ipoa.ipoa_flags |= IPOAF_BOUND_SRCADDR;
	}
Esempio n. 3
0
static void
encap_fillarg(
	struct mbuf *m,
	const struct encaptab *ep)
{
	struct m_tag	*tag;
	struct encaptabtag *et;
	
	tag = m_tag_create(KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_ENCAP,
					  sizeof(struct encaptabtag), M_WAITOK, m);
	
	if (tag != NULL) {
		et = (struct encaptabtag*)(tag + 1);
		et->arg = ep->arg;
		m_tag_prepend(m, tag);
	}
}
Esempio n. 4
0
errno_t
mbuf_tag_allocate(
	mbuf_t			mbuf,
	mbuf_tag_id_t	id,
	mbuf_tag_type_t	type,
	size_t			length,
	mbuf_how_t		how,
	void**			data_p)
{
	struct m_tag *tag;
	u_int32_t mtag_id_first, mtag_id_last;

	if (data_p != NULL)
		*data_p = NULL;

	/* Sanity check parameters */
	(void) net_str_id_first_last(&mtag_id_first, &mtag_id_last,
	    NSI_MBUF_TAG);
	if (mbuf == NULL || (mbuf->m_flags & M_PKTHDR) == 0 ||
	    id < mtag_id_first || id > mtag_id_last || length < 1 ||
	    (length & 0xffff0000) != 0 || data_p == NULL) {
		return (EINVAL);
	}

	/* Make sure this mtag hasn't already been allocated */
	tag = m_tag_locate(mbuf, id, type, NULL);
	if (tag != NULL) {
		return (EEXIST);
	}

	/* Allocate an mtag */
	tag = m_tag_create(id, type, length, how, mbuf);
	if (tag == NULL) {
		return (how == M_WAITOK ? ENOMEM : EWOULDBLOCK);
	}

	/* Attach the mtag and set *data_p */
	m_tag_prepend(mbuf, tag);
	*data_p = tag + 1;

	return (0);
}
Esempio n. 5
0
errno_t
mbuf_add_drvaux(mbuf_t mbuf, mbuf_how_t how, u_int32_t family,
    u_int32_t subfamily, size_t length, void **data_p)
{
	struct m_drvaux_tag *p;
	struct m_tag *tag;

	if (mbuf == NULL || !(mbuf->m_flags & M_PKTHDR) ||
	    length == 0 || length > MBUF_DRVAUX_MAXLEN)
		return (EINVAL);

	if (data_p != NULL)
		*data_p = NULL;

	/* Check if one is already associated */
	if ((tag = m_tag_locate(mbuf, KERNEL_MODULE_TAG_ID,
	    KERNEL_TAG_TYPE_DRVAUX, NULL)) != NULL)
		return (EEXIST);

	/* Tag is (m_drvaux_tag + module specific data) */
	if ((tag = m_tag_create(KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_DRVAUX,
	    sizeof (*p) + length, how, mbuf)) == NULL)
		return ((how == MBUF_WAITOK) ? ENOMEM : EWOULDBLOCK);

	p = (struct m_drvaux_tag *)(tag + 1);
	p->da_family = family;
	p->da_subfamily = subfamily;
	p->da_length = length;

	/* Associate the tag */
	m_tag_prepend(mbuf, tag);

	if (data_p != NULL)
		*data_p = (p + 1);

	return (0);
}