#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_pcb.h>
#include <netinet/ip_var.h>
#include <security/mac_internal.h>
static struct label *
mac_inpcb_label_alloc(int flag)
{
struct label *label;
int error;
label = mac_labelzone_alloc(flag);
if (label == NULL)
return (NULL);
MAC_CHECK(inpcb_label_init, label, flag);
if (error) {
MAC_PERFORM(inpcb_label_destroy, label);
mac_labelzone_free(label);
return (NULL);
}
return (label);
}
int
mac_inpcb_label_init(struct inpcb *inp, int flag)
{
inp->inp_label = mac_inpcb_label_alloc(flag);
if (inp->inp_label == NULL)
return (ENOMEM);
return (0);
}
static struct label *
mac_ipq_label_alloc(int flag)
{
struct label *label;
int error;
label = mac_labelzone_alloc(flag);
if (label == NULL)
return (NULL);
MAC_CHECK(ipq_label_init, label, flag);
if (error) {
MAC_PERFORM(ipq_label_destroy, label);
mac_labelzone_free(label);
return (NULL);
}
return (label);
}
int
mac_ipq_label_init(struct ipq *ipq, int flag)
{
ipq->ipq_label = mac_ipq_label_alloc(flag);
if (ipq->ipq_label == NULL)
return (ENOMEM);
return (0);
}
static void
mac_inpcb_label_free(struct label *label)
{
MAC_PERFORM(inpcb_label_destroy, label);
mac_labelzone_free(label);
}
void
mac_inpcb_label_destroy(struct inpcb *inp)
{
mac_inpcb_label_free(inp->inp_label);
inp->inp_label = NULL;
}
void
mac_inpcb_label_recycle(struct inpcb *inp)
{
MAC_PERFORM(inpcb_label_recycle, inp->inp_label);
}
static void
mac_ipq_label_free(struct label *label)
{
MAC_PERFORM(ipq_label_destroy, label);
mac_labelzone_free(label);
}
void
mac_ipq_label_destroy(struct ipq *ipq)
{
mac_ipq_label_free(ipq->ipq_label);
ipq->ipq_label = NULL;
}
void
mac_inpcb_label_associate(struct socket *so, struct inpcb *inp)
{
MAC_PERFORM(inpcb_label_associate, so, so->so_label, inp,
inp->inp_label);
}
void
mac_mbuf_label_associate_ipq(struct ipq *ipq, struct mbuf *m)
{
struct label *label;
label = mac_mbuf_to_label(m);
MAC_PERFORM(mbuf_label_associate_ipq, ipq, ipq->ipq_label, m, label);
}
void
mac_netinet_fragment(struct mbuf *datagram, struct mbuf *fragment)
{
struct label *datagramlabel, *fragmentlabel;
datagramlabel = mac_mbuf_to_label(datagram);
fragmentlabel = mac_mbuf_to_label(fragment);
MAC_PERFORM(netinet_fragment, datagram, datagramlabel, fragment,
fragmentlabel);
}
void
mac_ipq_label_associate(struct mbuf *fragment, struct ipq *ipq)
{
struct label *label;
label = mac_mbuf_to_label(fragment);
MAC_PERFORM(ipq_label_associate, fragment, label, ipq, ipq->ipq_label);
}
void
mac_mbuf_label_associate_inpcb(struct inpcb *inp, struct mbuf *m)
{
struct label *mlabel;
mlabel = mac_mbuf_to_label(m);
MAC_PERFORM(mbuf_label_associate_inpcb, inp, inp->inp_label, m, mlabel);
}
int
mac_ipq_label_compare(struct mbuf *fragment, struct ipq *ipq)
{
struct label *label;
int result;
label = mac_mbuf_to_label(fragment);
result = 1;
MAC_BOOLEAN(ipq_label_compare, &&, fragment, label, ipq, ipq->ipq_label);
return (result);
}
void
mac_netinet_icmp_reply(struct mbuf *m)
{
struct label *label;
label = mac_mbuf_to_label(m);
MAC_PERFORM(netinet_icmp_reply, m, label);
}
void
mac_netinet_tcp_reply(struct mbuf *m)
{
struct label *label;
label = mac_mbuf_to_label(m);
MAC_PERFORM(netinet_tcp_reply, m, label);
}
void
mac_ipq_label_update(struct mbuf *fragment, struct ipq *ipq)
{
struct label *label;
label = mac_mbuf_to_label(fragment);
MAC_PERFORM(ipq_label_update, fragment, label, ipq, ipq->ipq_label);
}
int
mac_inpcb_check_deliver(struct inpcb *inp, struct mbuf *m, int family, int type)
{
struct label *label;
int error;
if ((m->m_flags & M_PKTHDR) == 0)
panic("%s: no mbuf packet header!", __func__);
label = mac_mbuf_to_label(m);
MAC_CHECK(inpcb_check_deliver, inp, inp->inp_label, m, label,
family, type);
return (error);
}
void
mac_inpcb_label_update(struct socket *so)
{
struct inpcb *inp;
inp = sotoinpcb(so);
if (inp != NULL) {
MAC_PERFORM(inpcb_label_update, so, so->so_label, inp,
inp->inp_label);
}
}