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; }
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; }
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); } }
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); }
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); }